Skip to content
Snippets Groups Projects
Commit c29b039c authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Added tb_tech_eth_10g.vhd.

parent 7e0ada94
No related branches found
No related tags found
No related merge requests found
-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-- Purpose: Testbench for tech_eth_10g the 10G Ethernet IP technology wrapper.
-- Description:
-- The tb is self checking based on:
-- . proc_tech_mac_10g_rx_packet() for expected header and data type
-- . tx_pkt_cnt=rx_pkt_cnt > 0 must be true at the tb_end.
-- Usage:
-- > as 10
-- > run -all
LIBRARY IEEE, technology_lib, tech_mac_10g_lib, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_interface_layers_pkg.ALL;
USE common_lib.common_network_layers_pkg.ALL;
USE common_lib.common_network_total_header_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE technology_lib.technology_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
USE tech_mac_10g_lib.tech_mac_10g_component_pkg.ALL;
USE tech_mac_10g_lib.tb_tech_mac_10g_pkg.ALL;
ENTITY tb_tech_eth_10g IS
-- Test bench control parameters
GENERIC (
g_technology : NATURAL := c_tech_select_default;
-- g_data_type = c_tb_tech_mac_10g_data_type_symbols = 0
-- g_data_type = c_tb_tech_mac_10g_data_type_counter = 1
g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols
);
END tb_tech_eth_10g;
ARCHITECTURE tb OF tb_tech_eth_10g IS
CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz
CONSTANT tx_ref_clk_156_period : TIME := 6.4 ns; -- 156.25 MHz
CONSTANT phy_delay : TIME := 0 ns;
CONSTANT c_st_loopback : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT
CONSTANT c_rl : NATURAL := 1;
CONSTANT c_nof_tx_not_valid : NATURAL := 0; -- when > 0 then pull tx valid low for c_nof_tx_not_valid beats during tx
--CONSTANT c_pkt_length_arr : t_nat_natural_arr := (0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1472, 1473, 9000);
CONSTANT c_pkt_length_arr : t_nat_natural_arr := array_init(0, 50, 1) & (1472, 1473) & 9000; -- frame longer than 1518-46 = 1472 is received with rx_sosi.err = 8
-- jumbo frame is 9018-46 = 8972
CONSTANT c_nof_pkt : NATURAL := c_pkt_length_arr'LENGTH;
CONSTANT c_dst_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"10FA01020300";
CONSTANT c_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"123456789ABC"; -- = 12-34-56-78-9A-BC
CONSTANT c_src_mac_tx : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := c_src_mac;
--CONSTANT c_src_mac_tx : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"100056789ABC"; -- = 10-00-56-78-9A-BC
CONSTANT c_ethertype : STD_LOGIC_VECTOR(c_network_eth_type_slv'RANGE) := X"10FA";
CONSTANT c_etherlen : STD_LOGIC_VECTOR(c_network_eth_type_slv'RANGE) := "0000000000010000";
-- Packet headers
CONSTANT c_eth_header_ethertype : t_network_eth_header := (c_dst_mac, c_src_mac_tx, c_ethertype);
CONSTANT c_eth_header_etherlen : t_network_eth_header := (c_dst_mac, c_src_mac_tx, c_etherlen);
SIGNAL total_header : t_network_total_header := c_network_total_header_ones; -- default fill all fields with value 1
-- Clocks and reset
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL mm_clk : STD_LOGIC := '0'; -- memory-mapped bus clock
SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk
SIGNAL tx_ref_clk_312 : STD_LOGIC := '1'; -- mac_10g
SIGNAL tx_ref_clk_156 : STD_LOGIC := '0'; -- mac_10g reference clock
SIGNAL tx_rst : STD_LOGIC; -- reset synchronous with tx_ref_clk_156
SIGNAL rx_phy_clk_312 : STD_LOGIC := '1'; -- mac_10g
SIGNAL rx_phy_clk_156 : STD_LOGIC := '0'; -- mac_10g rx clock from phy = tx_ref_clk_156 in this tb
SIGNAL rx_rst : STD_LOGIC; -- reset synchronous with rx_phy_clk_156 = tx_ref_clk_156 in this tb
-- 10G MAC control interface
SIGNAL mm_init : STD_LOGIC := '1';
SIGNAL mm_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit;
SIGNAL mm_mosi : t_mem_mosi;
SIGNAL mm_miso : t_mem_miso;
SIGNAL mm_miso_rdval : STD_LOGIC;
SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit;
-- 10G MAC transmit interface
-- . The tb is the ST source
SIGNAL tx_en : STD_LOGIC := '1';
SIGNAL tx_siso : t_dp_siso;
SIGNAL tx_siso_arr : t_dp_siso_arr(0 DOWNTO 0);
SIGNAL tx_sosi : t_dp_sosi;
SIGNAL tx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit
SIGNAL tx_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0);
-- 10G MAC receive interface
-- . The tb is the ST sink
SIGNAL rx_siso : t_dp_siso;
SIGNAL rx_sosi : t_dp_sosi;
SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit
-- 10G PHY serial interface
SIGNAL tx_serial_arr : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
SIGNAL rx_serial_arr : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
-- Verification
SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1);
SIGNAL tx_pkt_cnt : NATURAL := 0;
SIGNAL rx_pkt_cnt : NATURAL := 0;
BEGIN
-- run 50 us
mm_clk <= NOT mm_clk AFTER mm_clk_period/2; -- MM clock
tx_ref_clk_156 <= NOT tx_ref_clk_156 AFTER tx_ref_clk_156_period/2; -- mac_10g tx reference clock
tx_ref_clk_312 <= NOT tx_ref_clk_312 AFTER tx_ref_clk_156_period/4;
rx_phy_clk_156 <= tx_ref_clk_156; -- use tx_ref_clk_156 to model PHY
rx_phy_clk_312 <= tx_ref_clk_312;
mm_rst <= '1', '0' AFTER mm_clk_period*10;
tx_rst <= '1', '0' AFTER tx_ref_clk_156_period*10;
rx_rst <= '1', '0' AFTER tx_ref_clk_156_period*10;
-- debug signals to ease monitoring in wave window
tx_sosi_data <= tx_sosi.data(c_tech_mac_10g_data_w-1 DOWNTO 0);
rx_sosi_data <= rx_sosi.data(c_tech_mac_10g_data_w-1 DOWNTO 0);
mm_mosi_wrdata <= mm_mosi.wrdata(c_word_w-1 DOWNTO 0);
mm_miso_rddata <= mm_miso.rddata(c_word_w-1 DOWNTO 0);
mm_miso_rdval <= '1' WHEN mm_mosi.rd='1' AND mm_miso.waitrequest='0' ELSE '0'; -- c_rd_latency = 1
-- Use signal to leave unused fields 'X'
total_header.eth <= c_eth_header_ethertype;
p_mm_setup : PROCESS
BEGIN
mm_init <= '1';
mm_mosi.wr <= '0';
mm_mosi.rd <= '0';
-- wait until after reset release
proc_common_wait_until_low(mm_clk, mm_rst);
proc_common_wait_some_cycles(mm_clk, 10);
proc_tech_mac_10g_setup(g_technology,
c_src_mac,
mm_clk, mm_miso, mm_mosi);
mm_init <= '0';
WAIT;
END PROCESS;
p_ff_transmitter : PROCESS
BEGIN
-- . Avalon ST
tx_sosi <= c_dp_sosi_rst;
WHILE mm_init/='0' LOOP
WAIT UNTIL rising_edge(tx_ref_clk_156);
END LOOP;
proc_common_wait_some_cycles(tx_ref_clk_156, 10);
-- Loopback txp->rxp so use promiscuous mode or use DST_MAC = c_src_mac to send to itself
-- TX frame:
-- . I=0 is empty payload, so only 4 words of the ETH header with 46 padding zeros, so empty = 2
-- . For I=1 to 46 the payload length remains 46 with padding zeros, so empty = 2
-- . For I>46 the payload length is I and empty = 4 - (I mod 4)
FOR I IN 0 TO c_nof_pkt-1 LOOP
proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr(I), g_data_type, c_rl, c_nof_tx_not_valid, tx_ref_clk_156, tx_en, tx_siso, tx_sosi);
proc_common_wait_some_cycles(tx_ref_clk_156, 0);
END LOOP;
proc_common_wait_some_cycles(tx_ref_clk_156, c_pkt_length_arr(c_nof_pkt-1)/c_tech_mac_10g_symbols_per_beat);
proc_common_wait_some_cycles(tx_ref_clk_156, 100);
tb_end <= '1';
WAIT;
END PROCESS;
p_ff_receiver : PROCESS
BEGIN
-- . Avalon ST
rx_siso <= c_dp_siso_hold;
WHILE mm_init/='0' LOOP
WAIT UNTIL rising_edge(rx_phy_clk_156);
END LOOP;
-- Receive forever
WHILE TRUE LOOP
proc_tech_mac_10g_rx_packet(total_header, g_data_type, rx_phy_clk_156, rx_sosi, rx_siso);
END LOOP;
WAIT;
END PROCESS;
p_ff_store_tx_sosi_at_eop : PROCESS(tx_ref_clk_156)
VARIABLE vI : NATURAL := 0;
BEGIN
IF rising_edge(tx_ref_clk_156) THEN
IF tx_sosi.eop='1' THEN
expected_sosi_arr(vI) <= tx_sosi;
vI := vI +1;
END IF;
END IF;
END PROCESS;
p_ff_verify_rx_sosi_at_eop : PROCESS(rx_phy_clk_156)
VARIABLE vI : NATURAL := 0;
VARIABLE vLow : NATURAL := 0;
BEGIN
IF rising_edge(rx_phy_clk_156) THEN
IF rx_sosi.eop='1' THEN
-- frame shorter than 64 get padded so em
IF c_pkt_length_arr(vI) < 64 - 14 - 20 - 8 - 4 THEN -- = minimum frame 64 - ETH 14 - IP 20 - UDP 8 - CRC 4
-- frame shorter than 64 get padded so empty after stripping the Rx CRC is fixed 4, which becomes 6 due to pre header padding for UDP word align
IF TO_UINT(rx_sosi.empty) /= 6 THEN
REPORT "RX: Wrong padded empty" SEVERITY ERROR;
END IF;
ELSE
IF rx_sosi.empty /= expected_sosi_arr(vI).empty THEN
REPORT "RX: Wrong empty" SEVERITY ERROR;
ELSE
vLow := TO_UINT(rx_sosi.empty)*8;
ASSERT rx_sosi.data(63 DOWNTO vLow) = expected_sosi_arr(vI).data(63 DOWNTO vLow) REPORT "RX: Wrong data at eop" SEVERITY ERROR;
END IF;
END IF;
vI := vI +1;
END IF;
END IF;
END PROCESS;
-- Rewire DP to DP array type.
tx_sosi_arr(0) <= tx_sosi;
tx_siso <= tx_siso_arr(0);
rx_siso_arr(0) <= rx_siso;
rx_sosi <= rx_sosi_arr(0);
gen_dut : IF c_st_loopback=FALSE GENERATE
dut : ENTITY work.tech_eth_10g
GENERIC MAP (
g_technology => g_technology,
g_sim => FALSE,
g_nof_channels => 1,
--g_pre_header_padding => FALSE
g_pre_header_padding => TRUE
)
PORT MAP (
-- Transceiver PLL reference clock
tr_ref_clk_644 : IN STD_LOGIC := '0'; -- 644.531250 MHz for 10GBASE-R
-- MM
mm_clk => mm_clk,
mm_rst => mm_rst,
mac_mosi => mm_mosi, -- CSR = control status register
mac_miso => mm_miso,
-- Clocks
clk_312 => tx_ref_clk_312,
clk_156 => tx_ref_clk_156, -- 156.25 MHz local reference
rst_156 => tx_rst,
-- ST
tx_snk_in_arr => tx_sosi_arr, -- 64 bit data @ clk_156
tx_snk_out_arr => tx_siso_arr,
rx_src_out_arr => rx_sosi_arr, -- 64 bit data @ clk_156
rx_src_in_arr => rx_siso_arr,
-- Serial
tx_serial_arr => tx_serial_arr,
rx_serial_arr => rx_serial_arr
);
END GENERATE;
no_dut : IF c_st_loopback=TRUE GENERATE
rx_sosi <= tx_sosi;
tx_siso <= rx_siso;
END GENERATE;
-- Loopback serial
rx_serial_arr <= TRANSPORT tx_serial_arr AFTER phy_delay;
-- Verification
tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(tx_ref_clk_156);
rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(rx_phy_clk_156);
p_tb_end : PROCESS
BEGIN
WAIT UNTIL tb_end='1';
-- Verify that all transmitted packets have been received
IF tx_pkt_cnt=0 THEN
REPORT "No packets were transmitted." SEVERITY ERROR;
ELSIF rx_pkt_cnt=0 THEN
REPORT "No packets were received." SEVERITY ERROR;
ELSIF tx_pkt_cnt/=rx_pkt_cnt THEN
REPORT "Not all transmitted packets were received." SEVERITY ERROR;
END IF;
-- Stop the simulation
ASSERT FALSE REPORT "Simulation finished." SEVERITY FAILURE;
WAIT;
END PROCESS;
END tb;
......@@ -23,6 +23,8 @@
-- Purpose: Combine mac_10g and 10gbase_r
-- Description:
-- . For c_tech_stratixiv: not available (yet)
--
-- . For c_tech_arria10:
-- __________________
-- | |
......@@ -53,42 +55,28 @@ ENTITY tech_eth_10g IS
);
PORT (
-- Transceiver PLL reference clock
tr_ref_clk_156 : IN STD_LOGIC := '0'; -- 156.26 MHz for XAUI
tr_ref_clk_644 : IN STD_LOGIC := '0'; -- 644.531250 MHz for 10GBASE-R
-- MM
mm_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
mac_mosi : IN t_mem_mosi; -- MAG_10G (CSR)
mac_mosi : IN t_mem_mosi; -- MAG_10G (CSR), aggregated for all g_nof_channels
mac_miso : OUT t_mem_miso;
xaui_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- XAUI
xaui_miso : OUT t_mem_miso;
-- Clocks
clk_312 : IN STD_LOGIC := '0';
clk_156 : IN STD_LOGIC := '0';
rst_156 : IN STD_LOGIC := '0';
-- ST
tx_snk_in_arr : IN t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); -- 64 bit data
tx_snk_in_arr : IN t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); -- 64 bit data @ clk_156
tx_snk_out_arr : OUT t_dp_siso_arr(g_nof_channels-1 DOWNTO 0);
rx_src_out_arr : OUT t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); -- 64 bit data
rx_src_out_arr : OUT t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); -- 64 bit data @ clk_156
rx_src_in_arr : IN t_dp_siso_arr(g_nof_channels-1 DOWNTO 0);
-- XAUI
cal_rec_clk : IN STD_LOGIC := '0';
crc_rx_ready_arr : OUT STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0); -- crc = synchronous to Cal_Rec_Clk
crc_tx_ready_arr : OUT STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0);
a_rx_channelaligned_arr : OUT STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0);
xaui_rx_arr : IN t_xaui_arr(g_nof_channels-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
xaui_tx_arr : OUT t_xaui_arr(g_nof_channels-1 DOWNTO 0);
-- 10GBASE-R
clk_312 : IN STD_LOGiC := '0';
clk_156 : IN STD_LOGiC := '0';
rst_156 : IN STD_LOGiC := '0';
-- Serial
tx_serial_arr : OUT STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0);
rx_serial_arr : IN STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0) := (OTHERS=>'0')
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment