+-- 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
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
);\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
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
attribute syn_hier : string;\r
attribute syn_hier of trb_net_sbuf5_arch : architecture is "flatten, firm";\r
\r
-\r
begin\r
\r
---------------------------------------------------------------------\r
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
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
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
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