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

Made wait for xon more robust (in case it is initially 'X') in proc_tech_mac_10g_tx_packet.

parent 19737b70
No related branches found
No related tags found
No related merge requests found
...@@ -49,7 +49,7 @@ ENTITY tb_tech_eth_10g IS ...@@ -49,7 +49,7 @@ ENTITY tb_tech_eth_10g IS
g_technology : NATURAL := c_tech_select_default; g_technology : NATURAL := c_tech_select_default;
g_tech_pll_clk_644_period : TIME := tech_pll_clk_644_period; 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_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_link_status_check : STD_LOGIC_VECTOR(c_tech_mac_10g_link_status_w-1 DOWNTO 0) := "11";
g_use_rx_serial_in : BOOLEAN := FALSE g_use_rx_serial_in : BOOLEAN := FALSE
); );
...@@ -62,9 +62,9 @@ END tb_tech_eth_10g; ...@@ -62,9 +62,9 @@ END tb_tech_eth_10g;
ARCHITECTURE tb OF tb_tech_eth_10g IS ARCHITECTURE tb OF tb_tech_eth_10g IS
CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz
CONSTANT phy_delay : TIME := 0 ns; 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_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_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_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 ...@@ -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_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_pkt1 : NATURAL := c_pkt_length_arr1'LENGTH;
CONSTANT c_nof_pkt2 : NATURAL := c_pkt_length_arr2'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_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 : 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 ...@@ -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 SIGNAL total_header : t_network_total_header := c_network_total_header_ones; -- default fill all fields with value 1
-- Clocks and reset -- Clocks and reset
SIGNAL rx_end : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL mm_clk : STD_LOGIC := '0'; -- memory-mapped bus clock SIGNAL mm_clk : STD_LOGIC := '0'; -- memory-mapped bus clock
SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk
...@@ -100,15 +101,14 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS ...@@ -100,15 +101,14 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS
-- 10G MAC control interface -- 10G MAC control interface
SIGNAL mm_init : STD_LOGIC := '1'; 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 : 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 : t_mem_miso;
SIGNAL mm_miso_rdval : STD_LOGIC; SIGNAL mm_miso_rdval : STD_LOGIC;
SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit;
-- 10G MAC transmit interface -- 10G MAC transmit interface
-- . The tb is the ST source -- . The tb is the ST source
SIGNAL tx_en : STD_LOGIC := '1';
SIGNAL tx_siso : t_dp_siso; SIGNAL tx_siso : t_dp_siso;
SIGNAL tx_siso_arr : t_dp_siso_arr(0 DOWNTO 0); SIGNAL tx_siso_arr : t_dp_siso_arr(0 DOWNTO 0);
SIGNAL tx_sosi : t_dp_sosi; SIGNAL tx_sosi : t_dp_sosi;
...@@ -125,154 +125,60 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS ...@@ -125,154 +125,60 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS
-- 10G PHY serial interface -- 10G PHY serial interface
SIGNAL tx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); 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); SIGNAL rx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0);
-- Model a serial link fault -- Model a serial link fault
SIGNAL link_fault : STD_LOGIC; SIGNAL link_fault : STD_LOGIC;
-- Verification -- Verification
SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1);
SIGNAL tx_pkt_cnt : NATURAL := 0; SIGNAL tx_pkt_cnt : NATURAL := 0;
SIGNAL rx_pkt_cnt : NATURAL := 0; SIGNAL rx_pkt_cnt : NATURAL := 0;
SIGNAL rx_toggle : STD_LOGIC; -- toggle after every received packet
BEGIN 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 -- 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_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_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 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' -- Use signal to leave unused fields 'X'
total_header.eth <= c_eth_header_ethertype; total_header.eth <= c_eth_header_ethertype;
p_mm_setup : PROCESS u_mm_setup : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_setup
BEGIN GENERIC MAP (
mm_init <= '1'; g_technology => g_technology,
mm_mosi.wr <= '0'; g_src_mac => c_src_mac
mm_mosi.rd <= '0'; )
PORT MAP (
-- wait until after reset release tb_end => tb_end,
proc_common_wait_until_low(mm_clk, mm_rst); mm_clk => mm_clk,
proc_common_wait_some_cycles(mm_clk, 10); mm_rst => mm_rst,
mm_init => mm_init,
proc_tech_mac_10g_setup(g_technology, mm_mosi => mm_mosi,
c_src_mac, mm_miso => mm_miso
mm_clk, mm_miso, mm_mosi); );
mm_init <= '0';
WAIT;
END PROCESS;
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;
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) -- Packet transmitter
VARIABLE vI : NATURAL := 0; u_transmitter : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_transmitter
VARIABLE vLow : NATURAL := 0; GENERIC MAP (
BEGIN g_data_type => g_data_type,
IF rising_edge(clk_156) THEN g_pkt_length_arr1 => c_pkt_length_arr1,
IF rx_sosi.eop='1' THEN g_pkt_length_arr2 => c_pkt_length_arr2,
-- frame shorter than 64 get padded so em g_verify_link_recovery => g_verify_link_recovery
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 PORT MAP (
IF TO_UINT(rx_sosi.empty) /= 6 THEN mm_init => mm_init,
REPORT "RX: Wrong padded empty" SEVERITY ERROR; total_header => total_header,
END IF; clk_156 => clk_156,
ELSE tx_siso => tx_siso,
IF rx_sosi.empty /= expected_sosi_arr(vI).empty THEN tx_sosi => tx_sosi,
REPORT "RX: Wrong empty" SEVERITY ERROR; link_fault => link_fault,
ELSE tx_end => rx_end
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. -- Rewire DP to DP array type.
tx_sosi_arr(0) <= tx_sosi; tx_sosi_arr(0) <= tx_sosi;
...@@ -295,6 +201,11 @@ BEGIN ...@@ -295,6 +201,11 @@ BEGIN
rst_312 => OPEN 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 gen_dut : IF c_st_loopback=FALSE GENERATE
dut : ENTITY work.tech_eth_10g dut : ENTITY work.tech_eth_10g
GENERIC MAP ( GENERIC MAP (
...@@ -334,47 +245,71 @@ BEGIN ...@@ -334,47 +245,71 @@ BEGIN
); );
END GENERATE; END GENERATE;
no_dut : IF c_st_loopback=TRUE GENERATE u_link_connect : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_link_connect
rx_sosi <= tx_sosi; GENERIC MAP (
tx_siso <= rx_siso; 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
END GENERATE; 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
-- Loopback serial -- . external connect
tx_serial_arr_dly <= TRANSPORT tx_serial_arr AFTER phy_delay; tx_serial_out => tx_serial_out, -- connects to delayed tx_serial_arr(0)
tx_serial_out <= tx_serial_arr_dly(0); rx_serial_in => rx_serial_in -- used when g_loopback=FALSE
);
p_rx_serial : PROCESS(tx_serial_arr_dly, rx_serial_in, link_fault) -- Packet receiver
BEGIN u_receiver : ENTITY tech_mac_10g_lib.tb_tech_mac_10_receiver
IF g_use_rx_serial_in=FALSE THEN GENERIC MAP (
rx_serial_arr <= tx_serial_arr_dly; g_data_type => g_data_type
ELSE )
rx_serial_arr(0) <= rx_serial_in; PORT MAP (
END IF; mm_init => mm_init,
IF link_fault='1' THEN total_header => total_header,
rx_serial_arr(0) <= '0'; clk_156 => clk_156,
END IF; rx_sosi => rx_sosi,
END PROCESS; rx_siso => rx_siso,
rx_toggle => rx_toggle
);
-- Verification -- Verification
tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(clk_156); u_verify_rx_at_eop : ENTITY tech_mac_10g_lib.tb_tech_mac_10_verify_rx_at_eop
rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(clk_156); 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 p_tb_end : PROCESS
BEGIN BEGIN
WAIT UNTIL tb_end='1'; 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); 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 --proc_common_wait_some_cycles(clk_156, 10000); -- uncomment to simulate somewhat longer without tx packet data
-- Stop the simulation -- Stop the simulation
tb_end <= '1';
ASSERT FALSE REPORT "Simulation finished." SEVERITY FAILURE; ASSERT FALSE REPORT "Simulation finished." SEVERITY FAILURE;
WAIT; WAIT;
END PROCESS; END PROCESS;
......
...@@ -14,6 +14,12 @@ synth_files = ...@@ -14,6 +14,12 @@ synth_files =
test_bench_files = test_bench_files =
tb_tech_mac_10g_pkg.vhd 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_tech_mac_10g.vhd
tb_tb_tech_mac_10g.vhd tb_tb_tech_mac_10g.vhd
......
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
-- Description: -- Description:
-- The tb is self checking based on: -- The tb is self checking based on:
-- . proc_tech_mac_10g_rx_packet() for expected header and data type -- . 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: -- Usage:
-- > do wave_tb_tech_mac_10g.do -- > as 10
-- > run -all -- > run -all
LIBRARY IEEE, technology_lib, common_lib, dp_lib; LIBRARY IEEE, technology_lib, common_lib, dp_lib;
...@@ -58,13 +58,11 @@ END tb_tech_mac_10g; ...@@ -58,13 +58,11 @@ END tb_tech_mac_10g;
ARCHITECTURE tb OF tb_tech_mac_10g IS 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 clk_156_period : TIME := 6.4 ns; -- 156.25 MHz
CONSTANT phy_delay : TIME := 0 ns; CONSTANT phy_delay : TIME := 0 ns;
CONSTANT c_rl : NATURAL := 1; 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_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 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 -- jumbo frame is 9018-46 = 8972
CONSTANT c_nof_pkt : NATURAL := c_pkt_length_arr'LENGTH; CONSTANT c_nof_pkt : NATURAL := c_pkt_length_arr'LENGTH;
...@@ -98,15 +96,14 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS ...@@ -98,15 +96,14 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS
-- 10G MAC control interface -- 10G MAC control interface
SIGNAL mm_init : STD_LOGIC := '1'; 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 : 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 : t_mem_miso;
SIGNAL mm_miso_rdval : STD_LOGIC; SIGNAL mm_miso_rdval : STD_LOGIC;
SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit;
-- 10G MAC transmit interface -- 10G MAC transmit interface
-- . The tb is the ST source -- . The tb is the ST source
SIGNAL tx_en : STD_LOGIC := '1';
SIGNAL tx_siso : t_dp_siso; SIGNAL tx_siso : t_dp_siso;
SIGNAL tx_sosi : t_dp_sosi; 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_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 ...@@ -115,7 +112,6 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS
-- . The tb is the ST sink -- . The tb is the ST sink
SIGNAL rx_siso : t_dp_siso; SIGNAL rx_siso : t_dp_siso;
SIGNAL rx_sosi : t_dp_sosi; 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 SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit
-- 10G MAC XGMII interface -- 10G MAC XGMII interface
...@@ -124,15 +120,12 @@ ARCHITECTURE tb OF tb_tech_mac_10g IS ...@@ -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 SIGNAL xgmii_rx_data : STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0); -- 72 bit
-- Verification -- Verification
SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1);
SIGNAL tx_pkt_cnt : NATURAL := 0; SIGNAL tx_pkt_cnt : NATURAL := 0;
SIGNAL rx_pkt_cnt : NATURAL := 0; SIGNAL rx_pkt_cnt : NATURAL := 0;
SIGNAL rx_toggle : STD_LOGIC := '0'; -- toggle after every received packet SIGNAL rx_toggle : STD_LOGIC; -- toggle after every received packet
BEGIN 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_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; clk_312 <= NOT clk_312 OR tb_end AFTER clk_156_period/4;
tx_ref_clk_156 <= clk_156; -- mac_10g tx reference clock tx_ref_clk_156 <= clk_156; -- mac_10g tx reference clock
...@@ -140,122 +133,49 @@ BEGIN ...@@ -140,122 +133,49 @@ BEGIN
rx_phy_clk_156 <= clk_156; -- use clk_156 to model PHY rx_phy_clk_156 <= clk_156; -- use clk_156 to model PHY
rx_phy_clk_312 <= clk_312; rx_phy_clk_312 <= clk_312;
mm_rst <= '1', '0' AFTER mm_clk_period*10;
tx_rst <= '1', '0' AFTER clk_156_period*10; tx_rst <= '1', '0' AFTER clk_156_period*10;
rx_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 -- 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_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_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 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' -- Use signal to leave unused fields 'X'
total_header.eth <= c_eth_header_ethertype; total_header.eth <= c_eth_header_ethertype;
p_mm_setup : PROCESS u_mm_setup : ENTITY work.tb_tech_mac_10g_setup
BEGIN GENERIC MAP (
mm_init <= '1'; g_technology => g_technology,
mm_mosi.wr <= '0'; g_src_mac => c_src_mac
mm_mosi.rd <= '0'; )
PORT MAP (
-- wait until after reset release tb_end => tb_end,
proc_common_wait_until_low(mm_clk, mm_rst); mm_clk => mm_clk,
proc_common_wait_some_cycles(mm_clk, 10); mm_rst => mm_rst,
mm_init => mm_init,
proc_tech_mac_10g_setup(g_technology, mm_mosi => mm_mosi,
c_src_mac, mm_miso => mm_miso
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;
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);
rx_toggle <= NOT rx_toggle;
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) -- Packet transmitter
VARIABLE vI : NATURAL := 0; u_transmitter : ENTITY work.tb_tech_mac_10g_transmitter
VARIABLE vLow : NATURAL := 0; GENERIC MAP (
BEGIN g_data_type => g_data_type,
IF rising_edge(rx_phy_clk_156) THEN g_pkt_length_arr1 => c_pkt_length_arr
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 PORT MAP (
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 mm_init => mm_init,
-- 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 total_header => total_header,
IF TO_UINT(rx_sosi_reg.empty) /= 6 THEN clk_156 => tx_ref_clk_156,
REPORT "RX: Wrong padded empty" SEVERITY ERROR; tx_siso => tx_siso,
END IF; tx_sosi => tx_sosi,
ELSE link_fault => OPEN,
IF rx_sosi_reg.empty /= expected_sosi_arr(vI).empty THEN tx_end => rx_end
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 no_dut : IF g_no_dut=TRUE GENERATE
-- ST loopback -- ST loopback
...@@ -267,7 +187,6 @@ BEGIN ...@@ -267,7 +187,6 @@ BEGIN
dut : ENTITY work.tech_mac_10g dut : ENTITY work.tech_mac_10g
GENERIC MAP ( GENERIC MAP (
g_technology => g_technology, g_technology => g_technology,
--g_pre_header_padding => FALSE
g_pre_header_padding => TRUE g_pre_header_padding => TRUE
) )
PORT MAP ( PORT MAP (
...@@ -298,28 +217,65 @@ BEGIN ...@@ -298,28 +217,65 @@ BEGIN
END GENERATE; END GENERATE;
-- Loopback XGMII -- 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
);
-- 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 -- Verification
tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(tx_ref_clk_156); u_verify_rx_at_eop : ENTITY work.tb_tech_mac_10_verify_rx_at_eop
rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(rx_phy_clk_156); 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 p_tb_end : PROCESS
BEGIN BEGIN
WAIT UNTIL rx_end='1'; 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); proc_common_wait_some_cycles(clk_156, 100);
-- Stop the simulation
tb_end <= '1'; tb_end <= '1';
ASSERT FALSE REPORT "Simulation finished." SEVERITY NOTE;
WAIT; WAIT;
END PROCESS; END PROCESS;
......
-------------------------------------------------------------------------------
--
-- 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;
-------------------------------------------------------------------------------
--
-- 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;
-------------------------------------------------------------------------------
--
-- 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;
-------------------------------------------------------------------------------
--
-- 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;
-------------------------------------------------------------------------------
--
-- 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;
-------------------------------------------------------------------------------
--
-- 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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment