diff --git a/libraries/technology/eth_10g/tb_tech_eth_10g.vhd b/libraries/technology/eth_10g/tb_tech_eth_10g.vhd index d643609e24855084f92e4e31c58f8e20795ab221..7b3ecee18d5ecc692330aa0e10a1140027d588dc 100644 --- a/libraries/technology/eth_10g/tb_tech_eth_10g.vhd +++ b/libraries/technology/eth_10g/tb_tech_eth_10g.vhd @@ -49,7 +49,7 @@ ENTITY tb_tech_eth_10g IS g_technology : NATURAL := c_tech_select_default; g_tech_pll_clk_644_period : TIME := tech_pll_clk_644_period; g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols; - g_verify_link_recovery : BOOLEAN := TRUE; + g_verify_link_recovery : BOOLEAN := FALSE;--TRUE; g_link_status_check : STD_LOGIC_VECTOR(c_tech_mac_10g_link_status_w-1 DOWNTO 0) := "11"; g_use_rx_serial_in : BOOLEAN := FALSE ); @@ -62,9 +62,9 @@ END tb_tech_eth_10g; ARCHITECTURE tb OF tb_tech_eth_10g IS - CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz CONSTANT phy_delay : TIME := 0 ns; + CONSTANT c_phy_loopback : BOOLEAN := NOT g_use_rx_serial_in; 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 @@ -74,7 +74,7 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS CONSTANT c_pkt_length_arr : t_nat_natural_arr := c_pkt_length_arr1 & c_pkt_length_arr2; CONSTANT c_nof_pkt1 : NATURAL := c_pkt_length_arr1'LENGTH; CONSTANT c_nof_pkt2 : NATURAL := c_pkt_length_arr2'LENGTH; - CONSTANT c_nof_pkt : NATURAL := c_nof_pkt1 + c_nof_pkt2; + CONSTANT c_nof_pkt : NATURAL := sel_a_b(g_verify_link_recovery, c_nof_pkt1 + c_nof_pkt2, c_nof_pkt1); 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 @@ -90,6 +90,7 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS SIGNAL total_header : t_network_total_header := c_network_total_header_ones; -- default fill all fields with value 1 -- Clocks and reset + SIGNAL rx_end : STD_LOGIC := '0'; 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 @@ -100,15 +101,14 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS -- 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_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; 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; @@ -125,155 +125,61 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS -- 10G PHY serial interface SIGNAL tx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); - SIGNAL tx_serial_arr_dly : STD_LOGIC_VECTOR(0 DOWNTO 0); SIGNAL rx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); -- Model a serial link fault SIGNAL link_fault : STD_LOGIC; -- 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; + SIGNAL tx_pkt_cnt : NATURAL := 0; + SIGNAL rx_pkt_cnt : NATURAL := 0; + SIGNAL rx_toggle : STD_LOGIC; -- toggle after every received packet BEGIN - -- run 50 us - mm_clk <= NOT mm_clk AFTER mm_clk_period/2; -- MM clock - - mm_rst <= '1', '0' AFTER mm_clk_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 - + + 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); + -- 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; - + u_mm_setup : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_setup + GENERIC MAP ( + g_technology => g_technology, + g_src_mac => c_src_mac + ) + PORT MAP ( + tb_end => tb_end, + mm_clk => mm_clk, + mm_rst => mm_rst, + mm_init => mm_init, + mm_mosi => mm_mosi, + mm_miso => mm_miso + ); - p_ff_transmitter : PROCESS - BEGIN - link_fault <= '0'; - - -- . Avalon ST - tx_sosi <= c_dp_sosi_rst; - - WHILE mm_init/='0' LOOP - WAIT UNTIL rising_edge(clk_156); - END LOOP; - proc_common_wait_some_cycles(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_pkt1-1 LOOP - proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr1(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); - proc_common_wait_some_cycles(clk_156, 0); - END LOOP; - - proc_common_wait_some_cycles(clk_156, c_pkt_length_arr1(c_nof_pkt1-1)/c_tech_mac_10g_symbols_per_beat); - proc_common_wait_some_cycles(clk_156, 100); - - IF g_verify_link_recovery=TRUE THEN - -- Model a link fault to verify Rx recovery - link_fault <= '1'; - proc_common_wait_some_cycles(clk_156, 1000); - link_fault <= '0'; - - FOR I IN 0 TO c_nof_pkt2-1 LOOP - proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr2(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); - proc_common_wait_some_cycles(clk_156, 0); - END LOOP; - - proc_common_wait_some_cycles(clk_156, c_pkt_length_arr2(c_nof_pkt2-1)/c_tech_mac_10g_symbols_per_beat); - proc_common_wait_some_cycles(clk_156, 100); - END IF; + -- Packet transmitter + u_transmitter : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_transmitter + GENERIC MAP ( + g_data_type => g_data_type, + g_pkt_length_arr1 => c_pkt_length_arr1, + g_pkt_length_arr2 => c_pkt_length_arr2, + g_verify_link_recovery => g_verify_link_recovery + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + clk_156 => clk_156, + tx_siso => tx_siso, + tx_sosi => tx_sosi, + link_fault => link_fault, + tx_end => rx_end + ); - 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(clk_156); - END LOOP; - - -- Receive forever - WHILE TRUE LOOP - proc_tech_mac_10g_rx_packet(total_header, g_data_type, clk_156, rx_sosi, rx_siso); - END LOOP; - - WAIT; - END PROCESS; - - - p_ff_store_tx_sosi_at_eop : PROCESS(clk_156) - VARIABLE vI : NATURAL := 0; - BEGIN - IF rising_edge(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(clk_156) - VARIABLE vI : NATURAL := 0; - VARIABLE vLow : NATURAL := 0; - BEGIN - IF rising_edge(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); @@ -295,6 +201,11 @@ BEGIN rst_312 => OPEN ); + no_dut : IF c_st_loopback=TRUE GENERATE + rx_sosi <= tx_sosi; + tx_siso <= rx_siso; + END GENERATE; + gen_dut : IF c_st_loopback=FALSE GENERATE dut : ENTITY work.tech_eth_10g GENERIC MAP ( @@ -334,47 +245,71 @@ BEGIN ); END GENERATE; - no_dut : IF c_st_loopback=TRUE GENERATE - rx_sosi <= tx_sosi; - tx_siso <= rx_siso; - END GENERATE; - - -- Loopback serial - tx_serial_arr_dly <= TRANSPORT tx_serial_arr AFTER phy_delay; - tx_serial_out <= tx_serial_arr_dly(0); + u_link_connect : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_link_connect + GENERIC MAP ( + g_loopback => c_phy_loopback, -- default TRUE for loopback tx to rx, else use FALSE to connect tx-tx, rx-rx between two tb devices + g_link_delay => phy_delay + ) + PORT MAP ( + -- Serial layer connect + link_fault => link_fault, -- when '1' then forces rx_serial_arr(0)='0' + tx_serial_arr => tx_serial_arr, + rx_serial_arr => rx_serial_arr, -- connects to delayed tx_serial_arr(0) when g_loopback=TRUE else to rx_serial_in + + -- . external connect + tx_serial_out => tx_serial_out, -- connects to delayed tx_serial_arr(0) + rx_serial_in => rx_serial_in -- used when g_loopback=FALSE + ); + + -- Packet receiver + u_receiver : ENTITY tech_mac_10g_lib.tb_tech_mac_10_receiver + GENERIC MAP ( + g_data_type => g_data_type + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + clk_156 => clk_156, + rx_sosi => rx_sosi, + rx_siso => rx_siso, + rx_toggle => rx_toggle + ); - p_rx_serial : PROCESS(tx_serial_arr_dly, rx_serial_in, link_fault) - BEGIN - IF g_use_rx_serial_in=FALSE THEN - rx_serial_arr <= tx_serial_arr_dly; - ELSE - rx_serial_arr(0) <= rx_serial_in; - END IF; - IF link_fault='1' THEN - rx_serial_arr(0) <= '0'; - END IF; - END PROCESS; - -- Verification - tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(clk_156); - rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(clk_156); + u_verify_rx_at_eop : ENTITY tech_mac_10g_lib.tb_tech_mac_10_verify_rx_at_eop + GENERIC MAP ( + g_no_padding => FALSE, + g_pkt_length_arr => c_pkt_length_arr + ) + PORT MAP ( + tx_clk_156 => clk_156, + tx_sosi => tx_sosi, + rx_clk_156 => clk_156, + rx_sosi => rx_sosi + ); + + u_verify_rx_pkt_cnt : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_verify_rx_pkt_cnt + GENERIC MAP ( + g_nof_pkt => c_nof_pkt + ) + PORT MAP ( + tx_clk_156 => clk_156, + tx_sosi => tx_sosi, + rx_clk_156 => clk_156, + rx_sosi => rx_sosi, + tx_pkt_cnt => tx_pkt_cnt, + rx_pkt_cnt => rx_pkt_cnt, + rx_end => rx_end + ); 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; + WAIT UNTIL rx_end='1'; proc_common_wait_some_cycles(clk_156, 100); --proc_common_wait_some_cycles(clk_156, 10000); -- uncomment to simulate somewhat longer without tx packet data -- Stop the simulation + tb_end <= '1'; ASSERT FALSE REPORT "Simulation finished." SEVERITY FAILURE; WAIT; END PROCESS; diff --git a/libraries/technology/mac_10g/hdllib.cfg b/libraries/technology/mac_10g/hdllib.cfg index 853302e9b317a8f2fa1a646ac5929b91cd730054..bfb3906b3b06722b25beba1f9aef6ee8b92cf55e 100644 --- a/libraries/technology/mac_10g/hdllib.cfg +++ b/libraries/technology/mac_10g/hdllib.cfg @@ -14,6 +14,12 @@ synth_files = test_bench_files = tb_tech_mac_10g_pkg.vhd + tb_tech_mac_10g_setup.vhd + tb_tech_mac_10g_transmitter.vhd + tb_tech_mac_10g_receiver.vhd + tb_tech_mac_10g_link_connect.vhd + tb_tech_mac_10g_verify_rx_at_eop.vhd + tb_tech_mac_10g_verify_rx_pkt_cnt.vhd tb_tech_mac_10g.vhd tb_tb_tech_mac_10g.vhd diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g.vhd index 33f1d4af4bafcc893e98207574441c8dc8367b35..2bc36de41d984dd53efa9d12839ba704fe8fd889 100644 --- a/libraries/technology/mac_10g/tb_tech_mac_10g.vhd +++ b/libraries/technology/mac_10g/tb_tech_mac_10g.vhd @@ -23,9 +23,9 @@ -- 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. +-- . rx_pkt_cnt = tx_pkt_cnt > 0 must be true at the tb_end. -- Usage: --- > do wave_tb_tech_mac_10g.do +-- > as 10 -- > run -all LIBRARY IEEE, technology_lib, common_lib, dp_lib; @@ -58,13 +58,11 @@ END tb_tech_mac_10g; ARCHITECTURE tb OF tb_tech_mac_10g IS - CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz CONSTANT clk_156_period : TIME := 6.4 ns; -- 156.25 MHz CONSTANT phy_delay : TIME := 0 ns; 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; @@ -98,15 +96,14 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS -- 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_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; 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_sosi : t_dp_sosi; SIGNAL tx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit @@ -115,7 +112,6 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS -- . The tb is the ST sink SIGNAL rx_siso : t_dp_siso; SIGNAL rx_sosi : t_dp_sosi; - SIGNAL rx_sosi_reg : t_dp_sosi; SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit -- 10G MAC XGMII interface @@ -124,15 +120,12 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS SIGNAL xgmii_rx_data : STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0); -- 72 bit -- 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; - SIGNAL rx_toggle : STD_LOGIC := '0'; -- toggle after every received packet + SIGNAL tx_pkt_cnt : NATURAL := 0; + SIGNAL rx_pkt_cnt : NATURAL := 0; + SIGNAL rx_toggle : STD_LOGIC; -- toggle after every received packet BEGIN - mm_clk <= NOT mm_clk OR tb_end AFTER mm_clk_period/2; -- MM clock clk_156 <= NOT clk_156 OR tb_end AFTER clk_156_period/2; clk_312 <= NOT clk_312 OR tb_end AFTER clk_156_period/4; tx_ref_clk_156 <= clk_156; -- mac_10g tx reference clock @@ -140,123 +133,50 @@ BEGIN rx_phy_clk_156 <= clk_156; -- use clk_156 to model PHY rx_phy_clk_312 <= clk_312; - mm_rst <= '1', '0' AFTER mm_clk_period*10; tx_rst <= '1', '0' AFTER clk_156_period*10; rx_rst <= '1', '0' AFTER 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); - rx_end <= '1'; - WAIT; - END PROCESS; - + 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); - 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; + -- Use signal to leave unused fields 'X' + total_header.eth <= c_eth_header_ethertype; - -- Receive forever - WHILE TRUE LOOP - proc_tech_mac_10g_rx_packet(total_header, g_data_type, rx_phy_clk_156, rx_sosi, rx_siso); - rx_toggle <= NOT rx_toggle; - END LOOP; + u_mm_setup : ENTITY work.tb_tech_mac_10g_setup + GENERIC MAP ( + g_technology => g_technology, + g_src_mac => c_src_mac + ) + PORT MAP ( + tb_end => tb_end, + mm_clk => mm_clk, + mm_rst => mm_rst, + mm_init => mm_init, + mm_mosi => mm_mosi, + mm_miso => mm_miso + ); - WAIT; - END PROCESS; - + -- Packet transmitter + u_transmitter : ENTITY work.tb_tech_mac_10g_transmitter + GENERIC MAP ( + g_data_type => g_data_type, + g_pkt_length_arr1 => c_pkt_length_arr + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + clk_156 => tx_ref_clk_156, + tx_siso => tx_siso, + tx_sosi => tx_sosi, + link_fault => OPEN, + tx_end => rx_end + ); - 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 - rx_sosi_reg <= rx_sosi; -- use rx_sosi_reg for verification at eop to account for once cycle latency in expected_sosi_arr() - IF rx_sosi_reg.eop='1' THEN - IF g_no_dut=FALSE AND 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 by MAC 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_reg.empty) /= 6 THEN - REPORT "RX: Wrong padded empty" SEVERITY ERROR; - END IF; - ELSE - IF rx_sosi_reg.empty /= expected_sosi_arr(vI).empty THEN - REPORT "RX: Wrong empty" SEVERITY ERROR; - ELSE - vLow := TO_UINT(rx_sosi_reg.empty)*8; - ASSERT rx_sosi_reg.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; - no_dut : IF g_no_dut=TRUE GENERATE -- ST loopback rx_sosi <= tx_sosi; @@ -267,7 +187,6 @@ BEGIN dut : ENTITY work.tech_mac_10g GENERIC MAP ( g_technology => g_technology, - --g_pre_header_padding => FALSE g_pre_header_padding => TRUE ) PORT MAP ( @@ -298,28 +217,65 @@ BEGIN END GENERATE; -- Loopback XGMII - xgmii_rx_data <= TRANSPORT xgmii_tx_data AFTER phy_delay; + u_link_connect : ENTITY work.tb_tech_mac_10g_link_connect + GENERIC MAP ( + g_loopback => TRUE, + g_link_delay => phy_delay + ) + PORT MAP ( + -- XGMII layer connect + xgmii_tx_data => xgmii_tx_data, + xgmii_rx_data => xgmii_rx_data + ); - -- 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); + -- Packet receiver + u_receiver : ENTITY work.tb_tech_mac_10_receiver + GENERIC MAP ( + g_data_type => g_data_type + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + clk_156 => rx_phy_clk_156, + rx_sosi => rx_sosi, + rx_siso => rx_siso, + rx_toggle => rx_toggle + ); + -- Verification + u_verify_rx_at_eop : ENTITY work.tb_tech_mac_10_verify_rx_at_eop + GENERIC MAP ( + g_no_padding => g_no_dut, + g_pkt_length_arr => c_pkt_length_arr + ) + PORT MAP ( + tx_clk_156 => tx_ref_clk_156, + tx_sosi => tx_sosi, + rx_clk_156 => rx_phy_clk_156, + rx_sosi => rx_sosi + ); + + u_verify_rx_pkt_cnt : ENTITY work.tb_tech_mac_10g_verify_rx_pkt_cnt + GENERIC MAP ( + g_nof_pkt => c_nof_pkt + ) + PORT MAP ( + tx_clk_156 => tx_ref_clk_156, + tx_sosi => tx_sosi, + rx_clk_156 => rx_phy_clk_156, + rx_sosi => rx_sosi, + tx_pkt_cnt => tx_pkt_cnt, + rx_pkt_cnt => rx_pkt_cnt, + rx_end => rx_end + ); + + -- Stop the simulation p_tb_end : PROCESS BEGIN WAIT UNTIL rx_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; proc_common_wait_some_cycles(clk_156, 100); - - -- Stop the simulation tb_end <= '1'; + ASSERT FALSE REPORT "Simulation finished." SEVERITY NOTE; WAIT; END PROCESS; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_link_connect.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_link_connect.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a56f0dbd838e41d4fd666cbd746a684b80019296 --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_link_connect.vhd @@ -0,0 +1,83 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench link connection for the tech_mac_10g +-- Description: +-- . Support XGMII layer connect +-- . Support serial layer connect with optional link_fault +-- . Support link delay + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_interface_layers_pkg.ALL; + + +ENTITY tb_tech_mac_10g_link_connect IS + GENERIC ( + g_loopback : BOOLEAN := TRUE; -- default TRUE for loopback tx to rx, else use FALSE to connect tx-tx, rx-rx between two tb devices + g_link_delay : TIME := 0 ns + ); + PORT ( + -- XGMII layer connect + xgmii_tx_data : IN STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0) := (OTHERS=>'X'); -- 72 bit + xgmii_rx_data : OUT STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0); -- 72 bit + + -- Serial layer connect + link_fault : IN STD_LOGIC := '0'; -- when '1' then forces rx_serial_arr(0)='0' + tx_serial_arr : IN STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS=>'X'); + rx_serial_arr : OUT STD_LOGIC_VECTOR(0 DOWNTO 0); -- connects to delayed tx_serial_arr(0) when g_loopback=TRUE else to rx_serial_in + + -- . external connect + tx_serial_out : OUT STD_LOGIC; -- connects to delayed tx_serial_arr(0) + rx_serial_in : IN STD_LOGIC := 'X' -- used when g_loopback=FALSE + ); +END tb_tech_mac_10g_link_connect; + + +ARCHITECTURE tb OF tb_tech_mac_10g_link_connect IS + + SIGNAL tx_serial_arr_dly : STD_LOGIC_VECTOR(0 DOWNTO 0); + +BEGIN + ----------------------------------------------------------------------------- + -- XGMII layer link + ----------------------------------------------------------------------------- + xgmii_rx_data <= TRANSPORT xgmii_tx_data AFTER g_link_delay; + + ----------------------------------------------------------------------------- + -- Serial layer link + ----------------------------------------------------------------------------- + tx_serial_arr_dly <= TRANSPORT tx_serial_arr AFTER g_link_delay; + tx_serial_out <= tx_serial_arr_dly(0); + + p_rx_serial : PROCESS(tx_serial_arr_dly, rx_serial_in, link_fault) + BEGIN + IF g_loopback=TRUE THEN + rx_serial_arr <= tx_serial_arr_dly; + ELSE + rx_serial_arr(0) <= rx_serial_in; + END IF; + IF link_fault='1' THEN + rx_serial_arr(0) <= '0'; + END IF; + END PROCESS; +END tb; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_receiver.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_receiver.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2d358352c2e3aedba69d1a6093fceabc66ddd262 --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_receiver.vhd @@ -0,0 +1,73 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench stimuli for tech_mac_10g receiver +-- Description: + +LIBRARY IEEE, technology_lib, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_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 WORK.tb_tech_mac_10g_pkg.ALL; + + +ENTITY tb_tech_mac_10_receiver IS + GENERIC ( + -- 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_counter + ); + PORT ( + mm_init : IN STD_LOGIC; + total_header : IN t_network_total_header; + clk_156 : IN STD_LOGIC; + rx_sosi : IN t_dp_sosi; + rx_siso : OUT t_dp_siso; + rx_toggle : OUT STD_LOGIC -- toggle after every received packet + ); +END tb_tech_mac_10_receiver; + + +ARCHITECTURE tb OF tb_tech_mac_10_receiver IS + SIGNAL i_rx_toggle : STD_LOGIC := '0'; +BEGIN + rx_toggle <= i_rx_toggle; + + p_ff_receiver : PROCESS + BEGIN + -- . Avalon ST + rx_siso <= c_dp_siso_hold; + + WHILE mm_init/='0' LOOP + WAIT UNTIL rising_edge(clk_156); + END LOOP; + + -- Receive forever + WHILE TRUE LOOP + proc_tech_mac_10g_rx_packet(total_header, g_data_type, clk_156, rx_sosi, rx_siso); + i_rx_toggle <= NOT i_rx_toggle; + END LOOP; + + WAIT; + END PROCESS; +END tb; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_setup.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_setup.vhd new file mode 100644 index 0000000000000000000000000000000000000000..eb0369b9e41b3e5b801b646ce139ab2fa6a84c76 --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_setup.vhd @@ -0,0 +1,85 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench stimuli to setup tech_mac_10g via MM +-- Description: + +LIBRARY IEEE, technology_lib, common_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE technology_lib.technology_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +USE WORK.tb_tech_mac_10g_pkg.ALL; + + +ENTITY tb_tech_mac_10g_setup IS + GENERIC ( + g_technology : NATURAL := c_tech_select_default; + g_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"123456789ABC" -- = 12-34-56-78-9A-BC + ); + PORT ( + tb_end : IN STD_LOGIC := '0'; + mm_clk : OUT STD_LOGIC; + mm_rst : OUT STD_LOGIC; + mm_init : OUT STD_LOGIC; + mm_mosi : OUT t_mem_mosi; + mm_miso : IN t_mem_miso + ); +END tb_tech_mac_10g_setup; + + +ARCHITECTURE tb OF tb_tech_mac_10g_setup IS + + CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz + + -- Clocks and reset + SIGNAL i_mm_clk : STD_LOGIC := '0'; -- memory-mapped bus clock + SIGNAL i_mm_rst : STD_LOGIC; -- reset synchronous with mm_clk + +BEGIN + + mm_clk <= i_mm_clk; + mm_rst <= i_mm_rst; + + i_mm_clk <= NOT i_mm_clk OR tb_end AFTER mm_clk_period/2; -- MM clock + i_mm_rst <= '1', '0' AFTER mm_clk_period*10; + + 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(i_mm_clk, i_mm_rst); + proc_common_wait_some_cycles(i_mm_clk, 10); + + proc_tech_mac_10g_setup(g_technology, + g_src_mac, + i_mm_clk, mm_miso, mm_mosi); + mm_init <= '0'; + WAIT; + END PROCESS; + +END tb; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_transmitter.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_transmitter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..16510cfde03df0a6b9296ac89ba014846509cbaa --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_transmitter.vhd @@ -0,0 +1,126 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench stimuli for tech_mac_10g transmitter +-- Description: +-- The packet transmission starts after mm_init goes low. The +-- g_pkt_length_arr1 contains the array of packet lengths for the packets +-- that will be transmitted. The packet data depends on g_data_type and can +-- be counter data that counts per word or per symbol. +-- If g_verify_link_recovery=TRUE then link_fault will be active for some +-- time during which no packets are transmitted. This link_fault can be used +-- to disable the rx path. +-- After link_fault is deasserted again the second series of packets defined +-- by g_pkt_length_arr2 will be transmitted to verify that the link has +-- recovered from the link_fault. +-- Some time after all packets have been transmitted the tx_end will go high. +-- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_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 WORK.tech_mac_10g_component_pkg.ALL; +USE WORK.tb_tech_mac_10g_pkg.ALL; + + +ENTITY tb_tech_mac_10g_transmitter IS + GENERIC ( + -- 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_counter; + g_pkt_length_arr1 : 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 + g_pkt_length_arr2 : t_nat_natural_arr := array_init(46, 10, 139) & 1472; + g_verify_link_recovery : BOOLEAN := FALSE + ); + PORT ( + mm_init : IN STD_LOGIC; + total_header : IN t_network_total_header; + clk_156 : IN STD_LOGIC; + tx_siso : IN t_dp_siso; + tx_sosi : OUT t_dp_sosi; + link_fault : OUT STD_LOGIC; + tx_end : OUT STD_LOGIC + ); +END tb_tech_mac_10g_transmitter; + + +ARCHITECTURE tb OF tb_tech_mac_10g_transmitter IS + + 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_nof_pkt1 : NATURAL := g_pkt_length_arr1'LENGTH; + CONSTANT c_nof_pkt2 : NATURAL := g_pkt_length_arr2'LENGTH; + + SIGNAL tx_en : STD_LOGIC := '1'; + +BEGIN + + p_ff_transmitter : PROCESS + BEGIN + tx_end <= '0'; + link_fault <= '0'; + tx_sosi <= c_dp_sosi_rst; + + proc_common_wait_until_low(clk_156, mm_init); + proc_common_wait_some_cycles(clk_156, 10); + + -- Loopback txp->rxp so use promiscuous mode or use DST_MAC = c_src_mac to send to itself + + -- TX frame:g_pkt_length_arr1 + -- . 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_pkt1-1 LOOP + proc_tech_mac_10g_tx_packet(total_header, g_pkt_length_arr1(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); + proc_common_wait_some_cycles(clk_156, 0); + END LOOP; + + proc_common_wait_some_cycles(clk_156, g_pkt_length_arr1(c_nof_pkt1-1)/c_tech_mac_10g_symbols_per_beat); + proc_common_wait_some_cycles(clk_156, 100); + + IF g_verify_link_recovery=TRUE THEN + -- Model a link fault to verify Rx recovery + link_fault <= '1'; + proc_common_wait_some_cycles(clk_156, 1000); + -- Remove the link fault and wait for tx_siso.xon to recover + link_fault <= '0'; + proc_common_wait_some_cycles(clk_156, 500); + + FOR I IN 0 TO c_nof_pkt2-1 LOOP + proc_tech_mac_10g_tx_packet(total_header, g_pkt_length_arr2(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); + proc_common_wait_some_cycles(clk_156, 0); + END LOOP; + + proc_common_wait_some_cycles(clk_156, g_pkt_length_arr2(c_nof_pkt2-1)/c_tech_mac_10g_symbols_per_beat); + proc_common_wait_some_cycles(clk_156, 100); + END IF; + + tx_end <= '1'; + WAIT; + END PROCESS; + +END tb; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_at_eop.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_at_eop.vhd new file mode 100644 index 0000000000000000000000000000000000000000..088c3775de684998e62bb57005336314987f443c --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_at_eop.vhd @@ -0,0 +1,93 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench verification for the tech_mac_10g +-- Description: +-- Based on the transmitted data at eop verify the received data at eop. + +LIBRARY IEEE, technology_lib, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_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 WORK.tb_tech_mac_10g_pkg.ALL; + + +ENTITY tb_tech_mac_10_verify_rx_at_eop IS + GENERIC ( + g_no_padding : BOOLEAN := FALSE; -- default FALSE to verify the data from MAC that is padded to minimal length, else use TRUE to verify the data of any length + g_pkt_length_arr : t_nat_natural_arr + ); + PORT ( + tx_clk_156 : IN STD_LOGIC; + tx_sosi : IN t_dp_sosi; + rx_clk_156 : IN STD_LOGIC; + rx_sosi : IN t_dp_sosi + ); +END tb_tech_mac_10_verify_rx_at_eop; + +ARCHITECTURE tb OF tb_tech_mac_10_verify_rx_at_eop IS + + CONSTANT c_nof_pkt : NATURAL := g_pkt_length_arr'LENGTH; + + SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1); + SIGNAL rx_sosi_reg : t_dp_sosi; + +BEGIN + + p_ff_store_tx_at_eop : PROCESS(tx_clk_156) + VARIABLE vI : NATURAL := 0; + BEGIN + IF rising_edge(tx_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_at_eop : PROCESS(rx_clk_156) + VARIABLE vI : NATURAL := 0; + VARIABLE vLow : NATURAL := 0; + BEGIN + IF rising_edge(rx_clk_156) THEN + rx_sosi_reg <= rx_sosi; -- use rx_sosi_reg for verification at eop to account for once cycle latency in expected_sosi_arr() + IF rx_sosi_reg.eop='1' THEN + IF g_no_padding=FALSE AND g_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 by MAC 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_reg.empty) /= 6 THEN + REPORT "RX at eop: Wrong padded empty" SEVERITY ERROR; + END IF; + ELSE + IF rx_sosi_reg.empty /= expected_sosi_arr(vI).empty THEN + REPORT "RX at eop: Wrong empty" SEVERITY ERROR; + ELSE + vLow := TO_UINT(rx_sosi_reg.empty)*8; + ASSERT rx_sosi_reg.data(63 DOWNTO vLow) = expected_sosi_arr(vI).data(63 DOWNTO vLow) REPORT "RX at eop: Wrong data" SEVERITY ERROR; + END IF; + END IF; + vI := vI +1; + END IF; + END IF; + END PROCESS; + +END tb; diff --git a/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_pkt_cnt.vhd b/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_pkt_cnt.vhd new file mode 100644 index 0000000000000000000000000000000000000000..7bdfe3715468a7a69c3fa2d89233e40c35008f46 --- /dev/null +++ b/libraries/technology/mac_10g/tb_tech_mac_10g_verify_rx_pkt_cnt.vhd @@ -0,0 +1,80 @@ +------------------------------------------------------------------------------- +-- +-- 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: Reusable test bench verification for the tech_mac_10g +-- Description: +-- . Verify that > 0 packets were transmitted and that all were received + + +LIBRARY IEEE, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE dp_lib.dp_stream_pkg.ALL; + + +ENTITY tb_tech_mac_10g_verify_rx_pkt_cnt IS + GENERIC ( + g_nof_pkt : NATURAL + ); + PORT ( + tx_clk_156 : IN STD_LOGIC; + tx_sosi : IN t_dp_sosi; + rx_clk_156 : IN STD_LOGIC; + rx_sosi : IN t_dp_sosi; + tx_pkt_cnt : OUT NATURAL; + rx_pkt_cnt : OUT NATURAL; + rx_end : IN STD_LOGIC + ); +END tb_tech_mac_10g_verify_rx_pkt_cnt; + + +ARCHITECTURE tb OF tb_tech_mac_10g_verify_rx_pkt_cnt IS + + SIGNAL i_tx_pkt_cnt : NATURAL := 0; + SIGNAL i_rx_pkt_cnt : NATURAL := 0; + +BEGIN + + tx_pkt_cnt <= i_tx_pkt_cnt; + rx_pkt_cnt <= i_rx_pkt_cnt; + + -- Verification + i_tx_pkt_cnt <= i_tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(tx_clk_156); + i_rx_pkt_cnt <= i_rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(rx_clk_156); + + p_verify_pkt_cnt : PROCESS + BEGIN + WAIT UNTIL rx_end='1'; + + -- Verify that all transmitted packets have been received + IF i_tx_pkt_cnt=0 THEN + REPORT "No packets were transmitted." SEVERITY ERROR; + ELSIF i_tx_pkt_cnt/=g_nof_pkt THEN + REPORT "Not all packets were transmitted." SEVERITY ERROR; + ELSIF i_rx_pkt_cnt=0 THEN + REPORT "No packets were received." SEVERITY ERROR; + ELSIF i_tx_pkt_cnt/=i_rx_pkt_cnt THEN + REPORT "Not all transmitted packets were received." SEVERITY ERROR; + END IF; + + WAIT; + END PROCESS; + +END tb;