]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
state machine completely reworked. new bugs inserted.
authorhadaq <hadaq>
Fri, 25 Jun 2010 10:04:36 +0000 (10:04 +0000)
committerhadaq <hadaq>
Fri, 25 Jun 2010 10:04:36 +0000 (10:04 +0000)
trb_net_sbuf5.vhd

index 6f7a2b9b443825f7372f8d282cab86bea33619f7..0abf5004246df9e15991003bb737b0104daf6b7e 100644 (file)
@@ -61,28 +61,24 @@ end component fifo_19x16_obuf;
 --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
@@ -108,31 +104,8 @@ attribute syn_hier : string;
 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
@@ -143,7 +116,7 @@ COMB_next_READ_OUT <= not fifo_almostfull;
 \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
@@ -159,20 +132,14 @@ port map(
        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
@@ -184,99 +151,116 @@ begin
                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
@@ -287,13 +271,12 @@ begin
                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
@@ -301,7 +284,7 @@ end process THE_DECODE_PROC;
 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
@@ -312,8 +295,8 @@ end process THE_SYNC_PROC;
 ---------------------------------------------------------------------\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