summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl
diff options
context:
space:
mode:
Diffstat (limited to 'netfpga10g/hdl')
-rw-r--r--netfpga10g/hdl/buff.vhd192
-rw-r--r--netfpga10g/hdl/dma.vhd640
-rw-r--r--netfpga10g/hdl/engine.vhd570
-rw-r--r--netfpga10g/hdl/eth.vhd219
-rw-r--r--netfpga10g/hdl/eth_rx.vhd84
-rw-r--r--netfpga10g/hdl/eth_tx.vhd68
-rw-r--r--netfpga10g/hdl/mdio.vhd223
-rw-r--r--netfpga10g/hdl/pcie.vhd268
-rw-r--r--netfpga10g/hdl/pcie_rx.vhd98
-rw-r--r--netfpga10g/hdl/pcie_tx.vhd178
-rw-r--r--netfpga10g/hdl/pcie_wrapper.vhd358
-rw-r--r--netfpga10g/hdl/port_fifo.vhd94
-rw-r--r--netfpga10g/hdl/recv_mux.vhd86
-rw-r--r--netfpga10g/hdl/rx_eth.vhd168
-rw-r--r--netfpga10g/hdl/send_mux.vhd77
-rw-r--r--netfpga10g/hdl/system_loop.vhd253
-rw-r--r--netfpga10g/hdl/top.vhd243
-rw-r--r--netfpga10g/hdl/tx_eth.vhd96
18 files changed, 3915 insertions, 0 deletions
diff --git a/netfpga10g/hdl/buff.vhd b/netfpga10g/hdl/buff.vhd
new file mode 100644
index 0000000..39b3a80
--- /dev/null
+++ b/netfpga10g/hdl/buff.vhd
@@ -0,0 +1,192 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+library UNISIM;
+use UNISIM.VComponents.all;
+
+entity buff is
+ Port ( wr_clk : in STD_LOGIC;
+ wr_en : in STD_LOGIC;
+ wr_data : in STD_LOGIC_VECTOR (63 downto 0);
+ wr_done : in STD_LOGIC;
+ wr_cancel : in std_logic := '0';
+ wr_accept : out STD_LOGIC;
+ rd_clk : in STD_LOGIC;
+ rd_en : in STD_LOGIC;
+ rd_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ rd_length : out STD_LOGIC_VECTOR (8 downto 0) := (others => '0');
+ rd_valid : out STD_LOGIC := '0');
+end buff;
+
+architecture arch of buff is
+
+ COMPONENT ram_4kB
+ PORT (
+ clka : IN STD_LOGIC;
+ wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
+ addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
+ dina : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
+ clkb : IN STD_LOGIC;
+ addrb : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
+ doutb : OUT STD_LOGIC_VECTOR(63 DOWNTO 0)
+ );
+ END COMPONENT;
+
+ signal ram_wr_en : std_logic_vector(0 downto 0);
+ signal ram_wr_addr : std_logic_vector(8 downto 0);
+ signal ram_wr_data : std_logic_vector(63 downto 0);
+
+ signal ram_rd_addr : std_logic_vector(8 downto 0);
+ signal ram_rd_data : std_logic_vector(63 downto 0);
+
+ constant W1 : std_logic_vector(1 downto 0) := "00";
+ constant W2 : std_logic_vector(1 downto 0) := "11";
+ constant R1 : std_logic_vector(1 downto 0) := "01";
+ constant R2 : std_logic_vector(1 downto 0) := "10";
+
+ signal wr_owner : std_logic_vector(1 downto 0) := W1;
+ signal rd_owner : std_logic_vector(1 downto 0) := W1;
+ signal wr_owner_tmp : std_logic_vector(1 downto 0) := W1;
+ signal wr_owner_sync : std_logic_vector(1 downto 0) := W1;
+
+ -- MAX: 256 bytes less than 4kB, for ouroboros
+ -- 4kB = 512 x 64 bits
+ -- 256 bytes = 32 x 64 bits
+ -- 512 - 32 = 480
+ -- 480 = "111100000"
+
+ constant MAX : std_logic_vector(8 downto 0) := "111100000";
+ constant ZERO : std_logic_vector(8 downto 0) := "000000000";
+ constant ONE : std_logic_vector(8 downto 0) := "000000001";
+
+ type state_t is (state_empty, state_wait, state_full, state_first, state_valid);
+
+ signal rd_state : state_t := state_empty;
+ signal rd_addr : std_logic_vector(8 downto 0) := MAX;
+
+begin
+
+ ram : ram_4kB
+ PORT MAP (
+ clka => wr_clk,
+ wea => ram_wr_en,
+ addra => ram_wr_addr,
+ dina => ram_wr_data,
+ clkb => rd_clk,
+ addrb => ram_rd_addr,
+ doutb => ram_rd_data
+ );
+
+ wr_accept <= '1' when (wr_owner = W1 or wr_owner = W2) and wr_done = '0' and wr_cancel = '0' else '0';
+
+ process (wr_clk)
+ variable wr_count : std_logic_vector(8 downto 0) := ZERO;
+ begin
+ if rising_edge(wr_clk) then
+ ram_wr_en(0) <= '0';
+ ram_wr_addr <= (others => '0');
+ ram_wr_data <= (others => '0');
+
+ if wr_owner = W1 or wr_owner = W2 then
+ if wr_cancel = '1' then
+ wr_count := ZERO;
+
+ elsif wr_done = '1' then
+ if wr_count /= ZERO then
+ if wr_owner = W1 then
+ wr_owner <= R1;
+ ram_wr_data(1 downto 0) <= R1;
+ else
+ wr_owner <= R2;
+ ram_wr_data(1 downto 0) <= R2;
+ end if;
+
+ ram_wr_en(0) <= '1';
+ ram_wr_addr <= MAX;
+ ram_wr_data(10 downto 2) <= wr_count;
+ wr_count := ZERO;
+ end if;
+
+ elsif wr_en = '1' then
+ if wr_count /= MAX then
+ ram_wr_en(0) <= '1';
+ ram_wr_addr <= wr_count;
+ ram_wr_data <= wr_data;
+ wr_count := std_logic_vector(unsigned(wr_count) + 1);
+ end if;
+ end if;
+ elsif wr_owner = R1 then
+ if wr_owner_sync = W2 then
+ wr_owner <= W2;
+ end if;
+ elsif wr_owner = R2 then
+ if wr_owner_sync = W1 then
+ wr_owner <= W1;
+ end if;
+ end if;
+
+ wr_owner_tmp <= rd_owner;
+ wr_owner_sync <= wr_owner_tmp;
+ end if;
+ end process;
+
+ ram_rd_addr <= std_logic_vector(unsigned(rd_addr) + 1)
+ when rd_state = state_valid and rd_en = '1'
+ else rd_addr;
+
+ process (rd_clk)
+ variable rd_count : std_logic_vector(8 downto 0) := ZERO;
+ variable tmp : std_logic_vector(1 downto 0);
+ begin
+ if rising_edge(rd_clk) then
+ if rd_state = state_empty then
+ rd_state <= state_wait;
+
+ elsif rd_state = state_wait then
+ tmp := ram_rd_data(1 downto 0);
+
+ if (rd_owner = W1 and tmp = R1) or
+ (rd_owner = W2 and tmp = R2) then
+
+ rd_state <= state_full;
+ rd_addr <= ZERO;
+ rd_count := ram_rd_data(10 downto 2);
+ rd_owner <= tmp;
+ end if;
+
+ elsif rd_state = state_full then
+ rd_state <= state_first;
+ rd_addr <= ONE;
+
+ elsif rd_state = state_first then
+ rd_state <= state_valid;
+ rd_valid <= '1';
+ rd_data <= ram_rd_data;
+ rd_length <= rd_count;
+
+ elsif rd_state = state_valid then
+ if rd_en = '1' then
+ if rd_addr = rd_count then
+ rd_state <= state_empty;
+ rd_addr <= MAX;
+ rd_valid <= '0';
+ rd_data <= (others => '0');
+ rd_length <= ZERO;
+ rd_count := ZERO;
+
+ if rd_owner = R1 then
+ rd_owner <= W2;
+ else
+ rd_owner <= W1;
+ end if;
+ else
+ rd_addr <= ram_rd_addr;
+ rd_data <= ram_rd_data;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/dma.vhd b/netfpga10g/hdl/dma.vhd
new file mode 100644
index 0000000..4c7e4f8
--- /dev/null
+++ b/netfpga10g/hdl/dma.vhd
@@ -0,0 +1,640 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity dma is
+generic (
+ BITS : integer := 14
+);
+port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ rx_read : in std_logic;
+ rx_write : in std_logic;
+ rx_complete : in std_logic;
+ rx_data : in std_logic_vector(63 downto 0);
+ rx_address : in std_logic_vector(28 downto 0);
+
+ tx_read : out std_logic;
+ tx_write : out std_logic;
+ tx_complete : out std_logic;
+ tx_data : out std_logic_vector(63 downto 0);
+ tx_address : out std_logic_vector(28 downto 0);
+ tx_length : out std_logic_vector(8 downto 0);
+ tx_accept : in std_logic;
+ tx_done : in std_logic;
+
+ port0_read : out std_logic;
+ port0_rd_data : in std_logic_vector(63 downto 0);
+ port0_rd_empty : in std_logic;
+ port0_rd_count : in std_logic_vector(BITS downto 0);
+
+ port0_write : out std_logic;
+ port0_wr_data : out std_logic_vector(63 downto 0);
+ port0_wr_full : in std_logic;
+ port0_wr_count : in std_logic_vector(BITS downto 0);
+
+ port1_read : out std_logic;
+ port1_rd_data : in std_logic_vector(63 downto 0);
+ port1_rd_empty : in std_logic;
+ port1_rd_count : in std_logic_vector(BITS downto 0);
+
+ port1_write : out std_logic;
+ port1_wr_data : out std_logic_vector(63 downto 0);
+ port1_wr_full : in std_logic;
+ port1_wr_count : in std_logic_vector(BITS downto 0);
+
+ port2_read : out std_logic;
+ port2_rd_data : in std_logic_vector(63 downto 0);
+ port2_rd_empty : in std_logic;
+ port2_rd_count : in std_logic_vector(BITS downto 0);
+
+ port2_write : out std_logic;
+ port2_wr_data : out std_logic_vector(63 downto 0);
+ port2_wr_full : in std_logic;
+ port2_wr_count : in std_logic_vector(BITS downto 0);
+
+ port3_read : out std_logic;
+ port3_rd_data : in std_logic_vector(63 downto 0);
+ port3_rd_empty : in std_logic;
+ port3_rd_count : in std_logic_vector(BITS downto 0);
+
+ port3_write : out std_logic;
+ port3_wr_data : out std_logic_vector(63 downto 0);
+ port3_wr_full : in std_logic;
+ port3_wr_count : in std_logic_vector(BITS downto 0);
+
+ max_read : in std_logic_vector(2 downto 0);
+ max_write : in std_logic_vector(2 downto 0);
+
+ interrupt : out std_logic;
+ interrupt_rdy : in std_logic;
+
+ mdio_command : out std_logic_vector(0 to 27);
+ mdio_data : in std_logic_vector(0 to 15);
+ mdio_enable : out std_logic;
+ mdio_done : in std_logic;
+
+ leds : out std_logic_vector(2 downto 0)
+);
+end dma;
+
+architecture arch of dma is
+ type state_t is (state_idle, state_tx_read, state_tx_write, state_tx_complete, state_rx_complete,
+ state_dma_read, state_dma_write, state_interrupt, state_command,
+ state_test_write_head, state_test_write,
+ state_test_read_head, state_test_read, state_test_complete,
+ state_mdio);
+ signal state : state_t;
+
+ signal fifo_read : std_logic;
+ signal fifo_write : std_logic;
+ signal fifo_din : std_logic_vector(63 downto 0);
+ signal fifo_dout : std_logic_vector(63 downto 0);
+ signal fifo_full : std_logic;
+ signal fifo_empty : std_logic;
+ signal fifo_count : std_logic_vector(BITS downto 0);
+
+ component simple_fifo port (
+ clk : in std_logic;
+ rst : in std_logic;
+ rd_en : in std_logic;
+ wr_en : in std_logic;
+ din : in std_logic_vector(63 downto 0);
+ dout : out std_logic_vector(63 downto 0);
+ full : out std_logic;
+ empty : out std_logic;
+ data_count : out std_logic_vector(BITS downto 0)
+ );
+ end component;
+
+ signal cmd_read : std_logic;
+ signal cmd_write : std_logic;
+ signal cmd_din : std_logic_vector(63 downto 0);
+ signal cmd_dout : std_logic_vector(63 downto 0);
+ signal cmd_full : std_logic;
+ signal cmd_empty : std_logic;
+
+ component cmd_fifo port (
+ clk : in std_logic;
+ rst : in std_logic;
+ rd_en : in std_logic;
+ wr_en : in std_logic;
+ din : in std_logic_vector(63 downto 0);
+ dout : out std_logic_vector(63 downto 0);
+ full : out std_logic;
+ empty : out std_logic
+ );
+ end component;
+
+ signal test_completion : std_logic_vector(63 downto 0);
+begin
+ process (clk, reset)
+ variable bar_addr : unsigned(BITS downto 0);
+ variable dma_addr : unsigned(28 downto 0);
+ variable length : unsigned(BITS downto 0);
+ variable remain : unsigned(BITS downto 0);
+ variable cycles : unsigned(BITS downto 0);
+ variable backup_addr : unsigned(28 downto 0);
+ variable backup_length : unsigned(BITS downto 0);
+ begin
+ if reset = '1' then
+ state <= state_idle;
+ tx_read <= '0';
+ tx_write <= '0';
+ tx_complete <= '0';
+ tx_data <= (others => '0');
+ tx_address <= (others => '0');
+ tx_length <= (others => '0');
+ fifo_read <= '0';
+ fifo_write <= '0';
+ fifo_din <= (others => '0');
+ interrupt <= '0';
+ cmd_read <= '0';
+ cmd_write <= '0';
+ cmd_din <= (others => '0');
+ test_completion <= (others => '0');
+ port0_read <= '0';
+ port0_write <= '0';
+ port0_wr_data <= (others => '0');
+ port1_read <= '0';
+ port1_write <= '0';
+ port1_wr_data <= (others => '0');
+ port2_read <= '0';
+ port2_write <= '0';
+ port2_wr_data <= (others => '0');
+ port3_read <= '0';
+ port3_write <= '0';
+ port3_wr_data <= (others => '0');
+ mdio_enable <= '0';
+ mdio_command <= (others => '0');
+
+ elsif rising_edge(clk) then
+ fifo_read <= '0';
+ fifo_write <= '0';
+ fifo_din <= (others => '0');
+ cmd_read <= '0';
+ cmd_write <= '0';
+ cmd_din <= (others => '0');
+ port0_read <= '0';
+ port0_write <= '0';
+ port1_read <= '0';
+ port1_write <= '0';
+ port2_read <= '0';
+ port2_write <= '0';
+ port3_read <= '0';
+ port3_write <= '0';
+
+ -- bar read
+ if state = state_idle and rx_read = '1' then
+ state <= state_tx_complete;
+ tx_complete <= '1';
+ tx_data <= (others => '0');
+ tx_address <= rx_address;
+ bar_addr := unsigned(rx_address(BITS downto 0));
+
+ -- read fifo
+ if bar_addr = 0 then
+ if fifo_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= fifo_dout;
+ fifo_read <= '1';
+ end if;
+
+ -- read command
+ elsif bar_addr = 1 then
+ if cmd_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= cmd_dout;
+ cmd_read <= '1';
+ end if;
+
+ -- other
+ elsif bar_addr = 3 then
+ tx_data(BITS downto 0) <= fifo_count;
+
+ elsif bar_addr = 4 then
+ tx_data(2 downto 0) <= max_read;
+
+ elsif bar_addr = 5 then
+ tx_data(2 downto 0) <= max_write;
+
+ elsif bar_addr = 6 then
+ tx_data <= test_completion;
+
+ -- read ports
+ elsif bar_addr = 10 then
+ if port0_rd_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= port0_rd_data;
+ port0_read <= '1';
+ end if;
+
+ elsif bar_addr = 11 then
+ if port1_rd_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= port1_rd_data;
+ port1_read <= '1';
+ end if;
+
+ elsif bar_addr = 12 then
+ if port2_rd_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= port2_rd_data;
+ port2_read <= '1';
+ end if;
+
+ elsif bar_addr = 13 then
+ if port3_rd_empty = '1' then
+ tx_data <= (others => '1');
+ else
+ tx_data <= port3_rd_data;
+ port3_read <= '1';
+ end if;
+
+ -- read counts
+ elsif bar_addr = 20 then
+ tx_data(BITS downto 0) <= port0_rd_count;
+
+ elsif bar_addr = 21 then
+ tx_data(BITS downto 0) <= port0_wr_count;
+
+ elsif bar_addr = 22 then
+ tx_data(BITS downto 0) <= port1_rd_count;
+
+ elsif bar_addr = 23 then
+ tx_data(BITS downto 0) <= port1_wr_count;
+
+ elsif bar_addr = 24 then
+ tx_data(BITS downto 0) <= port2_rd_count;
+
+ elsif bar_addr = 25 then
+ tx_data(BITS downto 0) <= port2_wr_count;
+
+ elsif bar_addr = 26 then
+ tx_data(BITS downto 0) <= port3_rd_count;
+
+ elsif bar_addr = 27 then
+ tx_data(BITS downto 0) <= port3_wr_count;
+
+ -- read mdio
+ elsif bar_addr = 30 then
+ tx_data(15 downto 0) <= mdio_data;
+ end if;
+
+ elsif state = state_tx_complete then
+ if tx_done = '1' then
+ state <= state_idle;
+ end if;
+
+ -- bar write
+ elsif state = state_idle and rx_write = '1' then
+ bar_addr := unsigned(rx_address(BITS downto 0));
+
+ -- write fifo
+ if bar_addr = 0 then
+ if fifo_full = '0' then
+ fifo_din <= rx_data;
+ fifo_write <= '1';
+ end if;
+
+ -- write command
+ elsif bar_addr = 1 then
+ if cmd_full = '0' then
+ cmd_din <= rx_data;
+ cmd_write <= '1';
+ end if;
+
+ if rx_data(0) = '1' then
+ state <= state_command;
+ end if;
+
+ -- write test
+ elsif bar_addr = 2 then
+ dma_addr := unsigned(rx_data(31 downto 3));
+ length := unsigned(rx_data(BITS+32 downto 32));
+ cycles := unsigned(rx_data(BITS+48 downto 48));
+ backup_addr := dma_addr;
+ backup_length := length;
+
+ if rx_data(1) = '0' then
+ state <= state_test_read_head;
+ else
+ state <= state_test_write_head;
+ end if;
+
+ -- write ports
+ elsif bar_addr = 10 then
+ if port0_wr_full = '0' then
+ port0_wr_data <= rx_data;
+ port0_write <= '1';
+ end if;
+
+ elsif bar_addr = 11 then
+ if port1_wr_full = '0' then
+ port1_wr_data <= rx_data;
+ port1_write <= '1';
+ end if;
+
+ elsif bar_addr = 12 then
+ if port2_wr_full = '0' then
+ port2_wr_data <= rx_data;
+ port2_write <= '1';
+ end if;
+
+ elsif bar_addr = 13 then
+ if port3_wr_full = '0' then
+ port3_wr_data <= rx_data;
+ port3_write <= '1';
+ end if;
+
+ -- write mdio
+ elsif bar_addr = 30 then
+ state <= state_mdio;
+ mdio_enable <= '1';
+ mdio_command <= rx_data(27 downto 0);
+ end if;
+
+ -- mdio
+ elsif state = state_mdio then
+ if mdio_done = '1' then
+ mdio_enable <= '0';
+ state <= state_interrupt;
+ interrupt <= '1';
+ end if;
+
+ -- test read
+ elsif state = state_test_read_head then
+ remain := 16 - resize(dma_addr(3 downto 0), remain'length);
+
+ if max_read = "001" then
+ remain := 32 - resize(dma_addr(4 downto 0), remain'length);
+ elsif max_read = "010" then
+ remain := 64 - resize(dma_addr(5 downto 0), remain'length);
+ elsif max_read = "011" then
+ remain := 128 - resize(dma_addr(6 downto 0), remain'length);
+ elsif max_read = "100" then
+ remain := 256 - resize(dma_addr(7 downto 0), remain'length);
+ elsif max_read = "101" then
+ remain := 512 - resize(dma_addr(8 downto 0), remain'length);
+ end if;
+
+ if remain > length then
+ remain := length;
+ end if;
+
+ state <= state_test_read;
+ tx_read <= '1';
+ tx_address <= std_logic_vector(dma_addr);
+ tx_length <= std_logic_vector(remain(8 downto 0));
+ length := length - remain;
+ dma_addr := dma_addr + remain;
+
+ elsif state = state_test_read then
+ if tx_done = '1' then
+ state <= state_test_complete;
+ end if;
+
+ elsif state = state_test_complete then
+ if rx_complete = '1' then
+ test_completion <= rx_data;
+ remain := remain - 1;
+
+ if remain = 0 then
+ if length > 0 then
+ state <= state_test_read_head;
+
+ elsif cycles > 1 then
+ state <= state_test_read_head;
+ dma_addr := backup_addr;
+ length := backup_length;
+ cycles := cycles - 1;
+ else
+ state <= state_interrupt;
+ interrupt <= '1';
+ end if;
+ end if;
+ end if;
+
+ -- test write
+ elsif state = state_test_write_head then
+ remain := 16 - resize(dma_addr(3 downto 0), remain'length);
+
+ if max_write = "001" then
+ remain := 32 - resize(dma_addr(4 downto 0), remain'length);
+ elsif max_write = "010" then
+ remain := 64 - resize(dma_addr(5 downto 0), remain'length);
+ elsif max_write = "011" then
+ remain := 128 - resize(dma_addr(6 downto 0), remain'length);
+ elsif max_write = "100" then
+ remain := 256 - resize(dma_addr(7 downto 0), remain'length);
+ elsif max_write = "101" then
+ remain := 512 - resize(dma_addr(8 downto 0), remain'length);
+ end if;
+
+ if remain > length then
+ remain := length;
+ end if;
+
+ state <= state_test_write;
+ tx_write <= '1';
+ tx_data <= x"FFEEDDCC00000000";
+ tx_address <= std_logic_vector(dma_addr);
+ tx_length <= std_logic_vector(remain(8 downto 0));
+ length := length - remain;
+ dma_addr := dma_addr + remain;
+
+ elsif state = state_test_write then
+ if tx_done = '1' then
+ if length > 0 then
+ state <= state_test_write_head;
+
+ elsif cycles > 1 then
+ state <= state_test_write_head;
+ dma_addr := backup_addr;
+ length := backup_length;
+ cycles := cycles - 1;
+ else
+ state <= state_interrupt;
+ interrupt <= '1';
+ end if;
+ end if;
+
+ -- command
+ elsif state = state_command then
+ if cmd_empty = '1' then
+ state <= state_interrupt;
+ interrupt <= '1';
+ else
+ cmd_read <= '1';
+
+ if cmd_dout(1) = '0' then
+ state <= state_dma_read;
+ dma_addr := unsigned(cmd_dout(31 downto 3));
+ length := unsigned(cmd_dout(BITS+32 downto 32));
+ fifo_din <= std_logic_vector(resize(length, fifo_din'length));
+ fifo_write <= '1';
+ else
+ state <= state_dma_write;
+ dma_addr := unsigned(cmd_dout(31 downto 3));
+ length := unsigned(fifo_dout(BITS downto 0)) + 1;
+ end if;
+ end if;
+
+ elsif state = state_interrupt then
+ if interrupt_rdy = '1' then
+ state <= state_idle;
+ interrupt <= '0';
+ end if;
+
+ -- dma read
+ elsif state = state_dma_read then
+ remain := 16 - resize(dma_addr(3 downto 0), remain'length);
+
+ if max_read = "001" then
+ remain := 32 - resize(dma_addr(4 downto 0), remain'length);
+ elsif max_read = "010" then
+ remain := 64 - resize(dma_addr(5 downto 0), remain'length);
+ elsif max_read = "011" then
+ remain := 128 - resize(dma_addr(6 downto 0), remain'length);
+ elsif max_read = "100" then
+ remain := 256 - resize(dma_addr(7 downto 0), remain'length);
+ elsif max_read = "101" then
+ remain := 512 - resize(dma_addr(8 downto 0), remain'length);
+ end if;
+
+ if remain > length then
+ remain := length;
+ end if;
+
+ state <= state_tx_read;
+ tx_read <= '1';
+ tx_address <= std_logic_vector(dma_addr);
+ tx_length <= std_logic_vector(remain(8 downto 0));
+ length := length - remain;
+ dma_addr := dma_addr + remain;
+
+ elsif state = state_tx_read then
+ if tx_done = '1' then
+ state <= state_rx_complete;
+ end if;
+
+ elsif state = state_rx_complete then
+ if rx_complete = '1' then
+ fifo_din <= rx_data;
+ fifo_write <= '1';
+ remain := remain - 1;
+
+ if remain = 0 then
+ if length > 0 then
+ state <= state_dma_read;
+ else
+ state <= state_command;
+ end if;
+ end if;
+ end if;
+
+ -- dma write
+ elsif state = state_dma_write then
+ remain := 16 - resize(dma_addr(3 downto 0), remain'length);
+
+ if max_write = "001" then
+ remain := 32 - resize(dma_addr(4 downto 0), remain'length);
+ elsif max_write = "010" then
+ remain := 64 - resize(dma_addr(5 downto 0), remain'length);
+ elsif max_write = "011" then
+ remain := 128 - resize(dma_addr(6 downto 0), remain'length);
+ elsif max_write = "100" then
+ remain := 256 - resize(dma_addr(7 downto 0), remain'length);
+ elsif max_write = "101" then
+ remain := 512 - resize(dma_addr(8 downto 0), remain'length);
+ end if;
+
+ if remain > length then
+ remain := length;
+ end if;
+
+ state <= state_tx_write;
+ tx_write <= '1';
+ tx_data <= fifo_dout;
+ tx_address <= std_logic_vector(dma_addr);
+ tx_length <= std_logic_vector(remain(8 downto 0));
+ fifo_read <= '1';
+ length := length - remain;
+ dma_addr := dma_addr + remain;
+ remain := remain - 1;
+
+ elsif state = state_tx_write then
+ if tx_done = '1' then
+ if length > 0 then
+ state <= state_dma_write;
+ else
+ state <= state_command;
+ end if;
+
+ elsif tx_accept = '1' and remain > 0 then
+ tx_data <= fifo_dout;
+ fifo_read <= '1';
+ remain := remain - 1;
+ end if;
+ end if;
+
+ if tx_done = '1' then
+ tx_read <= '0';
+ tx_write <= '0';
+ tx_complete <= '0';
+ tx_data <= (others => '0');
+ tx_address <= (others => '0');
+ tx_length <= (others => '0');
+ end if;
+ end if;
+ end process;
+
+ fifo : entity work.port_fifo port map (
+ reset => reset,
+
+ rd_clk => clk,
+ rd_read => fifo_read,
+ rd_data => fifo_dout,
+ rd_empty => fifo_empty,
+ rd_count => fifo_count,
+
+ wr_write => fifo_write,
+ wr_data => fifo_din,
+ wr_full => fifo_full
+ --wr_count => wr_count
+ );
+
+ commands : cmd_fifo port map (
+ clk => clk,
+ rst => reset,
+ rd_en => cmd_read,
+ wr_en => cmd_write,
+ din => cmd_din,
+ dout => cmd_dout,
+ full => cmd_full,
+ empty => cmd_empty
+ );
+
+ leds <= "000" when state = state_idle else
+ -- bar read
+ "001" when state = state_tx_complete else
+ -- dma read
+ "010" when state = state_dma_read or state = state_tx_read or state = state_rx_complete else
+ -- dma write
+ "011" when state = state_dma_write or state = state_tx_write else
+ -- mdio
+ "100" when state = state_mdio else
+ -- interrupt
+ "101" when state = state_interrupt else
+ -- other
+ "111";
+end arch;
+
diff --git a/netfpga10g/hdl/engine.vhd b/netfpga10g/hdl/engine.vhd
new file mode 100644
index 0000000..16f0a8b
--- /dev/null
+++ b/netfpga10g/hdl/engine.vhd
@@ -0,0 +1,570 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+library UNISIM;
+use UNISIM.VComponents.all;
+
+entity engine is
+generic (
+ BUFF_COUNT : integer := 16;
+ BUFF_BITS : integer := 4; -- 2^4 = 16
+ BAR_BITS : integer := 17;
+ TIME_BITS : integer := 20
+);
+port (
+ clk : in STD_LOGIC;
+
+ rd_buff : out STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0) := (others => '0');
+ rd_en : out STD_LOGIC := '0';
+ rd_data : in STD_LOGIC_VECTOR (63 downto 0);
+ rd_length : in STD_LOGIC_VECTOR (8 downto 0);
+ rd_valid : in STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+
+ wr_buff : out STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0) := (others => '0');
+ wr_en : out STD_LOGIC := '0';
+ wr_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ wr_done : out STD_LOGIC := '0';
+ wr_cancel : out STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+ wr_accept : in STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+
+ rx_read : in STD_LOGIC;
+ rx_write : in STD_LOGIC;
+ rx_complete : in STD_LOGIC;
+ rx_data : in STD_LOGIC_VECTOR (63 downto 0);
+ rx_address : in STD_LOGIC_VECTOR (63 downto 3);
+ rx_tag : in std_logic_vector(4 downto 0);
+
+ tx_read : out STD_LOGIC := '0';
+ tx_write : out STD_LOGIC := '0';
+ tx_complete : out STD_LOGIC := '0';
+ tx_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ tx_address : out STD_LOGIC_VECTOR (63 downto 3) := (others => '0');
+ tx_length : out STD_LOGIC_VECTOR (8 downto 0) := (others => '0');
+ tx_tag : out std_logic_vector(4 downto 0) := (others => '0');
+ tx_accept : in STD_LOGIC;
+ tx_done : in STD_LOGIC;
+
+ interrupt : out std_logic := '0';
+ interrupt_rdy : in std_logic;
+
+ max_read : in std_logic_vector(2 downto 0);
+ max_write : in std_logic_vector(2 downto 0);
+
+ mdio_command : out std_logic_vector(0 to 27) := (others => '0');
+ mdio_data : in std_logic_vector(0 to 15);
+ mdio_enable : out std_logic := '0';
+ mdio_done : in std_logic
+);
+end engine;
+
+architecture arch of engine is
+
+ constant BUFF_EMPTY : std_logic_vector(1 downto 0) := "00";
+ constant BUFF_ADDR : std_logic_vector(1 downto 0) := "01";
+ constant BUFF_DATA : std_logic_vector(1 downto 0) := "10";
+ constant BUFF_FULL : std_logic_vector(1 downto 0) := "11";
+
+ type buff_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(1 downto 0);
+ type length_t is array (0 to BUFF_COUNT - 1) of unsigned(8 downto 0);
+ type address_t is array (0 to BUFF_COUNT - 1) of unsigned(63 downto 3);
+ type time_t is array (0 to BUFF_COUNT - 1) of unsigned(TIME_BITS - 1 downto 0);
+
+ type rx_state_t is (rx_state_idle, rx_state_write_done, rx_state_mdio);
+ type tx_state_t is (tx_state_idle, tx_state_read, tx_state_write,
+ tx_state_complete, tx_state_interrupt);
+
+ signal rx_state : rx_state_t := rx_state_idle;
+ signal tx_state : tx_state_t := tx_state_idle;
+
+ signal tx_data_i : std_logic_vector(63 downto 0) := (others => '0');
+
+ constant CMD_STATUS : std_logic_vector(1 downto 0) := "00";
+ constant CMD_SEND : std_logic_vector(1 downto 0) := "01";
+ constant CMD_RECV : std_logic_vector(1 downto 0) := "10";
+ constant CMD_MDIO : std_logic_vector(1 downto 0) := "11";
+
+ signal send_buff : buff_t := (others => BUFF_FULL);
+ signal send_length : length_t := (others => (others => '0'));
+ signal send_remain : length_t := (others => (others => '0'));
+ signal send_address : address_t := (others => (others => '0'));
+ signal send_read_time : time_t := (others => (others => '0'));
+
+ signal recv_buff : buff_t := (others => BUFF_EMPTY);
+ signal recv_address0 : unsigned(63 downto 3);
+ signal recv_address1 : unsigned(63 downto 3);
+ signal recv_address2 : unsigned(63 downto 3);
+ signal recv_address3 : unsigned(63 downto 3);
+ signal recv_address4 : unsigned(63 downto 3);
+ signal recv_address5 : unsigned(63 downto 3);
+ signal recv_address6 : unsigned(63 downto 3);
+ signal recv_address7 : unsigned(63 downto 3);
+ signal recv_address8 : unsigned(63 downto 3);
+ signal recv_address9 : unsigned(63 downto 3);
+ signal recv_address10 : unsigned(63 downto 3);
+ signal recv_address11 : unsigned(63 downto 3);
+ signal recv_address12 : unsigned(63 downto 3);
+ signal recv_address13 : unsigned(63 downto 3);
+ signal recv_address14 : unsigned(63 downto 3);
+ signal recv_address15 : unsigned(63 downto 3);
+
+ signal send_int : std_logic := '0';
+ signal send_int_needed : std_logic := '0';
+ signal send_read : std_logic := '0';
+ signal send_read_done : std_logic := '0';
+ signal send_read_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+ signal send_read_length : unsigned(8 downto 0);
+ signal send_read_remain : unsigned(8 downto 0);
+ signal send_read_address : unsigned(63 downto 3);
+ signal send_write : std_logic := '0';
+ signal send_write_new : std_logic := '0';
+ signal send_write_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+ signal send_write_length : unsigned(8 downto 0);
+ signal send_write_address : unsigned(63 downto 3);
+
+ signal debug_address : std_logic_vector(63 downto 3) := (others => '0');
+ signal debug_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal debug_cmd : std_logic_vector(1 downto 0) := (others => '0');
+ signal debug_buff : std_logic_vector(BUFF_BITS - 1 downto 0) := (others => '0');
+ signal debug_length : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(42, 9));
+
+ signal debug_cmpl_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_cmpl_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal debug_cmpl_tag : std_logic_vector(4 downto 0) := (others => '0');
+ signal debug_cmpl_state : std_logic_vector(7 downto 0) := x"FF";
+
+ signal debug_write_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_write_length : std_logic_vector(8 downto 0) := (others => '0');
+ signal debug_write_addr : std_logic_vector(63 downto 3) := (others => '0');
+ signal debug_write_data : std_logic_vector(63 downto 0) := (others => '0');
+
+ signal debug_accept_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_done_count : unsigned(7 downto 0) := (others => '0');
+
+ signal timer : unsigned(TIME_BITS - 1 downto 0) := (others => '0');
+begin
+ rd_en <= tx_accept when tx_state = tx_state_write else '0';
+
+ tx_data <= rd_data when tx_state = tx_state_write else tx_data_i;
+
+ process (clk)
+ variable bar_read : std_logic := '0';
+ variable bar_read_address : std_logic_vector(63 downto 3) := (others => '0');
+
+ variable tmp_cmd : std_logic_vector(1 downto 0);
+ variable tmp_buff : integer range 0 to BUFF_COUNT - 1;
+ variable tmp_length : unsigned(8 downto 0);
+ variable tmp_remain : unsigned(8 downto 0);
+ variable tmp_address : unsigned(63 downto 3);
+ variable tmp_bar : unsigned(BAR_BITS - 1 downto 0);
+
+ -- see 'metered reads' in pcie core manual (xilinx)
+ -- a maximum of 8 openstanding reads is allowed
+ constant READ_MAX : unsigned(3 downto 0) := x"8";
+ variable read_count : unsigned(3 downto 0) := (others => '0');
+ variable read_decr : std_logic;
+ variable read_incr : std_logic;
+ begin
+ if rising_edge(clk) then
+ wr_en <= '0';
+ wr_data <= (others => '0');
+ wr_done <= '0';
+ wr_cancel <= (others => '0');
+ read_decr := '0';
+ read_incr := '0';
+
+ timer <= timer + 1;
+
+ -- ENGINE: RX
+ if rx_state = rx_state_idle then
+ if rx_read = '1' then
+ bar_read := '1';
+ bar_read_address := rx_address;
+
+ elsif rx_write = '1' then
+ tmp_cmd := rx_address(4 downto 3);
+ tmp_buff := to_integer(unsigned(rx_address(5 + BUFF_BITS - 1 downto 5)));
+ tmp_length := unsigned(rx_address(18 downto 10));
+ tmp_address := unsigned(rx_data(63 downto 3));
+
+ debug_address <= rx_address;
+ debug_data <= rx_data;
+ debug_cmd <= tmp_cmd;
+ debug_buff <= std_logic_vector(to_unsigned(tmp_buff, debug_buff'length));
+ debug_length <= std_logic_vector(tmp_length);
+
+ if tmp_cmd = CMD_SEND then
+ if send_buff(tmp_buff) = BUFF_EMPTY then
+ send_buff(tmp_buff) <= BUFF_ADDR;
+ send_address(tmp_buff) <= tmp_address;
+ send_length(tmp_buff) <= tmp_length;
+ end if;
+
+ elsif tmp_cmd = CMD_RECV then
+ if recv_buff(tmp_buff) = BUFF_FULL then
+ recv_buff(tmp_buff) <= BUFF_ADDR;
+
+ if tmp_buff = 0 then
+ recv_address0 <= tmp_address;
+ elsif tmp_buff = 1 then
+ recv_address1 <= tmp_address;
+ elsif tmp_buff = 2 then
+ recv_address2 <= tmp_address;
+ elsif tmp_buff = 3 then
+ recv_address3 <= tmp_address;
+ elsif tmp_buff = 4 then
+ recv_address4 <= tmp_address;
+ elsif tmp_buff = 5 then
+ recv_address5 <= tmp_address;
+ elsif tmp_buff = 6 then
+ recv_address6 <= tmp_address;
+ elsif tmp_buff = 7 then
+ recv_address7 <= tmp_address;
+ elsif tmp_buff = 8 then
+ recv_address8 <= tmp_address;
+ elsif tmp_buff = 9 then
+ recv_address9 <= tmp_address;
+ elsif tmp_buff = 10 then
+ recv_address10 <= tmp_address;
+ elsif tmp_buff = 11 then
+ recv_address11 <= tmp_address;
+ elsif tmp_buff = 12 then
+ recv_address12 <= tmp_address;
+ elsif tmp_buff = 13 then
+ recv_address13 <= tmp_address;
+ elsif tmp_buff = 14 then
+ recv_address14 <= tmp_address;
+ elsif tmp_buff = 15 then
+ recv_address15 <= tmp_address;
+ end if;
+ end if;
+
+ elsif tmp_cmd = CMD_MDIO then
+ rx_state <= rx_state_mdio;
+ mdio_enable <= '1';
+ mdio_command <= rx_data(27 downto 0);
+ end if;
+
+ elsif rx_complete = '1' then
+ tmp_buff := to_integer(unsigned(rx_tag(BUFF_BITS - 1 downto 0)));
+
+ debug_cmpl_count <= debug_cmpl_count + 1;
+ debug_cmpl_data <= rx_data;
+ debug_cmpl_tag <= rx_tag;
+ debug_cmpl_state <= x"00";
+
+ if send_buff(tmp_buff) = BUFF_DATA then
+ wr_en <= '1';
+ wr_data <= rx_data;
+ wr_buff <= std_logic_vector(to_unsigned(tmp_buff, BUFF_BITS));
+ send_remain(tmp_buff) <= send_remain(tmp_buff) - 1;
+ debug_cmpl_state <= x"01";
+
+ if send_remain(tmp_buff) = 1 then
+ read_decr := '1';
+
+ if send_length(tmp_buff) = 0 then
+ rx_state <= rx_state_write_done;
+ debug_cmpl_state <= x"02";
+ else
+ send_buff(tmp_buff) <= BUFF_ADDR;
+ debug_cmpl_state <= x"03";
+ end if;
+ end if;
+ end if;
+ end if;
+
+ elsif rx_state = rx_state_write_done then
+ rx_state <= rx_state_idle;
+ wr_done <= '1';
+
+ elsif rx_state = rx_state_mdio then
+ if mdio_done = '1' then
+ rx_state <= rx_state_idle;
+ mdio_enable <= '0';
+ end if;
+ end if;
+
+ -- ENGINE: TX
+ if send_read_done = '1' then
+ send_read_done <= '0';
+ send_buff(send_read_buff) <= BUFF_DATA;
+ send_length(send_read_buff) <= send_read_length - send_read_remain;
+ send_remain(send_read_buff) <= send_read_remain;
+ send_address(send_read_buff) <= send_read_address + send_read_remain;
+ send_read_time(send_read_buff) <= timer;
+ end if;
+
+ if tx_state = tx_state_idle or
+ (tx_state = tx_state_read and tx_done = '1') or
+ (tx_state = tx_state_write and tx_done = '1') or
+ (tx_state = tx_state_complete and tx_done = '1') or
+ (tx_state = tx_state_interrupt and interrupt_rdy = '1') then
+
+ tx_state <= tx_state_idle;
+ tx_read <= '0';
+ tx_write <= '0';
+ tx_complete <= '0';
+ tx_data_i <= (others => '0');
+ tx_address <= (others => '0');
+ tx_length <= (others => '0');
+ tx_tag <= (others => '0');
+ interrupt <= '0';
+
+ if bar_read = '1' then
+ tx_state <= tx_state_complete;
+ tx_complete <= '1';
+ tx_address <= bar_read_address;
+ tmp_cmd := bar_read_address(4 downto 3);
+ tmp_bar := unsigned(bar_read_address(3 + BAR_BITS - 1 downto 3));
+ bar_read := '0';
+
+ if tmp_bar = 0 then
+ --if tmp_cmd = CMD_STATUS then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tx_data_i(i*4 + 1 downto i*4 + 0) <= send_buff(i);
+ tx_data_i(i*4 + 3 downto i*4 + 2) <= recv_buff(i);
+ end loop;
+ send_int <= '0';
+ send_int_needed <= '1';
+
+ elsif tmp_bar = 1 then
+ tx_data_i(63 downto 3) <= debug_address;
+
+ elsif tmp_bar = 2 then
+ tx_data_i <= debug_data;
+
+ elsif tmp_bar = 3 then
+ tx_data_i(1 downto 0) <= debug_cmd;
+
+ elsif tmp_bar = 4 then
+ tx_data_i(BUFF_BITS - 1 downto 0) <= debug_buff;
+
+ elsif tmp_bar = 5 then
+ tx_data_i(8 downto 0) <= debug_length;
+
+ elsif tmp_bar = 10 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_cmpl_count);
+
+ elsif tmp_bar = 11 then
+ tx_data_i <= debug_cmpl_data;
+
+ elsif tmp_bar = 12 then
+ tx_data_i(4 downto 0) <= debug_cmpl_tag;
+
+ elsif tmp_bar = 13 then
+ tx_data_i(7 downto 0) <= debug_cmpl_state;
+
+ elsif tmp_bar = 20 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_write_count);
+
+ elsif tmp_bar = 21 then
+ tx_data_i(8 downto 0) <= debug_write_length;
+
+ elsif tmp_bar = 22 then
+ tx_data_i(63 downto 3) <= debug_write_addr;
+
+ elsif tmp_bar = 23 then
+ tx_data_i(63 downto 0) <= debug_write_data;
+
+ elsif tmp_bar = 24 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_accept_count);
+
+ elsif tmp_bar = 25 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_done_count);
+
+ elsif tmp_bar = 30 then
+ tx_data_i(15 downto 0) <= mdio_data;
+
+ else
+ tx_data_i(63 downto 3) <= bar_read_address;
+ end if;
+
+ elsif send_int = '1' and send_int_needed = '1' then
+ tx_state <= tx_state_interrupt;
+ interrupt <= '1';
+ send_int_needed <= '0';
+
+ elsif send_read = '1' and read_count < READ_MAX then
+ tmp_buff := send_read_buff;
+ tmp_length := send_read_length;
+ tmp_address := send_read_address;
+ tmp_remain := 16 - resize(tmp_address(6 downto 3), tmp_remain'length);
+
+ if max_read = "001" then
+ tmp_remain := 32 - resize(tmp_address(7 downto 3), tmp_remain'length);
+ elsif max_read = "010" then
+ tmp_remain := 64 - resize(tmp_address(8 downto 3), tmp_remain'length);
+ elsif max_read = "011" then
+ tmp_remain := 128 - resize(tmp_address(9 downto 3), tmp_remain'length);
+ elsif max_read = "100" then
+ tmp_remain := 256 - resize(tmp_address(10 downto 3), tmp_remain'length);
+ elsif max_read = "101" then
+ tmp_remain := 512 - resize(tmp_address(11 downto 3), tmp_remain'length);
+ end if;
+
+ if tmp_remain > tmp_length then
+ tmp_remain := tmp_length;
+ end if;
+
+ tx_state <= tx_state_read;
+ tx_read <= '1';
+ tx_address <= std_logic_vector(tmp_address);
+ tx_length <= std_logic_vector(tmp_remain);
+ tx_tag <= std_logic_vector(to_unsigned(tmp_buff, tx_tag'length));
+
+ send_read <= '0';
+ send_read_done <= '1';
+ send_read_remain <= tmp_remain;
+ read_incr := '1';
+
+ elsif send_write = '1' then
+ if send_write_new = '1' then
+ tmp_length := unsigned(rd_length);
+ else
+ tmp_length := send_write_length;
+ end if;
+ tmp_address := send_write_address;
+ tmp_remain := 16 - resize(tmp_address(6 downto 3), tmp_remain'length);
+
+ if max_write = "001" then
+ tmp_remain := 32 - resize(tmp_address(7 downto 3), tmp_remain'length);
+ elsif max_write = "010" then
+ tmp_remain := 64 - resize(tmp_address(8 downto 3), tmp_remain'length);
+ elsif max_write = "011" then
+ tmp_remain := 128 - resize(tmp_address(9 downto 3), tmp_remain'length);
+ elsif max_write = "100" then
+ tmp_remain := 256 - resize(tmp_address(10 downto 3), tmp_remain'length);
+ elsif max_write = "101" then
+ tmp_remain := 512 - resize(tmp_address(11 downto 3), tmp_remain'length);
+ end if;
+
+ if tmp_remain > tmp_length then
+ tmp_remain := tmp_length;
+ end if;
+
+ tx_state <= tx_state_write;
+ tx_write <= '1';
+ tx_address <= std_logic_vector(tmp_address);
+ tx_length <= std_logic_vector(tmp_remain);
+
+ debug_write_count <= debug_write_count + 1;
+ debug_write_length <= std_logic_vector(tmp_remain);
+ debug_write_addr <= std_logic_vector(tmp_address);
+ debug_write_data <= rd_data;
+
+ tmp_length := tmp_length - tmp_remain;
+ tmp_address := tmp_address + tmp_remain;
+
+ send_write_length <= tmp_length;
+ send_write_address <= tmp_address;
+ send_write_new <= '0';
+
+ if tmp_length = 0 then
+ send_write <= '0';
+ end if;
+ end if;
+ end if;
+
+ if read_decr = '1' and read_incr = '0' then
+ read_count := read_count - 1;
+ elsif read_decr = '0' and read_incr = '1' then
+ read_count := read_count + 1;
+ end if;
+
+ if tx_accept = '1' then
+ debug_accept_count <= debug_accept_count + 1;
+ end if;
+ if tx_done = '1' then
+ debug_done_count <= debug_done_count + 1;
+ end if;
+
+ for i in 0 to BUFF_COUNT - 1 loop
+ if send_buff(i) = BUFF_DATA and wr_accept(i) = '0' then
+ send_buff(i) <= BUFF_FULL;
+ -- no send_int here
+ end if;
+ if send_buff(i) = BUFF_FULL and wr_accept(i) = '1' then
+ send_buff(i) <= BUFF_EMPTY;
+ send_int <= '1';
+ end if;
+ if recv_buff(i) = BUFF_EMPTY and rd_valid(i) = '1' then
+ recv_buff(i) <= BUFF_FULL;
+ send_int <= '1';
+ end if;
+ if recv_buff(i) = BUFF_DATA and rd_valid(i) = '0' then
+ recv_buff(i) <= BUFF_EMPTY;
+ send_int <= '1';
+ end if;
+
+ if send_buff(i) = BUFF_DATA and send_read_time(i) = timer then
+ -- read timeout
+ wr_cancel(i) <= '1';
+ end if;
+ end loop;
+
+ if send_read = '0' and send_read_done = '0' then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (send_read_buff + i) mod BUFF_COUNT;
+
+ if send_buff(tmp_buff) = BUFF_ADDR then
+ send_read <= '1';
+ send_read_buff <= tmp_buff;
+ send_read_length <= send_length(tmp_buff);
+ send_read_address <= send_address(tmp_buff);
+ exit;
+ end if;
+ end loop;
+ end if;
+
+ if send_write = '0' and (tx_state /= tx_state_write or tx_done = '1') then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (send_write_buff + i) mod BUFF_COUNT;
+
+ if recv_buff(tmp_buff) = BUFF_ADDR then
+ recv_buff(tmp_buff) <= BUFF_DATA;
+ send_write <= '1';
+ send_write_new <= '1';
+ send_write_buff <= tmp_buff;
+ rd_buff <= std_logic_vector(to_unsigned(tmp_buff, BUFF_BITS));
+
+ if tmp_buff = 0 then
+ send_write_address <= recv_address0;
+ elsif tmp_buff = 1 then
+ send_write_address <= recv_address1;
+ elsif tmp_buff = 2 then
+ send_write_address <= recv_address2;
+ elsif tmp_buff = 3 then
+ send_write_address <= recv_address3;
+ elsif tmp_buff = 4 then
+ send_write_address <= recv_address4;
+ elsif tmp_buff = 5 then
+ send_write_address <= recv_address5;
+ elsif tmp_buff = 6 then
+ send_write_address <= recv_address6;
+ elsif tmp_buff = 7 then
+ send_write_address <= recv_address7;
+ elsif tmp_buff = 8 then
+ send_write_address <= recv_address8;
+ elsif tmp_buff = 9 then
+ send_write_address <= recv_address9;
+ elsif tmp_buff = 10 then
+ send_write_address <= recv_address10;
+ elsif tmp_buff = 11 then
+ send_write_address <= recv_address11;
+ elsif tmp_buff = 12 then
+ send_write_address <= recv_address12;
+ elsif tmp_buff = 13 then
+ send_write_address <= recv_address13;
+ elsif tmp_buff = 14 then
+ send_write_address <= recv_address14;
+ elsif tmp_buff = 15 then
+ send_write_address <= recv_address15;
+ end if;
+ exit;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;
diff --git a/netfpga10g/hdl/eth.vhd b/netfpga10g/hdl/eth.vhd
new file mode 100644
index 0000000..8034ceb
--- /dev/null
+++ b/netfpga10g/hdl/eth.vhd
@@ -0,0 +1,219 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity eth is
+generic (
+ BITS : integer := 14;
+ REVERSE_LANES : std_logic := '0'
+);
+port (
+ clk : in std_logic;
+ reset : in std_logic;
+ clk156_out : out std_logic;
+
+ read : out std_logic;
+ rd_data : in std_logic_vector(63 downto 0);
+ rd_empty : in std_logic;
+ rd_count : in std_logic_vector(BITS downto 0);
+
+ write : out std_logic;
+ wr_data : out std_logic_vector(63 downto 0);
+ wr_full : in std_logic;
+ wr_count : in std_logic_vector(BITS downto 0);
+
+ xaui_clk_p : in std_logic;
+ xaui_clk_n : in std_logic;
+ xaui_dclk : in std_logic;
+ xaui_tx_l0_p : out std_logic;
+ xaui_tx_l0_n : out std_logic;
+ xaui_tx_l1_p : out std_logic;
+ xaui_tx_l1_n : out std_logic;
+ xaui_tx_l2_p : out std_logic;
+ xaui_tx_l2_n : out std_logic;
+ xaui_tx_l3_p : out std_logic;
+ xaui_tx_l3_n : out std_logic;
+ xaui_rx_l0_p : in std_logic;
+ xaui_rx_l0_n : in std_logic;
+ xaui_rx_l1_p : in std_logic;
+ xaui_rx_l1_n : in std_logic;
+ xaui_rx_l2_p : in std_logic;
+ xaui_rx_l2_n : in std_logic;
+ xaui_rx_l3_p : in std_logic;
+ xaui_rx_l3_n : in std_logic
+);
+end eth;
+
+architecture arch of eth is
+ type state_t is (state_idle, state_length, state_data, state_end);
+
+ signal xgmii_txd : std_logic_vector(63 downto 0);
+ signal xgmii_txc : std_logic_vector(7 downto 0);
+ signal xgmii_rxd : std_logic_vector(63 downto 0);
+ signal xgmii_rxc : std_logic_vector(7 downto 0);
+
+ signal clk156 : std_logic;
+
+ signal rx_data : std_logic_vector(63 downto 0);
+ signal rx_start : std_logic;
+ signal rx_end : std_logic;
+ signal rx_rem : integer range 0 to 7;
+
+ signal tx_data : std_logic_vector(63 downto 0);
+ signal tx_start : std_logic;
+ signal tx_end : std_logic;
+ signal tx_rem : integer range 0 to 7;
+begin
+ clk156_out <= clk156;
+
+ -- sending
+ process (clk, reset)
+ variable state : state_t;
+ variable length : unsigned(BITS downto 0);
+ begin
+ if reset = '1' then
+ state := state_idle;
+ read <= '0';
+ tx_data <= (others => '0');
+ tx_start <= '0';
+ tx_end <= '0';
+ tx_rem <= 0;
+
+ elsif rising_edge(clk) then
+ read <= '0';
+ tx_data <= (others => '0');
+ tx_start <= '0';
+ tx_end <= '0';
+ tx_rem <= 0;
+
+ if state = state_idle then
+ if rd_empty = '0' then
+ length := unsigned(rd_data(BITS downto 0)) + 1;
+
+ if length <= unsigned(rd_count) then
+ state := state_data;
+ read <= '1';
+ tx_start <= '1';
+ end if;
+ end if;
+
+ elsif state = state_data then
+ tx_data <= rd_data;
+ length := length - 1;
+
+ if length > 0 then
+ read <= '1';
+ else
+ state := state_end;
+ end if;
+
+ elsif state = state_end then
+ state := state_idle;
+ tx_end <= '1';
+ tx_rem <= 0;
+ end if;
+ end if;
+ end process;
+
+ -- receiving
+ process (clk, reset)
+ variable state : state_t;
+ variable length : unsigned(BITS downto 0);
+ begin
+ if reset = '1' then
+ state := state_idle;
+ write <= '0';
+ wr_data <= (others => '0');
+
+ elsif rising_edge(clk) then
+ write <= '0';
+ wr_data <= (others => '0');
+
+ if state = state_idle then
+ if rx_start = '1' and rx_end = '0' then
+ state := state_length;
+ end if;
+
+ elsif state = state_length then
+ state := state_idle;
+
+ if rx_end = '0' and
+ unsigned(rx_data) <= 511 and
+ 16384 - unsigned(wr_count) >= 512
+ then
+ state := state_data;
+ length := unsigned(rx_data(BITS downto 0)) + 1;
+ end if;
+ end if;
+
+ if state = state_data then
+ write <= '1';
+ wr_data <= rx_data;
+ length := length - 1;
+
+ if length = 0 then
+ state := state_idle;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ xaui : entity work.xaui_top
+ generic map (
+ REVERSE_LANES => REVERSE_LANES
+ )
+ port map (
+ dclk => xaui_dclk,
+ reset => reset,
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc,
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc,
+ clk156_out => clk156,
+ refclk_p => xaui_clk_p,
+ refclk_n => xaui_clk_n,
+ xaui_tx_l0_p => xaui_tx_l0_p,
+ xaui_tx_l0_n => xaui_tx_l0_n,
+ xaui_tx_l1_p => xaui_tx_l1_p,
+ xaui_tx_l1_n => xaui_tx_l1_n,
+ xaui_tx_l2_p => xaui_tx_l2_p,
+ xaui_tx_l2_n => xaui_tx_l2_n,
+ xaui_tx_l3_p => xaui_tx_l3_p,
+ xaui_tx_l3_n => xaui_tx_l3_n,
+ xaui_rx_l0_p => xaui_rx_l0_p,
+ xaui_rx_l0_n => xaui_rx_l0_n,
+ xaui_rx_l1_p => xaui_rx_l1_p,
+ xaui_rx_l1_n => xaui_rx_l1_n,
+ xaui_rx_l2_p => xaui_rx_l2_p,
+ xaui_rx_l2_n => xaui_rx_l2_n,
+ xaui_rx_l3_p => xaui_rx_l3_p,
+ xaui_rx_l3_n => xaui_rx_l3_n
+ );
+
+ rx_eth : entity work.rx_eth port map (
+ clk => clk,
+ reset => reset,
+
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc,
+
+ rx_data => rx_data,
+ rx_start => rx_start,
+ rx_end => rx_end,
+ rx_rem => rx_rem
+ );
+
+ tx_eth : entity work.tx_eth port map (
+ clk => clk,
+ reset => reset,
+
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc,
+
+ tx_data => tx_data,
+ tx_start => tx_start,
+ tx_end => tx_end,
+ tx_rem => tx_rem
+ );
+end arch;
diff --git a/netfpga10g/hdl/eth_rx.vhd b/netfpga10g/hdl/eth_rx.vhd
new file mode 100644
index 0000000..bcd395f
--- /dev/null
+++ b/netfpga10g/hdl/eth_rx.vhd
@@ -0,0 +1,84 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity eth_rx is port (
+ clk : in std_logic;
+
+ wr_en : out std_logic := '0';
+ wr_data : out std_logic_vector (63 downto 0) := (others => '0');
+ wr_done : out std_logic := '0';
+ wr_accept : in std_logic;
+
+ xgmii_rxd : in std_logic_vector(63 downto 0);
+ xgmii_rxc : in std_logic_vector(7 downto 0)
+);
+end eth_rx;
+
+architecture arch of eth_rx is
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERMINATE : std_logic_vector(7 downto 0) := x"FD";
+ constant ERR : std_logic_vector(7 downto 0) := x"FE";
+
+ type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal lanes_a : lanes_t;
+ signal lanes_b : lanes_t;
+
+ signal control_a : std_logic_vector(7 downto 0);
+ signal control_b : std_logic_vector(7 downto 0);
+
+ type state_t is (state_idle, state_a, state_b);
+ signal state : state_t := state_idle;
+begin
+ gen_a : for i in 0 to 7 generate
+ lanes_a(i) <= xgmii_rxd(7+8*i downto 8*i);
+ control_a(i) <= xgmii_rxc(i);
+ end generate gen_a;
+
+ lanes_b(4 to 7) <= lanes_a(0 to 3);
+ control_b(7 downto 4) <= control_a(3 downto 0);
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ wr_en <= '0';
+ wr_data <= (others => '0');
+ wr_done <= '0';
+
+ lanes_b(0 to 3) <= lanes_a(4 to 7);
+ control_b(3 downto 0) <= control_a(7 downto 4);
+
+ if state = state_idle and wr_accept = '1' then
+ if control_a(0) = '1' and lanes_a(0) = START then
+ state <= state_a;
+ elsif control_b(0) = '1' and lanes_b(0) = START then
+ state <= state_b;
+ end if;
+
+ elsif state = state_a then
+ wr_en <= '1';
+ for i in 0 to 7 loop
+ wr_data(63-8*i downto 56-8*i) <= lanes_a(i);
+
+ if control_a(i) = '1' and (lanes_a(i) = TERMINATE or lanes_a(i) = ERR) then
+ state <= state_idle;
+ wr_done <= '1';
+ end if;
+ end loop;
+
+ elsif state = state_b then
+ wr_en <= '1';
+ for i in 0 to 7 loop
+ wr_data(63-8*i downto 56-8*i) <= lanes_b(i);
+
+ if control_b(i) = '1' and (lanes_b(i) = TERMINATE or lanes_b(i) = ERR) then
+ state <= state_idle;
+ wr_done <= '1';
+ end if;
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;
diff --git a/netfpga10g/hdl/eth_tx.vhd b/netfpga10g/hdl/eth_tx.vhd
new file mode 100644
index 0000000..cf0081d
--- /dev/null
+++ b/netfpga10g/hdl/eth_tx.vhd
@@ -0,0 +1,68 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity eth_tx is port (
+ clk : in std_logic;
+
+ rd_en : out std_logic;
+ rd_data : in std_logic_vector (63 downto 0);
+ rd_valid : in std_logic;
+
+ xgmii_txd : out std_logic_vector(63 downto 0);
+ xgmii_txc : out std_logic_vector(7 downto 0)
+);
+end eth_tx;
+
+architecture arch of eth_tx is
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERMINATE : std_logic_vector(7 downto 0) := x"FD";
+
+ constant PREAMBLE : std_logic_vector(7 downto 0) := "01010101";
+ constant SFD : std_logic_vector(7 downto 0) := "11010101";
+
+ type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal lanes : lanes_t := (others => IDLE);
+ signal control : std_logic_vector(7 downto 0) := (others => '1');
+
+ type state_t is (state_idle, state_data);
+ signal state : state_t := state_idle;
+begin
+ lanes_gen : for i in 0 to 7 generate
+ xgmii_txd(7+8*i downto 8*i) <= lanes(i);
+ xgmii_txc(i) <= control(i);
+ end generate lanes_gen;
+
+ rd_en <= '1' when state = state_data else '0';
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ lanes <= (others => IDLE);
+ control <= (others => '1');
+
+ if state = state_idle then
+ if rd_valid = '1' then
+ state <= state_data;
+ lanes(0) <= START;
+ lanes(1 to 6) <= (others => PREAMBLE);
+ lanes(7) <= SFD;
+ control(7 downto 1) <= (others => '0');
+ end if;
+
+ elsif state = state_data then
+ if rd_valid = '1' then
+ for i in 0 to 7 loop
+ lanes(i) <= rd_data(63-8*i downto 56-8*i);
+ control(i) <= '0';
+ end loop;
+ else
+ state <= state_idle;
+ lanes(0) <= TERMINATE;
+ end if;
+ end if;
+ end if;
+ end process;
+end arch;
diff --git a/netfpga10g/hdl/mdio.vhd b/netfpga10g/hdl/mdio.vhd
new file mode 100644
index 0000000..1cb34fa
--- /dev/null
+++ b/netfpga10g/hdl/mdio.vhd
@@ -0,0 +1,223 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity mdio is port (
+ clk125 : in std_logic;
+ reset125 : in std_logic;
+
+ command : in std_logic_vector(0 to 27); -- operation(2) & phyaddr(5) & devaddr(5) & data_in(16)
+ data_out : out std_logic_vector(0 to 15);
+ enable : in std_logic;
+ done : out std_logic;
+
+ mdio_in : in std_logic;
+ mdio_out : out std_logic;
+ mdio_Z : out std_logic;
+ mdc : out std_logic;
+ phy_reset_n : out std_logic;
+
+ total_count : out std_logic_vector(31 downto 0);
+ address_count : out std_logic_vector(31 downto 0);
+ write_count : out std_logic_vector(31 downto 0);
+ read_count : out std_logic_vector(31 downto 0);
+ read_incr_count : out std_logic_vector(31 downto 0)
+);
+end mdio;
+
+architecture arch of mdio is
+ type state_t is (state_idle, state_preamble, state_start, state_operation,
+ state_phyaddr, state_devaddr, state_turnaround, state_data);
+
+ signal state : state_t;
+ signal state_count : natural range 0 to 32;
+
+ signal operation : std_logic_vector(0 to 1);
+ signal phyaddr : std_logic_vector(0 to 4);
+ signal devaddr : std_logic_vector(0 to 4);
+ signal data_in : std_logic_vector(0 to 15);
+
+ signal mdc_count : natural range 0 to 25;
+ signal mdc_i : std_logic;
+
+ signal total_count_i : unsigned(31 downto 0);
+ signal address_count_i : unsigned(31 downto 0);
+ signal write_count_i : unsigned(31 downto 0);
+ signal read_count_i : unsigned(31 downto 0);
+ signal read_incr_count_i : unsigned(31 downto 0);
+
+ signal done_i : std_logic;
+begin
+ phy_reset_n <= not reset125;
+ mdc <= mdc_i;
+
+ operation <= command(0 to 1);
+ phyaddr <= command(2 to 6);
+ devaddr <= command(7 to 11);
+ data_in <= command(12 to 27);
+
+ done <= done_i;
+
+ process (clk125, reset125) begin
+ if reset125 = '1' then
+ mdc_i <= '0';
+ mdc_count <= 0;
+ done_i <= '0';
+
+ elsif rising_edge(clk125) then
+ done_i <= '0';
+
+ if mdc_count = 25 - 1 then
+ mdc_count <= 0;
+ mdc_i <= not mdc_i; -- 2.5 MHz
+
+ if mdc_i = '0' then -- rising edge
+ if state = state_data and state_count = 15 then
+ done_i <= '1';
+ end if;
+ end if;
+ else
+ mdc_count <= mdc_count + 1;
+ end if;
+ end if;
+ end process;
+
+ process (mdc_i, reset125) begin
+ if reset125 = '1' then
+ state <= state_idle;
+ state_count <= 0;
+ data_out <= (others => '0');
+
+ elsif rising_edge(mdc_i) then
+ state_count <= state_count + 1;
+
+ if state = state_preamble then
+ if state_count = 31 then
+ state <= state_start;
+ state_count <= 0;
+ end if;
+ elsif state = state_start then
+ if state_count = 1 then
+ state <= state_operation;
+ state_count <= 0;
+ end if;
+ elsif state = state_operation then
+ if state_count = 1 then
+ state <= state_phyaddr;
+ state_count <= 0;
+ end if;
+ elsif state = state_phyaddr then
+ if state_count = 4 then
+ state <= state_devaddr;
+ state_count <= 0;
+ end if;
+ elsif state = state_devaddr then
+ if state_count = 4 then
+ state <= state_turnaround;
+ state_count <= 0;
+ end if;
+ elsif state = state_turnaround then
+ if state_count = 1 then
+ state <= state_data;
+ state_count <= 0;
+ end if;
+ elsif state = state_data then
+ data_out(state_count) <= mdio_in;
+
+ if state_count = 15 then
+ state <= state_idle;
+ state_count <= 0;
+ end if;
+ else -- state = state_idle
+ if enable = '1' then
+ state <= state_preamble;
+ state_count <= 0;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process (mdc_i, reset125) begin
+ if reset125 = '1' then
+ mdio_out <= '0';
+ mdio_Z <= '1';
+
+ elsif falling_edge(mdc_i) then
+ mdio_out <= '0';
+ mdio_Z <= '1';
+
+ if state = state_preamble then
+ mdio_out <= '1';
+ mdio_Z <= '0';
+
+ elsif state = state_start then
+ mdio_out <= '0';
+ mdio_Z <= '0';
+
+ elsif state = state_operation then
+ mdio_out <= operation(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_phyaddr then
+ mdio_out <= phyaddr(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_devaddr then
+ mdio_out <= devaddr(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_turnaround then
+ if operation(0) = '0' then -- write or address
+ mdio_Z <= '0';
+
+ if state_count = 0 then
+ mdio_out <= '1';
+ else
+ mdio_out <= '0';
+ end if;
+ end if;
+
+ elsif state = state_data then
+ if operation(0) = '0' then -- write or address
+ mdio_Z <= '0';
+ mdio_out <= data_in(state_count);
+ end if;
+ end if;
+ end if;
+ end process;
+
+ total_count <= std_logic_vector(total_count_i);
+ address_count <= std_logic_vector(address_count_i);
+ write_count <= std_logic_vector(write_count_i);
+ read_count <= std_logic_vector(read_count_i);
+ read_incr_count <= std_logic_vector(read_incr_count_i);
+
+ process (clk125, reset125) begin
+ if reset125 = '1' then
+ total_count_i <= (others => '0');
+ address_count_i <= (others => '0');
+ write_count_i <= (others => '0');
+ read_count_i <= (others => '0');
+ read_incr_count_i <= (others => '0');
+
+ elsif rising_edge(clk125) then
+ if done_i = '1' then
+ total_count_i <= total_count_i + 1;
+
+ if operation = "00" then
+ address_count_i <= address_count_i + 1;
+ end if;
+ if operation = "01" then
+ write_count_i <= write_count_i + 1;
+ end if;
+ if operation = "11" then
+ read_count_i <= read_count_i + 1;
+ end if;
+ if operation = "10" then
+ read_incr_count_i <= read_incr_count_i + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+end arch;
diff --git a/netfpga10g/hdl/pcie.vhd b/netfpga10g/hdl/pcie.vhd
new file mode 100644
index 0000000..6dd99cf
--- /dev/null
+++ b/netfpga10g/hdl/pcie.vhd
@@ -0,0 +1,268 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity pcie is
+generic (
+ BITS : integer := 14
+);
+port (
+ pcie_clk_p : in std_logic;
+ pcie_clk_n : in std_logic;
+ reset25 : in std_logic;
+
+ clk125_out : out std_logic;
+ reset125_out : out std_logic;
+
+ pci_exp_rxn : in std_logic_vector(7 downto 0);
+ pci_exp_rxp : in std_logic_vector(7 downto 0);
+ pci_exp_txn : out std_logic_vector(7 downto 0);
+ pci_exp_txp : out std_logic_vector(7 downto 0);
+
+ port0_read : out std_logic;
+ port0_rd_data : in std_logic_vector(63 downto 0);
+ port0_rd_empty : in std_logic;
+ port0_rd_count : in std_logic_vector(BITS downto 0);
+
+ port0_write : out std_logic;
+ port0_wr_data : out std_logic_vector(63 downto 0);
+ port0_wr_full : in std_logic;
+ port0_wr_count : in std_logic_vector(BITS downto 0);
+
+ port1_read : out std_logic;
+ port1_rd_data : in std_logic_vector(63 downto 0);
+ port1_rd_empty : in std_logic;
+ port1_rd_count : in std_logic_vector(BITS downto 0);
+
+ port1_write : out std_logic;
+ port1_wr_data : out std_logic_vector(63 downto 0);
+ port1_wr_full : in std_logic;
+ port1_wr_count : in std_logic_vector(BITS downto 0);
+
+ port2_read : out std_logic;
+ port2_rd_data : in std_logic_vector(63 downto 0);
+ port2_rd_empty : in std_logic;
+ port2_rd_count : in std_logic_vector(BITS downto 0);
+
+ port2_write : out std_logic;
+ port2_wr_data : out std_logic_vector(63 downto 0);
+ port2_wr_full : in std_logic;
+ port2_wr_count : in std_logic_vector(BITS downto 0);
+
+ port3_read : out std_logic;
+ port3_rd_data : in std_logic_vector(63 downto 0);
+ port3_rd_empty : in std_logic;
+ port3_rd_count : in std_logic_vector(BITS downto 0);
+
+ port3_write : out std_logic;
+ port3_wr_data : out std_logic_vector(63 downto 0);
+ port3_wr_full : in std_logic;
+ port3_wr_count : in std_logic_vector(BITS downto 0);
+
+ mdio_command : out std_logic_vector(0 to 27);
+ mdio_data : in std_logic_vector(0 to 15);
+ mdio_enable : out std_logic;
+ mdio_done : in std_logic;
+
+ leds : out std_logic_vector(2 downto 0)
+);
+end pcie;
+
+architecture arch of pcie is
+ signal clk125 : std_logic;
+ signal reset125 : std_logic;
+
+ signal rx_frame : std_logic_vector(63 downto 0);
+ signal rx_sof : std_logic;
+ signal rx_eof : std_logic;
+ signal rx_valid : std_logic;
+
+ signal rx_read : std_logic;
+ signal rx_write : std_logic;
+ signal rx_complete : std_logic;
+ signal rx_data : std_logic_vector(63 downto 0);
+ signal rx_address : std_logic_vector(28 downto 0);
+
+ signal tx_frame : std_logic_vector(63 downto 0);
+ signal tx_sof : std_logic;
+ signal tx_eof : std_logic;
+ signal tx_half : std_logic;
+ signal tx_valid : std_logic;
+ signal tx_ready : std_logic;
+
+ signal tx_read : std_logic;
+ signal tx_write : std_logic;
+ signal tx_complete : std_logic;
+ signal tx_data : std_logic_vector(63 downto 0);
+ signal tx_address : std_logic_vector(28 downto 0);
+ signal tx_length : std_logic_vector(8 downto 0);
+ signal tx_accept : std_logic;
+ signal tx_done : std_logic;
+
+ signal bus_dev_func : std_logic_vector(15 downto 0);
+ signal transaction_id : std_logic_vector(23 downto 0);
+
+ signal max_read : std_logic_vector(2 downto 0);
+ signal max_write : std_logic_vector(2 downto 0);
+
+ signal interrupt : std_logic;
+ signal interrupt_rdy : std_logic;
+
+ signal bar0 : std_logic;
+begin
+ clk125_out <= clk125;
+ reset125_out <= reset125;
+
+ pcie_wrapper : entity work.pcie_wrapper port map (
+ pcie_clk_p => pcie_clk_p,
+ pcie_clk_n => pcie_clk_n,
+ reset25 => reset25,
+
+ clk125 => clk125,
+ reset125 => reset125,
+
+ pci_exp_rxn => pci_exp_rxn,
+ pci_exp_rxp => pci_exp_rxp,
+ pci_exp_txn => pci_exp_txn,
+ pci_exp_txp => pci_exp_txp,
+
+ rx_frame => rx_frame,
+ rx_sof => rx_sof,
+ rx_eof => rx_eof,
+ rx_valid => rx_valid,
+
+ tx_frame => tx_frame,
+ tx_sof => tx_sof,
+ tx_eof => tx_eof,
+ tx_half => tx_half,
+ tx_valid => tx_valid,
+ tx_ready => tx_ready,
+
+ bus_dev_func => bus_dev_func,
+
+ max_read => max_read,
+ max_write => max_write,
+
+ interrupt => interrupt,
+ interrupt_rdy => interrupt_rdy,
+
+ bar0 => bar0
+ );
+
+ pcie_rx : entity work.pcie_rx port map (
+ clk => clk125,
+ reset => reset125,
+
+ frame => rx_frame,
+ sof => rx_sof,
+ eof => rx_eof,
+ valid => rx_valid,
+
+ read => rx_read,
+ write => rx_write,
+ complete => rx_complete,
+ data => rx_data,
+ address => rx_address,
+
+ transaction_id => transaction_id,
+ bar0 => bar0
+ );
+
+ pcie_tx : entity work.pcie_tx port map (
+ clk => clk125,
+ reset => reset125,
+
+ frame => tx_frame,
+ sof => tx_sof,
+ eof => tx_eof,
+ half => tx_half,
+ valid => tx_valid,
+ ready => tx_ready,
+
+ read => tx_read,
+ write => tx_write,
+ complete => tx_complete,
+ data => tx_data,
+ address => tx_address,
+ length => tx_length,
+ accept => tx_accept,
+ done => tx_done,
+
+ transaction_id => transaction_id,
+ bus_dev_func => bus_dev_func
+ );
+
+ dma : entity work.dma port map (
+ clk => clk125,
+ reset => reset125,
+
+ rx_read => rx_read,
+ rx_write => rx_write,
+ rx_complete => rx_complete,
+ rx_data => rx_data,
+ rx_address => rx_address,
+
+ tx_read => tx_read,
+ tx_write => tx_write,
+ tx_complete => tx_complete,
+ tx_data => tx_data,
+ tx_address => tx_address,
+ tx_length => tx_length,
+ tx_accept => tx_accept,
+ tx_done => tx_done,
+
+ port0_read => port0_read,
+ port0_rd_data => port0_rd_data,
+ port0_rd_empty => port0_rd_empty,
+ port0_rd_count => port0_rd_count,
+
+ port0_write => port0_write,
+ port0_wr_data => port0_wr_data,
+ port0_wr_full => port0_wr_full,
+ port0_wr_count => port0_wr_count,
+
+ port1_read => port1_read,
+ port1_rd_data => port1_rd_data,
+ port1_rd_empty => port1_rd_empty,
+ port1_rd_count => port1_rd_count,
+
+ port1_write => port1_write,
+ port1_wr_data => port1_wr_data,
+ port1_wr_full => port1_wr_full,
+ port1_wr_count => port1_wr_count,
+
+ port2_read => port2_read,
+ port2_rd_data => port2_rd_data,
+ port2_rd_empty => port2_rd_empty,
+ port2_rd_count => port2_rd_count,
+
+ port2_write => port2_write,
+ port2_wr_data => port2_wr_data,
+ port2_wr_full => port2_wr_full,
+ port2_wr_count => port2_wr_count,
+
+ port3_read => port3_read,
+ port3_rd_data => port3_rd_data,
+ port3_rd_empty => port3_rd_empty,
+ port3_rd_count => port3_rd_count,
+
+ port3_write => port3_write,
+ port3_wr_data => port3_wr_data,
+ port3_wr_full => port3_wr_full,
+ port3_wr_count => port3_wr_count,
+
+ max_read => max_read,
+ max_write => max_write,
+
+ interrupt => interrupt,
+ interrupt_rdy => interrupt_rdy,
+
+ mdio_command => mdio_command,
+ mdio_data => mdio_data,
+ mdio_enable => mdio_enable,
+ mdio_done => mdio_done,
+
+ leds => leds
+ );
+end arch;
+
diff --git a/netfpga10g/hdl/pcie_rx.vhd b/netfpga10g/hdl/pcie_rx.vhd
new file mode 100644
index 0000000..c4ee177
--- /dev/null
+++ b/netfpga10g/hdl/pcie_rx.vhd
@@ -0,0 +1,98 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity pcie_rx is port (
+ clk : in std_logic;
+
+ frame : in std_logic_vector(63 downto 0);
+ sof : in std_logic;
+ eof : in std_logic;
+ valid : in std_logic;
+
+ read : out std_logic := '0';
+ write : out std_logic := '0';
+ complete : out std_logic := '0';
+ data : out std_logic_vector(63 downto 0) := (others => '0');
+ address : out std_logic_vector(63 downto 3) := (others => '0');
+ tag : out std_logic_vector(4 downto 0) := (others => '0');
+ remote : out std_logic_vector(23 downto 0) := (others => '0');
+
+ bar0 : in std_logic
+);
+end pcie_rx;
+
+architecture arch of pcie_rx is
+ type state_t is (state_idle, state_read, state_write, state_write_head,
+ state_complete, state_complete_head);
+
+ signal fmt : std_logic_vector(1 downto 0);
+ signal typ : std_logic_vector(4 downto 0);
+ signal status : std_logic_vector(2 downto 0);
+begin
+ fmt <= frame(62 downto 61);
+ typ <= frame(60 downto 56);
+ status <= frame(15 downto 13);
+
+ process (clk)
+ variable state : state_t := state_idle;
+ variable extra : std_logic_vector(31 downto 0) := (others => '0');
+ begin
+ if rising_edge(clk) then
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+
+ if valid = '0' then
+ -- nothing
+
+ elsif state = state_idle and sof = '1' then
+ data <= (others => '0');
+ address <= (others => '0');
+ tag <= (others => '0');
+
+ if fmt = "00" and typ = "00000" and bar0 = '1' then
+ state := state_read;
+ remote <= frame(31 downto 8);
+
+ elsif fmt = "10" and typ = "00000" and bar0 = '1' then
+ state := state_write_head;
+
+ elsif fmt = "10" and typ = "01010" and status = "000" then
+ state := state_complete_head;
+ end if;
+
+ elsif state = state_read then
+ state := state_idle;
+ read <= '1';
+ address <= x"00000000" & frame(63 downto 35);
+
+ elsif state = state_write_head then
+ state := state_write;
+ address <= x"00000000" & frame(63 downto 35);
+ extra := frame(31 downto 0);
+
+ elsif state = state_write then
+ state := state_idle;
+ write <= '1';
+ data <= extra & frame(63 downto 32);
+
+ elsif state = state_complete_head then
+ state := state_complete;
+ tag <= frame(44 downto 40);
+ extra := frame(31 downto 0);
+
+ elsif state = state_complete then
+ complete <= '1';
+ data <= extra & frame(63 downto 32);
+ extra := frame(31 downto 0);
+ end if;
+
+ if valid = '1' and eof = '1' then
+ state := state_idle;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/pcie_tx.vhd b/netfpga10g/hdl/pcie_tx.vhd
new file mode 100644
index 0000000..dc892b4
--- /dev/null
+++ b/netfpga10g/hdl/pcie_tx.vhd
@@ -0,0 +1,178 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity pcie_tx is port (
+ clk : in std_logic;
+
+ frame : out std_logic_vector(63 downto 0) := (others => '0');
+ sof : out std_logic := '0';
+ eof : out std_logic := '0';
+ half : out std_logic := '0';
+ valid : out std_logic := '0';
+ ready : in std_logic;
+
+ read : in std_logic;
+ write : in std_logic;
+ complete : in std_logic;
+ data : in std_logic_vector(63 downto 0);
+ address : in std_logic_vector(63 downto 3);
+ length : in std_logic_vector(8 downto 0);
+ tag : in std_logic_vector(4 downto 0);
+ local : in std_logic_vector(15 downto 0);
+ remote : in std_logic_vector(23 downto 0);
+ accept : out std_logic;
+ done : out std_logic
+);
+end pcie_tx;
+
+architecture arch of pcie_tx is
+ type state_t is (state_idle, state_read_32, state_read_64,
+ state_write_32, state_write_64,
+ state_write_end_32, state_write_head_64,
+ state_complete, state_complete_head, state_done);
+ signal state : state_t := state_idle;
+begin
+ accept <= ready when state = state_write_32 or state = state_write_64 else '0';
+ done <= ready when state = state_done else '0';
+
+ process (clk)
+ variable extra : std_logic_vector(31 downto 0) := (others => '0');
+ variable remain : unsigned(8 downto 0) := (others => '0');
+ begin
+ if rising_edge(clk) and (ready = '1' or state = state_idle) then
+ frame <= (others => '0');
+ sof <= '0';
+ eof <= '0';
+ half <= '0';
+ valid <= '0';
+
+ -- read
+ if state = state_idle and read = '1' then
+ if unsigned(length) = 0 then
+ state <= state_done;
+ else
+ if address(63 downto 32) = x"00000000" then
+ state <= state_read_32;
+ frame <= "0" & "00" & "00000" & x"00" &
+ "000000" &
+ length & "0" &
+ local &
+ "000" & tag & x"FF";
+ else
+ state <= state_read_64;
+ frame <= "0" & "01" & "00000" & x"00" &
+ "000000" &
+ length & "0" &
+ local &
+ "000" & tag & x"FF";
+ end if;
+ sof <= '1';
+ valid <= '1';
+ end if;
+
+ elsif state = state_read_32 then
+ state <= state_done;
+ frame <= address(31 downto 3) & "000" & x"00000000";
+ eof <= '1';
+ half <= '1';
+ valid <= '1';
+
+ elsif state = state_read_64 then
+ state <= state_done;
+ frame <= address & "000";
+ eof <= '1';
+ valid <= '1';
+
+ -- write
+ elsif state = state_idle and write = '1' then
+ if unsigned(length) = 0 then
+ state <= state_done;
+ else
+ if address(63 downto 32) = x"00000000" then
+ state <= state_write_32;
+ frame <= "0" & "10" & "00000" & x"00" &
+ "000000" &
+ length & "0" &
+ local &
+ x"00" & x"FF";
+ extra := address(31 downto 3) & "000";
+ else
+ state <= state_write_head_64;
+ frame <= "0" & "11" & "00000" & x"00" &
+ "000000" &
+ length & "0" &
+ local &
+ x"00" & x"FF";
+ end if;
+ sof <= '1';
+ valid <= '1';
+ remain := unsigned(length);
+ end if;
+
+ elsif state = state_write_32 then
+ frame <= extra & data(63 downto 32);
+ extra := data(31 downto 0);
+ valid <= '1';
+
+ remain := remain - 1;
+
+ if remain = 0 then
+ state <= state_write_end_32;
+ end if;
+
+ elsif state = state_write_end_32 then
+ state <= state_done;
+ frame <= extra & x"00000000";
+ eof <= '1';
+ half <= '1';
+ valid <= '1';
+
+ elsif state = state_write_head_64 then
+ state <= state_write_64;
+ frame <= address & "000";
+ valid <= '1';
+
+ elsif state = state_write_64 then
+ frame <= data;
+ valid <= '1';
+
+ remain := remain - 1;
+
+ if remain = 0 then
+ state <= state_done;
+ eof <= '1';
+ end if;
+
+ -- complete
+ elsif state = state_idle and complete = '1' then
+ state <= state_complete_head;
+ frame <= "0" & "10" & "01010" & x"00" &
+ x"0002" &
+ local &
+ x"0008";
+ sof <= '1';
+ valid <= '1';
+
+ elsif state = state_complete_head then
+ state <= state_complete;
+ frame <= remote & "0" & address(6 downto 3) & "000" &
+ data(63 downto 32);
+ valid <= '1';
+
+ elsif state = state_complete then
+ state <= state_done;
+ frame <= data(31 downto 0) & x"00000000";
+ eof <= '1';
+ half <= '1';
+ valid <= '1';
+
+ -- done
+ elsif state = state_done then
+ state <= state_idle;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/pcie_wrapper.vhd b/netfpga10g/hdl/pcie_wrapper.vhd
new file mode 100644
index 0000000..35c6047
--- /dev/null
+++ b/netfpga10g/hdl/pcie_wrapper.vhd
@@ -0,0 +1,358 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity pcie_wrapper is port (
+ pcie_clk_p : in std_logic;
+ pcie_clk_n : in std_logic;
+ reset25 : in std_logic;
+
+ clk125 : out std_logic;
+ reset125 : out std_logic;
+
+ pci_exp_rxn : in std_logic_vector(7 downto 0);
+ pci_exp_rxp : in std_logic_vector(7 downto 0);
+ pci_exp_txn : out std_logic_vector(7 downto 0);
+ pci_exp_txp : out std_logic_vector(7 downto 0);
+
+ rx_frame : out std_logic_vector(63 downto 0);
+ rx_sof : out std_logic;
+ rx_eof : out std_logic;
+ rx_valid : out std_logic;
+
+ tx_frame : in std_logic_vector(63 downto 0);
+ tx_sof : in std_logic;
+ tx_eof : in std_logic;
+ tx_half : in std_logic;
+ tx_valid : in std_logic;
+ tx_ready : out std_logic;
+
+ bus_dev_func : out std_logic_vector(15 downto 0);
+
+ max_read : out std_logic_vector(2 downto 0);
+ max_write : out std_logic_vector(2 downto 0);
+
+ interrupt : in std_logic;
+ interrupt_rdy : out std_logic;
+
+ bar0 : out std_logic
+);
+end pcie_wrapper;
+
+architecture arch of pcie_wrapper is
+
+ component pcie_core port (
+ pci_exp_rxn : in std_logic_vector(7 downto 0);
+ pci_exp_rxp : in std_logic_vector(7 downto 0);
+ pci_exp_txn : out std_logic_vector(7 downto 0);
+ pci_exp_txp : out std_logic_vector(7 downto 0);
+
+ sys_clk : in std_logic;
+ sys_reset_n : in std_logic;
+
+ refclkout : out std_logic;
+
+ trn_clk : out std_logic;
+ trn_reset_n : out std_logic;
+ trn_lnk_up_n : out std_logic;
+
+ trn_rd : out std_logic_vector(63 downto 0);
+ trn_rrem_n : out std_logic_vector(7 downto 0);
+ trn_rsof_n : out std_logic;
+ trn_reof_n : out std_logic;
+ trn_rsrc_dsc_n : out std_logic;
+ trn_rsrc_rdy_n : out std_logic;
+ trn_rbar_hit_n : out std_logic_vector(6 downto 0);
+ trn_rdst_rdy_n : in std_logic;
+ trn_rerrfwd_n : out std_logic;
+ trn_rnp_ok_n : in std_logic;
+ trn_rfc_npd_av : out std_logic_vector(11 downto 0);
+ trn_rfc_nph_av : out std_logic_vector(7 downto 0);
+ trn_rfc_pd_av : out std_logic_vector(11 downto 0);
+ trn_rfc_ph_av : out std_logic_vector(7 downto 0);
+ trn_rcpl_streaming_n : in std_logic;
+
+ trn_td : in std_logic_vector(63 downto 0);
+ trn_trem_n : in std_logic_vector(7 downto 0);
+ trn_tsof_n : in std_logic;
+ trn_teof_n : in std_logic;
+ trn_tsrc_dsc_n : in std_logic;
+ trn_tsrc_rdy_n : in std_logic;
+ trn_tdst_dsc_n : out std_logic;
+ trn_tdst_rdy_n : out std_logic;
+ trn_terrfwd_n : in std_logic ;
+ trn_tbuf_av : out std_logic_vector(3 downto 0);
+
+ cfg_do : out std_logic_vector(31 downto 0);
+ cfg_rd_wr_done_n : out std_logic;
+ cfg_di : in std_logic_vector(31 downto 0);
+ cfg_byte_en_n : in std_logic_vector(3 downto 0);
+ cfg_dwaddr : in std_logic_vector(9 downto 0);
+ cfg_wr_en_n : in std_logic;
+ cfg_rd_en_n : in std_logic;
+
+ cfg_err_cor_n : in std_logic;
+ cfg_err_cpl_abort_n : in std_logic;
+ cfg_err_cpl_timeout_n : in std_logic;
+ cfg_err_cpl_unexpect_n : in std_logic;
+ cfg_err_ecrc_n : in std_logic;
+ cfg_err_posted_n : in std_logic;
+ cfg_err_tlp_cpl_header : in std_logic_vector(47 downto 0);
+ cfg_err_ur_n : in std_logic;
+ cfg_err_cpl_rdy_n : out std_logic;
+ cfg_err_locked_n : in std_logic;
+ cfg_interrupt_n : in std_logic;
+ cfg_interrupt_rdy_n : out std_logic;
+ cfg_pm_wake_n : in std_logic;
+ cfg_pcie_link_state_n : out std_logic_vector(2 downto 0);
+ cfg_to_turnoff_n : out std_logic;
+ cfg_interrupt_assert_n : in std_logic;
+ cfg_interrupt_di : in std_logic_vector(7 downto 0);
+ cfg_interrupt_do : out std_logic_vector(7 downto 0);
+ cfg_interrupt_mmenable : out std_logic_vector(2 downto 0);
+ cfg_interrupt_msienable : out std_logic;
+
+ cfg_trn_pending_n : in std_logic;
+ cfg_bus_number : out std_logic_vector(7 downto 0);
+ cfg_device_number : out std_logic_vector(4 downto 0);
+ cfg_function_number : out std_logic_vector(2 downto 0);
+ cfg_status : out std_logic_vector(15 downto 0);
+ cfg_command : out std_logic_vector(15 downto 0);
+ cfg_dstatus : out std_logic_vector(15 downto 0);
+ cfg_dcommand : out std_logic_vector(15 downto 0);
+ cfg_lstatus : out std_logic_vector(15 downto 0);
+ cfg_lcommand : out std_logic_vector(15 downto 0);
+ cfg_dsn : in std_logic_vector(63 downto 0);
+
+ fast_train_simulation_only : in std_logic
+ );
+ end component;
+
+ signal sys_reset_n : std_logic;
+
+ signal trn_clk : std_logic;
+ signal trn_reset_n : std_logic;
+ signal trn_lnk_up_n : std_logic;
+
+ signal trn_rd : std_logic_vector(63 downto 0);
+ signal trn_rrem_n : std_logic_vector(7 downto 0);
+ signal trn_rsof_n : std_logic;
+ signal trn_reof_n : std_logic;
+ signal trn_rsrc_dsc_n : std_logic;
+ signal trn_rsrc_rdy_n : std_logic;
+ signal trn_rbar_hit_n : std_logic_vector(6 downto 0);
+ signal trn_rdst_rdy_n : std_logic;
+ signal trn_rerrfwd_n : std_logic;
+ signal trn_rnp_ok_n : std_logic;
+ signal trn_rfc_npd_av : std_logic_vector(11 downto 0);
+ signal trn_rfc_nph_av : std_logic_vector(7 downto 0);
+ signal trn_rfc_pd_av : std_logic_vector(11 downto 0);
+ signal trn_rfc_ph_av : std_logic_vector(7 downto 0);
+ signal trn_rcpl_streaming_n : std_logic;
+
+ signal trn_td : std_logic_vector(63 downto 0);
+ signal trn_trem_n : std_logic_vector(7 downto 0);
+ signal trn_tsof_n : std_logic;
+ signal trn_teof_n : std_logic;
+ signal trn_tsrc_dsc_n : std_logic;
+ signal trn_tsrc_rdy_n : std_logic;
+ signal trn_tdst_dsc_n : std_logic;
+ signal trn_tdst_rdy_n : std_logic;
+ signal trn_terrfwd_n : std_logic;
+ signal trn_tbuf_av : std_logic_vector(3 downto 0);
+
+ signal cfg_do : std_logic_vector(31 downto 0);
+ signal cfg_rd_wr_done_n : std_logic;
+ signal cfg_di : std_logic_vector(31 downto 0);
+ signal cfg_byte_en_n : std_logic_vector(3 downto 0);
+ signal cfg_dwaddr : std_logic_vector(9 downto 0);
+ signal cfg_wr_en_n : std_logic;
+ signal cfg_rd_en_n : std_logic;
+
+ signal cfg_err_cor_n : std_logic;
+ signal cfg_err_cpl_abort_n : std_logic;
+ signal cfg_err_cpl_timeout_n : std_logic;
+ signal cfg_err_cpl_unexpect_n : std_logic;
+ signal cfg_err_ecrc_n : std_logic;
+ signal cfg_err_posted_n : std_logic;
+ signal cfg_err_tlp_cpl_header : std_logic_vector(47 downto 0);
+ signal cfg_err_ur_n : std_logic;
+ signal cfg_err_cpl_rdy_n : std_logic;
+ signal cfg_err_locked_n : std_logic;
+ signal cfg_interrupt_n : std_logic;
+ signal cfg_interrupt_rdy_n : std_logic;
+ signal cfg_pm_wake_n : std_logic;
+ signal cfg_pcie_link_state_n : std_logic_vector(2 downto 0);
+ signal cfg_to_turnoff_n : std_logic;
+ signal cfg_interrupt_assert_n : std_logic;
+ signal cfg_interrupt_di : std_logic_vector(7 downto 0);
+ signal cfg_interrupt_do : std_logic_vector(7 downto 0);
+ signal cfg_interrupt_mmenable : std_logic_vector(2 downto 0);
+ signal cfg_interrupt_msienable : std_logic;
+
+ signal cfg_trn_pending_n : std_logic;
+ signal cfg_bus_number : std_logic_vector(7 downto 0);
+ signal cfg_device_number : std_logic_vector(4 downto 0);
+ signal cfg_function_number : std_logic_vector(2 downto 0);
+ signal cfg_status : std_logic_vector(15 downto 0);
+ signal cfg_command : std_logic_vector(15 downto 0);
+ signal cfg_dstatus : std_logic_vector(15 downto 0);
+ signal cfg_dcommand : std_logic_vector(15 downto 0);
+ signal cfg_lstatus : std_logic_vector(15 downto 0);
+ signal cfg_lcommand : std_logic_vector(15 downto 0);
+ signal cfg_dsn : std_logic_vector(63 downto 0);
+
+ signal pcie_clk : std_logic;
+begin
+ pcie_clk_ibuf : IBUFDS port map (
+ O => pcie_clk,
+ I => pcie_clk_p,
+ IB => pcie_clk_n
+ );
+
+ sys_reset_n <= not reset25;
+
+ trn_rdst_rdy_n <= '0';
+ trn_rnp_ok_n <= '0';
+ trn_rcpl_streaming_n <= '1';
+
+ trn_tsrc_dsc_n <= '1';
+ trn_terrfwd_n <= '1';
+
+ cfg_di <= (others => '0');
+ cfg_byte_en_n <= (others => '1');
+ cfg_dwaddr <= (others => '0');
+ cfg_wr_en_n <= '1';
+ cfg_rd_en_n <= '1';
+
+ cfg_err_cor_n <= '1';
+ cfg_err_cpl_abort_n <= '1';
+ cfg_err_cpl_timeout_n <= '1';
+ cfg_err_cpl_unexpect_n <= '1';
+ cfg_err_ecrc_n <= '1';
+ cfg_err_posted_n <= '1';
+ cfg_err_tlp_cpl_header <= (others => '0');
+ cfg_err_ur_n <= '1';
+ cfg_err_locked_n <= '1';
+ cfg_interrupt_n <= not interrupt;
+ cfg_pm_wake_n <= '1';
+ cfg_interrupt_assert_n <= '1';
+ cfg_interrupt_di <= (others => '0');
+ interrupt_rdy <= not cfg_interrupt_rdy_n;
+
+ cfg_trn_pending_n <= '1';
+ cfg_dsn <= (others => '0');
+
+ ep : pcie_core port map (
+ pci_exp_rxn => pci_exp_rxn,
+ pci_exp_rxp => pci_exp_rxp,
+ pci_exp_txn => pci_exp_txn,
+ pci_exp_txp => pci_exp_txp,
+
+ sys_clk => pcie_clk,
+ sys_reset_n => sys_reset_n,
+
+ refclkout => open,
+
+ trn_clk => trn_clk,
+ trn_reset_n => trn_reset_n,
+ trn_lnk_up_n => trn_lnk_up_n,
+
+ trn_rd => trn_rd,
+ trn_rrem_n => trn_rrem_n,
+ trn_rsof_n => trn_rsof_n,
+ trn_reof_n => trn_reof_n,
+ trn_rsrc_dsc_n => trn_rsrc_dsc_n,
+ trn_rsrc_rdy_n => trn_rsrc_rdy_n,
+ trn_rbar_hit_n => trn_rbar_hit_n,
+ trn_rdst_rdy_n => trn_rdst_rdy_n,
+ trn_rerrfwd_n => trn_rerrfwd_n,
+ trn_rnp_ok_n => trn_rnp_ok_n,
+ trn_rfc_npd_av => trn_rfc_npd_av,
+ trn_rfc_nph_av => trn_rfc_nph_av,
+ trn_rfc_pd_av => trn_rfc_pd_av,
+ trn_rfc_ph_av => trn_rfc_ph_av,
+ trn_rcpl_streaming_n => trn_rcpl_streaming_n,
+
+ trn_td => trn_td,
+ trn_trem_n => trn_trem_n,
+ trn_tsof_n => trn_tsof_n,
+ trn_teof_n => trn_teof_n,
+ trn_tsrc_dsc_n => trn_tsrc_dsc_n,
+ trn_tsrc_rdy_n => trn_tsrc_rdy_n,
+ trn_tdst_dsc_n => trn_tdst_dsc_n,
+ trn_tdst_rdy_n => trn_tdst_rdy_n,
+ trn_terrfwd_n => trn_terrfwd_n,
+ trn_tbuf_av => trn_tbuf_av,
+
+ cfg_do => cfg_do,
+ cfg_rd_wr_done_n => cfg_rd_wr_done_n,
+ cfg_di => cfg_di,
+ cfg_byte_en_n => cfg_byte_en_n,
+ cfg_dwaddr => cfg_dwaddr,
+ cfg_wr_en_n => cfg_wr_en_n,
+ cfg_rd_en_n => cfg_rd_en_n,
+
+ cfg_err_cor_n => cfg_err_cor_n,
+ cfg_err_cpl_abort_n => cfg_err_cpl_abort_n,
+ cfg_err_cpl_timeout_n => cfg_err_cpl_timeout_n,
+ cfg_err_cpl_unexpect_n => cfg_err_cpl_unexpect_n,
+ cfg_err_ecrc_n => cfg_err_ecrc_n,
+ cfg_err_posted_n => cfg_err_posted_n,
+ cfg_err_tlp_cpl_header => cfg_err_tlp_cpl_header,
+ cfg_err_ur_n => cfg_err_ur_n,
+ cfg_err_cpl_rdy_n => cfg_err_cpl_rdy_n,
+ cfg_err_locked_n => cfg_err_locked_n,
+ cfg_interrupt_n => cfg_interrupt_n,
+ cfg_interrupt_rdy_n => cfg_interrupt_rdy_n,
+ cfg_pm_wake_n => cfg_pm_wake_n,
+ cfg_pcie_link_state_n => cfg_pcie_link_state_n,
+ cfg_to_turnoff_n => cfg_to_turnoff_n,
+ cfg_interrupt_assert_n => cfg_interrupt_assert_n,
+ cfg_interrupt_di => cfg_interrupt_di,
+ cfg_interrupt_do => cfg_interrupt_do,
+ cfg_interrupt_mmenable => cfg_interrupt_mmenable,
+ cfg_interrupt_msienable => cfg_interrupt_msienable,
+
+ cfg_trn_pending_n => cfg_trn_pending_n,
+ cfg_bus_number => cfg_bus_number,
+ cfg_device_number => cfg_device_number,
+ cfg_function_number => cfg_function_number,
+ cfg_status => cfg_status,
+ cfg_command => cfg_command,
+ cfg_dstatus => cfg_dstatus,
+ cfg_dcommand => cfg_dcommand,
+ cfg_lstatus => cfg_lstatus,
+ cfg_lcommand => cfg_lcommand,
+ cfg_dsn => cfg_dsn,
+
+ fast_train_simulation_only => '0'
+ );
+
+ clk125 <= trn_clk;
+ reset125 <= not trn_reset_n;
+
+ rx_frame <= trn_rd;
+ rx_sof <= not trn_rsof_n;
+ rx_eof <= not trn_reof_n;
+ rx_valid <= not trn_rsrc_rdy_n;
+
+ trn_td <= tx_frame;
+ trn_tsof_n <= not tx_sof;
+ trn_teof_n <= not tx_eof;
+ trn_tsrc_rdy_n <= not tx_valid;
+ trn_trem_n <= x"0F" when tx_half = '1' else x"00";
+
+ tx_ready <= not trn_tdst_rdy_n;
+
+ bus_dev_func <= cfg_bus_number & cfg_device_number & cfg_function_number;
+
+ max_read <= cfg_dcommand(14 downto 12);
+ max_write <= cfg_dcommand(7 downto 5);
+
+ bar0 <= not trn_rbar_hit_n(0);
+end arch;
+
diff --git a/netfpga10g/hdl/port_fifo.vhd b/netfpga10g/hdl/port_fifo.vhd
new file mode 100644
index 0000000..ff8c93a
--- /dev/null
+++ b/netfpga10g/hdl/port_fifo.vhd
@@ -0,0 +1,94 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity port_fifo is
+generic (
+ BITS : integer := 14
+);
+port (
+ reset : in std_logic;
+
+ rd_clk : in std_logic;
+ rd_read : in std_logic;
+ rd_data : out std_logic_vector(63 downto 0);
+ rd_empty : out std_logic;
+ rd_count : out std_logic_vector(BITS downto 0);
+
+ wr_clk : in std_logic;
+ wr_write : in std_logic;
+ wr_data : in std_logic_vector(63 downto 0);
+ wr_full : out std_logic;
+ wr_count : out std_logic_vector(BITS downto 0)
+);
+end port_fifo;
+
+architecture arch of port_fifo is
+
+ component data_fifo port (
+ rst : in std_logic;
+ rd_clk : in std_logic;
+ rd_en : in std_logic;
+ dout : out std_logic_vector(63 downto 0);
+ empty : out std_logic;
+ rd_data_count : out std_logic_vector(BITS downto 0);
+ wr_clk : in std_logic;
+ wr_en : in std_logic;
+ din : in std_logic_vector(63 downto 0);
+ full : out std_logic;
+ wr_data_count : out std_logic_vector(BITS downto 0)
+ );
+ end component;
+
+ signal raw_read : std_logic;
+ signal raw_data : std_logic_vector(63 downto 0);
+ signal raw_empty : std_logic;
+ signal raw_count : std_logic_vector(BITS downto 0);
+
+ signal has_extra : std_logic;
+ signal extra : std_logic_vector(63 downto 0);
+begin
+ rd_data <= extra when has_extra = '1' and rd_read = '0' else raw_data;
+ rd_empty <= '0' when has_extra = '1' and rd_read = '0' else '1';
+ rd_count <= std_logic_vector(unsigned(raw_count) + 1) when has_extra = '1' and rd_read = '0' else raw_count;
+
+ raw_read <= '0' when has_extra = '1' and rd_read = '0' else '1';
+
+ process (rd_clk, reset)
+ begin
+ if reset = '1' then
+ has_extra <= '0';
+ extra <= (others => '0');
+
+ elsif rising_edge(rd_clk) then
+ if has_extra = '1' then
+ if rd_read = '1' then
+ has_extra <= not raw_empty;
+ extra <= raw_data;
+ end if;
+ else
+ if rd_read = '0' then
+ has_extra <= not raw_empty;
+ extra <= raw_data;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ fifo : data_fifo port map (
+ rst => reset,
+
+ rd_clk => rd_clk,
+ rd_en => raw_read,
+ dout => raw_data,
+ empty => raw_empty,
+ rd_data_count => raw_count,
+
+ wr_clk => wr_clk,
+ wr_en => wr_write,
+ din => wr_data,
+ full => wr_full,
+ wr_data_count => wr_count
+ );
+end arch;
diff --git a/netfpga10g/hdl/recv_mux.vhd b/netfpga10g/hdl/recv_mux.vhd
new file mode 100644
index 0000000..42932af
--- /dev/null
+++ b/netfpga10g/hdl/recv_mux.vhd
@@ -0,0 +1,86 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+entity recv_mux is
+generic (
+ BUFF_COUNT : integer := 16;
+ BUFF_BITS : integer := 4 -- 2^4 = 16
+);
+port (
+ rd_clk : in std_logic;
+ rd_buff : in std_logic_vector (BUFF_BITS - 1 downto 0);
+ rd_en : in std_logic;
+ rd_data : out std_logic_vector (63 downto 0) := (others => '0');
+ rd_length : out std_logic_vector (8 downto 0) := (others => '0');
+ rd_valid : out std_logic_vector (BUFF_COUNT - 1 downto 0) := (others => '0');
+
+ wr_clk : in std_logic;
+ wr_en : in std_logic;
+ wr_data : in std_logic_vector (63 downto 0);
+ wr_done : in std_logic;
+ wr_accept : out std_logic := '0'
+);
+end recv_mux;
+
+architecture arch of recv_mux is
+ type rd_data_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(63 downto 0);
+ type rd_length_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(8 downto 0);
+
+ signal wr_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal wr_done_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal wr_accept_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal wr_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+
+ signal rd_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal rd_data_i : rd_data_t := (others => (others => '0'));
+ signal rd_length_i : rd_length_t := (others => (others => '0'));
+ signal rd_buff_i : integer range 0 to BUFF_COUNT - 1 := 0;
+begin
+ rd_buff_i <= to_integer(unsigned(rd_buff));
+
+ recv_gen: for i in 0 to BUFF_COUNT - 1 generate
+ recv_buff : entity work.buff port map (
+ wr_clk => wr_clk,
+ wr_en => wr_en_i(i),
+ wr_data => wr_data,
+ wr_done => wr_done_i(i),
+ wr_accept => wr_accept_i(i),
+
+ rd_clk => rd_clk,
+ rd_en => rd_en_i(i),
+ rd_data => rd_data_i(i),
+ rd_length => rd_length_i(i),
+ rd_valid => rd_valid(i)
+ );
+
+ wr_en_i(i) <= wr_en when wr_buff = i else '0';
+ wr_done_i(i) <= wr_done when wr_buff = i else '0';
+
+ rd_en_i(i) <= rd_en when rd_buff_i = i else '0';
+ end generate recv_gen;
+
+ rd_data <= rd_data_i(rd_buff_i);
+ rd_length <= rd_length_i(rd_buff_i);
+
+ wr_accept <= wr_accept_i(wr_buff);
+
+ process (wr_clk)
+ variable tmp_buff : integer range 0 to BUFF_COUNT - 1;
+ begin
+ if rising_edge(wr_clk) then
+ if wr_accept_i(wr_buff) = '0' then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (i + wr_buff) mod BUFF_COUNT;
+
+ if wr_accept_i(tmp_buff) = '1' then
+ wr_buff <= tmp_buff;
+ exit;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/rx_eth.vhd b/netfpga10g/hdl/rx_eth.vhd
new file mode 100644
index 0000000..fe6e65e
--- /dev/null
+++ b/netfpga10g/hdl/rx_eth.vhd
@@ -0,0 +1,168 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity rx_eth is port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ xgmii_rxd : in std_logic_vector(63 downto 0);
+ xgmii_rxc : in std_logic_vector(7 downto 0);
+
+ rx_data : out std_logic_vector(63 downto 0);
+ rx_start : out std_logic;
+ rx_end : out std_logic;
+ rx_rem : out integer range 0 to 7;
+
+ start_count_out : out std_logic_vector(31 downto 0);
+ end_count_out : out std_logic_vector(31 downto 0)
+);
+end rx_eth;
+
+architecture arch of rx_eth is
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERMINATE : std_logic_vector(7 downto 0) := x"FD";
+ constant ERR : std_logic_vector(7 downto 0) := x"FE";
+
+ constant PREAMBLE : std_logic_vector(7 downto 0) := "01010101";
+ constant SFD : std_logic_vector(7 downto 0) := "11010101";
+
+ type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal lanes_a : lanes_t;
+ signal lanes_b : lanes_t;
+
+ signal control_a : std_logic_vector(7 downto 0);
+ signal control_b : std_logic_vector(7 downto 0);
+
+ signal use_a : std_logic;
+
+ signal start_count : unsigned(31 downto 0);
+ signal end_count : unsigned(31 downto 0);
+begin
+ start_count_out <= std_logic_vector(start_count);
+ end_count_out <= std_logic_vector(end_count);
+
+ rx_lanes_gen : for i in 0 to 7 generate
+ lanes_a(i) <= xgmii_rxd(7+8*i downto 8*i);
+ end generate rx_lanes_gen;
+
+ control_a <= xgmii_rxc;
+ lanes_b(4) <= lanes_a(0);
+ lanes_b(5) <= lanes_a(1);
+ lanes_b(6) <= lanes_a(2);
+ lanes_b(7) <= lanes_a(3);
+ control_b(4) <= control_a(0);
+ control_b(5) <= control_a(1);
+ control_b(6) <= control_a(2);
+ control_b(7) <= control_a(3);
+
+ rx_logic : process (clk, reset) begin
+ if reset = '1' then
+ rx_data <= (others => '0');
+ rx_start <= '0';
+ rx_end <= '0';
+ rx_rem <= 0;
+ start_count <= (others => '0');
+ end_count <= (others => '0');
+ lanes_b(0) <= (others => '0');
+ lanes_b(1) <= (others => '0');
+ lanes_b(2) <= (others => '0');
+ lanes_b(3) <= (others => '0');
+ control_b(3 downto 0) <= (others => '0');
+ use_a <= '1';
+
+ elsif rising_edge(clk) then
+ rx_start <= '0';
+ rx_end <= '0';
+ rx_rem <= 0;
+
+ lanes_b(0) <= lanes_a(4);
+ lanes_b(1) <= lanes_a(5);
+ lanes_b(2) <= lanes_a(6);
+ lanes_b(3) <= lanes_a(7);
+ control_b(3 downto 0) <= control_a(7 downto 4);
+
+ for i in 0 to 7 loop
+ if use_a = '1' then
+ rx_data(63-8*i downto 56-8*i) <= lanes_a(i);
+ else
+ rx_data(63-8*i downto 56-8*i) <= lanes_b(i);
+ end if;
+ end loop;
+
+ if control_a(0) = '1' and lanes_a(0) = START then
+ rx_start <= '1';
+ use_a <= '1';
+ elsif control_b(0) = '1' and lanes_b(0) = START then
+ rx_start <= '1';
+ use_a <= '0';
+ start_count <= start_count + 1;
+ end if;
+
+ if use_a = '1' then
+ if control_a(0) = '1' and (lanes_a(0) = TERMINATE or lanes_a(0) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 0;
+ elsif control_a(1) = '1' and (lanes_a(1) = TERMINATE or lanes_a(1) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 1;
+ elsif control_a(2) = '1' and (lanes_a(2) = TERMINATE or lanes_a(2) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 2;
+ elsif control_a(3) = '1' and (lanes_a(3) = TERMINATE or lanes_a(3) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 3;
+ elsif control_a(4) = '1' and (lanes_a(4) = TERMINATE or lanes_a(4) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 4;
+ elsif control_a(5) = '1' and (lanes_a(5) = TERMINATE or lanes_a(5) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 5;
+ elsif control_a(6) = '1' and (lanes_a(6) = TERMINATE or lanes_a(6) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 6;
+ elsif control_a(7) = '1' and (lanes_a(7) = TERMINATE or lanes_a(7) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 7;
+ end if;
+ else
+ if control_b(0) = '1' and (lanes_b(0) = TERMINATE or lanes_b(0) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 0;
+ end_count <= end_count + 1;
+ elsif control_b(1) = '1' and (lanes_b(1) = TERMINATE or lanes_b(1) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 1;
+ end_count <= end_count + 1;
+ elsif control_b(2) = '1' and (lanes_b(2) = TERMINATE or lanes_b(2) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 2;
+ end_count <= end_count + 1;
+ elsif control_b(3) = '1' and (lanes_b(3) = TERMINATE or lanes_b(3) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 3;
+ end_count <= end_count + 1;
+ elsif control_b(4) = '1' and (lanes_b(4) = TERMINATE or lanes_b(4) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 4;
+ end_count <= end_count + 1;
+ elsif control_b(5) = '1' and (lanes_b(5) = TERMINATE or lanes_b(5) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 5;
+ end_count <= end_count + 1;
+ elsif control_b(6) = '1' and (lanes_b(6) = TERMINATE or lanes_b(6) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 6;
+ end_count <= end_count + 1;
+ elsif control_b(7) = '1' and (lanes_b(7) = TERMINATE or lanes_b(7) = ERR) then
+ rx_end <= '1';
+ rx_rem <= 7;
+ end_count <= end_count + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/send_mux.vhd b/netfpga10g/hdl/send_mux.vhd
new file mode 100644
index 0000000..8d9f667
--- /dev/null
+++ b/netfpga10g/hdl/send_mux.vhd
@@ -0,0 +1,77 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+entity send_mux is
+generic (
+ BUFF_COUNT : integer := 16;
+ BUFF_BITS : integer := 4 -- 2^4 = 16
+);
+ Port ( wr_clk : in STD_LOGIC;
+ wr_buff : in STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0);
+ wr_en : in STD_LOGIC;
+ wr_data : in STD_LOGIC_VECTOR (63 downto 0);
+ wr_done : in STD_LOGIC;
+ wr_cancel : in STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+ wr_accept : out STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0) := (others => '0');
+ rd_clk : in STD_LOGIC;
+ rd_en : in STD_LOGIC;
+ rd_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ rd_valid : out STD_LOGIC := '0');
+end send_mux;
+
+architecture arch of send_mux is
+ type rd_data_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(63 downto 0);
+
+ signal wr_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal wr_done_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+
+ signal rd_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal rd_data_i : rd_data_t := (others => (others => '0'));
+ signal rd_valid_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
+ signal rd_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+begin
+ send_gen: for i in 0 to BUFF_COUNT - 1 generate
+ send_buff : entity work.buff port map (
+ wr_clk => wr_clk,
+ wr_en => wr_en_i(i),
+ wr_data => wr_data,
+ wr_done => wr_done_i(i),
+ wr_cancel => wr_cancel(i),
+ wr_accept => wr_accept(i),
+
+ rd_clk => rd_clk,
+ rd_en => rd_en_i(i),
+ rd_data => rd_data_i(i),
+ rd_length => open,
+ rd_valid => rd_valid_i(i)
+ );
+
+ wr_en_i(i) <= wr_en when to_integer(unsigned(wr_buff)) = i else '0';
+ wr_done_i(i) <= wr_done when to_integer(unsigned(wr_buff)) = i else '0';
+
+ rd_en_i(i) <= rd_en when rd_buff = i else '0';
+ end generate send_gen;
+
+ rd_data <= rd_data_i(rd_buff);
+ rd_valid <= rd_valid_i(rd_buff);
+
+ process (rd_clk)
+ variable tmp_buff : integer range 0 to BUFF_COUNT - 1;
+ begin
+ if rising_edge(rd_clk) then
+ if rd_valid_i(rd_buff) = '0' then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (i + rd_buff) mod BUFF_COUNT;
+
+ if rd_valid_i(tmp_buff) = '1' then
+ rd_buff <= tmp_buff;
+ exit;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;
+
diff --git a/netfpga10g/hdl/system_loop.vhd b/netfpga10g/hdl/system_loop.vhd
new file mode 100644
index 0000000..79031c3
--- /dev/null
+++ b/netfpga10g/hdl/system_loop.vhd
@@ -0,0 +1,253 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library unisim;
+use unisim.vcomponents.all;
+
+entity system_loop is
+generic (
+ BUFF_COUNT : integer := 16;
+ BUFF_BITS : integer := 4 -- 2^4 = 16
+);
+port (
+ eth_clk : in std_logic;
+ pcie_clk : in std_logic;
+
+ rx_frame : in std_logic_vector(63 downto 0);
+ rx_sof : in std_logic;
+ rx_eof : in std_logic;
+ rx_valid : in std_logic;
+ rx_bar0 : in std_logic;
+
+ tx_frame : out std_logic_vector(63 downto 0);
+ tx_sof : out std_logic;
+ tx_eof : out std_logic;
+ tx_half : out std_logic;
+ tx_valid : out std_logic;
+ tx_ready : in std_logic;
+
+ interrupt : out std_logic;
+ interrupt_rdy : in std_logic;
+
+ max_read : in std_logic_vector(2 downto 0);
+ max_write : in std_logic_vector(2 downto 0);
+
+ local : in std_logic_vector(15 downto 0);
+
+ xgmii_rxd : in std_logic_vector(63 downto 0);
+ xgmii_rxc : in std_logic_vector(7 downto 0);
+
+ xgmii_txd : out std_logic_vector(63 downto 0);
+ xgmii_txc : out std_logic_vector(7 downto 0);
+
+ mdio_command : out std_logic_vector(0 to 27);
+ mdio_data : in std_logic_vector(0 to 15);
+ mdio_enable : out std_logic;
+ mdio_done : in std_logic
+);
+end system_loop;
+
+architecture arch of system_loop is
+ -- send mux
+ signal send_rd_en : std_logic;
+ signal send_rd_data : std_logic_vector (63 downto 0);
+ signal send_rd_valid : std_logic;
+
+ signal send_wr_buff : std_logic_vector (BUFF_BITS - 1 downto 0) := (others => '0');
+ signal send_wr_en : std_logic := '0';
+ signal send_wr_data : std_logic_vector (63 downto 0) := (others => '0');
+ signal send_wr_done : std_logic := '0';
+ signal send_wr_cancel : std_logic_vector (BUFF_COUNT - 1 downto 0);
+ signal send_wr_accept : std_logic_vector (BUFF_COUNT - 1 downto 0);
+
+ -- recv mux
+ signal recv_wr_en : std_logic;
+ signal recv_wr_data : std_logic_vector (63 downto 0);
+ signal recv_wr_done : std_logic;
+ signal recv_wr_accept : std_logic;
+
+ signal recv_rd_buff : std_logic_vector (BUFF_BITS - 1 downto 0) := (others => '0');
+ signal recv_rd_en : std_logic := '0';
+ signal recv_rd_data : std_logic_vector (63 downto 0);
+ signal recv_rd_length : std_logic_vector (8 downto 0);
+ signal recv_rd_valid : std_logic_vector (BUFF_COUNT - 1 downto 0);
+
+ -- pcie_rx
+ signal rx_read : std_logic;
+ signal rx_write : std_logic;
+ signal rx_complete : std_logic;
+ signal rx_data : std_logic_vector(63 downto 0);
+ signal rx_address : std_logic_vector(63 downto 3);
+ signal rx_tag : std_logic_vector(4 downto 0);
+
+ signal remote : std_logic_vector(23 downto 0);
+
+ -- pcie_tx
+ signal tx_read : std_logic;
+ signal tx_write : std_logic;
+ signal tx_complete : std_logic;
+ signal tx_data : std_logic_vector(63 downto 0);
+ signal tx_address : std_logic_vector(63 downto 3);
+ signal tx_length : std_logic_vector(8 downto 0);
+ signal tx_tag : std_logic_vector(4 downto 0);
+ signal tx_accept : std_logic;
+ signal tx_done : std_logic;
+begin
+ eth_rx : entity work.eth_rx port map (
+ clk => eth_clk,
+
+ wr_en => recv_wr_en,
+ wr_data => recv_wr_data,
+ wr_done => recv_wr_done,
+ wr_accept => recv_wr_accept,
+
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc
+ );
+
+ eth_tx : entity work.eth_tx port map (
+ clk => eth_clk,
+
+ rd_en => send_rd_en,
+ rd_data => send_rd_data,
+ rd_valid => send_rd_valid,
+
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc
+ );
+
+ send_mux : entity work.send_mux
+ generic map (
+ BUFF_COUNT => BUFF_COUNT,
+ BUFF_BITS => BUFF_BITS
+ )
+ port map (
+ wr_clk => pcie_clk,
+ wr_buff => send_wr_buff,
+ wr_en => send_wr_en,
+ wr_data => send_wr_data,
+ wr_done => send_wr_done,
+ wr_cancel => send_wr_cancel,
+ wr_accept => send_wr_accept,
+
+ rd_clk => eth_clk,
+ rd_en => send_rd_en,
+ rd_data => send_rd_data,
+ rd_valid => send_rd_valid
+ );
+
+ recv_mux : entity work.recv_mux
+ generic map (
+ BUFF_COUNT => BUFF_COUNT,
+ BUFF_BITS => BUFF_BITS
+ )
+ port map (
+ rd_clk => pcie_clk,
+ rd_buff => recv_rd_buff,
+ rd_en => recv_rd_en,
+ rd_data => recv_rd_data,
+ rd_length => recv_rd_length,
+ rd_valid => recv_rd_valid,
+
+ wr_clk => eth_clk,
+ wr_en => recv_wr_en,
+ wr_data => recv_wr_data,
+ wr_done => recv_wr_done,
+ wr_accept => recv_wr_accept
+ );
+
+ engine : entity work.engine
+ generic map (
+ BUFF_COUNT => BUFF_COUNT,
+ BUFF_BITS => BUFF_BITS
+ )
+ port map (
+ clk => pcie_clk,
+
+ rd_buff => recv_rd_buff,
+ rd_en => recv_rd_en,
+ rd_data => recv_rd_data,
+ rd_length => recv_rd_length,
+ rd_valid => recv_rd_valid,
+
+ wr_buff => send_wr_buff,
+ wr_en => send_wr_en,
+ wr_data => send_wr_data,
+ wr_done => send_wr_done,
+ wr_cancel => send_wr_cancel,
+ wr_accept => send_wr_accept,
+
+ rx_read => rx_read,
+ rx_write => rx_write,
+ rx_complete => rx_complete,
+ rx_data => rx_data,
+ rx_address => rx_address,
+ rx_tag => rx_tag,
+
+ tx_read => tx_read,
+ tx_write => tx_write,
+ tx_complete => tx_complete,
+ tx_data => tx_data,
+ tx_address => tx_address,
+ tx_length => tx_length,
+ tx_tag => tx_tag,
+ tx_accept => tx_accept,
+ tx_done => tx_done,
+
+ interrupt => interrupt,
+ interrupt_rdy => interrupt_rdy,
+
+ max_read => max_read,
+ max_write => max_write,
+
+ mdio_command => mdio_command,
+ mdio_data => mdio_data,
+ mdio_enable => mdio_enable,
+ mdio_done => mdio_done
+ );
+
+ pcie_rx : entity work.pcie_rx port map (
+ clk => pcie_clk,
+
+ frame => rx_frame,
+ sof => rx_sof,
+ eof => rx_eof,
+ valid => rx_valid,
+
+ read => rx_read,
+ write => rx_write,
+ complete => rx_complete,
+ data => rx_data,
+ address => rx_address,
+ tag => rx_tag,
+ remote => remote,
+
+ bar0 => rx_bar0
+ );
+
+ pcie_tx : entity work.pcie_tx port map (
+ clk => pcie_clk,
+
+ frame => tx_frame,
+ sof => tx_sof,
+ eof => tx_eof,
+ half => tx_half,
+ valid => tx_valid,
+ ready => tx_ready,
+
+ read => tx_read,
+ write => tx_write,
+ complete => tx_complete,
+ data => tx_data,
+ address => tx_address,
+ length => tx_length,
+ tag => tx_tag,
+ local => local,
+ remote => remote,
+ accept => tx_accept,
+ done => tx_done
+ );
+
+end arch;
+
diff --git a/netfpga10g/hdl/top.vhd b/netfpga10g/hdl/top.vhd
new file mode 100644
index 0000000..83a5002
--- /dev/null
+++ b/netfpga10g/hdl/top.vhd
@@ -0,0 +1,243 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+Library UNISIM;
+use UNISIM.vcomponents.all;
+
+entity top is port (
+ led1 : out std_logic;
+ led2 : out std_logic;
+ led3 : out std_logic;
+
+ pcie_clk_p : in std_logic;
+ pcie_clk_n : in std_logic;
+ clk25 : in std_logic;
+ clk100 : in std_logic;
+
+ pci_exp_rxn : in std_logic_vector(7 downto 0);
+ pci_exp_rxp : in std_logic_vector(7 downto 0);
+ pci_exp_txn : out std_logic_vector(7 downto 0);
+ pci_exp_txp : out std_logic_vector(7 downto 0);
+
+ mdio : inout std_logic;
+ mdc : out std_logic;
+ phy_reset_n : out std_logic;
+
+ xaui0_clk_p : in std_logic;
+ xaui0_clk_n : in std_logic;
+ xaui0_tx_l0_p : out std_logic;
+ xaui0_tx_l0_n : out std_logic;
+ xaui0_tx_l1_p : out std_logic;
+ xaui0_tx_l1_n : out std_logic;
+ xaui0_tx_l2_p : out std_logic;
+ xaui0_tx_l2_n : out std_logic;
+ xaui0_tx_l3_p : out std_logic;
+ xaui0_tx_l3_n : out std_logic;
+ xaui0_rx_l0_p : in std_logic;
+ xaui0_rx_l0_n : in std_logic;
+ xaui0_rx_l1_p : in std_logic;
+ xaui0_rx_l1_n : in std_logic;
+ xaui0_rx_l2_p : in std_logic;
+ xaui0_rx_l2_n : in std_logic;
+ xaui0_rx_l3_p : in std_logic;
+ xaui0_rx_l3_n : in std_logic
+);
+end top;
+
+architecture arch of top is
+ signal clk125 : std_logic;
+ signal reset125 : std_logic;
+
+ signal count25 : unsigned(6 downto 0) := (others => '0');
+ signal reset25 : std_logic := '1';
+
+ signal clk50 : std_logic;
+ signal clk156 : std_logic;
+
+ signal rx_frame : std_logic_vector(63 downto 0);
+ signal rx_sof : std_logic;
+ signal rx_eof : std_logic;
+ signal rx_valid : std_logic;
+ signal rx_bar0 : std_logic;
+
+ signal tx_frame : std_logic_vector(63 downto 0);
+ signal tx_sof : std_logic;
+ signal tx_eof : std_logic;
+ signal tx_half : std_logic;
+ signal tx_valid : std_logic;
+ signal tx_ready : std_logic;
+
+ signal interrupt : std_logic;
+ signal interrupt_rdy : std_logic;
+
+ signal max_read : std_logic_vector(2 downto 0);
+ signal max_write : std_logic_vector(2 downto 0);
+
+ signal local : std_logic_vector(15 downto 0);
+
+ signal xgmii_rxd : std_logic_vector(63 downto 0);
+ signal xgmii_rxc : std_logic_vector(7 downto 0);
+ signal xgmii_txd : std_logic_vector(63 downto 0);
+ signal xgmii_txc : std_logic_vector(7 downto 0);
+
+ signal mdio_command : std_logic_vector(0 to 27);
+ signal mdio_data : std_logic_vector(0 to 15);
+ signal mdio_enable : std_logic;
+ signal mdio_done : std_logic;
+
+ signal mdio_in : std_logic;
+ signal mdio_out : std_logic;
+ signal mdio_Z : std_logic;
+begin
+ led1 <= '1';
+ led2 <= '0';
+ led3 <= '1';
+
+ process (clk25) begin
+ if rising_edge(clk25) then
+ if count25 = 100 then
+ reset25 <= '0';
+ else
+ count25 <= count25 + 1;
+ end if;
+ end if;
+ end process;
+
+ process (clk100, reset125) begin
+ if reset125 = '1' then
+ clk50 <= '0';
+ elsif rising_edge(clk100) then
+ clk50 <= not clk50;
+ end if;
+ end process;
+
+ pcie_wrapper : entity work.pcie_wrapper port map (
+ pcie_clk_p => pcie_clk_p,
+ pcie_clk_n => pcie_clk_n,
+ reset25 => reset25,
+
+ clk125 => clk125,
+ reset125 => reset125,
+
+ pci_exp_rxn => pci_exp_rxn,
+ pci_exp_rxp => pci_exp_rxp,
+ pci_exp_txn => pci_exp_txn,
+ pci_exp_txp => pci_exp_txp,
+
+ rx_frame => rx_frame,
+ rx_sof => rx_sof,
+ rx_eof => rx_eof,
+ rx_valid => rx_valid,
+
+ tx_frame => tx_frame,
+ tx_sof => tx_sof,
+ tx_eof => tx_eof,
+ tx_half => tx_half,
+ tx_valid => tx_valid,
+ tx_ready => tx_ready,
+
+ bus_dev_func => local,
+
+ max_read => max_read,
+ max_write => max_write,
+
+ interrupt => interrupt,
+ interrupt_rdy => interrupt_rdy,
+
+ bar0 => rx_bar0
+ );
+
+ system_loop: entity work.system_loop port map (
+ eth_clk => clk156,
+ pcie_clk => clk125,
+
+ rx_frame => rx_frame,
+ rx_sof => rx_sof,
+ rx_eof => rx_eof,
+ rx_valid => rx_valid,
+ rx_bar0 => rx_bar0,
+
+ tx_frame => tx_frame,
+ tx_sof => tx_sof,
+ tx_eof => tx_eof,
+ tx_half => tx_half,
+ tx_valid => tx_valid,
+ tx_ready => tx_ready,
+
+ interrupt => interrupt,
+ interrupt_rdy => interrupt_rdy,
+
+ max_read => max_read,
+ max_write => max_write,
+
+ local => local,
+
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc,
+
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc,
+
+ mdio_command => mdio_command,
+ mdio_data => mdio_data,
+ mdio_enable => mdio_enable,
+ mdio_done => mdio_done
+ );
+
+ xaui : entity work.xaui_top
+ generic map (
+ REVERSE_LANES => '1'
+ )
+ port map (
+ dclk => clk50,
+ reset => reset125,
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc,
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc,
+ clk156_out => clk156,
+ refclk_p => xaui0_clk_p,
+ refclk_n => xaui0_clk_n,
+ xaui_tx_l0_p => xaui0_tx_l0_p,
+ xaui_tx_l0_n => xaui0_tx_l0_n,
+ xaui_tx_l1_p => xaui0_tx_l1_p,
+ xaui_tx_l1_n => xaui0_tx_l1_n,
+ xaui_tx_l2_p => xaui0_tx_l2_p,
+ xaui_tx_l2_n => xaui0_tx_l2_n,
+ xaui_tx_l3_p => xaui0_tx_l3_p,
+ xaui_tx_l3_n => xaui0_tx_l3_n,
+ xaui_rx_l0_p => xaui0_rx_l0_p,
+ xaui_rx_l0_n => xaui0_rx_l0_n,
+ xaui_rx_l1_p => xaui0_rx_l1_p,
+ xaui_rx_l1_n => xaui0_rx_l1_n,
+ xaui_rx_l2_p => xaui0_rx_l2_p,
+ xaui_rx_l2_n => xaui0_rx_l2_n,
+ xaui_rx_l3_p => xaui0_rx_l3_p,
+ xaui_rx_l3_n => xaui0_rx_l3_n
+ );
+
+ mdio_iobuf : IOBUF port map (
+ O => mdio_in,
+ IO => mdio,
+ I => mdio_out,
+ T => mdio_Z
+ );
+
+ mdio_module : entity work.mdio port map (
+ clk125 => clk125,
+ reset125 => reset125,
+
+ command => mdio_command,
+ data_out => mdio_data,
+ enable => mdio_enable,
+ done => mdio_done,
+
+ mdio_in => mdio_in,
+ mdio_out => mdio_out,
+ mdio_Z => mdio_Z,
+ mdc => mdc,
+ phy_reset_n => phy_reset_n
+ );
+end arch;
diff --git a/netfpga10g/hdl/tx_eth.vhd b/netfpga10g/hdl/tx_eth.vhd
new file mode 100644
index 0000000..fab9cac
--- /dev/null
+++ b/netfpga10g/hdl/tx_eth.vhd
@@ -0,0 +1,96 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity tx_eth is port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ xgmii_txd : out std_logic_vector(63 downto 0);
+ xgmii_txc : out std_logic_vector(7 downto 0);
+
+ tx_data : in std_logic_vector(63 downto 0);
+ tx_start : in std_logic;
+ tx_end : in std_logic;
+ tx_rem : in integer range 0 to 7;
+
+ start_count_out : out std_logic_vector(31 downto 0);
+ end_count_out : out std_logic_vector(31 downto 0)
+);
+end tx_eth;
+
+architecture arch of tx_eth is
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERMINATE : std_logic_vector(7 downto 0) := x"FD";
+
+ constant PREAMBLE : std_logic_vector(7 downto 0) := "01010101";
+ constant SFD : std_logic_vector(7 downto 0) := "11010101";
+
+ type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal lanes : lanes_t;
+
+ signal in_packet : std_logic;
+
+ signal start_count : unsigned(31 downto 0);
+ signal end_count : unsigned(31 downto 0);
+begin
+ start_count_out <= std_logic_vector(start_count);
+ end_count_out <= std_logic_vector(end_count);
+
+ tx_lanes_gen : for i in 0 to 7 generate
+ xgmii_txd(7+8*i downto 8*i) <= lanes(i);
+ end generate tx_lanes_gen;
+
+ tx_logic : process (clk, reset) begin
+ if reset = '1' then
+ in_packet <= '0';
+ start_count <= (others => '0');
+ end_count <= (others => '0');
+
+ for i in 0 to 7 loop
+ lanes(i) <= IDLE;
+ xgmii_txc(i) <= '1';
+ end loop;
+
+ elsif rising_edge(clk) then
+ for i in 0 to 7 loop
+ lanes(i) <= IDLE;
+ xgmii_txc(i) <= '1';
+ end loop;
+
+ if tx_start = '1' then
+ in_packet <= '1';
+ lanes(0) <= START;
+ xgmii_txc(0) <= '1';
+ lanes(1 to 6) <= (others => PREAMBLE);
+ xgmii_txc(6 downto 1) <= (others => '0');
+ lanes(7) <= SFD;
+ xgmii_txc(7) <= '0';
+ start_count <= start_count + 1;
+
+ elsif tx_end = '1' then
+ in_packet <= '0';
+ end_count <= end_count + 1;
+
+ for i in 0 to 7 loop
+ if i < tx_rem then
+ lanes(i) <= tx_data(63-8*i downto 56-8*i);
+ xgmii_txc(i) <= '0';
+ elsif i = tx_rem then
+ lanes(i) <= TERMINATE;
+ xgmii_txc(i) <= '1';
+ end if;
+ end loop;
+
+ elsif in_packet = '1' then
+ for i in 0 to 7 loop
+ lanes(i) <= tx_data(63-8*i downto 56-8*i);
+ xgmii_txc(i) <= '0';
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;
+