summaryrefslogtreecommitdiff
path: root/netfpga10g
diff options
context:
space:
mode:
Diffstat (limited to 'netfpga10g')
-rw-r--r--netfpga10g/constraints.ucf52
-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
-rw-r--r--netfpga10g/tests/buff_test.vhd151
-rw-r--r--netfpga10g/tests/engine_test.vhd1123
-rw-r--r--netfpga10g/tests/eth_buff_loop_test.vhd173
-rw-r--r--netfpga10g/tests/eth_rx_test.vhd225
-rw-r--r--netfpga10g/tests/eth_tx_test.vhd126
-rw-r--r--netfpga10g/tests/pcie_rx_test.vhd322
-rw-r--r--netfpga10g/tests/pcie_tx_test.vhd561
-rw-r--r--netfpga10g/tests/queue_test.vhd149
-rw-r--r--netfpga10g/tests/send_mux_test.vhd199
-rw-r--r--netfpga10g/tests/system_loop_test.vhd285
29 files changed, 7281 insertions, 0 deletions
diff --git a/netfpga10g/constraints.ucf b/netfpga10g/constraints.ucf
new file mode 100644
index 0000000..9f16110
--- /dev/null
+++ b/netfpga10g/constraints.ucf
@@ -0,0 +1,52 @@
+
+CONFIG PART = xc5vtx240tff1759-2;
+
+NET "clk25" LOC = "AJ25" | IOSTANDARD = LVCMOS33;
+NET "clk100" LOC = "AN25" | IOSTANDARD = LVCMOS33;
+
+NET "clk25" TNM_NET=TNM_NET_CLK25;
+TIMESPEC TS_CLK25 = PERIOD TNM_NET_CLK25 25 MHz;
+
+NET "clk100" TNM_NET=TNM_NET_CLK100;
+TIMESPEC TS_CLK100 = PERIOD TNM_NET_CLK100 100 MHz;
+
+NET "led1" LOC = "AK25" | IOSTANDARD = LVCMOS33;
+NET "led2" LOC = "AM24" | IOSTANDARD = LVCMOS33;
+NET "led3" LOC = "AP20" | IOSTANDARD = LVCMOS33;
+
+# PCI express
+NET "pcie_clk_p" LOC = "AT4";
+NET "pcie_clk_n" LOC = "AT3";
+INST "pcie_wrapper/pcie_clk_ibuf" DIFF_TERM = "TRUE";
+
+INST "pcie_wrapper/ep/pcie_ep0/pcie_blk/SIO/.pcie_gt_wrapper_i/GTD[0].GT_i" LOC = GTX_DUAL_X1Y5;
+INST "pcie_wrapper/ep/pcie_ep0/pcie_blk/SIO/.pcie_gt_wrapper_i/GTD[2].GT_i" LOC = GTX_DUAL_X1Y4;
+INST "pcie_wrapper/ep/pcie_ep0/pcie_blk/SIO/.pcie_gt_wrapper_i/GTD[4].GT_i" LOC = GTX_DUAL_X1Y3;
+INST "pcie_wrapper/ep/pcie_ep0/pcie_blk/SIO/.pcie_gt_wrapper_i/GTD[6].GT_i" LOC = GTX_DUAL_X1Y2;
+
+NET "clk125" TNM_NET=TNM_NET_CLK125;
+TIMESPEC TS_CLK125 = PERIOD TNM_NET_CLK125 125 MHz;
+
+# mdio
+
+NET "phy_reset_n" LOC = "AR20" | IOSTANDARD = LVCMOS33;
+NET "mdc" LOC = "AK23" | IOSTANDARD = LVCMOS33;
+NET "mdio" LOC = "AL20" | IOSTANDARD = LVCMOS33;
+
+# xaui
+
+NET "xaui/txoutclk" TNM_NET="clk156_top";
+TIMESPEC "TS_clk156_top" = PERIOD "clk156_top" 156.25 MHz;
+
+NET "clk50" TNM_NET=DCLK_CLK;
+TIMESPEC TS_DCLK_CLK = PERIOD DCLK_CLK 50 MHz;
+
+NET *xaui_block/rocketio_wrapper_i/tile1_rxrecclk0_i TNM_NET=clk156_rec;
+TIMESPEC TS_clk156_rec = PERIOD clk156_rec 156.25MHz;
+
+INST xaui/xaui_block/rocketio_wrapper_i/tile0_xaui_v10_4_rocketio_wrapper_i/YES_REVERSE_LANES.gtx_dual_i LOC=GTX_DUAL_X1Y6;
+INST xaui/xaui_block/rocketio_wrapper_i/tile1_xaui_v10_4_rocketio_wrapper_i/YES_REVERSE_LANES.gtx_dual_i LOC=GTX_DUAL_X1Y7;
+
+NET "xaui0_clk_p" LOC = "M4" ;
+NET "xaui0_clk_n" LOC = "M3" ;
+
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;
+
diff --git a/netfpga10g/tests/buff_test.vhd b/netfpga10g/tests/buff_test.vhd
new file mode 100644
index 0000000..d9f4a0a
--- /dev/null
+++ b/netfpga10g/tests/buff_test.vhd
@@ -0,0 +1,151 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY buff_test IS
+END buff_test;
+
+ARCHITECTURE behavior OF buff_test IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+
+ COMPONENT buff
+ 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_accept : OUT std_logic;
+ rd_clk : IN std_logic;
+ rd_en : IN std_logic;
+ rd_data : OUT std_logic_vector(63 downto 0);
+ rd_length : OUT std_logic_vector(8 downto 0);
+ rd_valid : OUT std_logic
+ );
+ END COMPONENT;
+
+
+ signal wr_clk : std_logic := '0';
+ signal wr_en : std_logic := '0';
+ signal wr_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal wr_done : std_logic := '0';
+ signal wr_accept : std_logic;
+
+ signal rd_clk : std_logic := '0';
+ signal rd_en : std_logic := '0';
+ signal rd_data : std_logic_vector(63 downto 0);
+ signal rd_length : std_logic_vector(8 downto 0);
+ signal rd_valid : std_logic;
+
+ -- Clock period definitions
+ constant wr_clk_period : time := 10 ns;
+ constant rd_clk_period : time := 7 ns;
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: buff PORT MAP (
+ wr_clk => wr_clk,
+ wr_en => wr_en,
+ wr_data => wr_data,
+ wr_done => wr_done,
+ wr_accept => wr_accept,
+ rd_clk => rd_clk,
+ rd_en => rd_en,
+ rd_data => rd_data,
+ rd_length => rd_length,
+ rd_valid => rd_valid
+ );
+
+ -- Clock process definitions
+ wr_clk_process :process
+ begin
+ wr_clk <= '0';
+ wait for wr_clk_period/2;
+ wr_clk <= '1';
+ wait for wr_clk_period/2;
+ end process;
+
+ rd_clk_process :process
+ begin
+ rd_clk <= '0';
+ wait for rd_clk_period/2;
+ rd_clk <= '1';
+ wait for rd_clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ wait for wr_clk_period;
+
+ wr_en <= '1';
+ wr_data <= x"0123456789ABCDEF";
+
+ wait for wr_clk_period;
+
+ wr_en <= '1';
+ wr_data <= x"FEDCBA9876543210";
+
+ wait for wr_clk_period;
+
+ wr_en <= '0';
+ wr_data <= x"0000000000000000";
+ wr_done <= '1';
+
+ wait for wr_clk_period;
+
+ wr_done <= '0';
+
+ wait until wr_accept = '1';
+ wait for wr_clk_period / 2;
+
+ wr_en <= '1';
+ wr_data <= x"AAAAAAAAAAAAAAAA";
+ wait for wr_clk_period;
+ wr_data <= x"BBBBBBBBBBBBBBBB";
+ wait for wr_clk_period;
+ wr_data <= x"CCCCCCCCCCCCCCCC";
+ wait for wr_clk_period;
+ wr_data <= x"DDDDDDDDDDDDDDDD";
+ wait for wr_clk_period;
+ wr_en <= '0';
+ wr_data <= x"0000000000000000";
+ wr_done <= '1';
+ wait for wr_clk_period;
+ wr_done <= '0';
+
+ wait until wr_accept = '1';
+ wait for wr_clk_period / 2;
+ wait for wr_clk_period;
+
+ wr_en <= '1';
+ wr_data <= x"0123456789ABCDEF";
+ wait for wr_clk_period;
+ wr_data <= x"FEDCBA9876543210";
+ wait for wr_clk_period;
+ wr_data <= x"0123456789ABCDEF";
+ wait for wr_clk_period;
+ wr_data <= x"FEDCBA9876543210";
+ wait for wr_clk_period;
+
+ wr_en <= '0';
+ wr_data <= x"0000000000000000";
+ wr_done <= '1';
+ wait for wr_clk_period;
+ wr_done <= '0';
+
+ wait;
+ end process;
+
+ process
+ begin
+ rd_en <= '0';
+ wait for rd_clk_period;
+ rd_en <= '1';
+ wait for rd_clk_period * 2;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/engine_test.vhd b/netfpga10g/tests/engine_test.vhd
new file mode 100644
index 0000000..bf1b3c3
--- /dev/null
+++ b/netfpga10g/tests/engine_test.vhd
@@ -0,0 +1,1123 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY engine_test IS
+END engine_test;
+
+ARCHITECTURE behavior OF engine_test IS
+
+ COMPONENT engine
+ PORT(
+ clk : IN std_logic;
+ rd_buff : OUT std_logic_vector(3 downto 0);
+ rd_en : OUT std_logic;
+ rd_data : IN std_logic_vector(63 downto 0);
+ rd_length : IN std_logic_vector(8 downto 0);
+ rd_valid : IN std_logic_vector(15 downto 0);
+ wr_buff : OUT std_logic_vector(3 downto 0);
+ wr_en : OUT std_logic;
+ wr_data : OUT std_logic_vector(63 downto 0);
+ wr_done : OUT std_logic;
+ wr_accept : IN std_logic_vector(15 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;
+ 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(63 downto 3);
+ tx_length : OUT std_logic_vector(8 downto 0);
+ tx_tag : OUT std_logic_vector(4 downto 0);
+ tx_accept : IN std_logic;
+ tx_done : 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)
+ );
+ END COMPONENT;
+
+ signal clk : std_logic := '0';
+
+ signal rd_buff : std_logic_vector(3 downto 0);
+ signal rd_en : std_logic;
+ signal rd_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal rd_length : std_logic_vector(8 downto 0) := (others => '0');
+ signal rd_valid : std_logic_vector(15 downto 0) := (others => '0');
+
+ signal wr_buff : std_logic_vector(3 downto 0);
+ signal wr_en : std_logic;
+ signal wr_data : std_logic_vector(63 downto 0);
+ signal wr_done : std_logic;
+ signal wr_accept : std_logic_vector(15 downto 0) := (others => '0');
+
+ signal rx_read : std_logic := '0';
+ signal rx_write : std_logic := '0';
+ signal rx_complete : std_logic := '0';
+ signal rx_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal rx_address : std_logic_vector(63 downto 3) := (others => '0');
+ signal rx_tag : std_logic_vector(4 downto 0) := (others => '0');
+
+ 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 := '0';
+ signal tx_done : std_logic := '0';
+
+ signal interrupt : std_logic;
+ signal interrupt_rdy : std_logic := '0';
+
+ signal max_read : std_logic_vector(2 downto 0) := (others => '0');
+ signal max_write : std_logic_vector(2 downto 0) := (others => '0');
+
+ constant clk_period : time := 10 ns;
+
+ signal test_fail : std_logic := '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";
+
+ constant ADDR_31 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(31, 61));
+ constant ADDR_32 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(32, 61));
+ constant ADDR_4 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(4, 61));
+
+ constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9));
+ constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9));
+ constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9));
+
+ constant BUFF_0 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(0, 4));
+ constant BUFF_2 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(2, 4));
+ constant BUFF_5 : std_logic_vector(3 downto 0) := std_logic_vector(to_unsigned(5, 4));
+
+ constant TAG_2 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(2, 5));
+ constant TAG_5 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(5, 5));
+
+ constant EMPTY : std_logic_vector(1 downto 0) := "00";
+ constant ADDR : std_logic_vector(1 downto 0) := "01";
+ constant DATA : std_logic_vector(1 downto 0) := "10";
+ constant FULL : std_logic_vector(1 downto 0) := "11";
+
+ constant DATA_A : std_logic_vector(63 downto 0) := x"123AAAAAAAAAAAAA";
+ constant DATA_B : std_logic_vector(63 downto 0) := x"123BBBBBBBBBBBBB";
+ constant DATA_C : std_logic_vector(63 downto 0) := x"123CCCCCCCCCCCCC";
+ constant DATA_D : std_logic_vector(63 downto 0) := x"123DDDDDDDDDDDDD";
+ constant DATA_E : std_logic_vector(63 downto 0) := x"123EEEEEEEEEEEEE";
+BEGIN
+
+ uut: engine PORT MAP (
+ clk => clk,
+ rd_buff => rd_buff,
+ rd_en => rd_en,
+ rd_data => rd_data,
+ rd_length => rd_length,
+ rd_valid => rd_valid,
+ wr_buff => wr_buff,
+ wr_en => wr_en,
+ wr_data => wr_data,
+ wr_done => wr_done,
+ wr_accept => 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
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ wr_accept <= (others => '1');
+
+ wait for clk_period;
+
+ -- read status
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- send page: addr = 31, len = 3, data = ABC, buff = 2
+ -- expecting two reads:
+ -- first: addr = 31, len = 1, tag = 2
+ -- second: addr = 32, len = 2, tag = 2
+
+ rx_write <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_SEND;
+ rx_address(8 downto 5) <= BUFF_2;
+ rx_address(18 downto 10) <= LEN_3;
+ rx_data <= ADDR_31 & "000";
+
+ wait for clk_period * 3;
+
+ if tx_read /= '1' or
+ tx_address /= ADDR_31 or
+ tx_length /= LEN_1 or
+ tx_tag /= TAG_2 then
+ test_fail <= '1';
+ end if;
+
+ rx_write <= '0';
+ rx_address <= (others => '0');
+ rx_data <= (others => '0');
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= DATA or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- answer the previous read with completions
+ -- data = A, tag = 2, len = 1
+ rx_complete <= '1';
+ rx_data <= DATA_A;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = A)
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_A or
+ wr_done /= '0' or
+ tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '0';
+ rx_data <= (others => '0');
+ rx_tag <= (others => '0');
+
+ wait for clk_period * 2;
+
+ -- expect new tx_read (tag 2, len 2, addr 32)
+ if wr_en /= '0' or
+ tx_read /= '1' or
+ tx_tag /= TAG_2 or
+ tx_length /= LEN_2 or
+ tx_address /= ADDR_32 then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ -- answer read with completions
+ -- data = B and C, tag = 2, len = 2
+ rx_complete <= '1';
+ rx_data <= DATA_B;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = B) and no tx action
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_B or
+ wr_done /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '1';
+ rx_data <= DATA_C;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = C) and no tx action
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_C or
+ wr_done /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '0';
+ rx_data <= (others => '0');
+ rx_tag <= (others => '0');
+
+ wait for clk_period;
+
+ -- expect wr_done and no tx action
+ if wr_done /= '1' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- buff will respond to wr_done with wr_accept = 0
+ wr_accept(2) <= '0';
+
+ wait for clk_period;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= FULL or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ wr_accept(2) <= '1';
+
+ wait for clk_period;
+
+ -- read status again, but this time buff must be EMPTY
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= EMPTY or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ -- EMPTY buff doesn't result in interrupt, because status is just read
+ if tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- RECEIVE PACKET
+ -- the buff will say there is data to read (rd_valid)
+ -- interrupt will be send
+ -- status is read
+ -- addr will be gotten via rx_write
+ -- data will be send via tx_write
+ -- interrupt will be send
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- buff 5 becomes valid
+ rd_valid(5) <= '1';
+
+ wait for clk_period * 2;
+
+ -- expect interrupt
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '1' then
+ test_fail <= '1';
+ end if;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+ interrupt_rdy <= '1';
+
+ wait for clk_period;
+
+ -- expect complete, no interrupt
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '1' or
+ interrupt /= '0' or
+ tx_data(5*4 + 1 downto 5*4 + 0) /= EMPTY or
+ tx_data(5*4 + 3 downto 5*4 + 2) /= FULL then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+ interrupt_rdy <= '0';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ rd_buff /= BUFF_0 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- recv page: addr = 4, buff = 5
+ rx_write <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_RECV;
+ rx_address(8 downto 5) <= BUFF_5;
+ rx_data <= ADDR_4 & "000";
+
+ wait for clk_period;
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ rd_buff /= BUFF_0 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_write <= '0';
+ rx_address <= (others => '0');
+ rx_data <= (others => '0');
+
+ wait for clk_period;
+
+ -- expect to read buff 5, but no tx actions yet
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- data = D and E, length = 2
+ rd_data <= DATA_D;
+ rd_length <= LEN_2;
+
+ wait for clk_period;
+
+ -- tx_write: data = D, addr = 4, length = 2
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- same
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ tx_accept <= '1';
+
+ wait for clk_period;
+
+ -- data D
+ if rd_en /= '1' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ rd_data <= DATA_E;
+
+ wait for clk_period;
+
+ -- data E
+ if rd_en /= '1' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_E or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ rd_valid(5) <= '0';
+ rd_data <= (others => '0');
+ rd_length <= (others => '0');
+ tx_accept <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- interrupt because writing is done
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '1' then
+ test_fail <= '1';
+ end if;
+
+ interrupt_rdy <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ interrupt_rdy <= '0';
+
+ wait for clk_period * 5;
+
+
+
+ -- ======================
+ -- LETS GO AGAIN !!!!!!!
+ -- ======================
+
+
+
+ -- read status
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- send page: addr = 31, len = 3, data = ABC, buff = 2
+ -- expecting two reads:
+ -- first: addr = 31, len = 1, tag = 2
+ -- second: addr = 32, len = 2, tag = 2
+
+ rx_write <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_SEND;
+ rx_address(8 downto 5) <= BUFF_2;
+ rx_address(18 downto 10) <= LEN_3;
+ rx_data <= ADDR_31 & "000";
+
+ wait for clk_period * 3;
+
+ if tx_read /= '1' or
+ tx_address /= ADDR_31 or
+ tx_length /= LEN_1 or
+ tx_tag /= TAG_2 then
+ test_fail <= '1';
+ end if;
+
+ rx_write <= '0';
+ rx_address <= (others => '0');
+ rx_data <= (others => '0');
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= DATA or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- answer the previous read with completions
+ -- data = A, tag = 2, len = 1
+ rx_complete <= '1';
+ rx_data <= DATA_A;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = A)
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_A or
+ wr_done /= '0' or
+ tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '0';
+ rx_data <= (others => '0');
+ rx_tag <= (others => '0');
+
+ wait for clk_period * 2;
+
+ -- expect new tx_read (tag 2, len 2, addr 32)
+ if wr_en /= '0' or
+ tx_read /= '1' or
+ tx_tag /= TAG_2 or
+ tx_length /= LEN_2 or
+ tx_address /= ADDR_32 then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_read /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ -- answer read with completions
+ -- data = B and C, tag = 2, len = 2
+ rx_complete <= '1';
+ rx_data <= DATA_B;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = B) and no tx action
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_B or
+ wr_done /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '1';
+ rx_data <= DATA_C;
+ rx_tag <= TAG_2;
+
+ wait for clk_period;
+
+ -- expect wr_en (buff = 2, data = C) and no tx action
+ if wr_buff /= BUFF_2 or
+ wr_en /= '1' or
+ wr_data /= DATA_C or
+ wr_done /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_complete <= '0';
+ rx_data <= (others => '0');
+ rx_tag <= (others => '0');
+
+ wait for clk_period;
+
+ -- expect wr_done and no tx action
+ if wr_done /= '1' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- buff will respond to wr_done with wr_accept = 0
+ wr_accept(2) <= '0';
+
+ wait for clk_period;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= FULL or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ wr_accept(2) <= '1';
+
+ wait for clk_period;
+
+ -- read status again, but this time buff must be EMPTY
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+
+ wait for clk_period;
+
+ if tx_complete /= '1' or
+ tx_data(2*4 + 1 downto 2*4 + 0) /= EMPTY or
+ tx_data(2*4 + 3 downto 2*4 + 2) /= EMPTY then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ -- EMPTY buff doesn't result in interrupt, because status is just read
+ if tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- RECEIVE PACKET
+ -- the buff will say there is data to read (rd_valid)
+ -- interrupt will be send
+ -- status is read
+ -- addr will be gotten via rx_write
+ -- data will be send via tx_write
+ -- interrupt will be send
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- buff 5 becomes valid
+ rd_valid(5) <= '1';
+
+ wait for clk_period * 2;
+
+ -- expect interrupt
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '1' then
+ test_fail <= '1';
+ end if;
+
+ -- read status again
+ rx_read <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_STATUS;
+ interrupt_rdy <= '1';
+
+ wait for clk_period;
+
+ -- expect complete, no interrupt
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '1' or
+ interrupt /= '0' or
+ tx_data(5*4 + 1 downto 5*4 + 0) /= EMPTY or
+ tx_data(5*4 + 3 downto 5*4 + 2) /= FULL then
+ test_fail <= '1';
+ end if;
+
+ rx_read <= '0';
+ tx_done <= '1';
+ interrupt_rdy <= '0';
+
+ wait for clk_period;
+
+ if tx_complete /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- recv page: addr = 4, buff = 5
+ rx_write <= '1';
+ rx_address <= (others => '0');
+ rx_address(4 downto 3) <= CMD_RECV;
+ rx_address(8 downto 5) <= BUFF_5;
+ rx_data <= ADDR_4 & "000";
+
+ wait for clk_period;
+
+ -- no reading and no tx actions
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_write <= '0';
+ rx_address <= (others => '0');
+ rx_data <= (others => '0');
+
+ wait for clk_period;
+
+ -- expect to read buff 5, but no tx actions yet
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- data = D and E, length = 2
+ rd_data <= DATA_D;
+ rd_length <= LEN_2;
+
+ wait for clk_period;
+
+ -- tx_write: data = D, addr = 4, length = 2
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- same
+ if rd_en /= '0' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ tx_accept <= '1';
+
+ wait for clk_period;
+
+ -- data D
+ if rd_en /= '1' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_D or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ rd_data <= DATA_E;
+
+ wait for clk_period;
+
+ -- data E
+ if rd_en /= '1' or
+ rd_buff /= BUFF_5 or
+ tx_read /= '0' or
+ tx_write /= '1' or
+ tx_complete /= '0' or
+ interrupt /= '0' or
+ tx_data /= DATA_E or
+ tx_address /= ADDR_4 or
+ tx_length /= LEN_2 then
+ test_fail <= '1';
+ end if;
+
+ rd_valid(5) <= '0';
+ rd_data <= (others => '0');
+ rd_length <= (others => '0');
+ tx_accept <= '0';
+ tx_done <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_done <= '0';
+
+ wait for clk_period;
+
+ -- interrupt because writing is done
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '1' then
+ test_fail <= '1';
+ end if;
+
+ interrupt_rdy <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if rd_en /= '0' or
+ tx_read /= '0' or
+ tx_write /= '0' or
+ tx_complete /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ interrupt_rdy <= '0';
+
+ wait for clk_period * 5;
+
+
+
+
+
+
+
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/eth_buff_loop_test.vhd b/netfpga10g/tests/eth_buff_loop_test.vhd
new file mode 100644
index 0000000..b8c5902
--- /dev/null
+++ b/netfpga10g/tests/eth_buff_loop_test.vhd
@@ -0,0 +1,173 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY eth_buff_loop_test IS
+END eth_buff_loop_test;
+
+ARCHITECTURE behavior OF eth_buff_loop_test IS
+
+ signal eth_clk : std_logic := '0';
+ signal pcie_clk: std_logic := '0';
+
+ signal eth_rd_en : std_logic := '0';
+ signal eth_rd_data : std_logic_vector(63 downto 0);
+ signal eth_rd_length : std_logic_vector(8 downto 0);
+ signal eth_rd_valid : std_logic;
+
+ signal eth_wr_en : std_logic := '0';
+ signal eth_wr_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal eth_wr_done : std_logic := '0';
+ signal eth_wr_accept : std_logic;
+
+ signal pcie_rd_en : std_logic := '0';
+ signal pcie_rd_data : std_logic_vector(63 downto 0);
+ signal pcie_rd_length : std_logic_vector(8 downto 0);
+ signal pcie_rd_valid : std_logic;
+
+ signal pcie_wr_en : std_logic := '0';
+ signal pcie_wr_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal pcie_wr_done : std_logic := '0';
+ signal pcie_wr_accept : std_logic;
+
+ constant eth_clk_period : time := 7 ns;
+ constant pcie_clk_period : time := 10 ns;
+
+ signal xgmii_data : std_logic_vector(63 downto 0);
+ signal xgmii_control : std_logic_vector(7 downto 0);
+
+ signal test_fail : std_logic := '0';
+
+BEGIN
+
+ buff_tx : entity work.buff port map (
+ wr_clk => pcie_clk,
+ wr_en => pcie_wr_en,
+ wr_data => pcie_wr_data,
+ wr_done => pcie_wr_done,
+ wr_accept => pcie_wr_accept,
+ rd_clk => eth_clk,
+ rd_en => eth_rd_en,
+ rd_data => eth_rd_data,
+ rd_length => eth_rd_length,
+ rd_valid => eth_rd_valid
+ );
+
+ buff_rx : entity work.buff port map (
+ wr_clk => eth_clk,
+ wr_en => eth_wr_en,
+ wr_data => eth_wr_data,
+ wr_done => eth_wr_done,
+ wr_accept => eth_wr_accept,
+ rd_clk => pcie_clk,
+ rd_en => pcie_rd_en,
+ rd_data => pcie_rd_data,
+ rd_length => pcie_rd_length,
+ rd_valid => pcie_rd_valid
+ );
+
+ eth_rx: entity work.eth_rx port map(
+ clk => eth_clk,
+ wr_en => eth_wr_en,
+ wr_data => eth_wr_data,
+ wr_done => eth_wr_done,
+ wr_accept => eth_wr_accept,
+ xgmii_rxd => xgmii_data,
+ xgmii_rxc => xgmii_control
+ );
+
+ eth_tx: entity work.eth_tx port map (
+ clk => eth_clk,
+ rd_en => eth_rd_en,
+ rd_data => eth_rd_data,
+ rd_valid => eth_rd_valid,
+ xgmii_txd => xgmii_data,
+ xgmii_txc => xgmii_control
+ );
+
+ -- Clock process definitions
+ eth_clk_process : process
+ begin
+ eth_clk <= '0';
+ wait for eth_clk_period/2;
+ eth_clk <= '1';
+ wait for eth_clk_period/2;
+ end process;
+
+ pcie_clk_process :process
+ begin
+ pcie_clk <= '0';
+ wait for pcie_clk_period/2;
+ pcie_clk <= '1';
+ wait for pcie_clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ wait for pcie_clk_period;
+
+ if pcie_wr_accept /= '1' then
+ test_fail <= '1';
+ end if;
+
+ pcie_wr_en <= '1';
+ pcie_wr_data <= x"0123456789ABCDEF";
+
+ wait for pcie_clk_period;
+
+ pcie_wr_en <= '1';
+ pcie_wr_data <= x"AAAAAAAAAAAAAAAA";
+
+ wait for pcie_clk_period;
+
+ pcie_wr_en <= '0';
+ pcie_wr_data <= (others => '0');
+ pcie_wr_done <= '1';
+
+ wait for pcie_clk_period;
+
+ pcie_wr_done <= '0';
+
+ wait until pcie_rd_valid = '1';
+ wait for pcie_clk_period / 2;
+
+ if pcie_rd_data /= x"0123456789ABCDEF" or
+ pcie_rd_length /= "000000010" then
+ test_fail <= '1';
+ end if;
+
+ pcie_rd_en <= '1';
+
+ wait for pcie_clk_period;
+
+ if pcie_rd_data /= x"AAAAAAAAAAAAAAAA" then
+ test_fail <= '1';
+ end if;
+
+ pcie_rd_en <= '1';
+
+ wait for pcie_clk_period;
+
+ if pcie_rd_valid /= '0' or
+ pcie_rd_data /= x"0000000000000000" or
+ pcie_rd_length /= "000000000" then
+ test_fail <= '1';
+ end if;
+
+ pcie_rd_en <= '0';
+
+ wait for pcie_clk_period;
+
+ if pcie_rd_valid /= '0' or
+ pcie_rd_data /= x"0000000000000000" or
+ pcie_rd_length /= "000000000" then
+ test_fail <= '1';
+ end if;
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/eth_rx_test.vhd b/netfpga10g/tests/eth_rx_test.vhd
new file mode 100644
index 0000000..7497a97
--- /dev/null
+++ b/netfpga10g/tests/eth_rx_test.vhd
@@ -0,0 +1,225 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY eth_rx_test IS
+END eth_rx_test;
+
+ARCHITECTURE behavior OF eth_rx_test IS
+
+ COMPONENT eth_rx
+ PORT(
+ clk : IN std_logic;
+ wr_en : OUT std_logic;
+ wr_data : OUT std_logic_vector(63 downto 0);
+ wr_done : OUT std_logic;
+ wr_accept : IN std_logic;
+ xgmii_rxd : IN std_logic_vector(63 downto 0);
+ xgmii_rxc : IN std_logic_vector(7 downto 0)
+ );
+ END COMPONENT;
+
+ signal clk : std_logic := '0';
+
+ signal wr_en : std_logic;
+ signal wr_data : std_logic_vector(63 downto 0);
+ signal wr_done : std_logic;
+ signal wr_accept : std_logic := '0';
+
+ signal xgmii_rxd : std_logic_vector(63 downto 0) := (others => '0');
+ signal xgmii_rxc : std_logic_vector(7 downto 0) := (others => '0');
+
+ constant clk_period : time := 10 ns;
+
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERM : std_logic_vector(7 downto 0) := x"FD";
+ constant ERR : std_logic_vector(7 downto 0) := x"FE";
+
+ constant PRE : std_logic_vector(7 downto 0) := "01010101";
+ constant SFD : std_logic_vector(7 downto 0) := "11010101";
+
+ signal test_fail : std_logic := '0';
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: eth_rx PORT MAP (
+ clk => clk,
+ wr_en => wr_en,
+ wr_data => wr_data,
+ wr_done => wr_done,
+ wr_accept => wr_accept,
+ xgmii_rxd => xgmii_rxd,
+ xgmii_rxc => xgmii_rxc
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE;
+ xgmii_rxc <= "00000000";
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START;
+ xgmii_rxc <= "00000001";
+ wr_accept <= '1';
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= x"EFCDAB8967452301";
+ xgmii_rxc <= "00000000";
+
+ wait for clk_period;
+
+ if wr_en /= '1' or
+ wr_data /= x"0123456789ABCDEF" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & TERM;
+ xgmii_rxc <= "11111111";
+
+ wait for clk_period;
+
+ if wr_done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE;
+ xgmii_rxc <= "11111111";
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START;
+ xgmii_rxc <= "00000001";
+ wr_accept <= '0';
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= x"EFCDAB8967452301";
+ xgmii_rxc <= "00000000";
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START;
+ xgmii_rxc <= "00000001";
+ wr_accept <= '1';
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= x"ABCDABCDABCDABCD";
+ xgmii_rxc <= "00000000";
+
+ wait for clk_period;
+
+ if wr_en /= '1' or
+ wr_data /= x"CDABCDABCDABCDAB" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= IDLE & IDLE & IDLE & ERR & IDLE & IDLE & IDLE & IDLE;
+ xgmii_rxc <= "00010000";
+
+ wait for clk_period;
+
+ if wr_done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= PRE & PRE & PRE & START & IDLE & IDLE & IDLE & IDLE;
+ xgmii_rxc <= "00011111";
+ wr_accept <= '1';
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= x"67452311" & SFD & PRE & PRE & PRE;
+ xgmii_rxc <= "00000000";
+
+ wait for clk_period;
+
+ if wr_en /= '0' or
+ wr_data /= x"0000000000000000" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= IDLE & IDLE & IDLE & TERM & x"EFCDAB89";
+ xgmii_rxc <= "11110000";
+
+ wait for clk_period;
+
+ if wr_en /= '1' or
+ wr_data /= x"1123456789ABCDEF" or
+ wr_done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ xgmii_rxd <= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE;
+ xgmii_rxc <= "11111111";
+
+ wait for clk_period;
+
+ if wr_done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/eth_tx_test.vhd b/netfpga10g/tests/eth_tx_test.vhd
new file mode 100644
index 0000000..0697b84
--- /dev/null
+++ b/netfpga10g/tests/eth_tx_test.vhd
@@ -0,0 +1,126 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY eth_tx_test IS
+END eth_tx_test;
+
+ARCHITECTURE behavior OF eth_tx_test IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+
+ COMPONENT eth_tx
+ 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 COMPONENT;
+
+ signal clk : std_logic := '0';
+ signal rd_en : std_logic;
+ signal rd_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal rd_valid : std_logic := '0';
+
+ signal xgmii_txd : std_logic_vector(63 downto 0);
+ signal xgmii_txc : std_logic_vector(7 downto 0);
+
+ -- Clock period definitions
+ constant clk_period : time := 10 ns;
+
+ signal test_fail : std_logic := '0';
+
+ constant IDLE : std_logic_vector(7 downto 0) := x"07";
+ constant START : std_logic_vector(7 downto 0) := x"FB";
+ constant TERM : std_logic_vector(7 downto 0) := x"FD";
+
+ constant PRE : std_logic_vector(7 downto 0) := "01010101";
+ constant SFD : std_logic_vector(7 downto 0) := "11010101";
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: eth_tx PORT MAP (
+ clk => clk,
+ rd_en => rd_en,
+ rd_data => rd_data,
+ rd_valid => rd_valid,
+ xgmii_txd => xgmii_txd,
+ xgmii_txc => xgmii_txc
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ for i in 1 to 5 loop
+
+ if i = 1 or i = 2 then
+ wait for clk_period;
+
+ if rd_en /= '0' or
+ xgmii_txd /= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE or
+ xgmii_txc /= "11111111" then
+ test_fail <= '1';
+ end if;
+ end if;
+
+ rd_valid <= '1';
+ rd_data <= x"0123456789ABCDEF";
+
+ wait for clk_period;
+
+ if rd_en /= '1' or
+ xgmii_txd /= SFD & PRE & PRE & PRE & PRE & PRE & PRE & START or
+ xgmii_txc /= "00000001" then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ if rd_en /= '1' or
+ xgmii_txd /= x"EFCDAB8967452301" or
+ xgmii_txc /= "00000000" then
+ test_fail <= '1';
+ end if;
+
+ rd_valid <= '1';
+ rd_data <= x"BBBBBBBBBBBBBBBB";
+
+ wait for clk_period;
+
+ if rd_en /= '1' or
+ xgmii_txd /= x"BBBBBBBBBBBBBBBB" or
+ xgmii_txc /= "00000000" then
+ test_fail <= '1';
+ end if;
+
+ rd_valid <= '0';
+ rd_data <= x"0000000000000000";
+
+ wait for clk_period;
+
+ if rd_en /= '0' or
+ xgmii_txd /= IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & IDLE & TERM or
+ xgmii_txc /= "11111111" then
+ test_fail <= '1';
+ end if;
+
+ end loop;
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/pcie_rx_test.vhd b/netfpga10g/tests/pcie_rx_test.vhd
new file mode 100644
index 0000000..4180b81
--- /dev/null
+++ b/netfpga10g/tests/pcie_rx_test.vhd
@@ -0,0 +1,322 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY pcie_rx_test IS
+END pcie_rx_test;
+
+ARCHITECTURE behavior OF pcie_rx_test IS
+
+ COMPONENT pcie_rx
+ 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;
+ write : OUT std_logic;
+ complete : OUT std_logic;
+ data : OUT std_logic_vector(63 downto 0);
+ address : OUT std_logic_vector(63 downto 3);
+ tag : OUT std_logic_vector(4 downto 0);
+ remote : OUT std_logic_vector(15 downto 0);
+ bar0 : IN std_logic
+ );
+ END COMPONENT;
+
+
+ signal clk : std_logic := '0';
+
+ signal frame : std_logic_vector(63 downto 0) := (others => '0');
+ signal sof : std_logic := '0';
+ signal eof : std_logic := '0';
+ signal valid : std_logic := '0';
+
+ signal read : std_logic;
+ signal write : std_logic;
+ signal complete : std_logic;
+ signal data : std_logic_vector(63 downto 0);
+ signal address : std_logic_vector(63 downto 3);
+ signal tag : std_logic_vector(4 downto 0);
+ signal remote : std_logic_vector(15 downto 0);
+ signal bar0 : std_logic := '0';
+
+ constant clk_period : time := 10 ns;
+
+ constant ADDR_0 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(0, 61));
+ constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61));
+ constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61));
+
+ constant TAG_0 : std_logic_vector(4 downto 0) := "0" & x"0";
+ constant TAG_A : std_logic_vector(4 downto 0) := "0" & x"A";
+ constant TAG_B : std_logic_vector(4 downto 0) := "0" & x"B";
+
+ constant ID_0 : std_logic_vector(15 downto 0) := x"0000";
+ constant ID_A : std_logic_vector(15 downto 0) := x"AAAA";
+ constant ID_B : std_logic_vector(15 downto 0) := x"BBBB";
+
+ constant DATA_0 : std_logic_vector(63 downto 0) := x"0000000000000000";
+ constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA";
+ constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB";
+
+ signal test_fail : std_logic := '0';
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: pcie_rx PORT MAP (
+ clk => clk,
+ frame => frame,
+ sof => sof,
+ eof => eof,
+ valid => valid,
+ read => read,
+ write => write,
+ complete => complete,
+ data => data,
+ address => address,
+ tag => tag,
+ remote => remote,
+ bar0 => bar0
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ bar0 <= '1';
+
+ wait for clk_period;
+
+ -- expect nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_0 then
+ test_fail <= '1';
+ end if;
+
+ -- read: addr = 1, tag = A, remote = A
+ frame <= "0" & "00" & "00000" &
+ x"00" &
+ "000000" & "0000000010" &
+ ID_A & "000" & TAG_A & x"FF";
+ sof <= '1';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- remote = A
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= ADDR_1(31 downto 3) & "000" & x"00000000";
+ sof <= '0';
+ eof <= '1';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- read: addr = 1, tag = A, remote = A
+ if read /= '1' or
+ write /= '0' or
+ complete /= '0' or
+ data /= DATA_0 or
+ address /= ADDR_1 or
+ tag /= TAG_A or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ -- write: data = A, addr = 2
+ frame <= "0" & "10" & "00000" &
+ x"00" &
+ "000000" & "0000000010" &
+ ID_B & x"00" & x"FF";
+ sof <= '1';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- remote stays A
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= ADDR_2(31 downto 3) & "000" & DATA_A(63 downto 32);
+ sof <= '0';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- expect nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= DATA_A(31 downto 0) & x"00000000";
+ sof <= '0';
+ eof <= '1';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- write: data = A, addr = 2
+ if read /= '0' or
+ write /= '1' or
+ complete /= '0' or
+ data /= DATA_A or
+ address /= ADDR_2 or
+ tag /= TAG_0 or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= (others => '0');
+ sof <= '0';
+ eof <= '0';
+ valid <= '0';
+
+ wait for clk_period;
+
+ -- expect nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ -- complete: length = 2x32b, data = A + B, tag = B
+ frame <= "0" & "10" & "01010" &
+ x"00" &
+ "000000" & "0000000100" &
+ ID_B & x"0004";
+ sof <= '1';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- expect nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= ID_B & "000" & TAG_B & x"00" &
+ DATA_A(63 downto 32);
+ sof <= '0';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= DATA_A(31 downto 0) & DATA_B(63 downto 32);
+ sof <= '0';
+ eof <= '0';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- completion: data = A, tag = B
+ if read /= '0' or
+ write /= '0' or
+ complete /= '1' or
+ data /= DATA_A or
+ address /= ADDR_0 or
+ tag /= TAG_B or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= (others => '0');
+ sof <= '0';
+ eof <= '0';
+ valid <= '0';
+
+ wait for clk_period;
+
+ -- nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= DATA_B(31 downto 0) & x"01234567";
+ sof <= '0';
+ eof <= '1';
+ valid <= '1';
+
+ wait for clk_period;
+
+ -- completion: data = B, tag = B
+ if read /= '0' or
+ write /= '0' or
+ complete /= '1' or
+ data /= DATA_B or
+ address /= ADDR_0 or
+ tag /= TAG_B or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+ frame <= (others => '0');
+ sof <= '0';
+ eof <= '0';
+ valid <= '0';
+
+ wait for clk_period;
+
+ -- nothing
+ if read /= '0' or
+ write /= '0' or
+ complete /= '0' or
+ remote /= ID_A then
+ test_fail <= '1';
+ end if;
+
+
+
+
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/pcie_tx_test.vhd b/netfpga10g/tests/pcie_tx_test.vhd
new file mode 100644
index 0000000..4f9e091
--- /dev/null
+++ b/netfpga10g/tests/pcie_tx_test.vhd
@@ -0,0 +1,561 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY pcie_tx_test IS
+END pcie_tx_test;
+
+ARCHITECTURE behavior OF pcie_tx_test IS
+
+ COMPONENT pcie_tx
+ PORT(
+ clk : IN std_logic;
+ frame : OUT std_logic_vector(63 downto 0);
+ sof : OUT std_logic;
+ eof : OUT std_logic;
+ half : OUT std_logic;
+ valid : OUT std_logic;
+ 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(15 downto 0);
+ accept : OUT std_logic;
+ done : OUT std_logic
+ );
+ END COMPONENT;
+
+
+ signal clk : std_logic := '0';
+
+ signal read : std_logic := '0';
+ signal write : std_logic := '0';
+ signal complete : std_logic := '0';
+ signal data : std_logic_vector(63 downto 0) := (others => '0');
+ signal address : std_logic_vector(63 downto 3) := (others => '0');
+ signal length : std_logic_vector(8 downto 0) := (others => '0');
+ signal tag : std_logic_vector(4 downto 0) := (others => '0');
+ signal local : std_logic_vector(15 downto 0) := (others => '0');
+ signal remote : std_logic_vector(15 downto 0) := (others => '0');
+ signal accept : std_logic;
+ signal done : std_logic;
+
+ signal frame : std_logic_vector(63 downto 0);
+ signal sof : std_logic;
+ signal eof : std_logic;
+ signal half : std_logic;
+ signal valid : std_logic;
+ signal ready : std_logic := '0';
+
+ constant clk_period : time := 10 ns;
+
+ signal test_fail : std_logic := '0';
+
+ constant FRAME_0 : std_logic_vector(63 downto 0) := (others => '0');
+
+ constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA";
+ constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB";
+ constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC";
+
+ constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61));
+ constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61));
+ constant ADDR_3 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(3, 61));
+ constant ADDR_HIGH : std_logic_vector(63 downto 3) := x"100000000000000" & "0";
+
+ constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9));
+ constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9));
+ constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9));
+
+ constant TAG_A : std_logic_vector(4 downto 0) := "0" & x"A";
+ constant TAG_B : std_logic_vector(4 downto 0) := "0" & x"B";
+ constant TAG_C : std_logic_vector(4 downto 0) := "0" & x"C";
+
+ constant ID_A : std_logic_vector(15 downto 0) := x"AAAA";
+ constant ID_B : std_logic_vector(15 downto 0) := x"BBBB";
+ constant ID_C : std_logic_vector(15 downto 0) := x"CCCC";
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: pcie_tx PORT MAP (
+ clk => clk,
+ frame => frame,
+ sof => sof,
+ eof => eof,
+ half => half,
+ valid => valid,
+ ready => ready,
+ read => read,
+ write => write,
+ complete => complete,
+ data => data,
+ address => address,
+ length => length,
+ tag => tag,
+ local => local,
+ remote => remote,
+ accept => accept,
+ done => done
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ variable expect : std_logic_vector(63 downto 0) := (others => '0');
+ begin
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- read: addr = 1, len = 1, tag = A, local = A
+ read <= '1';
+ address <= ADDR_1;
+ length <= LEN_1;
+ tag <= TAG_A;
+ local <= ID_A;
+
+ wait for clk_period;
+
+ -- expect 32 bit read: sof valid
+ expect := "0" & "00" & "00000" & x"00" &
+ "000000" & "0000000010" &
+ ID_A & "000" & TAG_A & x"0F";
+
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period * 3 / 4;
+ ready <= '1';
+ wait for clk_period / 4;
+
+ -- same thing, because ready was 0 during clk
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period * 3 / 4;
+ ready <= '0';
+ wait for clk_period / 4;
+
+ -- read address: eof half valid
+ expect := ADDR_1(31 downto 3) & "000" & x"00000000";
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '1' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period * 3 / 4;
+ ready <= '1';
+ wait for clk_period / 4;
+
+ -- same thing, because ready was 0
+ -- but ready now, so done next time
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '1' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- done, so...
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+ data <= (others => '0');
+ address <= (others => '0');
+ length <= (others => '0');
+ tag <= (others => '0');
+ local <= (others => '0');
+ remote <= (others => '0');
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- write: data = B+C, addr = 2, length = 2, local = B
+ write <= '1';
+ data <= DATA_B;
+ address <= ADDR_2;
+ length <= LEN_2;
+ local <= ID_B;
+
+ wait for clk_period;
+
+ -- write: sof valid
+ expect := "0" & "10" & "00000" & x"00" &
+ x"0004" &
+ ID_B & x"00" & x"FF";
+
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '1' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- write 32bit address + data: valid
+ expect := ADDR_2(31 downto 3) & "000" & DATA_B(63 downto 32);
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '1' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ data <= DATA_C;
+
+ wait for clk_period;
+
+ -- write data: valid
+ expect := DATA_B(31 downto 0) & DATA_C(63 downto 32);
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ data <= (others => '0');
+
+ wait for clk_period;
+
+ -- write half data: eof half valid done
+ expect := DATA_C(31 downto 0) & x"00000000";
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '1' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- done, so...
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+ data <= (others => '0');
+ address <= (others => '0');
+ length <= (others => '0');
+ tag <= (others => '0');
+ local <= (others => '0');
+ remote <= (others => '0');
+
+ -- complete: data = C, addr = 3, tag = C, local = A, remote = B
+ complete <= '1';
+ data <= DATA_C;
+ address <= ADDR_3;
+ tag <= TAG_C;
+ local <= ID_A;
+ remote <= ID_B;
+
+ wait for clk_period;
+
+ -- expect completion 64bit
+ expect := "0" & "10" & "01010" & x"00" &
+ x"0002" & ID_A & x"0008";
+
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- compl header + data(higher 32b)
+ expect := ID_B & "000" & TAG_C & "0" & x"3" & "000" &
+ DATA_C(63 downto 32);
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- read of compl data: eof half valid done
+ expect := DATA_C(31 downto 0) & x"00000000";
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '1' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- done, so...
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+ data <= (others => '0');
+ address <= (others => '0');
+ length <= (others => '0');
+ tag <= (others => '0');
+ local <= (others => '0');
+ remote <= (others => '0');
+
+ -- 64bit read: addr = HIGH, length = 3, tag = C, local = C
+ read <= '1';
+ address <= ADDR_HIGH;
+ length <= LEN_3;
+ tag <= TAG_C;
+ local <= ID_C;
+
+ wait for clk_period;
+
+ -- expect 64bit read
+ expect := "0" & "01" & "00000" & x"00" & x"0006" &
+ ID_C & "000" & TAG_C & x"FF";
+
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect 64bit address: eof valid done
+ expect := ADDR_HIGH & "000";
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- done, so...
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+ data <= (others => '0');
+ address <= (others => '0');
+ length <= (others => '0');
+ tag <= (others => '0');
+ local <= (others => '0');
+ remote <= (others => '0');
+
+ -- 64bit write: addr = HIGH, length = 1, data = A, local = A
+ write <= '1';
+ address <= ADDR_HIGH;
+ length <= LEN_1;
+ data <= DATA_A;
+ local <= ID_A;
+
+ wait for clk_period;
+
+ -- expect 64bit write header; sof valid
+ expect := "0" & "11" & "00000" & x"00" & x"0002" &
+ ID_A & x"00" & x"0F";
+
+ if frame /= expect or
+ sof /= '1' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect addr HIGH: valid accept
+ expect := ADDR_HIGH & "000";
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '1' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect data A: eof valid done
+ expect := DATA_A;
+
+ if frame /= expect or
+ sof /= '0' or
+ eof /= '1' or
+ half /= '0' or
+ valid /= '1' or
+ accept /= '0' or
+ done /= '1' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- expect nothing
+ if frame /= FRAME_0 or
+ sof /= '0' or
+ eof /= '0' or
+ half /= '0' or
+ valid /= '0' or
+ accept /= '0' or
+ done /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- done, so...
+ read <= '0';
+ write <= '0';
+ complete <= '0';
+ data <= (others => '0');
+ address <= (others => '0');
+ length <= (others => '0');
+ tag <= (others => '0');
+ local <= (others => '0');
+ remote <= (others => '0');
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/queue_test.vhd b/netfpga10g/tests/queue_test.vhd
new file mode 100644
index 0000000..dc53ea0
--- /dev/null
+++ b/netfpga10g/tests/queue_test.vhd
@@ -0,0 +1,149 @@
+--------------------------------------------------------------------------------
+-- Company:
+-- Engineer:
+--
+-- Create Date: 17:42:12 02/23/2017
+-- Design Name:
+-- Module Name: /home/alexander/Code/raptor2/hw/tests/queue_test.vhd
+-- Project Name: raptor2
+-- Target Device:
+-- Tool versions:
+-- Description:
+--
+-- VHDL Test Bench Created by ISE for module: queue
+--
+-- Dependencies:
+--
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+-- Notes:
+-- This testbench has been automatically generated using types std_logic and
+-- std_logic_vector for the ports of the unit under test. Xilinx recommends
+-- that these types always be used for the top-level I/O of a design in order
+-- to guarantee that the testbench will bind correctly to the post-implementation
+-- simulation model.
+--------------------------------------------------------------------------------
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+
+-- Uncomment the following library declaration if using
+-- arithmetic functions with Signed or Unsigned values
+--USE ieee.numeric_std.ALL;
+
+ENTITY queue_test IS
+END queue_test;
+
+ARCHITECTURE behavior OF queue_test IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+
+ COMPONENT queue
+ PORT(
+ clk : IN std_logic;
+ reset : IN std_logic;
+ in_data : IN std_logic_vector(63 downto 0);
+ in_valid : in std_logic;
+ in_end : IN std_logic;
+ in_cancel : IN std_logic;
+ out_data : OUT std_logic_vector(63 downto 0);
+ out_valid : OUT std_logic;
+ out_next : IN std_logic
+ );
+ END COMPONENT;
+
+
+ --Inputs
+ signal clk : std_logic := '0';
+ signal reset : std_logic := '0';
+ signal in_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal in_valid : std_logic := '0';
+ signal in_end : std_logic := '0';
+ signal in_cancel : std_logic := '0';
+ signal out_next : std_logic := '0';
+
+ --Outputs
+ signal out_data : std_logic_vector(63 downto 0);
+ signal out_valid : std_logic;
+
+ -- Clock period definitions
+ constant clk_period : time := 10 ns;
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: queue PORT MAP (
+ clk => clk,
+ reset => reset,
+ in_data => in_data,
+ in_valid => in_valid,
+ in_end => in_end,
+ in_cancel => in_cancel,
+ out_data => out_data,
+ out_valid => out_valid,
+ out_next => out_next
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+ -- TESTS
+ process begin
+ reset <= '1';
+ wait for 5 ns;
+ reset <= '0';
+ wait;
+ end process;
+
+ process begin
+ wait for clk_period * 2;
+ in_data <= x"AAAAAAAAAAAAAAAA";
+ in_valid <= '1';
+ wait for clk_period;
+ in_data <= x"BBBBBBBBBBBBBBBB";
+ in_valid <= '0';
+ wait for clk_period;
+ in_data <= x"CCCCCCCCCCCCCCCC";
+ in_valid <= '1';
+ wait for clk_period;
+ in_data <= x"DDDDDDDDDDDDDDDD";
+ in_valid <= '1';
+ in_end <= '1';
+ wait for clk_period;
+ in_valid <= '0';
+ in_end <= '0';
+
+ wait for clk_period * 2;
+ in_data <= x"AAAAAAAAAAAAAAAA";
+ in_valid <= '1';
+ wait for clk_period;
+ in_data <= x"BBBBBBBBBBBBBBBB";
+ in_valid <= '1';
+ wait for clk_period;
+ in_data <= x"CCCCCCCCCCCCCCCC";
+ in_valid <= '1';
+ wait for clk_period;
+ in_data <= x"DDDDDDDDDDDDDDDD";
+ in_valid <= '1';
+ in_cancel <= '1';
+ wait for clk_period;
+ in_valid <= '0';
+ in_cancel <= '0';
+ end process;
+
+ process begin
+ wait for clk_period * 15;
+ out_next <= '1';
+ wait for clk_period * 2;
+ out_next <= '0';
+ wait for clk_period * 2;
+ out_next <= '1';
+ end process;
+END;
diff --git a/netfpga10g/tests/send_mux_test.vhd b/netfpga10g/tests/send_mux_test.vhd
new file mode 100644
index 0000000..f737ca9
--- /dev/null
+++ b/netfpga10g/tests/send_mux_test.vhd
@@ -0,0 +1,199 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY send_mux_test IS
+END send_mux_test;
+
+ARCHITECTURE behavior OF send_mux_test IS
+
+ COMPONENT send_mux
+ PORT(
+ wr_clk : IN std_logic;
+ wr_buff : IN std_logic_vector(3 downto 0);
+ wr_en : IN std_logic;
+ wr_data : IN std_logic_vector(63 downto 0);
+ wr_done : IN std_logic;
+ wr_accept : OUT std_logic_vector(15 downto 0);
+ rd_clk : IN std_logic;
+ rd_en : IN std_logic;
+ rd_data : OUT std_logic_vector(63 downto 0);
+ rd_valid : OUT std_logic
+ );
+ END COMPONENT;
+
+ signal wr_clk : std_logic := '0';
+ signal wr_buff : std_logic_vector(3 downto 0) := (others => '0');
+ signal wr_en : std_logic := '0';
+ signal wr_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal wr_done : std_logic := '0';
+ signal wr_accept : std_logic_vector(15 downto 0);
+
+ signal rd_clk : std_logic := '0';
+ signal rd_en : std_logic := '0';
+ signal rd_data : std_logic_vector(63 downto 0);
+ signal rd_valid : std_logic;
+
+ constant wr_clk_period : time := 10 ns;
+ constant rd_clk_period : time := 7 ns;
+
+ constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA";
+ constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB";
+ constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC";
+
+ constant BUFF_1 : std_logic_vector (3 downto 0) := x"1";
+ constant BUFF_2 : std_logic_vector (3 downto 0) := x"2";
+ constant BUFF_3 : std_logic_vector (3 downto 0) := x"3";
+
+ signal test_fail : std_logic := '0';
+ signal test_done : std_logic := '0';
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: send_mux PORT MAP (
+ wr_clk => wr_clk,
+ wr_buff => wr_buff,
+ wr_en => wr_en,
+ wr_data => wr_data,
+ wr_done => wr_done,
+ wr_accept => wr_accept,
+ rd_clk => rd_clk,
+ rd_en => rd_en,
+ rd_data => rd_data,
+ rd_valid => rd_valid
+ );
+
+ -- Clock process definitions
+ wr_clk_process :process
+ begin
+ wr_clk <= '0';
+ wait for wr_clk_period/2;
+ wr_clk <= '1';
+ wait for wr_clk_period/2;
+ end process;
+
+ rd_clk_process :process
+ begin
+ rd_clk <= '0';
+ wait for rd_clk_period/2;
+ rd_clk <= '1';
+ wait for rd_clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ begin
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFF" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_1;
+ wr_en <= '1';
+ wr_data <= DATA_A;
+ wr_done <= '0';
+
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFF" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_2;
+ wr_en <= '1';
+ wr_data <= DATA_A;
+ wr_done <= '0';
+
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFF" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_3;
+ wr_en <= '1';
+ wr_data <= DATA_A;
+ wr_done <= '0';
+
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFF" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_1;
+ wr_en <= '1';
+ wr_data <= DATA_B;
+ wr_done <= '0';
+
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFF" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_1;
+ wr_en <= '0';
+ wr_data <= (others => '0');
+ wr_done <= '1';
+
+ wait for wr_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFD" then
+ test_fail <= '1';
+ end if;
+
+ wr_buff <= BUFF_1;
+ wr_en <= '0';
+ wr_data <= (others => '0');
+ wr_done <= '0';
+
+ wait until rd_valid = '1';
+ wait for rd_clk_period / 2;
+
+ if rd_valid /= '1' or
+ rd_data /= DATA_A or
+ wr_accept /= x"FFFD" then
+ test_fail <= '1';
+ end if;
+
+ rd_en <= '1';
+
+ wait for rd_clk_period;
+
+ if rd_valid /= '1' or
+ rd_data /= DATA_B or
+ wr_accept /= x"FFFD" then
+ test_fail <= '1';
+ end if;
+
+ rd_en <= '1';
+
+ wait for rd_clk_period;
+
+ if rd_valid /= '0' or
+ wr_accept /= x"FFFD" then
+ test_fail <= '1';
+ end if;
+
+ rd_en <= '0';
+
+ wait until wr_accept(1) = '1';
+
+ report "done";
+ test_done <= '1';
+
+ wait;
+ end process;
+
+END;
diff --git a/netfpga10g/tests/system_loop_test.vhd b/netfpga10g/tests/system_loop_test.vhd
new file mode 100644
index 0000000..81a4f6e
--- /dev/null
+++ b/netfpga10g/tests/system_loop_test.vhd
@@ -0,0 +1,285 @@
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY system_loop_test IS
+END system_loop_test;
+
+ARCHITECTURE behavior OF system_loop_test IS
+
+ COMPONENT system_loop
+ PORT(
+ 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)
+ );
+ END COMPONENT;
+
+ signal clk : std_logic := '0';
+
+ signal rx_frame : std_logic_vector(63 downto 0) := (others => '0');
+ signal rx_sof : std_logic := '0';
+ signal rx_eof : std_logic := '0';
+ signal rx_valid : std_logic := '0';
+ signal rx_bar0 : std_logic := '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 := '0';
+
+ signal interrupt : std_logic;
+ signal interrupt_rdy : std_logic := '0';
+
+ signal max_read : std_logic_vector(2 downto 0) := (others => '0');
+ signal max_write : std_logic_vector(2 downto 0) := (others => '0');
+ signal local : std_logic_vector(15 downto 0) := (others => '0');
+
+ constant clk_period : time := 10 ns;
+
+ signal test_fail : std_logic := '0';
+
+ constant LEN_1 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(1, 9));
+ constant LEN_2 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(2, 9));
+ constant LEN_3 : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(3, 9));
+
+ constant TAG_1 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(1, 5));
+ constant TAG_2 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(2, 5));
+ constant TAG_3 : std_logic_vector(4 downto 0) := std_logic_vector(to_unsigned(3, 5));
+
+ constant ADDR_1 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(1, 61));
+ constant ADDR_2 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(2, 61));
+ constant ADDR_3 : std_logic_vector(63 downto 3) := std_logic_vector(to_unsigned(3, 61));
+
+ constant DATA_A : std_logic_vector(63 downto 0) := x"AAAAAAAAAAAAAAAA";
+ constant DATA_B : std_logic_vector(63 downto 0) := x"BBBBBBBBBBBBBBBB";
+ constant DATA_C : std_logic_vector(63 downto 0) := x"CCCCCCCCCCCCCCCC";
+
+ constant ID_A : std_logic_vector(15 downto 0) := x"AAAA";
+ constant ID_B : std_logic_vector(15 downto 0) := x"BBBB";
+ constant ID_C : std_logic_vector(15 downto 0) := x"CCCC";
+
+ constant BUFF_1 : std_logic_vector(3 downto 0) := x"1";
+ constant BUFF_2 : std_logic_vector(3 downto 0) := x"2";
+ constant BUFF_3 : std_logic_vector(3 downto 0) := x"3";
+
+ 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";
+
+ constant FRAME_0 : std_logic_vector(63 downto 0) := (others => '0');
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: system_loop PORT MAP (
+ clk => clk,
+ 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
+ );
+
+ -- Clock process definitions
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Stimulus process
+ stim_proc: process
+ variable bar_addr : std_logic_vector(31 downto 0);
+ variable bar_data : std_logic_vector(63 downto 0);
+ variable expect : std_logic_vector(63 downto 0);
+ variable remote : std_logic_vector(15 downto 0);
+ begin
+ -- local = A
+ -- remote = B
+ local <= ID_A;
+ remote := ID_B;
+
+ -- always bar0
+ rx_bar0 <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- rx_write of 64 bits to bar
+ rx_frame <= "0" & "10" & "00000" & x"00" & x"0002" &
+ remote & x"00" & x"0F";
+ rx_sof <= '1';
+ rx_eof <= '0';
+ rx_valid <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ -- rx_write:
+ -- bar_addr: cmd = SEND, buff = 2, len = 2
+ -- bar_data: addr = 2
+ bar_addr := (others => '0');
+ bar_addr(4 downto 3) := CMD_SEND;
+ bar_addr(8 downto 5) := BUFF_2;
+ bar_addr(18 downto 10) := LEN_2;
+ bar_data := ADDR_2 & "000";
+
+ rx_frame <= bar_addr & bar_data(63 downto 32);
+ rx_sof <= '0';
+ rx_eof <= '0';
+ rx_valid <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_frame <= bar_data(31 downto 0) & x"00000000";
+ rx_sof <= '0';
+ rx_eof <= '1';
+ rx_valid <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ rx_frame <= (others => '0');
+ rx_sof <= '0';
+ rx_eof <= '0';
+ rx_valid <= '0';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ wait for clk_period;
+
+ -- tx_read: addr = 2, len = 2, tag = 2
+ expect := "0" & "00" & "00000" & x"00" & "000000" & LEN_2 & "0" &
+ local & "000" & TAG_2 & x"FF";
+
+ if tx_frame /= expect or
+ tx_sof /= '1' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '1' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_ready <= '1';
+
+ wait for clk_period;
+
+ expect := ADDR_2(31 downto 3) & "000" & x"00000000";
+
+ if tx_frame /= expect or
+ tx_sof /= '0' or
+ tx_eof /= '1' or
+ tx_half /= '1' or
+ tx_valid /= '1' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_ready <= '1';
+
+ wait for clk_period;
+
+ -- nothing
+ if tx_frame /= FRAME_0 or
+ tx_sof /= '0' or
+ tx_eof /= '0' or
+ tx_half /= '0' or
+ tx_valid /= '0' or
+ interrupt /= '0' then
+ test_fail <= '1';
+ end if;
+
+ tx_ready <= '0';
+
+
+
+
+
+ wait;
+ end process;
+
+END;