ENTITY fifo IS PORT( --INPUT reset : IN STD_LOGIC ; --Global reset signal txclk : IN STD_LOGIC ; --Transmission clock rxclk : IN STD_LOGIC ; --Receive clock rxer : IN STD_LOGIC ; --Receive error rxdv : IN STD_LOGIC ; --Receive data valid rxd : IN STD_LOGIC_VECTOR(3 downto 0) ; --Receive data --OUTPUT txd : OUT STD_LOGIC_VECTOR(3 downto 0) ; --Transmission data txen : OUT STD_LOGIC ; --Transmission data enable txer : OUT STD_LOGIC --Transmission error ); END fifo;
ARCHITECTURE behavior OF fifo IS SIGNAL in_sel : STD_LOGIC_VECTOR(1 downto 0) ; --Write buffer pointer SIGNAL out_sel : STD_LOGIC_VECTOR(1 downto 0) ; --Read buffer pointer SIGNAL dff_0 : STD_LOGIC_VECTOR(4 downto 0) ; --Buffer 0 SIGNAL dff_1 : STD_LOGIC_VECTOR(4 downto 0) ; --Buffer 1 SIGNAL dff_2 : STD_LOGIC_VECTOR(4 downto 0) ; --Buffer 2 SIGNAL dff_3 : STD_LOGIC_VECTOR(4 downto 0) ; --Buffer 3 SIGNAL reset_rx : STD_LOGIC ; --Data Input Enable SIGNAL reset_tx : STD_LOGIC ; --Data Output Enable BEGIN
--//////////////////////////////////// -- -- Input data to the fifo -- --////////////////////////////////////
inputs: PROCESS(rxclk, reset_rx) BEGIN if( reset = '0')then --Global reset ; in_sel <= "00"; dff_0 <= "00000" ; dff_1 <= "00000" ; dff_2 <= "00000" ; dff_3 <= "00000" ; elsif(rxclk'EVENT AND rxclk = '1')THEN --Synchronize the rising edge of the rxclk ; IF(reset_rx = '0' ) THEN --No data need to write ; if(reset_tx = '0')then --No data in fifo ; in_sel <= "00"; --Reset the write-pointer; dff_0 <= "00000"; --Set the buffer to zero ; dff_1 <= "00000"; dff_2 <= "00000"; dff_3 <= "00000"; ELSE --Valid data still in the fifo; IF(in_sel = "00")THEN dff_0 <= "00000"; --Set the present buffer to zero and in_sel <= "01"; --Move the write-pointer to next buffer ; elsif(in_sel = "01")THEN dff_1 <= "00000"; in_sel <= "10"; elsif(in_sel = "10")THEN dff_2 <= "00000"; in_sel<= "11"; elsif(in_sel = "11")THEN dff_3 <= "00000"; in_sel <= "00"; END IF; END IF; ELSE --Want to write data into the fifo ; IF(in_sel = "00")THEN --when write-pointer in_sel is "00" ; dff_0 <= rxd & rxdv; --Load data into dff_0 in_sel <= "01"; --Move the write-pointer the next buffer ; elsif(in_sel = "01")THEN dff_1 <= rxd & rxdv; in_sel <= "10"; elsif(in_sel = "10")THEN dff_2 <= rxd & rxdv; in_sel <= "11"; elsif(in_sel = "11")THEN dff_3 <= rxd & rxdv; in_sel <= "00"; END IF; END IF; END IF; END PROCESS;
--//////////////////////////////////// -- -- Output data from the fifo -- --////////////////////////////////////
outputs: PROCESS(txclk, reset_tx) BEGIN if(reset = '0')then --Global reset ; txd <="0000"; out_sel <= "10"; elsif(txclk'EVENT AND txclk = '0')THEN --Synchronize the falling edge of the txclk ; IF(reset_tx = '0') THEN --Do not need to read data from fifo ; txd <= "0000"; --Reset state & pointer for next packet ; out_sel <= "10"; ELSE IF(out_sel = "00")THEN --When read-pointer out_sel is "00" txd <= dff_0(4 downto 1); --Read the data from buffer dff_0 ; --txer <= dff_b(1); txen <= dff_0(0); out_sel <= "01"; --Move the pointer to next buffer; elsif(out_sel = "01")then txd <= dff_1(4 downto 1); --txer <= dff_a(1); txen <= dff_1(0); out_sel <= "10"; elsif(out_sel = "10")then txd <= dff_2(4 downto 1); --txer <= dff_a(1); txen <= dff_2(0); out_sel <= "11"; elsif(out_sel = "11")then txd <= dff_3(4 downto 1); --txer <= dff_a(1); txen <= dff_3(0); out_sel <= "00"; END IF; END IF; END IF; END PROCESS;
--/////////////////////////////////////////////// -- -- Data Input Enable reset_rx generation -- --///////////////////////////////////////////////
reset_rx_gen: PROCESS(rxclk, rxdv) BEGIN if(reset = '0')then --Global reset ; reset_rx <= '0'; elsif(reset_rx = '0')THEN --When do not need to write data to the buffer ; reset_rx <= rxdv; --Asynchronous set... setup before the rising edge else if(rxclk'EVENT AND rxclk = '1')THEN --When need to write data to the buffer and -- IF(reset_rx = '1')THEN reset_rx <= rxdv; --Synchronous clear -- END IF; END IF; END IF; END PROCESS;
--//////////////////////////////////////////////// -- -- Data Output Enable reset_tx generation -- --//////////////////////////////////////////////// reset_tx_gen: PROCESS(txclk, rxdv) BEGIN if(reset = '0')then --Global reset ; reset_tx <= '0'; elsif(txclk'EVENT AND txclk = '0')THEN --Synchronize the falling edge of the txclk ; reset_tx <= rxdv OR dff_0(0) OR dff_1(0) OR dff_2(0) OR dff_3(0) ; END IF; --Setting the read-flag to true When valid data in the buffer END PROCESS;
用户1487752 2011-5-14 22:16
用户120337 2011-5-14 18:48
用户1471583 2009-7-19 13:13
用户124183 2009-7-11 11:34
用户212292 2009-7-6 21:15