From 43085119b711ce07cd5d58cb03da9dcf2555d5be Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 28 Mar 2010 17:05:00 +0000 Subject: [PATCH] - added reset gen - improved IFG counter 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@836 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/emac/src/emac_tx.vhd | 70 +++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/lib/emac/src/emac_tx.vhd b/lib/emac/src/emac_tx.vhd index 1ab3426..bfe0cfb 100644 --- a/lib/emac/src/emac_tx.vhd +++ b/lib/emac/src/emac_tx.vhd @@ -48,7 +48,7 @@ ARCHITECTURE behavior OF emac_tx IS signal cmd_fifo_empty : std_logic; signal cmd_fifo_full : std_logic; - signal flush_en : std_logic; + signal reset_en : std_logic; signal fill_base : word_ptr_t; signal fill_size : word_ptr_t; @@ -104,15 +104,18 @@ ARCHITECTURE behavior OF emac_tx IS signal piso_dout : unsigned(7 downto 0); signal piso_dout_vld : std_logic; signal piso_10mbps_din_rdy : std_logic; + signal tx_en : std_logic; - subtype inter_frame_gap_cnt_t is natural range 0 to natural(1.0*f_sysclk)-1; + signal reset_pipe : unsigned(31 downto 0); + + subtype inter_frame_gap_cnt_t is natural range 0 to 95; signal inter_frame_gap_cnt : inter_frame_gap_cnt_t; signal inter_frame_gap_rdy : std_logic; type host_state_t is (host_init, host_flush, 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_wait, xfer_active, xfer_free); + type xfer_state_t is (xfer_init, xfer_idle, xfer_setup, xfer_wait, xfer_active, xfer_uncommit, xfer_free); signal xfer_s, xfer_sn : xfer_state_t; type piso_byte_mask_array_t is array (0 to 3) of unsigned (3 downto 0); @@ -129,6 +132,7 @@ begin ctrl_out.pkt_alloc_req <= alloc_req; ctrl_out.pkt_done <= cmd_fifo_empty; + ctrl_out.reset_busy <= reset_en; mii_tx_er <= ctrl_in.tx_er; @@ -152,12 +156,26 @@ begin ram_addr_b <= xfer_ptr; xfer_tag <= cmd_fifo_dout(35 downto 32); + reset_en <= reset_pipe(reset_pipe'left); +------------------------------------------------------------------ +reset_gen: + process(clk) + begin + if rising_edge(clk) then + if rst = '1' or ctrl_in.reset = '1' then + reset_pipe <= (others => '1'); + else + reset_pipe <= reset_pipe(reset_pipe'left-1 downto 0) & '0'; + end if; + end if; + end process; + ------------------------------------------------------------------ host_state_next: process(clk) begin if rising_edge(clk) then - if rst = '1' then + if reset_en = '1' then host_s <= host_init; else host_s <= host_sn; @@ -169,7 +187,6 @@ host_state: process(host_s, alloc_req, alloc_OK, fill_rdy, din_vld, ctrl_in.pkt_commit_en) begin - flush_en <= '0'; fill_cnt_set <= '0'; fill_cnt_adv <= '0'; fill_ptr_set <= '0'; @@ -183,13 +200,8 @@ host_state: case host_s is when host_init => - flush_en <= '1'; - host_sn <= host_flush; + host_sn <= host_idle; - when host_flush => - flush_en <= '1'; - host_sn <= host_idle; - when host_idle => if alloc_req = '1' then host_sn <= host_alloc; @@ -237,7 +249,7 @@ alloc_request_logic: process(clk) begin if rising_edge(clk) then - if rst = '1' then + if reset_en = '1' then alloc_req <= '0'; elsif ctrl_in.pkt_alloc_en = '1' and alloc_req = '0' then alloc_req <= '1'; @@ -260,7 +272,7 @@ fill_base_logic: process(clk) begin if rising_edge(clk) then - if flush_en = '1' then + if reset_en = '1' then fill_base <= (others => '0'); elsif commit_en = '1' then fill_base <= fill_ptr; @@ -287,7 +299,7 @@ nwords_free_counter: process(clk) begin if rising_edge(clk) then - if flush_en = '1' then + if reset_en = '1' then nwords_free <= (others => '1'); elsif mem_alloc_en = '1' then nwords_free <= nwords_free - fill_size; @@ -336,7 +348,7 @@ xfer_state_next: process(clk) begin if rising_edge(clk) then - if rst = '1' then + if reset_en = '1' then xfer_s <= xfer_init; else xfer_s <= xfer_sn; @@ -391,14 +403,19 @@ xfer_state: xfer_cnt_adv <= '0'; xfer_ptr_adv <= '0'; if mii_fifo_full = '0' then - xfer_sn <= xfer_free; + xfer_sn <= xfer_uncommit; end if; end if; - when xfer_free => + 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 inter_frame_gap_rdy = '0' then xfer_sn <= xfer_idle; end if; @@ -410,12 +427,12 @@ xfer_state: ------------------------------------------------------------------ interframe_gap_counter: - process(clk) + process(mii_tx_clk) begin - if rising_edge(clk) then - if flush_en = '1' then + if rising_edge(mii_tx_clk) then + if reset_en = '1' then inter_frame_gap_rdy <= '1'; - elsif mii_fifo_empty = '0' then + elsif tx_en = '1' then inter_frame_gap_rdy <= '0'; inter_frame_gap_cnt <= inter_frame_gap_cnt_t'high; elsif inter_frame_gap_cnt /= 0 then @@ -495,7 +512,7 @@ inst_cmd_fifo: entity work.fifo_sync ) PORT MAP ( - rst => flush_en, + rst => reset_en, clk => clk, we => cmd_fifo_we, re => cmd_fifo_re, @@ -517,7 +534,7 @@ inst_mii_fifo: entity work.fifo_async ) PORT MAP ( - rst => rst, + rst => reset_en, clk_w => clk, clk_r => mii_tx_clk, we => mii_fifo_we, @@ -539,7 +556,7 @@ inst_piso : entity work.piso ) PORT MAP ( - rst => rst, + rst => reset_en, clk => mii_tx_clk, din_vld => data_vld, din_rdy => piso_din_rdy, @@ -560,18 +577,19 @@ inst_piso_10mbps : entity work.piso ) PORT MAP ( - rst => rst, + rst => reset_en, clk => mii_tx_clk, din_vld => piso_dout_vld, din_rdy => piso_10mbps_din_rdy, din_be => "11", din => piso_dout, - dout_vld => mii_tx_en, + dout_vld => tx_en, dout_en => '1', dout => mii_tx(3 downto 0) ); + mii_tx_en <= tx_en; mii_tx(7 downto 4) <= "0000"; end behavior;