]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
bug fixed version of sbuf5: new statemachine handles (hopefully, keep fingers crossed)
authorhadaq <hadaq>
Fri, 25 Jun 2010 15:36:33 +0000 (15:36 +0000)
committerhadaq <hadaq>
Fri, 25 Jun 2010 15:36:33 +0000 (15:36 +0000)
all FIFO fill levels correctly now, independent of the data stream timing on the input.

trb_net_sbuf5.vhd

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