From 39c15ef86c9f381df66b0bdb211dfd802fdf277d Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Tue, 6 Apr 2010 15:35:21 +0000 Subject: [PATCH] - simplified: removed MII-FIFO. Connected RAM to MII-domain - cleaned up Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@858 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/emac/src/emac_tx.vhd | 330 +++++++++++++++------------------------ 1 file changed, 130 insertions(+), 200 deletions(-) diff --git a/lib/emac/src/emac_tx.vhd b/lib/emac/src/emac_tx.vhd index 5d72565..ec5390f 100644 --- a/lib/emac/src/emac_tx.vhd +++ b/lib/emac/src/emac_tx.vhd @@ -34,13 +34,6 @@ ARCHITECTURE behavior OF emac_tx IS subtype word_ptr_t is unsigned(RAM_ADDR_WIDTH-1 downto 0); - signal mii_fifo_din : unsigned(35 downto 0); - signal mii_fifo_dout : unsigned(35 downto 0); - signal mii_fifo_we : std_logic; - signal mii_fifo_re : std_logic; - signal mii_fifo_empty : std_logic; - signal mii_fifo_full : std_logic; - signal cmd_fifo_din : unsigned(2*word_ptr_t'length-1 downto 0); signal cmd_fifo_dout : unsigned(2*word_ptr_t'length-1 downto 0); signal cmd_fifo_we : std_logic; @@ -72,38 +65,38 @@ ARCHITECTURE behavior OF emac_tx IS signal mem_alloc_en : std_logic; signal mem_free_en : std_logic; signal nwords_free : word_ptr_t; + signal mem_free_req : std_logic; + signal mem_free_ack : unsigned(1 downto 0); signal xfer_size : word_ptr_t; signal xfer_ptr : word_ptr_t; signal xfer_cnt : word_ptr_t; signal xfer_set : std_logic; signal xfer_en : std_logic; - signal xfer_sync : unsigned(1 downto 0); signal xfer_cnt_en : std_logic; signal xfer_bsy : std_logic; + signal xfer_free_en : std_logic; signal ram_en_a : std_logic; signal ram_we_a : std_logic; signal ram_addr_a : word_ptr_t; signal ram_din_a : unsigned(35 downto 0); - signal ram_dout_a : unsigned(35 downto 0); signal ram_en_b : std_logic; signal ram_addr_b : word_ptr_t; - signal ram_din_b : unsigned(35 downto 0); signal ram_dout_b : unsigned(35 downto 0); - signal piso8_din : unsigned(31 downto 0); - signal piso8_din_be : unsigned(3 downto 0); - signal piso8_din_rdy : std_logic; - signal piso8_din_vld : std_logic; + signal piso32_din : unsigned(31 downto 0); + signal piso32_din_be : unsigned(3 downto 0); + signal piso32_din_rdy : std_logic; + signal piso32_din_vld : std_logic; - signal piso8_dout : unsigned(7 downto 0); - signal piso8_dout_vld : std_logic; - signal piso8_dout_en : std_logic; + signal piso32_dout : unsigned(7 downto 0); + signal piso32_dout_vld : std_logic; + signal piso32_dout_en : std_logic; - signal piso4_dout_vld : std_logic; - signal piso4_din_rdy : std_logic; - signal piso4_dout : unsigned(3 downto 0); + signal piso8_dout_vld : std_logic; + signal piso8_din_rdy : std_logic; + signal piso8_dout : unsigned(3 downto 0); signal reset_pipe : unsigned(31 downto 0); @@ -116,12 +109,9 @@ ARCHITECTURE behavior OF emac_tx IS type host_state_t is (host_init, host_idle, host_alloc, host_setup, host_arm, host_fill, host_commit); signal host_s, host_sn : host_state_t; - type xfer_state_t is (xfer_init, xfer_idle, xfer_setup, xfer_arm, xfer_active, xfer_uncommit, xfer_free); + type xfer_state_t is (xfer_init, xfer_idle, xfer_start, xfer_preamble0, xfer_preamble1, xfer_active, xfer_crc, xfer_stop, xfer_finish); signal xfer_s, xfer_sn : xfer_state_t; - type stream_state_t is (stream_init, stream_idle, stream_start, stream_preamble0, stream_preamble1, stream_active, stream_crc, stream_stop, stream_finish); - signal stream_s, stream_sn : stream_state_t; - type piso_byte_mask_array_t is array (0 to 3) of unsigned (3 downto 0); constant piso_byte_mask_rom : piso_byte_mask_array_t := ( @@ -155,22 +145,20 @@ begin ram_din_a(35 downto 32) <= piso_byte_mask_rom(to_integer(fill_remain)) when fill_pre_rdy = '1' else "1111"; ram_addr_a <= fill_ptr; - mii_fifo_din <= ram_dout_b; - - piso8_din <= preamble(preamble_addr) when preamble_en = '1' else mii_fifo_dout(31 downto 0); - piso8_din_be <= "1111" when preamble_en = '1' else mii_fifo_dout(35 downto 32); + piso32_din <= preamble(preamble_addr) when preamble_en = '1' else ram_dout_b(31 downto 0); + piso32_din_be <= "1111" when preamble_en = '1' else ram_dout_b(35 downto 32); cmd_fifo_we <= commit_en; cmd_fifo_re <= uncommit_en; cmd_fifo_din <= fill_size & fill_base; - ram_en_b <= not mii_fifo_full; + ram_en_b <= piso32_din_rdy; ram_addr_b <= xfer_ptr; reset_en <= reset_pipe(reset_pipe'left); - mii_fifo_we <= xfer_bsy; - xfer_cnt_en <= xfer_bsy and not mii_fifo_full; + xfer_cnt_en <= xfer_bsy and piso32_din_rdy; fill_cnt_en <= fill_bsy and din_vld; + mem_free_en <= not mem_free_ack(0) and mem_free_ack(1); ------------------------------------------------------------------ reset_gen: @@ -199,7 +187,7 @@ host_state_next: end process; host_state: - process(host_s, alloc_OK, fill_bsy, ctrl_in.pkt_commit_en, alloc_req) + process(host_s, alloc_OK, fill_bsy, ctrl_in.pkt_commit_en, alloc_req, mem_free_ack) begin fill_set <= '0'; @@ -246,9 +234,11 @@ host_state: end if; when host_commit => - commit_en <= '1'; - mem_alloc_en <= '1'; - host_sn <= host_idle; + if mem_free_ack = "00" then + commit_en <= '1'; + mem_alloc_en <= '1'; + host_sn <= host_idle; + end if; when others => host_sn <= host_idle; @@ -318,7 +308,7 @@ fill_base_logic: end process; ------------------------------------------------------------------ -nwords_free_counter: +mem_free_counter: process(clk) begin if rising_edge(clk) then @@ -332,6 +322,39 @@ nwords_free_counter: end if; end process; +mem_free_mii: + process(mii_tx_clk) + begin + if rising_edge(mii_tx_clk) then + if reset_en = '1' then + mem_free_req <= '0'; + elsif mem_free_ack(0) = '0' then + if xfer_free_en = '1' then + mem_free_req <= '1'; + end if; + else + mem_free_req <= '0'; + end if; + end if; + end process; + +mem_free_host: + process(clk) + begin + if rising_edge(clk) then + mem_free_ack(1) <= mem_free_ack(0); + if reset_en = '1' then + mem_free_ack <= "00"; + elsif mem_free_req = '1' then + if mem_alloc_en = '0' then + mem_free_ack(0) <= '1'; + end if; + else + mem_free_ack(0) <= '0'; + end if; + end if; + end process; + ------------------------------------------------------------------ -- Fill stuff ------------------------------------------------------------------ @@ -375,89 +398,13 @@ fill_pointer: ------------------------------------------------------------------ -- Transfer stuff ------------------------------------------------------------------- -xfer_state_next: - process(clk) - begin - if rising_edge(clk) then - if reset_en = '1' then - xfer_s <= xfer_init; - else - xfer_s <= xfer_sn; - end if; - end if; - end process; - -xfer_state: - process(xfer_s, cmd_fifo_empty, xfer_bsy, xfer_sync, mem_alloc_en) - begin - - xfer_set <= '0'; - xfer_en <= '0'; - mem_free_en <= '0'; - uncommit_en <= '0'; - - xfer_sn <= xfer_s; - - case xfer_s is - - when xfer_init => - xfer_sn <= xfer_idle; - - when xfer_idle => - if cmd_fifo_empty = '0' then - xfer_sn <= xfer_setup; - end if; - - when xfer_setup => - xfer_set <= '1'; - xfer_sn <= xfer_arm; - - when xfer_arm => - xfer_en <= '1'; - xfer_sn <= xfer_active; - - when xfer_active => - xfer_en <= '1'; - if xfer_bsy = '0' then - xfer_sn <= xfer_uncommit; - end if; - - when xfer_uncommit => - mem_free_en <= not mem_alloc_en; - if mem_alloc_en = '0' then - uncommit_en <= '1'; - xfer_sn <= xfer_free; - end if; - - when xfer_free => - if xfer_sync(1) = '1' then - xfer_sn <= xfer_idle; - end if; - - when others => - xfer_sn <= xfer_idle; - end case; - - end process; - ------------------------------------------------------------------- -interframe_gap_ready: - process(clk) - begin - if rising_edge(clk) then - xfer_sync(1) <= xfer_sync(0); - xfer_sync(0) <= mii_fifo_empty; - end if; - end process; - ------------------------------------------------------------------ interframe_gap_counter: process(mii_tx_clk) begin if rising_edge(mii_tx_clk) then ifg_idle <= '0'; - if reset_en = '1' or piso8_dout_vld = '1' then + if reset_en = '1' or piso32_dout_vld = '1' then ifg_cnt <= ifg_cnt_t'high; ifg_idle <= '1'; elsif ifg_cnt /= 0 then @@ -470,9 +417,9 @@ interframe_gap_counter: ------------------------------------------------------------------ xfer_counter: - process(clk) + process(mii_tx_clk) begin - if rising_edge(clk) then + if rising_edge(mii_tx_clk) then xfer_bsy <= '0'; if xfer_set = '1' then xfer_cnt <= cmd_fifo_dout(cmd_fifo_dout'left downto word_ptr_t'length); @@ -493,9 +440,9 @@ xfer_counter: end process; xfer_pointer: - process(clk) + process(mii_tx_clk) begin - if rising_edge(clk) then + if rising_edge(mii_tx_clk) then if xfer_set = '1' then xfer_ptr <= cmd_fifo_dout(xfer_ptr'left downto 0); elsif xfer_en = '1' then @@ -508,82 +455,87 @@ xfer_pointer: end process; ------------------------------------------------------------------ -stream_state_next: +xfer_state_next: process(mii_tx_clk) begin if rising_edge(mii_tx_clk) then if reset_en = '1' then - stream_s <= stream_init; + xfer_s <= xfer_init; else - stream_s <= stream_sn; + xfer_s <= xfer_sn; end if; end if; end process; -stream_state: - process(stream_s, ifg_idle, mii_fifo_empty, piso8_din_rdy, piso8_dout_vld) +xfer_state: + process(xfer_s, ifg_idle, cmd_fifo_empty, piso32_din_rdy, piso32_dout_vld, xfer_bsy) begin - piso8_din_vld <= '0'; - mii_fifo_re <= '0'; + piso32_din_vld <= '0'; preamble_en <= '0'; preamble_addr <= 0; + xfer_set <= '0'; + xfer_en <= '0'; + xfer_free_en <= '0'; + uncommit_en <= '0'; - stream_sn <= stream_s; + xfer_sn <= xfer_s; - case stream_s is + case xfer_s is - when stream_init => - if mii_fifo_empty = '1' then - stream_sn <= stream_idle; + when xfer_init => + xfer_sn <= xfer_idle; + + when xfer_idle => + if cmd_fifo_empty = '0' and piso32_din_rdy = '1' then + xfer_sn <= xfer_start; end if; - when stream_idle => - if mii_fifo_empty = '0' and piso8_din_rdy = '1' then - stream_sn <= stream_start; - end if; - - when stream_start => - stream_sn <= stream_preamble0; + when xfer_start => + xfer_set <= '1'; + xfer_sn <= xfer_preamble0; - when stream_preamble0 => + when xfer_preamble0 => preamble_addr <= 0; preamble_en <= '1'; - piso8_din_vld <= '1'; - if piso8_din_rdy = '1' then - stream_sn <= stream_preamble1; + piso32_din_vld <= '1'; + if piso32_din_rdy = '1' then + xfer_sn <= xfer_preamble1; end if; - when stream_preamble1 => + when xfer_preamble1 => preamble_addr <= 1; preamble_en <= '1'; - piso8_din_vld <= '1'; - if piso8_din_rdy = '1' then - stream_sn <= stream_active; + piso32_din_vld <= '1'; + if piso32_din_rdy = '1' then + xfer_sn <= xfer_active; + xfer_en <= '1'; end if; - when stream_active => - piso8_din_vld <= not mii_fifo_empty; - mii_fifo_re <= piso8_din_rdy; - if mii_fifo_empty = '1' then - stream_sn <= stream_crc; + when xfer_active => + piso32_din_vld <= xfer_bsy; + xfer_en <= '1'; + if xfer_bsy = '0' then + uncommit_en <= '1'; + xfer_free_en <= '1'; + xfer_sn <= xfer_crc; end if; - when stream_crc => - stream_sn <= stream_stop; + when xfer_crc => + xfer_sn <= xfer_stop; - when stream_stop => - if piso8_dout_vld = '0' then - stream_sn <= stream_finish; + when xfer_stop => + if piso32_dout_vld = '0' then + xfer_sn <= xfer_finish; end if; - when stream_finish => + when xfer_finish => if ifg_idle = '0' then - stream_sn <= stream_idle; + xfer_sn <= xfer_idle; end if; when others => - stream_sn <= stream_idle; + xfer_sn <= xfer_idle; end case; end process; @@ -598,7 +550,7 @@ inst_ram : entity work.dpram_1w1r PORT MAP ( clka => clk, - clkb => clk, + clkb => mii_tx_clk, en_a => ram_en_a, en_b => ram_en_b, we_a => ram_we_a, @@ -609,7 +561,7 @@ inst_ram : entity work.dpram_1w1r ); -- Instantiate synchronous FIFO -inst_cmd_fifo: entity work.fifo_sync +inst_cmd_fifo: entity work.fifo_async GENERIC MAP ( addr_width => NextExpBaseTwo(RAM_SIZE) - 4, -- RAMSIZE(words)/MIN_PACKET_LEN(words) @@ -619,7 +571,8 @@ inst_cmd_fifo: entity work.fifo_sync PORT MAP ( rst => reset_en, - clk => clk, + clk_w => clk, + clk_r => mii_tx_clk, we => cmd_fifo_we, re => cmd_fifo_re, fifo_full => cmd_fifo_full, @@ -630,30 +583,7 @@ inst_cmd_fifo: entity work.fifo_sync data_r => cmd_fifo_dout ); --- Instantiate synchronous FIFO -inst_mii_fifo: entity work.fifo_async - GENERIC MAP - ( - addr_width => 4, - data_width => mii_fifo_din'length, - do_last_read_update => true - ) - PORT MAP - ( - rst => reset_en, - clk_w => clk, - clk_r => mii_tx_clk, - we => mii_fifo_we, - re => mii_fifo_re, - fifo_full => mii_fifo_full, - fifo_empty => mii_fifo_empty, - fifo_afull => open, - fifo_aempty => open, - data_w => mii_fifo_din, - data_r => mii_fifo_dout - ); - -inst_piso8 : entity work.piso +inst_piso32 : entity work.piso GENERIC MAP ( data_width_in => 32, @@ -664,19 +594,19 @@ inst_piso8 : entity work.piso ( rst => reset_en, clk => mii_tx_clk, - din_vld => piso8_din_vld, - din_rdy => piso8_din_rdy, - din_be => piso8_din_be, - din => piso8_din, - dout_vld => piso8_dout_vld, - dout_en => piso8_dout_en, - dout => piso8_dout + din_vld => piso32_din_vld, + din_rdy => piso32_din_rdy, + din_be => piso32_din_be, + din => piso32_din, + dout_vld => piso32_dout_vld, + dout_en => piso32_dout_en, + dout => piso32_dout ); - piso8_dout_en <= piso4_din_rdy and ifg_idle; + piso32_dout_en <= piso8_din_rdy and ifg_idle; -inst_piso4 : entity work.piso +inst_piso8 : entity work.piso GENERIC MAP ( data_width_in => 8, @@ -687,17 +617,17 @@ inst_piso4 : entity work.piso ( rst => reset_en, clk => mii_tx_clk, - din_vld => piso8_dout_vld, - din_rdy => piso4_din_rdy, + din_vld => piso32_dout_vld, + din_rdy => piso8_din_rdy, din_be => "11", - din => piso8_dout, - dout_vld => piso4_dout_vld, + din => piso32_dout, + dout_vld => piso8_dout_vld, dout_en => '1', - dout => piso4_dout + dout => piso8_dout ); - mii_tx_en <= piso4_dout_vld; - mii_tx <= "0000" & piso4_dout; + mii_tx_en <= piso8_dout_vld; + mii_tx <= "0000" & piso8_dout; end behavior;