Skip to content

Commit d9a8476

Browse files
committed
Merge branch 'marushchenko-feat-uvm-network_module-cmac-add_verification_support' into 'devel'
UVM NETWORK_MODULE CMAC [FEATURE]: add a support of the CMAC variant See merge request ndk/ndk-fpga!94
2 parents 9251cc2 + c785cde commit d9a8476

File tree

21 files changed

+1477
-127
lines changed

21 files changed

+1477
-127
lines changed

core/comp/eth/network_mod/uvm/Modules.tcl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ if {$ARCHGRP == "E_TILE"} {
3434
lappend MOD "$ENTITY_BASE/tbench/f-tile/env/pkg.sv" \
3535
"$ENTITY_BASE/tbench/f-tile/dut.sv" \
3636
"$ENTITY_BASE/tbench/f-tile/testbench.sv"
37+
} elseif {$ARCHGRP == "CMAC"} {
38+
lappend COMPONENTS [ list "SV_LOGIC_VECTOR_ARRAY_LBUS" "$SV_UVM_BASE/logic_vector_array_lbus" "FULL"]
39+
lappend MOD "$ENTITY_BASE/tbench/cmac/env/pkg.sv" \
40+
"$ENTITY_BASE/tbench/cmac/dut.sv" \
41+
"$ENTITY_BASE/tbench/cmac/property.sv" \
42+
"$ENTITY_BASE/tbench/cmac/testbench.sv"
3743
}

core/comp/eth/network_mod/uvm/signals_sig.fdo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# SPDX-License-Identifier: BSD-3-Clause
66

7-
set ETH_PORTS 2
7+
set ETH_PORTS 4
88

99
add wave -divider "CLK"
1010
add_wave "-noupdate -color yellow" /testbench/CLK_USR

core/comp/eth/network_mod/uvm/tbench/base/env/env.sv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class env #(
7676
return m_scoreboard.used();
7777
endfunction
7878

79+
virtual function void eth_full_speed_set();
80+
`uvm_fatal(this.get_full_name(), "\n\tIf you want to run full speed test you have to specified full speed sequece for ethernet");
81+
endfunction
82+
7983
// Create base components of environment.
8084
function void build_phase(uvm_phase phase);
8185
uvm_reset::config_item cfg_rst;
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
// dut.sv: Xilinx CMAC DUT
2+
// Copyright (C) 2024 CESNET z. s. p. o.
3+
// Author(s): Yaroslav Marushchenko <[email protected]>
4+
5+
// SPDX-License-Identifier: BSD-3-Clause
6+
7+
module DUT #(
8+
string ETH_CORE_ARCH,
9+
int unsigned ETH_PORTS,
10+
int unsigned ETH_PORT_SPEED[ETH_PORTS-1 : 0],
11+
12+
int unsigned ETH_PORT_CHAN [ETH_PORTS-1 : 0],
13+
int unsigned EHIP_PORT_TYPE [ETH_PORTS-1 : 0],
14+
int unsigned ETH_PORT_RX_MTU[ETH_PORTS-1 : 0],
15+
int unsigned ETH_PORT_TX_MTU[ETH_PORTS-1 : 0],
16+
17+
int unsigned LANES,
18+
19+
int unsigned QSFP_PORTS,
20+
int unsigned QSFP_I2C_PORTS,
21+
int unsigned QSFP_I2C_TRISTATE,
22+
23+
int unsigned ETH_TX_HDR_WIDTH,
24+
int unsigned ETH_RX_HDR_WIDTH,
25+
26+
int unsigned REGIONS,
27+
int unsigned REGION_SIZE,
28+
int unsigned BLOCK_SIZE,
29+
int unsigned ITEM_WIDTH,
30+
31+
int unsigned MI_DATA_WIDTH,
32+
int unsigned MI_ADDR_WIDTH,
33+
34+
int unsigned MI_DATA_WIDTH_PHY,
35+
int unsigned MI_ADDR_WIDTH_PHY,
36+
37+
int unsigned LANE_RX_POLARITY,
38+
int unsigned LANE_TX_POLARITY,
39+
40+
int unsigned RESET_WIDTH,
41+
42+
string DEVICE,
43+
string BOARD
44+
)(
45+
input wire logic CLK_ETH[ETH_PORTS],
46+
input wire logic CLK_USR,
47+
input wire logic CLK_MI,
48+
input wire logic CLK_MI_PHY,
49+
input wire logic CLK_MI_PMD,
50+
input wire logic CLK_TSU,
51+
52+
reset_if.dut rst_usr,
53+
reset_if.dut rst_eth[ETH_PORTS],
54+
reset_if.dut rst_mi,
55+
reset_if.dut rst_mi_phy,
56+
reset_if.dut rst_mi_pmd,
57+
reset_if.dut rst_tsu,
58+
59+
lbus_if.dut_tx eth_tx[ETH_PORTS],
60+
lbus_if.dut_rx eth_rx[ETH_PORTS],
61+
62+
mfb_if.dut_rx usr_rx [ETH_PORTS],
63+
mfb_if.dut_tx usr_tx_data[ETH_PORTS],
64+
mvb_if.dut_tx usr_tx_hdr [ETH_PORTS],
65+
66+
mi_if.dut_slave mi,
67+
mi_if.dut_slave mi_phy,
68+
mi_if.dut_slave mi_pmd,
69+
70+
mvb_if.dut_rx tsu
71+
);
72+
DUT_BASE #(
73+
.ETH_CORE_ARCH (ETH_CORE_ARCH ),
74+
.ETH_PORTS (ETH_PORTS ),
75+
.ETH_PORT_SPEED (ETH_PORT_SPEED ),
76+
.ETH_PORT_CHAN (ETH_PORT_CHAN ),
77+
.EHIP_PORT_TYPE (EHIP_PORT_TYPE ),
78+
.ETH_PORT_RX_MTU (ETH_PORT_RX_MTU ),
79+
.ETH_PORT_TX_MTU (ETH_PORT_TX_MTU ),
80+
.LANES (LANES ),
81+
.QSFP_PORTS (QSFP_PORTS ),
82+
.QSFP_I2C_PORTS (QSFP_I2C_PORTS ),
83+
.QSFP_I2C_TRISTATE(QSFP_I2C_TRISTATE),
84+
.ETH_TX_HDR_WIDTH (ETH_TX_HDR_WIDTH ),
85+
.ETH_RX_HDR_WIDTH (ETH_RX_HDR_WIDTH ),
86+
.REGIONS (REGIONS ),
87+
.REGION_SIZE (REGION_SIZE ),
88+
.BLOCK_SIZE (BLOCK_SIZE ),
89+
.ITEM_WIDTH (ITEM_WIDTH ),
90+
.MI_DATA_WIDTH (MI_DATA_WIDTH ),
91+
.MI_ADDR_WIDTH (MI_ADDR_WIDTH ),
92+
.MI_DATA_WIDTH_PHY(MI_DATA_WIDTH_PHY),
93+
.MI_ADDR_WIDTH_PHY(MI_ADDR_WIDTH_PHY),
94+
.LANE_RX_POLARITY (LANE_RX_POLARITY ),
95+
.LANE_TX_POLARITY (LANE_TX_POLARITY ),
96+
.RESET_WIDTH (RESET_WIDTH ),
97+
.DEVICE (DEVICE ),
98+
.BOARD (BOARD )
99+
) DUT_BASE_U (
100+
.CLK_USR (CLK_USR ),
101+
.CLK_MI (CLK_MI ),
102+
.CLK_MI_PHY (CLK_MI_PHY),
103+
.CLK_MI_PMD (CLK_MI_PMD),
104+
.CLK_TSU (CLK_TSU ),
105+
106+
.rst_usr (rst_usr ),
107+
.rst_eth (rst_eth ),
108+
.rst_mi (rst_mi ),
109+
.rst_mi_phy (rst_mi_phy),
110+
.rst_mi_pmd (rst_mi_pmd),
111+
.rst_tsu (rst_tsu ),
112+
113+
.usr_rx (usr_rx ),
114+
.usr_tx_data (usr_tx_data),
115+
.usr_tx_hdr (usr_tx_hdr ),
116+
117+
.mi (mi ),
118+
.mi_phy (mi_phy),
119+
.mi_pmd (mi_pmd),
120+
121+
.tsu (tsu)
122+
);
123+
124+
generate;
125+
for (genvar eth_it = 0; eth_it < ETH_PORTS; eth_it++) begin
126+
localparam int unsigned ETH_PORT_CHAN_LOCAL = ETH_PORT_CHAN[eth_it];
127+
initial assert(ETH_PORT_CHAN_LOCAL == 1);
128+
129+
wire logic [4*128-1 : 0] eth_rx_data;
130+
131+
// ------- //
132+
// TX side //
133+
// ------- //
134+
135+
for (genvar slice = 0; slice < 4; slice++) begin
136+
initial begin
137+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_data[slice] = {<<8{eth_tx[eth_it].DATA[128*(slice+1)-1 -: 128]}}; // Byte reordering
138+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_mty [slice] = eth_tx[eth_it].MTY[4*(slice+1)-1 -: 4];
139+
end
140+
end
141+
142+
initial begin
143+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_ena = eth_tx[eth_it].ENA;
144+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_sop = eth_tx[eth_it].SOP;
145+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_eop = eth_tx[eth_it].EOP;
146+
force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_rx_lbus_err = eth_tx[eth_it].ERR;
147+
end
148+
149+
assign eth_tx[eth_it].RDY = 1'b1; // Always ready
150+
151+
// ------- //
152+
// RX side //
153+
// ------- //
154+
155+
assign eth_rx_data = {>>{DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_data}};
156+
for (genvar segment = 0; segment < 4; segment++) begin
157+
wire logic [128-1 : 0] segment_data;
158+
159+
assign segment_data = eth_rx_data[128*(segment+1)-1 -: 128];
160+
assign eth_rx[eth_it].DATA[128*(segment+1)-1 -: 128] = {<<8{segment_data}}; // Byte reordering
161+
end
162+
163+
assign eth_rx[eth_it].ENA = DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_ena;
164+
assign eth_rx[eth_it].SOP = DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_sop;
165+
assign eth_rx[eth_it].EOP = DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_eop;
166+
assign eth_rx[eth_it].ERR = DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_err;
167+
assign eth_rx[eth_it].MTY = {>>{DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_mty}};
168+
169+
initial force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_rdy = eth_rx[eth_it].RDY;
170+
171+
// ----- //
172+
// Other //
173+
// ----- //
174+
175+
// CLK connection
176+
initial force DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_gt_tx_clk_322m = CLK_ETH[eth_it];
177+
end
178+
endgenerate
179+
180+
endmodule
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// env.sv: Environment for the Xilinx CMAC device
2+
// Copyright (C) 2024 CESNET z. s. p. o.
3+
// Author(s): Yaroslav Marushchenko <[email protected]>
4+
5+
// SPDX-License-Identifier: BSD-3-Clause
6+
7+
class env #(
8+
string ETH_CORE_ARCH,
9+
int unsigned ETH_PORTS,
10+
11+
int unsigned ETH_PORT_SPEED[ETH_PORTS-1:0],
12+
int unsigned ETH_PORT_CHAN[ETH_PORTS-1 : 0],
13+
14+
int unsigned ETH_TX_HDR_WIDTH,
15+
int unsigned ETH_RX_HDR_WIDTH,
16+
17+
int unsigned REGIONS,
18+
int unsigned REGION_SIZE,
19+
int unsigned BLOCK_SIZE,
20+
int unsigned ITEM_WIDTH,
21+
22+
int unsigned MI_DATA_WIDTH,
23+
int unsigned MI_ADDR_WIDTH
24+
) extends uvm_network_mod_env::env #(
25+
ETH_CORE_ARCH,
26+
ETH_PORTS,
27+
ETH_PORT_SPEED,
28+
ETH_PORT_CHAN,
29+
ETH_TX_HDR_WIDTH,
30+
ETH_RX_HDR_WIDTH,
31+
REGIONS,
32+
REGION_SIZE,
33+
BLOCK_SIZE,
34+
ITEM_WIDTH,
35+
MI_DATA_WIDTH,
36+
MI_ADDR_WIDTH
37+
);
38+
`uvm_component_param_utils(uvm_network_mod_cmac_env::env #(ETH_CORE_ARCH, ETH_PORTS, ETH_PORT_SPEED, ETH_PORT_CHAN, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH))
39+
40+
// BYTE ARRAY LBUS environments
41+
protected uvm_logic_vector_array_lbus::env_tx m_eth_tx[ETH_PORTS];
42+
protected uvm_logic_vector_array_lbus::env_rx m_eth_rx[ETH_PORTS];
43+
44+
tx_error_expander m_tx_error_expander[ETH_PORTS];
45+
46+
// Constructor
47+
function new(string name = "env", uvm_component parent = null);
48+
super.new(name, parent);
49+
endfunction
50+
51+
52+
virtual function void eth_full_speed_set();
53+
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
54+
uvm_logic_vector_array_lbus::sequence_library_tx::type_id::set_inst_override(
55+
uvm_logic_vector_array_lbus::sequence_library_tx_fullspeed::get_type(),
56+
$sformatf("m_eth_tx_%0d.*", it),
57+
this
58+
);
59+
60+
uvm_lbus::sequence_library_rx::type_id::set_inst_override(
61+
uvm_lbus::sequence_library_rx_fullspeed::get_type(),
62+
$sformatf("m_eth_rx_%0d.*", it),
63+
this
64+
);
65+
end
66+
endfunction
67+
68+
function void build_phase(uvm_phase phase);
69+
// -------------------------------------- //
70+
// Overriding the base components/objects //
71+
// -------------------------------------- //
72+
73+
uvm_network_mod_env::sequencer_port #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::type_id::set_inst_override(
74+
uvm_network_mod_cmac_env::sequencer_port #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::get_type(),
75+
"m_sequencer.*",
76+
this
77+
);
78+
79+
uvm_network_mod_env::virt_sequence_port #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::type_id::set_type_override(
80+
uvm_network_mod_cmac_env::virt_sequence_port #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::get_type()
81+
);
82+
uvm_network_mod_env::virt_sequence_port_stop #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::type_id::set_type_override(
83+
uvm_network_mod_cmac_env::virt_sequence_port_stop #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH)::get_type()
84+
);
85+
uvm_network_mod_env::virt_sequence_simple #(ETH_PORTS, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH)::type_id::set_type_override(
86+
uvm_network_mod_cmac_env::virt_sequence_simple #(ETH_PORTS, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH)::get_type()
87+
);
88+
uvm_network_mod_env::virt_sequence_stop #(ETH_PORTS, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH)::type_id::set_type_override(
89+
uvm_network_mod_cmac_env::virt_sequence_stop #(ETH_PORTS, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH)::get_type()
90+
);
91+
92+
// Build of base environment
93+
super.build_phase(phase);
94+
95+
// ------------------------- //
96+
// Build of CMAC environment //
97+
// ------------------------- //
98+
99+
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
100+
uvm_logic_vector_array_lbus::config_item cfg_eth_tx;
101+
uvm_logic_vector_array_lbus::config_item cfg_eth_rx;
102+
103+
cfg_eth_tx = new();
104+
cfg_eth_tx.active = UVM_ACTIVE;
105+
cfg_eth_tx.interface_name = $sformatf("vif_eth_tx_%0d", it);
106+
uvm_config_db #(uvm_logic_vector_array_lbus::config_item)::set(this, $sformatf("m_eth_tx_%0d", it), "m_config", cfg_eth_tx);
107+
m_eth_tx[it] = uvm_logic_vector_array_lbus::env_tx::type_id::create($sformatf("m_eth_tx_%0d", it), this);
108+
109+
cfg_eth_rx = new();
110+
cfg_eth_rx.active = UVM_ACTIVE;
111+
cfg_eth_rx.interface_name = $sformatf("vif_eth_rx_%0d", it);
112+
uvm_config_db #(uvm_logic_vector_array_lbus::config_item)::set(this, $sformatf("m_eth_rx_%0d", it), "m_config", cfg_eth_rx);
113+
m_eth_rx[it] = uvm_logic_vector_array_lbus::env_rx::type_id::create($sformatf("m_eth_rx_%0d", it), this);
114+
115+
m_tx_error_expander[it] = tx_error_expander::type_id::create($sformatf("m_tx_error_expander_%0d", it), this);
116+
end
117+
endfunction
118+
119+
function void connect_phase(uvm_phase phase);
120+
super.connect_phase(phase);
121+
122+
// Connection of resets
123+
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
124+
m_eth_rst[it].sync_connect(m_eth_tx[it].reset_sync);
125+
m_eth_rst[it].sync_connect(m_eth_rx[it].reset_sync);
126+
end
127+
128+
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
129+
// TX packet
130+
m_eth_tx[it].analysis_port_packet.connect(m_scoreboard.eth_rx_data[it]);
131+
// TX error
132+
m_eth_tx[it].analysis_port_error.connect(m_tx_error_expander[it].analysis_export);
133+
m_tx_error_expander[it].analysis_port.connect(m_scoreboard.eth_rx_hdr[it]);
134+
135+
// RX packet
136+
m_eth_rx[it].analysis_port_packet.connect(m_scoreboard.eth_tx_data[it]);
137+
// RX error
138+
m_eth_rx[it].analysis_port_error.connect(m_scoreboard.eth_tx_hdr[it]);
139+
end
140+
141+
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
142+
sequencer_port #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN[0], MI_DATA_WIDTH, MI_ADDR_WIDTH) cast_sequencer_port;
143+
assert($cast(cast_sequencer_port, m_sequencer.port[it]))
144+
else begin
145+
`uvm_fatal(this.get_full_name(), $sformatf("\n\tCast failed: %s", m_sequencer.port[it].get_full_name()))
146+
end
147+
148+
cast_sequencer_port.eth_tx_packet = m_eth_tx[it].m_sequencer.packet;
149+
cast_sequencer_port.eth_tx_error = m_eth_tx[it].m_sequencer.error;
150+
cast_sequencer_port.eth_rx = m_eth_rx[it].m_sequencer;
151+
end
152+
endfunction
153+
154+
endclass
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// pkg.sv: Package for the Xilinx CMAC environment
2+
// Copyright (C) 2024 CESNET z. s. p. o.
3+
// Author(s): Yaroslav Marushchenko <[email protected]>
4+
5+
// SPDX-License-Identifier: BSD-3-Clause
6+
7+
`ifndef NETWORK_MOD_CMAC_ENV_SV
8+
`define NETWORK_MOD_CMAC_ENV_SV
9+
10+
package uvm_network_mod_cmac_env;
11+
12+
`include "uvm_macros.svh"
13+
import uvm_pkg::*;
14+
15+
`include "sequencer_port.sv"
16+
`include "sequence.sv"
17+
`include "tx_error_expander.sv"
18+
`include "env.sv"
19+
20+
endpackage
21+
22+
`endif

0 commit comments

Comments
 (0)