📄 i8255a.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY i8255A IS
PORT(
RESET,CS,WR,RD:IN STD_LOGIC;
AD:STD_LOGIC_VECTOR(1 downto 0);--地址线的低两位
Data,PA,PB:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);--Data CPU 总线
pch,pcl:INOUT STD_LOGIC_VECTOR(3 DOWNTO 0);
SA,SB,SCh,SCl:OUT STD_LOGIC);--只是为了测试验证而设置--各端口状态寄存器值--
END i8255A;
ARCHITECTURE my_arch OF i8255A IS
--port state constants
CONSTANT psIn: STD_LOGIC:='1';
CONSTANT psOut: STD_LOGIC:='0';
----端口状态寄存器
SIGNAL StateA,StateB,StateCLo,StateCHi: STD_LOGIC;
----端口输出数据寄存器--------
SIGNAL RegAOut,RegBOut: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RegCHiOut,RegCLoOut: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
SA<=StateA;
SB<=StateB;
SCh<=StateCHi;
SCl<=StateCLo;
-----响应置端口状态指令,改变端口状态寄存器
PROCESSChangeState:
PROCESS (RESET,WR)
BEGIN
if reset='1' then
StateA<=psIn; StateB<=psIn;
StateCHi<=psIn;StateCLo<=psIn;
elsif rising_edge(wr) then
if AD="11" and Data(7)='1' and CS='0' then
StateA<=Data(4);StateCHi<=Data(3);
StateB<=Data(1);StateCLo<=Data(0);
end if;
end if;
end process ProcessChangeState;
------应答读端口指令,向CPU总线写端口寄存器的数据----
ProcessDataToCPU:
PROCESS (RD,CS,ad,StateA,StateB,StateCHi,StateCLo,PA,PB,pch,pcl)
BEGIN
if RD='0' and CS='0' then
CASE (ad) is
when "00"=>
if StateA<=psIn then Data<= PA;
else Data<= RegAOut;
end if;
when "01"=>
if StateB<=psIn then Data<= PB;
else Data<= RegBOut;
end if;
when "10"=>
if StateCHi<=psIn then Data(7 downto 4)<= pch;
else Data(7 downto 4)<= RegCHiOut;
end if;
if StateCLo<=psIn then Data(3 downto 0)<= pcl;
else Data(3 downto 0)<= RegCLoOut;
end if;
when others =>
null;
end case;
else Data<="ZZZZZZZZ";
end if ;
end process ProcessDataToCPU;
----响应写端口指令,从CPU总线获取数据并写往相应的端口寄存器----
ProcessDataFromBus:
PROCESS (WR,reset)
BEGIN
if reset='1' then
RegAOut<="00000000";
RegBOut<="00000000";
RegCHiOut<="0000";
RegCLoOut<="0000";
elsif rising_edge(wr) then
if CS='0' THEN
CASE (ad) is
when "00"=>
if StateA<=psOut then RegAOut<= Data;
end if;
when "01"=>
if StateB<=psOut then RegBOut<= Data;
end if;
when "10"=>
if StateCHi<=psOut then RegCHiOut<= Data(7 downto 4);
end if;
if StateCLo<=psOut then RegCLoOut<= Data(3 downto 0);
end if;
when "11"=>
if Data(7)='0' then
case Data(3 downto 0) is
when "0000" => RegCLoOut(0)<='0';
when "0010" => RegCLoOut(1)<='0';
when "0100" => RegCLoOut(2)<='0';
when "0110" => RegCLoOut(3)<='0';
when "1000" => RegCHiOut(0)<='0';
when "1010" => RegCHiOut(1)<='0';
when "1100"=> RegCHiOut(2)<='0';
when "1110" => RegCHiOut(3)<='0';
when "0001" => RegCLoOut(0)<='0';
when "0011" => RegCLoOut(1)<='0';
when "0101" => RegCLoOut(2)<='0';
when "0111" => RegCLoOut(3)<='0';
when "1001" => RegCHiOut(0)<='0';
when "1011" => RegCHiOut(1)<='0';
when "1101"=> RegCHiOut(2)<='0';
when "1111" => RegCHiOut(3)<='0';
when others =>
null;
end case;
end if;
when others =>
null;
end case;
end if;
end if ;
end PROCESS ProcessDataFromBus ;
---- 实现对端口输出数据-------------------
ProcessOnRegAOutChange:
process (StateA,RegAOut)
begin
if StateA=psOut then PA<=RegAOut;
else PA<="ZZZZZZZZ";
end if;
end process ProcessOnRegAOutChange;
ProcessOnRegBOutChange:
process (StateB,RegBOut)
begin
if StateB=psOut then PB<=RegBOut;
else PB<="ZZZZZZZZ";
end if;
end process ProcessOnRegBOutChange;
ProcessOnRegCOutChange:
process (StateCHi,StateCLo,RegCHiOut,RegCLoOut)
begin
if StateCHi=psOut then PCh<=RegCHiOut;
else PCh<="ZZZZ";
end if;
if StateCLo=psOut then PCl<=RegCLoOut;
else PCl<="ZZZZ";
end if;
end process ProcessOnRegCOutChange;
END my_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -