From a2b149a2210c228bb64fbe92b64097d7c7b19df8 Mon Sep 17 00:00:00 2001 From: hadaq Date: Fri, 25 Jun 2010 10:04:36 +0000 Subject: [PATCH] state machine completely reworked. new bugs inserted. --- trb_net_sbuf5.vhd | 163 +++++++++++++++++++++------------------------- 1 file changed, 73 insertions(+), 90 deletions(-) diff --git a/trb_net_sbuf5.vhd b/trb_net_sbuf5.vhd index 6f7a2b9..0abf500 100644 --- a/trb_net_sbuf5.vhd +++ b/trb_net_sbuf5.vhd @@ -61,28 +61,24 @@ end component fifo_19x16_obuf; --end component dbg_reg; -type STATES is (IDLE, RD1, RD2, RD3, RD4, RD5, WT5, WR5, WD5, DEL); +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 syn_dataready_x : std_logic; signal syn_dataready : std_logic; -signal update_x : std_logic; -signal update : std_logic; signal syn_data : std_logic_vector(18 downto 0); -signal p_wait_x : std_logic; -signal p_avail_x : std_logic; -signal p_really_x : std_logic; - signal fifo_data_i : std_logic_vector(18 downto 0); signal fifo_data_o : std_logic_vector(18 downto 0); signal fifo_wr_en : std_logic; signal fifo_rd_en_x : std_logic; signal fifo_reset : std_logic; -signal fifo_wcnt : std_logic_vector(4 downto 0); +signal fifo_wcnt_stdlv : std_logic_vector(4 downto 0); +signal fifo_wcnt : unsigned(4 downto 0); signal fifo_full : std_logic; signal fifo_almostfull : std_logic; @@ -108,31 +104,8 @@ attribute syn_hier : string; attribute syn_hier of trb_net_sbuf5_arch : architecture is "flatten, firm"; ---attribute syn_noprune : boolean; ---attribute syn_noprune of THE_DBG_REG : label is true; ---signal my_debug : std_logic_vector(26 downto 0); - - begin - ---------------------------------------------------------------------- --- VHDL / Synplify workaround for fixed nodes... creepy. ---------------------------------------------------------------------- ---THE_DBG_REG: dbg_reg ---generic map( --- WIDTH => 27 ---) ---port map( --- DEBUG_IN => my_debug, --- DEBUG_OUT => open ---); --- ---my_debug(8 downto 4) <= fifo_wcnt; ---my_debug(3 downto 0) <= bsm; ---------------------------------------------------------------------- ---------------------------------------------------------------------- - --------------------------------------------------------------------- -- I/O --------------------------------------------------------------------- @@ -143,7 +116,7 @@ COMB_next_READ_OUT <= not fifo_almostfull; DEBUG <= debug_x; DEBUG_BSM <= bsm; -DEBUG_WCNT <= fifo_wcnt; +DEBUG_WCNT <= fifo_wcnt_stdlv; STAT_BUFFER <= fifo_full; SYN_DATA_OUT <= syn_data; @@ -159,20 +132,14 @@ port map( WrEn => fifo_wr_en, RdEn => fifo_rd_en_x, Reset => fifo_reset, - AmFullThresh => x"C", + AmFullThresh => x"b", Q => fifo_data_o, - WCNT => fifo_wcnt, + WCNT => fifo_wcnt_stdlv, Full => fifo_full, - AlmostFull => fifo_almostfull --open + AlmostFull => fifo_almostfull ); -p_wait_x <= '1' when (unsigned(fifo_wcnt) > x"0") else '0'; -p_avail_x <= '1' when ((unsigned(fifo_wcnt) >= x"2") and (COMB_DATAREADY_IN = '1')) or - (unsigned(fifo_wcnt) >= x"3") - else '0'; -p_really_x <= '1' when (unsigned(fifo_wcnt) >= x"3") else '0'; - --- was 3 and 4 +fifo_wcnt <= unsigned(fifo_wcnt_stdlv); --------------------------------------------------------------------- -- State machine @@ -184,99 +151,116 @@ begin if( RESET = '1' ) then CURRENT_STATE <= IDLE; syn_dataready <= '0'; - update <= '0'; bsm <= x"0"; else CURRENT_STATE <= NEXT_STATE; syn_dataready <= syn_dataready_x; - update <= update_x; bsm <= bsm_x; end if; end if; end process STATE_MEM; -- state transitions -STATE_TRANSFORM: process( CURRENT_STATE, p_wait_x, p_avail_x, p_really_x, SYN_READ_IN, syn_dataready, COMB_DATAREADY_IN ) +STATE_TRANSFORM: process( CURRENT_STATE, fifo_wcnt, SYN_READ_IN, syn_dataready, COMB_DATAREADY_IN ) begin NEXT_STATE <= IDLE; -- avoid latches fifo_rd_en_x <= '0'; syn_dataready_x <= '0'; update_x <= '0'; case CURRENT_STATE is - when IDLE => if( p_wait_x = '1' ) then - NEXT_STATE <= RD1; + when IDLE => if( fifo_wcnt > 0 ) then + -- we have at least one data word in FIFO, so we prefetch it + NEXT_STATE <= RD1; fifo_rd_en_x <= '1'; - update_x <= '1'; else NEXT_STATE <= IDLE; end if; - when RD1 => if( p_wait_x = '1' ) then + when RD1 => if( fifo_wcnt > 0 ) then + -- second data word is available in FIFO, so we prefetch it and + -- forward the first word to the output register NEXT_STATE <= RD2; fifo_rd_en_x <= '1'; + update_x <= '1'; else NEXT_STATE <= RD1; end if; - when RD2 => if ( (p_avail_x = '1') and (SYN_READ_IN = '1') and (syn_dataready = '1') ) then - NEXT_STATE <= RD3; - syn_dataready_x <= '1'; - fifo_rd_en_x <= '1'; - elsif( (p_avail_x = '1') and (SYN_READ_IN = '1') and (syn_dataready = '0') ) then - NEXT_STATE <= DEL; + when RD2 => if ( fifo_wcnt > 2 ) then + -- at least all three missing words in FIFO... so we go ahead and notify full packet availability + NEXT_STATE <= RDI; syn_dataready_x <= '1'; else NEXT_STATE <= RD2; - syn_dataready_x <= p_avail_x; --?!? end if; - when DEL => syn_dataready_x <= '1'; + when RDI => syn_dataready_x <= '1'; if( SYN_READ_IN = '1' ) then + -- first word of packet has been transfered, update output register and prefetch next data word NEXT_STATE <= RD3; fifo_rd_en_x <= '1'; + update_x <= '1'; else - NEXT_STATE <= DEL; + NEXT_STATE <= RDI; end if; when RD3 => syn_dataready_x <= '1'; if( SYN_READ_IN = '1' ) then + -- second word of packet has been transfered, update output register and prefetch next data word NEXT_STATE <= RD4; fifo_rd_en_x <= '1'; + update_x <= '1'; else NEXT_STATE <= RD3; end if; when RD4 => syn_dataready_x <= '1'; + -- third word of packet has been transfered, update output register and prefetch next data word if( SYN_READ_IN = '1' ) then NEXT_STATE <= RD5; fifo_rd_en_x <= '1'; + update_x <= '1'; else NEXT_STATE <= RD4; end if; - when RD5 => - syn_dataready_x <= '1'; - if ( (SYN_READ_IN = '1') and (p_avail_x = '1') ) then - NEXT_STATE <= WR5; + 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. + -- so we update output register only, no prefetch + NEXT_STATE <= RDO; + update_x <= '1'; + elsif( (SYN_READ_IN = '1') and (fifo_wcnt > 0) ) 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; fifo_rd_en_x <= '1'; - elsif( (SYN_READ_IN = '1') and (p_avail_x = '0') ) then - NEXT_STATE <= WT5; + update_x <= '1'; else NEXT_STATE <= RD5; end if; - when WR5 => - if( (SYN_READ_IN = '0') and (syn_dataready = '1') ) then - NEXT_STATE <= WR5; - syn_dataready_x <= '1'; - elsif ( (SYN_READ_IN = '1') and (p_really_x = '1') ) then - NEXT_STATE <= RD3; -- was RD2 + when RDO => if ( (SYN_READ_IN = '1') and (fifo_wcnt = 0) ) then + -- last word of packet DONE, 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. + -- so we enter the prefetch phase again. + NEXT_STATE <= RD1; fifo_rd_en_x <= '1'; - syn_dataready_x <= '1'; - else - NEXT_STATE <= WR5; - syn_dataready_x <= p_really_x; - end if; - when WT5 => - if( SYN_READ_IN = '1' ) then - NEXT_STATE <= IDLE; else - NEXT_STATE <= WT5; + NEXT_STATE <= RDO; 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. + 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. + NEXT_STATE <= RD2; + fifo_rd_en_x <= '1'; + update_x <= '1'; + else + NEXT_STATE <= RDW; + syn_dataready_x <= '1'; + end if; when others => NEXT_STATE <= IDLE; end case; end process STATE_TRANSFORM; @@ -287,13 +271,12 @@ begin when IDLE => bsm_x <= x"0"; when RD1 => bsm_x <= x"1"; when RD2 => bsm_x <= x"2"; - when RD3 => bsm_x <= x"3"; - when RD4 => bsm_x <= x"4"; - when RD5 => bsm_x <= x"5"; - when WT5 => bsm_x <= x"6"; - when WR5 => bsm_x <= x"7"; - when WD5 => bsm_x <= x"8"; - when DEL => bsm_x <= x"9"; + when RDI => bsm_x <= x"3"; + when RD3 => bsm_x <= x"4"; + when RD4 => bsm_x <= x"5"; + when RD5 => bsm_x <= x"6"; + when RDO => bsm_x <= x"7"; + when RDW => bsm_x <= x"8"; when others => bsm_x <= x"f"; end case; end process THE_DECODE_PROC; @@ -301,7 +284,7 @@ end process THE_DECODE_PROC; THE_SYNC_PROC: process( CLK ) begin if( rising_edge(CLK) ) then - if( ((syn_dataready = '1') and (syn_read_in = '1')) or (update = '1') ) then + if( update_x = '1' ) then syn_data <= fifo_data_o; end if; end if; @@ -312,8 +295,8 @@ end process THE_SYNC_PROC; --------------------------------------------------------------------- debug_x(7 downto 4) <= x"0"; debug_x(3) <= COMB_DATAREADY_IN; -debug_x(2) <= fifo_rd_en_x; -debug_x(1) <= p_avail_x; -debug_x(0) <= p_wait_x; +debug_x(2) <= '0'; +debug_x(1) <= '0'; +debug_x(0) <= fifo_rd_en_x; end architecture; \ No newline at end of file -- 2.43.0