LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY Interf IS -- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! PORT ( CLK : IN STD_LOGIC; DATA_GEN : IN STD_LOGIC_VECTOR(7 downto 0); FRAMEn : IN STD_LOGIC; IRDYn : IN STD_LOGIC; CBEn : IN STD_LOGIC_VECTOR(3 downto 0); IDSEL : IN STD_LOGIC; RSTn : IN STD_LOGIC; RST : OUT STD_LOGIC; GEN : OUT STD_LOGIC; DEVSELn : OUT STD_LOGIC; TRDYn : OUT STD_LOGIC; STOPn : OUT STD_LOGIC; OUT1 : OUT STD_LOGIC_VECTOR(31 downto 0); OUT2 : OUT STD_LOGIC_VECTOR(3 downto 0); AD1 : INOUT STD_LOGIC_VECTOR(31 downto 0); PAR : INOUT STD_LOGIC ); -- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! END Interf; ARCHITECTURE Interf_architecture OF Interf IS --Функция проверки чётности. Возвращает "1", если количество 1 не чётное и "0", если чётное. function PARITY (X : std_logic_vector) return std_ulogic is variable TMP : std_logic := '0'; begin for J in X'range loop TMP := TMP xor X(J); end loop; return TMP; end PARITY; --++++++++ --Функция декодирования адреса 32-разрядного регистра в пространстве конфигурации function DECODER (X : std_logic_vector(5 downto 0)) return natural is begin case X is when "000000" => return 0; when "000001" => return 1; when "000010" => return 2; when "000011" => return 3; when "000100" => return 4; when "000101" => return 5; when "000110" => return 6; when "000111" => return 7; when "001000" => return 8; when "001001" => return 9; when "001010" => return 10; when "001011" => return 11; when "001100" => return 12; when "001101" => return 13; when "001110" => return 14; when "001111" => return 15; when "010000" => return 16; when others => return 17; end case; end DECODER; --+++++++++ CONSTANT ZST : std_logic_vector (31 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; CONSTANT NUL : std_logic_vector (31 downto 0) := "00000000000000000000000000000000"; --Пространство конфигурации type DWORD is array (0 to 17) of std_logic_vector(31 downto 0); CONSTANT Vendor_ID : std_logic_vector (15 downto 0) :="0000000000011010"; CONSTANT Device_ID : std_logic_vector (15 downto 0) :="1111000000011010"; SHARED VARIABLE STATUS : std_logic_vector (15 downto 0) :="0000000000000000"; CONSTANT COMAND : std_logic_vector (15 downto 0) :="0000000000000001"; CONSTANT Class_code : std_logic_vector (23 downto 0) :="111111110000000000000000"; CONSTANT Revision_ID : std_logic_vector (7 downto 0) :="00000000"; CONSTANT BIST : std_logic_vector (7 downto 0) :="00000000"; CONSTANT Header_type : std_logic_vector (7 downto 0) :="00000000"; CONSTANT Latency_timer : std_logic_vector (7 downto 0) :="00000000"; CONSTANT Cache_line_Size : std_logic_vector (7 downto 0) :="00000000"; SHARED VARIABLE BAR : std_logic_vector (31 downto 0) := "00000000000000000000000000001001"; CONSTANT MAX_LAT : std_logic_vector (7 downto 0) :="00000000"; CONSTANT MIN_GNT : std_logic_vector (7 downto 0) :="00000000"; CONSTANT Interrupt_Pin : std_logic_vector (7 downto 0) :="00000000"; CONSTANT Interrupt_Line : std_logic_vector (7 downto 0) :="11111111"; CONSTANT ELSE_REG : std_logic_vector (31 downto 0) :=NUL; signal CNF : DWORD:= ( 0 => (Vendor_ID & Device_ID), 1 => (STATUS & COMAND), 2 => (Class_code & Revision_ID), 3 => (BIST & Header_type & Latency_timer & Cache_line_size), 4 => BAR, 16 => (MAX_LAT & MIN_GNT & Interrupt_Pin & Interrupt_Line), others => ELSE_REG ); --+++++++++ type state is (IDLE,B_BUSY,S_DATA,BACKOFF,CONF_WR,CONF_RD); signal STAT : STATE:=IDLE; signal nxt_stat : STATE:=IDLE; signal RD_TX :STD_LOGIC:='0'; --Read transaction signal signal CNF_RD :STD_LOGIC:='0'; --Configuration read transaction signal signal CNF_WR :STD_LOGIC:='0'; --Configuration write transaction signal signal NOT_WE :STD_LOGIC:='0'; --Other divace address signal signal DONE :STD_LOGIC:='1'; --Transaction done signal signal OTHER_CMD :STD_LOGIC:='0'; signal ADDR : STD_LOGIC_VECTOR(5 downto 0):="000000"; --Адрес 32-разрядного регистра в пространстве конфигурации --signal DATA_G : std_logic_vector (7 downto 0):="00110011"; --shared variable G : BIT:='1'; shared variable CMD : std_logic_vector(3 downto 0):="0000"; shared variable ADR : std_logic_vector(31 downto 0):=BAR; BEGIN --********************** --*NEXT_STATE_GENERATOR* --********************** Process(CLK,RSTn) begin if ( RSTn = '0' ) then STAT<=IDLE; RST<='1'; elsif(CLK'event and CLK='1') then STAT<=nxt_stat; RST<='0'; end if; end process; --************************** --*STATE_mashine_controller* --************************** process(NOT_WE,CNF_WR,CNF_RD,DONE,OTHER_CMD) begin case STAT is when IDLE => if (NOT_WE='0') then if CBEn="0010" then nxt_stat<=S_DATA; else nxt_stat<=BACKOFF; end if; elsif (CNF_RD='1') then nxt_stat<=CONF_RD; elsif (CNF_WR='1') then nxt_stat<=CONF_WR; elsif (OTHER_CMD='1') then nxt_stat<=BACKOFF; elsif (DONE='0') then nxt_stat<=B_BUSY; else nxt_stat<=IDLE; end if; --READ when S_DATA => if (DONE='1') then nxt_stat<=IDLE; else nxt_stat<=S_DATA; end if; --Configuration Read when CONF_RD => if (DONE='1') then nxt_stat<=IDLE; else nxt_stat<=CONF_RD; end if; --Configuration write when CONF_WR => if (DONE='1') then nxt_stat<=IDLE; else nxt_stat<=CONF_WR; end if; --Bus busy when B_BUSY => if (DONE='1') then nxt_stat<=IDLE; else nxt_stat<=B_BUSY; end if; --Not supported comand when BACKOFF => if (DONE='1') then nxt_stat<=IDLE; else nxt_stat<=BACKOFF; end if; when OTHERS => nxt_stat<=IDLE; end case; end process; --********* --*SIGNALS* --********* NOT_WE <= '0' when (FRAMEn='0' and AD1=ADR ) else '1' when (DONE='0') else 'Z'; --Не распознан адрес RD_TX <= '1' when (FRAMEn='0' and CNF(4)=AD1) else '0'; --Транзакция чтения данных and CBEn="0010" CNF_RD <= '1' when (FRAMEn='0' and IDSEL='1' and CBEn="1010") else '0'; --Транзакция чтения конфигурации CNF_WR <= '1' when (FRAMEn='0' and IDSEL='1' and CBEn="1011") else '0'; --Транзакция записи конфигурации DONE <= '1' when (FRAMEn='1' and IRDYn='1') else '0'; --Транзакция Закончена GEN <= '1' when (nxt_stat=S_DATA) else '0'; --Запрос генератору на ПСП --Сохранение адреса читаемого регистра в пространстве конфигурации Process(CNF_RD) begin if (CNF_RD'event and CNF_RD='1') then ADDR <= AD1(7 downto 2); end if; end process; --Сохранение адреса устройства в регистр адреса в пространстве конфигурации Process(CNF_WR) begin if (CNF_WR'event and CNF_WR='0') then ADR:= AD1(31 downto 2)&"01" ; end if; end process; OUT1<=ADR; OUT2(0)<=NOT_WE; OUT2(1)<=RD_TX; ---NEED!! OUT2(2)<=CNF_RD; ---NEED!! OUT2(3)<=CNF_WR; MAIN:PROCESS(STAT) --************ --*PROCEDURES* --************ --Чтение данных Procedure DATA_READ is begin DEVSELn <='0'; STOPn <='1'; TRDYn <='0'; PAR <= PARITY(DATA_GEN) XOR PARITY(CBEn); AD1(7 downto 0) <= DATA_GEN; AD1(31 downto 8) <="000000000000000000000000"; end DATA_READ; --Состояние ожидания Procedure IDLE_PRC is begin DEVSELn <='Z'; STOPn <='Z'; TRDYn <='Z'; PAR <='Z'; AD1 <=ZST; end IDLE_PRC; --Неспособность обработать данную команду Procedure BACKOFF_PRC is begin DEVSELn <='1'; STOPn <='0'; TRDYn <='1'; PAR <='Z'; AD1 <=ZST; end BACKOFF_PRC; --Чтение пространства конфигурации Procedure CONF_READ is begin DEVSELn <='0'; STOPn <='1'; TRDYn <='0'; if (DECODER(ADDR)=4) then PAR <= PARITY(ADR) XOR PARITY(CBEn); AD1 <= ADR; else PAR <= PARITY(CNF(DECODER(ADDR))) XOR PARITY(CBEn); AD1 <= CNF(DECODER(ADDR)); end if; end CONF_READ; --Запись в пространство конфигурации (BAR) Procedure CONF_WRITE is begin DEVSELn <='0'; STOPn <='1'; TRDYn <='0'; PAR <='Z'; end CONF_WRITE; --************** --*MAIN_PROCESS* --************** begin case STAT is when S_DATA => DATA_READ; when IDLE => IDLE_PRC; when CONF_WR => CONF_WRITE; when CONF_RD => CONF_READ; when BACKOFF => BACKOFF_PRC; when others => IDLE_PRC; end case; end process MAIN; END Interf_architecture;