--end component dbg_reg;\r
\r
\r
-type STATES is (IDLE, RD1, RD2, RD3, RD4, RD5, WT5, WR5, WD5, DEL);\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
\r
signal syn_dataready_x : std_logic;\r
signal syn_dataready : std_logic;\r
-signal update_x : std_logic;\r
-signal update : std_logic;\r
\r
signal syn_data : std_logic_vector(18 downto 0);\r
\r
-signal p_wait_x : std_logic;\r
-signal p_avail_x : std_logic;\r
-signal p_really_x : std_logic;\r
-\r
signal fifo_data_i : std_logic_vector(18 downto 0);\r
signal fifo_data_o : std_logic_vector(18 downto 0);\r
signal fifo_wr_en : std_logic;\r
signal fifo_rd_en_x : std_logic;\r
signal fifo_reset : std_logic;\r
-signal fifo_wcnt : std_logic_vector(4 downto 0);\r
+signal fifo_wcnt_stdlv : std_logic_vector(4 downto 0);\r
+signal fifo_wcnt : unsigned(4 downto 0);\r
signal fifo_full : std_logic;\r
signal fifo_almostfull : std_logic;\r
\r
attribute syn_hier of trb_net_sbuf5_arch : architecture is "flatten, firm";\r
\r
\r
---attribute syn_noprune : boolean;\r
---attribute syn_noprune of THE_DBG_REG : label is true;\r
---signal my_debug : std_logic_vector(26 downto 0);\r
-\r
-\r
begin\r
\r
-\r
----------------------------------------------------------------------\r
--- VHDL / Synplify workaround for fixed nodes... creepy.\r
----------------------------------------------------------------------\r
---THE_DBG_REG: dbg_reg\r
---generic map(\r
--- WIDTH => 27\r
---)\r
---port map(\r
--- DEBUG_IN => my_debug,\r
--- DEBUG_OUT => open\r
---);\r
---\r
---my_debug(8 downto 4) <= fifo_wcnt;\r
---my_debug(3 downto 0) <= bsm;\r
----------------------------------------------------------------------\r
----------------------------------------------------------------------\r
-\r
---------------------------------------------------------------------\r
-- I/O\r
---------------------------------------------------------------------\r
\r
DEBUG <= debug_x;\r
DEBUG_BSM <= bsm;\r
-DEBUG_WCNT <= fifo_wcnt;\r
+DEBUG_WCNT <= fifo_wcnt_stdlv;\r
STAT_BUFFER <= fifo_full;\r
\r
SYN_DATA_OUT <= syn_data;\r
WrEn => fifo_wr_en,\r
RdEn => fifo_rd_en_x,\r
Reset => fifo_reset,\r
- AmFullThresh => x"C",\r
+ AmFullThresh => x"b",\r
Q => fifo_data_o,\r
- WCNT => fifo_wcnt,\r
+ WCNT => fifo_wcnt_stdlv,\r
Full => fifo_full,\r
- AlmostFull => fifo_almostfull --open\r
+ AlmostFull => fifo_almostfull\r
);\r
\r
-p_wait_x <= '1' when (unsigned(fifo_wcnt) > x"0") else '0';\r
-p_avail_x <= '1' when ((unsigned(fifo_wcnt) >= x"2") and (COMB_DATAREADY_IN = '1')) or\r
- (unsigned(fifo_wcnt) >= x"3")\r
- else '0';\r
-p_really_x <= '1' when (unsigned(fifo_wcnt) >= x"3") else '0';\r
-\r
--- was 3 and 4\r
+fifo_wcnt <= unsigned(fifo_wcnt_stdlv);\r
\r
---------------------------------------------------------------------\r
-- State machine\r
if( RESET = '1' ) then\r
CURRENT_STATE <= IDLE;\r
syn_dataready <= '0';\r
- update <= '0';\r
bsm <= x"0";\r
else\r
CURRENT_STATE <= NEXT_STATE;\r
syn_dataready <= syn_dataready_x;\r
- update <= update_x;\r
bsm <= bsm_x;\r
end if;\r
end if;\r
end process STATE_MEM;\r
\r
-- state transitions\r
-STATE_TRANSFORM: process( CURRENT_STATE, p_wait_x, p_avail_x, p_really_x, SYN_READ_IN, syn_dataready, COMB_DATAREADY_IN )\r
+STATE_TRANSFORM: process( CURRENT_STATE, fifo_wcnt, SYN_READ_IN, syn_dataready, COMB_DATAREADY_IN )\r
begin\r
NEXT_STATE <= IDLE; -- avoid latches\r
fifo_rd_en_x <= '0';\r
syn_dataready_x <= '0';\r
update_x <= '0';\r
case CURRENT_STATE is\r
- when IDLE => if( p_wait_x = '1' ) then\r
- NEXT_STATE <= RD1;\r
+ when IDLE => if( fifo_wcnt > 0 ) then\r
+ -- we have at least one data word in FIFO, so we prefetch it\r
+ NEXT_STATE <= RD1; \r
fifo_rd_en_x <= '1';\r
- update_x <= '1';\r
else\r
NEXT_STATE <= IDLE;\r
end if;\r
- when RD1 => if( p_wait_x = '1' ) then\r
+ when RD1 => if( fifo_wcnt > 0 ) then\r
+ -- second data word is available in FIFO, so we prefetch it and \r
+ -- forward the first word to the output register\r
NEXT_STATE <= RD2;\r
fifo_rd_en_x <= '1';\r
+ update_x <= '1';\r
else\r
NEXT_STATE <= RD1;\r
end if;\r
- when RD2 => if ( (p_avail_x = '1') and (SYN_READ_IN = '1') and (syn_dataready = '1') ) then\r
- NEXT_STATE <= RD3;\r
- syn_dataready_x <= '1';\r
- fifo_rd_en_x <= '1';\r
- elsif( (p_avail_x = '1') and (SYN_READ_IN = '1') and (syn_dataready = '0') ) then\r
- NEXT_STATE <= DEL;\r
+ when RD2 => if ( fifo_wcnt > 2 ) then\r
+ -- at least all three missing words in FIFO... so we go ahead and notify full packet availability\r
+ NEXT_STATE <= RDI;\r
syn_dataready_x <= '1';\r
else\r
NEXT_STATE <= RD2;\r
- syn_dataready_x <= p_avail_x; --?!?\r
end if;\r
- when DEL => syn_dataready_x <= '1';\r
+ when RDI => syn_dataready_x <= '1';\r
if( SYN_READ_IN = '1' ) then\r
+ -- first word of packet has been transfered, update output register and prefetch next data word\r
NEXT_STATE <= RD3;\r
fifo_rd_en_x <= '1';\r
+ update_x <= '1';\r
else\r
- NEXT_STATE <= DEL;\r
+ NEXT_STATE <= RDI;\r
end if;\r
when RD3 => syn_dataready_x <= '1';\r
if( SYN_READ_IN = '1' ) then\r
+ -- second word of packet has been transfered, update output register and prefetch next data word\r
NEXT_STATE <= RD4;\r
fifo_rd_en_x <= '1';\r
+ update_x <= '1';\r
else\r
NEXT_STATE <= RD3;\r
end if;\r
when RD4 => syn_dataready_x <= '1';\r
+ -- third word of packet has been transfered, update output register and prefetch next data word\r
if( SYN_READ_IN = '1' ) then\r
NEXT_STATE <= RD5;\r
fifo_rd_en_x <= '1';\r
+ update_x <= '1';\r
else\r
NEXT_STATE <= RD4;\r
end if;\r
- when RD5 => \r
- syn_dataready_x <= '1';\r
- if ( (SYN_READ_IN = '1') and (p_avail_x = '1') ) then\r
- NEXT_STATE <= WR5;\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
+ -- 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
+ -- 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
fifo_rd_en_x <= '1';\r
- elsif( (SYN_READ_IN = '1') and (p_avail_x = '0') ) then\r
- NEXT_STATE <= WT5;\r
+ update_x <= '1';\r
else\r
NEXT_STATE <= RD5;\r
end if;\r
- when WR5 =>\r
- if( (SYN_READ_IN = '0') and (syn_dataready = '1') ) then\r
- NEXT_STATE <= WR5;\r
- syn_dataready_x <= '1';\r
- elsif ( (SYN_READ_IN = '1') and (p_really_x = '1') ) then\r
- NEXT_STATE <= RD3; -- was RD2\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
+ -- 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
+ -- so we enter the prefetch phase again.\r
+ NEXT_STATE <= RD1;\r
fifo_rd_en_x <= '1';\r
- syn_dataready_x <= '1';\r
- else\r
- NEXT_STATE <= WR5;\r
- syn_dataready_x <= p_really_x;\r
- end if;\r
- when WT5 => \r
- if( SYN_READ_IN = '1' ) then\r
- NEXT_STATE <= IDLE;\r
else\r
- NEXT_STATE <= WT5;\r
+ NEXT_STATE <= RDO;\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
+ 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
+ NEXT_STATE <= RD2;\r
+ fifo_rd_en_x <= '1';\r
+ update_x <= '1';\r
+ else\r
+ NEXT_STATE <= RDW;\r
+ syn_dataready_x <= '1'; \r
+ end if; \r
when others => NEXT_STATE <= IDLE;\r
end case;\r
end process STATE_TRANSFORM;\r
when IDLE => bsm_x <= x"0";\r
when RD1 => bsm_x <= x"1";\r
when RD2 => bsm_x <= x"2";\r
- when RD3 => bsm_x <= x"3";\r
- when RD4 => bsm_x <= x"4";\r
- when RD5 => bsm_x <= x"5";\r
- when WT5 => bsm_x <= x"6";\r
- when WR5 => bsm_x <= x"7";\r
- when WD5 => bsm_x <= x"8";\r
- when DEL => bsm_x <= x"9";\r
+ when RDI => bsm_x <= x"3";\r
+ when RD3 => bsm_x <= x"4";\r
+ when RD4 => bsm_x <= x"5";\r
+ when RD5 => bsm_x <= x"6";\r
+ when RDO => bsm_x <= x"7";\r
+ when RDW => bsm_x <= x"8";\r
when others => bsm_x <= x"f";\r
end case;\r
end process THE_DECODE_PROC;\r
THE_SYNC_PROC: process( CLK )\r
begin\r
if( rising_edge(CLK) ) then\r
- if( ((syn_dataready = '1') and (syn_read_in = '1')) or (update = '1') ) then\r
+ if( update_x = '1' ) then\r
syn_data <= fifo_data_o;\r
end if;\r
end if;\r
---------------------------------------------------------------------\r
debug_x(7 downto 4) <= x"0";\r
debug_x(3) <= COMB_DATAREADY_IN;\r
-debug_x(2) <= fifo_rd_en_x;\r
-debug_x(1) <= p_avail_x;\r
-debug_x(0) <= p_wait_x;\r
+debug_x(2) <= '0';\r
+debug_x(1) <= '0';\r
+debug_x(0) <= fifo_rd_en_x;\r
\r
end architecture;
\ No newline at end of file