From 0b2f2ea1c9aca423c4a2fbdb21aaa0fde0344cd7 Mon Sep 17 00:00:00 2001 From: hadaq Date: Fri, 25 Jun 2010 15:36:33 +0000 Subject: [PATCH] bug fixed version of sbuf5: new statemachine handles (hopefully, keep fingers crossed) all FIFO fill levels correctly now, independent of the data stream timing on the input. --- trb_net_sbuf5.vhd | 72 +++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/trb_net_sbuf5.vhd b/trb_net_sbuf5.vhd index 0abf500..75cc0f0 100644 --- a/trb_net_sbuf5.vhd +++ b/trb_net_sbuf5.vhd @@ -1,3 +1,10 @@ +-- sbuf5: sends only full packets. +-- This version is optimized for safety, not speed. +-- Speed can be gained by "looking ahead" on the write side of FIFO, especially by +-- monitoring the comb_dataready_in signal to gain one clock cycle. +-- If optimizing is needed, be careful: RD5 state needs to be handled correctly, +-- as it can easily end up in scrambled data and loads of problems in the network. +-- 25.06.2010 MB LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; @@ -20,7 +27,7 @@ port( COMB_DATA_IN : in std_logic_vector(18 downto 0); -- output SYN_DATAREADY_OUT : out std_logic; - SYN_DATA_OUT : out std_logic_vector(18 downto 0); -- Data word + SYN_DATA_OUT : out std_logic_vector(18 downto 0); SYN_READ_IN : in std_logic; -- Status and control port DEBUG : out std_logic_vector(7 downto 0); @@ -49,28 +56,30 @@ port( ); end component fifo_19x16_obuf; - ---component dbg_reg is ---generic( --- WIDTH : integer := 1 ---); ---port( --- DEBUG_IN : in std_logic_vector(WIDTH-1 downto 0); --- DEBUG_OUT : out std_logic_vector(WIDTH-1 downto 0) ---); ---end component dbg_reg; - +-- State description: +-- +-- IDLE: wait for any data to be written into the FIFO +-- RD1 : first word prefetch +-- RD2 : first word output reg, second word prefetch, wait state for full packet in FIFO +-- RDI : generates initial dataready_out, wait state for handshake of first data word +-- RD3 : second word output reg, third word prefetch, wait state for handshake of second data word +-- RD4 : third word output reg, fourth word prefetch, wait state for handshake of third data word +-- RD5 : fourth word output reg, fifth word prefetch, wait state for handshake of forth data word +-- => decision: continous data stream or stalling as FIFO runs empty! +-- RDO : fifth word output reg, wait state for handshake of fifth data word, can also resume transmission +-- if new data is available in FIFO +-- RDW : fifth word output reg, first word prefetch, wait state for handshake of fifth data word, +-- continue data stream or stall if for complete packet type STATES is (IDLE, RD1, RD2, RDI, RD3, RD4, RD5, RDO, RDW); signal CURRENT_STATE, NEXT_STATE: STATES; signal bsm_x : std_logic_vector(3 downto 0); signal bsm : std_logic_vector(3 downto 0); -signal update_x : std_logic; +signal update_x : std_logic; -- load FIFO data into output register signal syn_dataready_x : std_logic; -signal syn_dataready : std_logic; - -signal syn_data : std_logic_vector(18 downto 0); +signal syn_dataready : std_logic; -- must be registered +signal syn_data : std_logic_vector(18 downto 0); -- output register signal fifo_data_i : std_logic_vector(18 downto 0); signal fifo_data_o : std_logic_vector(18 downto 0); @@ -87,13 +96,12 @@ signal debug_x : std_logic_vector(7 downto 0); attribute syn_preserve : boolean; attribute syn_noprune : boolean; attribute syn_keep : boolean; -attribute syn_preserve of fifo_wcnt : signal is true; -attribute syn_keep of fifo_wcnt : signal is true; -attribute syn_noprune of fifo_wcnt : signal is true; -attribute syn_preserve of bsm : signal is true; -attribute syn_keep of bsm : signal is true; -attribute syn_noprune of bsm : signal is true; - +--attribute syn_preserve of fifo_wcnt : signal is true; +--attribute syn_keep of fifo_wcnt : signal is true; +--attribute syn_noprune of fifo_wcnt : signal is true; +--attribute syn_preserve of bsm : signal is true; +--attribute syn_keep of bsm : signal is true; +--attribute syn_noprune of bsm : signal is true; attribute syn_preserve of syn_data : signal is true; attribute syn_keep of syn_data : signal is true; @@ -103,7 +111,6 @@ attribute syn_keep of syn_dataready : signal is true; attribute syn_hier : string; attribute syn_hier of trb_net_sbuf5_arch : architecture is "flatten, firm"; - begin --------------------------------------------------------------------- @@ -219,12 +226,14 @@ begin NEXT_STATE <= RD4; end if; when RD5 => syn_dataready_x <= '1'; - if ( (SYN_READ_IN = '1') and (fifo_wcnt = 0) ) then - -- fourth word of packet DONE, and FIFO has not seen any new packet word. + -- DANGER. This is the key state for decisions here. + -- There are many ways to do it the wrong way, depending on the FIFO fill level. + if ( (SYN_READ_IN = '1') and (fifo_wcnt < 2) ) then + -- fourth word of packet has been transfered, and FIFO has not seen any new packet word. -- so we update output register only, no prefetch NEXT_STATE <= RDO; update_x <= '1'; - elsif( (SYN_READ_IN = '1') and (fifo_wcnt > 0) ) then + elsif( (SYN_READ_IN = '1') and (fifo_wcnt > 1) ) then -- fourth word of packet DONE, new packet data already in the FIFO -- so we can prefetch on data word already and update the output register NEXT_STATE <= RDW; @@ -234,11 +243,11 @@ begin NEXT_STATE <= RD5; end if; when RDO => if ( (SYN_READ_IN = '1') and (fifo_wcnt = 0) ) then - -- last word of packet DONE, and no new data words to handle. + -- last word of packet has been transfered, and no new data words to handle. -- we keep the last transfered word in the output register and wait for new packets to arrive. NEXT_STATE <= IDLE; elsif( (SYN_READ_IN = '1') and (fifo_wcnt > 0) ) then - -- last word of packet DONE, and a new packet data available. + -- last word of packet has been transfered, and a new packet data available. -- so we enter the prefetch phase again. NEXT_STATE <= RD1; fifo_rd_en_x <= '1'; @@ -247,13 +256,13 @@ begin syn_dataready_x <= '1'; end if; when RDW => if ( (SYN_READ_IN = '1') and (fifo_wcnt > 3) ) then - -- last word of packet DONE, complete packet in FIFO, so we can go ahead. + -- last word of packet has been transfered, complete packet in FIFO, so we can go ahead. NEXT_STATE <= RDI; fifo_rd_en_x <= '1'; update_x <= '1'; syn_dataready_x <= '1'; elsif( (SYN_READ_IN = '1') and (fifo_wcnt < 4 ) ) then - -- last word of packet DONE, but new packet not complete yet. + -- last word of packet has been transfered, but new packet not complete yet. NEXT_STATE <= RD2; fifo_rd_en_x <= '1'; update_x <= '1'; @@ -265,6 +274,7 @@ begin end case; end process STATE_TRANSFORM; +-- just for debugging THE_DECODE_PROC: process( NEXT_STATE ) begin case NEXT_STATE is -- 2.43.0