Initial version
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@809 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
use std.textio.all; -- Imports the standard textio package.
|
||||
|
||||
use work.emac_types.all;
|
||||
use work.utils_pkg.all;
|
||||
|
||||
ENTITY emac_rx IS
|
||||
Generic
|
||||
(
|
||||
f_sysclk : real := 100.0;
|
||||
RAM_SIZE : natural := 2048
|
||||
);
|
||||
Port
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
rst : in STD_LOGIC;
|
||||
dout : out unsigned(31 downto 0);
|
||||
ctrl_in : in rx_ctrl_in_t;
|
||||
ctrl_out : out rx_ctrl_out_t;
|
||||
mii_rx_clk : in STD_LOGIC;
|
||||
mii_rx_dv : in STD_LOGIC;
|
||||
mii_rx_er : in STD_LOGIC;
|
||||
mii_rx : in unsigned(7 downto 0);
|
||||
mii_crs : in STD_LOGIC;
|
||||
mii_col : in STD_LOGIC
|
||||
|
||||
);
|
||||
END emac_rx;
|
||||
|
||||
ARCHITECTURE behavior OF emac_rx IS
|
||||
|
||||
constant RAM_ADDR_WIDTH : natural := NextExpBaseTwo(RAM_SIZE);
|
||||
|
||||
subtype word_ptr_t is unsigned(RAM_ADDR_WIDTH-1 downto 0);
|
||||
|
||||
-- Signals for EMAC connections
|
||||
signal fifo_din : unsigned(35 downto 0);
|
||||
signal fifo_dout : unsigned(35 downto 0);
|
||||
signal fifo_we : std_logic;
|
||||
signal fifo_re : std_logic;
|
||||
signal fifo_empty : std_logic;
|
||||
signal fifo_full : std_logic;
|
||||
|
||||
signal flush_en : std_logic;
|
||||
signal flush_rdy : std_logic;
|
||||
signal flush_ptr_set : std_logic;
|
||||
signal flush_ptr : word_ptr_t;
|
||||
|
||||
signal fill_size : word_ptr_t;
|
||||
signal fill_cnt : word_ptr_t;
|
||||
signal fill_ptr : word_ptr_t;
|
||||
signal fill_rdy : std_logic;
|
||||
signal fill_cnt_set : std_logic;
|
||||
signal fill_cnt_adv : std_logic;
|
||||
signal fill_ptr_set : std_logic;
|
||||
signal fill_ptr_adv : std_logic;
|
||||
signal fill_remain : unsigned(1 downto 0);
|
||||
|
||||
signal nwords_free : word_ptr_t;
|
||||
|
||||
signal free_en : std_logic;
|
||||
signal uncommit_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_we_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 sipo_dout : unsigned(31 downto 0);
|
||||
signal sipo_dout_be : unsigned(3 downto 0);
|
||||
signal sipo_dout_vld : std_logic;
|
||||
signal sipo_rst : std_logic;
|
||||
|
||||
signal byte_count : word_ptr_t;
|
||||
signal byte_count_reg : word_ptr_t;
|
||||
signal rx_dv_r : std_logic;
|
||||
|
||||
type xfer_state_t is (xfer_init, xfer_idle, xfer_setup, xfer_wait, xfer_active, xfer_free);
|
||||
signal xfer_s, xfer_sn : xfer_state_t;
|
||||
|
||||
alias ram_data_in_a is ram_din_a(31 downto 0);
|
||||
alias ram_tag_in_a is ram_din_a(35 downto 32);
|
||||
alias ram_data_out_a is ram_dout_a(31 downto 0);
|
||||
alias ram_tag_out_a is ram_dout_a(35 downto 32);
|
||||
|
||||
alias ram_data_in_b is ram_din_b(31 downto 0);
|
||||
alias ram_tag_in_b is ram_din_b(35 downto 32);
|
||||
alias ram_data_out_b is ram_dout_b(31 downto 0);
|
||||
alias ram_tag_out_b is ram_dout_b(35 downto 32);
|
||||
|
||||
begin
|
||||
|
||||
dout <= sipo_dout;
|
||||
fifo_din <= sipo_dout_be & sipo_dout;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Transfer stuff
|
||||
------------------------------------------------------------------
|
||||
xfer_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
xfer_s <= xfer_init;
|
||||
else
|
||||
xfer_s <= xfer_sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
xfer_state:
|
||||
process(xfer_s, mii_rx_dv)
|
||||
begin
|
||||
|
||||
xfer_sn <= xfer_s;
|
||||
|
||||
case xfer_s is
|
||||
|
||||
when xfer_init =>
|
||||
xfer_sn <= xfer_idle;
|
||||
|
||||
when xfer_idle =>
|
||||
xfer_sn <= xfer_setup;
|
||||
|
||||
when xfer_setup =>
|
||||
xfer_sn <= xfer_wait;
|
||||
|
||||
when xfer_wait =>
|
||||
if mii_rx_dv = '1' then
|
||||
xfer_sn <= xfer_active;
|
||||
end if;
|
||||
|
||||
when xfer_active =>
|
||||
if mii_rx_dv = '0' then
|
||||
xfer_sn <= xfer_free;
|
||||
end if;
|
||||
|
||||
when xfer_free =>
|
||||
xfer_sn <= xfer_init;
|
||||
|
||||
when others =>
|
||||
xfer_sn <= xfer_idle;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
byte_counter:
|
||||
process(mii_rx_clk)
|
||||
begin
|
||||
if rising_edge(mii_rx_clk) then
|
||||
if mii_rx_dv = '0' then
|
||||
byte_count <= (others => '0');
|
||||
else
|
||||
byte_count <= byte_count + 1;
|
||||
end if;
|
||||
rx_dv_r <= mii_rx_dv;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
byte_count_register:
|
||||
process(mii_rx_clk)
|
||||
begin
|
||||
if rising_edge(mii_rx_clk) then
|
||||
if rst = '1' then
|
||||
byte_count_reg <= (others => '0');
|
||||
elsif rx_dv_r = '1' and mii_rx_dv = '0' then
|
||||
byte_count_reg <= byte_count;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sipo_rst <= not mii_rx_dv;
|
||||
------------------------------------------------------------------
|
||||
inst_ram : entity work.dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => RAM_ADDR_WIDTH,
|
||||
data_width => 36
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => ram_en_a,
|
||||
en_b => ram_en_b,
|
||||
we_a => ram_we_a,
|
||||
we_b => ram_we_b,
|
||||
addr_a => ram_addr_a,
|
||||
addr_b => ram_addr_b,
|
||||
din_a => ram_din_a,
|
||||
din_b => ram_din_b,
|
||||
dout_a => ram_dout_a,
|
||||
dout_b => ram_dout_b
|
||||
);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 5,
|
||||
data_width => 36,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk_w => clk,
|
||||
clk_r => mii_rx_clk,
|
||||
we => fifo_we,
|
||||
re => fifo_re,
|
||||
fifo_full => fifo_full,
|
||||
fifo_empty => fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => fifo_din,
|
||||
data_r => fifo_dout
|
||||
);
|
||||
|
||||
inst_sipo : entity work.sipo
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width_in => 8,
|
||||
data_width_out => 32,
|
||||
msb_first => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => sipo_rst,
|
||||
clk => mii_rx_clk,
|
||||
enable => '1',
|
||||
din_en => mii_rx_dv,
|
||||
din => mii_rx,
|
||||
dout_be => sipo_dout_be,
|
||||
dout_vld => sipo_dout_vld,
|
||||
dout => sipo_dout
|
||||
|
||||
);
|
||||
|
||||
end behavior;
|
||||
Reference in New Issue
Block a user