📄 pci_144.vhd
字号:
-- PCI Target Interface Design for XC73144 ---- Synopsys VHDL Solution using Xilinx XC7000 Library --library IEEE, xc7000;use IEEE.STD_LOGIC_1164.all;use IEEE.STD_LOGIC_misc.all;use IEEE.STD_LOGIC_arith.all;use IEEE.STD_LOGIC_UNSIGNED.all;use IEEE.STD_LOGIC_components.all;use xc7000.components.all;entity pci_144 is port ( -- PCI bus signals -- CLK : in bit; FRAMEI, IRDYI, IDSELI : in boolean; TRDY, STOP : inout std_logic; DEVSEL : buffer std_logic; AD : inout std_logic_vector (31 downto 0); CBE : inout std_logic_vector (3 downto 0); -- Target interface signals -- TERM,READY,T_ABORT,TAR_DLY : in boolean; T_AD : inout std_logic_vector (31 downto 0); T_CBE : inout std_logic_vector (3 downto 0); S0, S1 : buffer std_logic; -- registers -- RD_WR, MEM_EN : buffer boolean; -- registers -- PAR_OE, PERR_OE : out boolean -- registers -- );end pci_144;architecture BEHAVIOR of pci_144 is-- Internal signals -- -- PCI AD bus output register -- signal PCI_AD_BUS : std_logic_vector (31 downto 0); -- PCI AD bus input register -- signal PCI_AD_REG : std_logic_vector (31 downto 0); signal ADI0, ADI1 : boolean; -- Target AD bus output register -- signal T_AD_BUS : std_logic_vector (31 downto 0); -- PCI CBE bus output register -- signal PCI_CBE : std_logic_vector (3 downto 0); -- PCI CBE bus input register -- signal PCI_CBE_REG : std_logic_vector (3 downto 0); -- Target CBE bus output register -- signal T_CBE_BUS : std_logic_vector (3 downto 0); signal BASE_AD_REG : std_logic_vector (31 downto 24); -- register -- signal NODE_CFG_04h, NODE_CFG_10h, HIT, MATCH : boolean; signal CFGQ : std_logic_vector (7 downto 2); -- register -- signal BURST, LOAD : boolean; signal FRAME, IRDY, IDSEL : boolean; -- registers -- signal TRDY_REG, STOP_REG : std_logic; signal DEVSEL_REG : std_logic; signal CFG_WR : boolean; -- registers -- signal TRDY_OE, AD_OE, T_AD_OE : boolean; -- registers -- signal DEVSEL_VAL, TRDY_VAL, STOP_VAL : boolean; signal COMMAND_TYPE : std_logic_vector (3 downto 1); signal IO_SPACE, MEMORY_SPACE, CONFIG_SPACE, MEMORY_MULT, MEMORY_CACHE : boolean; type TARGET_TYPE is (IDLE_STATE, B_BUSY_STATE, S_DATA_STATE, TURN_AR_STATE, BACKOFF_STATE); signal TARGET_SEQ : TARGET_TYPE; -- state register signal IDLE, B_BUSY, S_DATA, TURN_AR, BACKOFF : boolean; -- state decoders -- PCI Bus Command Encoding -- constant IO_SPACE_CMD : std_logic_vector (3 downto 1) := "001"; constant MEMORY_SPACE_CMD : std_logic_vector (3 downto 1) := "011"; constant CONFIG_SPACE_CMD : std_logic_vector (3 downto 1) := "101"; constant MEMORY_MULT_CMD : std_logic_vector (3 downto 1) := "110"; constant MEMORY_CACHE_CMD : std_logic_vector (3 downto 1) := "111";-- Re-declare attribute cells with boolean ports -- component f port (I : in boolean); end component; component opt_off port (I : in boolean); end component;begin-- XEPLD fitter attributes -- XU1: f port map (IRDY); XU2: f port map (FRAME); XU3: opt_off port map (HIT); XU5: opt_off port map (NODE_CFG_04h); XU6: opt_off port map (NODE_CFG_10h);-- PCI bus to Target interface data path ---- Target interface passes address and data transfers synchronously-- through interface. DATA_PATH: process begin wait until (CLK'event and CLK = '1'); PCI_AD_BUS <= T_AD; PCI_AD_REG <= AD; ADI0 <= (PCI_AD_REG(0) = '1'); ADI1 <= (PCI_AD_REG(1) = '1'); T_AD_BUS <= PCI_AD_REG; PCI_CBE <= T_CBE; PCI_CBE_REG <= CBE; T_CBE_BUS <= PCI_CBE_REG; FRAME <= FRAMEI; IRDY <= IRDYI; IDSEL <= IDSELI; end process; AD <= PCI_AD_BUS when AD_OE else "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; CBE <= PCI_CBE when AD_OE else "ZZZZ"; T_AD <= T_AD_BUS when T_AD_OE else "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; T_CBE <= T_CBE_BUS when T_AD_OE else "ZZZZ";-- Configuration base address register and address comparator for-- Target interface NODE_CFG_10h <= (CFGQ = "000100"); NODE_CFG_04h <= (CFGQ = "000001"); HIT <= (MATCH and MEM_EN); MATCH <= (PCI_AD_REG (31 downto 24) = BASE_AD_REG); -- 8-bit equality comparator -- BURST <= S_DATA and not IRDY and not TRDY_VAL; LOAD <= not FRAME and IDSEL and CONFIG_SPACE;-- Configuration space address counter with and parallel load -- process (CLK) begin if (CLK'event and CLK='1') then if (LOAD) then CFGQ <= PCI_AD_REG(7 downto 2); -- Counter parallel load -- elsif (BURST) then CFGQ <= CFGQ + 1; -- Counter increment -- end if; end if; end process; BASE_ADDR: process begin wait until (CLK'event and CLK = '1'); if (NODE_CFG_10h and CFG_WR) then BASE_AD_REG <= PCI_AD_REG (31 downto 24); end if; if (NODE_CFG_04h and CFG_WR) then MEM_EN <= ADI1; end if; if (IDSEL and CONFIG_SPACE and not ADI1 and not ADI0) then CFG_WR <= ADI1; end if; end process;-- Target Interface State Machine -- TARGET: process begin wait until (CLK'event and CLK = '1'); case TARGET_SEQ is-- IDLE -- Idle condition. when IDLE_STATE => if (not FRAME) then if (not HIT) then TARGET_SEQ <= B_BUSY_STATE; elsif ( (IDSEL and CONFIG_SPACE and not ADI1 and not ADI0) or (HIT and MEMORY_SPACE and not ADI1 and not ADI0) or (HIT and MEMORY_MULT and not ADI1 and not ADI0) ) then TARGET_SEQ <= S_DATA_STATE; else TARGET_SEQ <= BACKOFF_STATE; end if; end if;-- B_BUSY -- Agent not involved in current transaction. when B_BUSY_STATE => if (FRAME) then TARGET_SEQ <= IDLE_STATE; elsif (IRDY or HIT) then if (not IRDY and HIT and (not TERM or READY)) then TARGET_SEQ <= S_DATA_STATE; else TARGET_SEQ <= BACKOFF_STATE; end if; end if;-- S_DATA -- Agent has accepted request and will respond. when S_DATA_STATE => if (FRAME and (not TRDY_VAL or not STOP_VAL)) then TARGET_SEQ <= TURN_AR_STATE; elsif (not STOP_VAL and (TRDY_VAL or not IRDY)) then TARGET_SEQ <= BACKOFF_STATE; end if;-- TURN_AR -- Completed transaction on bus. when TURN_AR_STATE => if (FRAME) then TARGET_SEQ <= IDLE_STATE; elsif (not HIT) then TARGET_SEQ <= B_BUSY_STATE; elsif (not TERM or READY) then TARGET_SEQ <= S_DATA_STATE; else TARGET_SEQ <= BACKOFF_STATE; end if;-- BACKOFF -- Agent busy, unable to respond at this time. when BACKOFF_STATE => if (FRAME) then TARGET_SEQ <= TURN_AR_STATE; end if; end case; end process; IDLE <= (TARGET_SEQ = IDLE_STATE); B_BUSY <= (TARGET_SEQ = B_BUSY_STATE); S_DATA <= (TARGET_SEQ = S_DATA_STATE); TURN_AR <= (TARGET_SEQ = TURN_AR_STATE); BACKOFF <= (TARGET_SEQ = BACKOFF_STATE);-- DEVSEL is asserted from address hit until either TURN_AR or T_ABORT is -- asserted by the Target agent. DEVSEL <= 'Z' when (not TRDY_OE) else DEVSEL_REG;DEVSEL_VAL <= (DEVSEL = '1');-- Target agent ready to complete current data trasaction.-- TRDY is asserted while the Target transfers data (S_DATA)-- and remains asserted while READY asserted and T_ABORT de-asserted. TRDY <= 'Z' when (not TRDY_OE) else TRDY_REG; TRDY_VAL <= (TRDY = '1');-- Target requests Master to stop the current transaction.-- STOP is asserted in response to T_ABORT -- and remains asserted until entering TURN_AR. STOP <= 'Z' when (not TRDY_OE) else STOP_REG; STOP_VAL <= (STOP = '1');CONTROL : process begin wait until (CLK'event and CLK = '1'); if (not ((IDLE and not FRAME and CONFIG_SPACE and not ADI1 and not ADI0) or (IDLE and not FRAME and MEMORY_SPACE and not ADI1 and not ADI0) or (IDLE and not FRAME and MEMORY_MULT and not ADI1 and not ADI0) or (S_DATA and ((not IRDY) or (not TRDY_VAL) or (FRAME)) and T_ABORT) or (BACKOFF and FRAME and DEVSEL_VAL))) then DEVSEL_REG <= '1' ; else DEVSEL_REG <= '0'; end if; if (not ((BACKOFF) or (S_DATA and (T_ABORT or TERM) and TAR_DLY))) then STOP_REG <= '1'; else STOP_REG <= '0'; end if; if (not (S_DATA and (not IRDY or not TRDY_VAL) and READY and not T_ABORT and not TAR_DLY)) then TRDY_REG <= '1'; else TRDY_REG <= '0'; end if; end process;-- PCI Bus Command Decoder COMMAND_TYPE <= PCI_CBE_REG (3 downto 1); IO_SPACE <= (COMMAND_TYPE = IO_SPACE_CMD); MEMORY_SPACE <= (COMMAND_TYPE = MEMORY_SPACE_CMD); CONFIG_SPACE <= (COMMAND_TYPE = CONFIG_SPACE_CMD); MEMORY_MULT <= (COMMAND_TYPE = MEMORY_MULT_CMD); MEMORY_CACHE <= (COMMAND_TYPE = MEMORY_CACHE_CMD); OE: process begin wait until (CLK'event and CLK = '1'); TRDY_OE <= BACKOFF or S_DATA or TURN_AR; AD_OE <= S_DATA and TAR_DLY and RD_WR; T_AD_OE <= (IDLE and FRAME and RD_WR and (AD(1 downto 0) = "00")) or (HIT and not RD_WR) or (S_DATA and not RD_WR and not T_ABORT); if (IDLE) then RD_WR <= (CBE(0) = '0'); end if; if (not S_DATA) then S0 <= '0'; S1 <= '0'; if (IDLE and not FRAME) then if (MEMORY_SPACE or MEMORY_MULT or MEMORY_CACHE) then S0 <= '1'; end if; if (IO_SPACE) then S1 <= '1'; end if; end if; end if; PAR_OE <= S_DATA and not TRDY_VAL and RD_WR; PERR_OE <= not IRDY and not RD_WR; end process;end BEHAVIOR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -