Skip to content

Commit 0103c17

Browse files
committed
Merge branch 'marushchenko-feat-uvm-network_module-add_mac_check_support' into 'devel'
Add MAC Check support to the NETWORK MODULE verification See merge request ndk/ndk-fpga!192
2 parents 83bc6a0 + d1a83d3 commit 0103c17

File tree

14 files changed

+297
-75
lines changed

14 files changed

+297
-75
lines changed

comp/uvm/packet_generators/Modules.tcl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ set SV_UVM_BASE "$OFM_PATH/comp/uvm"
99

1010
lappend COMPONENTS \
1111
[ list "SV_COMMON_BASE" "$SV_UVM_BASE/common" "FULL"] \
12-
[ list "SV_LOGIC_VECTOR_ARRAY_UVM_BASE" "$SV_UVM_BASE/logic_vector_array" "FULL"]
12+
[ list "SV_LOGIC_VECTOR_ARRAY_UVM_BASE" "$SV_UVM_BASE/logic_vector_array" "FULL"] \
13+
[ list "SV_PCAP_BASE" "$SV_UVM_BASE/pcap" "FULL"]
1314

1415
lappend MOD "$ENTITY_BASE/pkg.sv"

comp/uvm/packet_generators/config.sv

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
// SPDX-License-Identifier: BSD-3-Clause
66

77
class config_sequence extends uvm_logic_vector_array::config_sequence;
8-
logic [31 : 0] ipv4_addresses [$];
9-
logic [127 : 0] ipv6_addresses [$];
8+
bit [31 : 0] ipv4_addresses [$];
9+
bit [127 : 0] ipv6_addresses [$];
10+
bit [47 : 0] mac_addresses [$];
1011

11-
function void add_ipv4_address(logic [31 : 0] ipv4_address);
12+
function void add_ipv4_address(bit [31 : 0] ipv4_address);
1213
ipv4_addresses.push_back(ipv4_address);
1314
endfunction
1415

15-
function void add_ipv6_address(logic [127 : 0] ipv6_address);
16+
function void add_ipv6_address(bit [127 : 0] ipv6_address);
1617
ipv6_addresses.push_back(ipv6_address);
1718
endfunction
1819

20+
function void add_mac_address(bit [47 : 0] mac_address);
21+
mac_addresses.push_back(mac_address);
22+
endfunction
23+
1924
endclass

comp/uvm/packet_generators/sequence_flowtest.sv

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ class sequence_flowtest #(int unsigned ITEM_WIDTH) extends uvm_common::sequence_
88
`uvm_object_param_utils(uvm_packet_generators::sequence_flowtest #(ITEM_WIDTH))
99
`uvm_declare_p_sequencer(uvm_logic_vector_array::sequencer #(ITEM_WIDTH));
1010

11+
// Packet size configuration options
12+
int unsigned packet_size_min = 60; // Packets below are padded
13+
int unsigned packet_size_max = 1500; // Packets above are ignored
14+
1115
// Packet size configuration options
1216
int unsigned forward_packet_number_min = 10;
1317
int unsigned forward_packet_number_max = 100;
@@ -37,8 +41,8 @@ class sequence_flowtest #(int unsigned ITEM_WIDTH) extends uvm_common::sequence_
3741
int unsigned mac_mask_max = 48;
3842

3943
// Generator options
40-
logic generated_config = 1;
41-
logic generated_profile = 1;
44+
bit generated_config = 1;
45+
bit generated_profile = 1;
4246

4347
string config_filepath = "./config.yaml";
4448
string profile_filepath = "./profile.csv";
@@ -123,18 +127,51 @@ class sequence_flowtest #(int unsigned ITEM_WIDTH) extends uvm_common::sequence_
123127
cfg = new();
124128
endfunction
125129

130+
function void post_randomize();
131+
configure();
132+
endfunction
133+
126134
function void configure();
127-
foreach (cfg.ipv4_addresses[i]) begin
135+
// Get the unique configured addresses
136+
bit [32 -1 : 0] cfg_ipv4_addresses[$] = cfg.ipv4_addresses.unique();
137+
bit [128-1 : 0] cfg_ipv6_addresses[$] = cfg.ipv6_addresses.unique();
138+
bit [48 -1 : 0] cfg_mac_addresses [$] = cfg.mac_addresses .unique();
139+
140+
// Generate address counts to add
141+
int unsigned cfg_ipv4_addresses_count_to_add = $urandom_range(cfg_ipv4_addresses.size(), 0);
142+
int unsigned cfg_ipv6_addresses_count_to_add = $urandom_range(cfg_ipv6_addresses.size(), 0);
143+
int unsigned cfg_mac_addresses_count_to_add = $urandom_range(cfg_mac_addresses .size(), 0);
144+
145+
// Shuffle the addresses
146+
cfg_ipv4_addresses.shuffle();
147+
cfg_ipv6_addresses.shuffle();
148+
cfg_mac_addresses .shuffle();
149+
150+
// Add IPv4 addresses
151+
for (int unsigned i = 0; i < cfg_ipv4_addresses_count_to_add; i++) begin
128152
ipv4 = new[ipv4.size()+1](ipv4);
129153
ipv4[ipv4.size()-1].address = cfg.ipv4_addresses[i];
130154
ipv4[ipv4.size()-1].mask = 32;
131155
end
132156

133-
foreach (cfg.ipv6_addresses[i]) begin
157+
// Add IPv6 addresses
158+
for (int unsigned i = 0; i < cfg_ipv6_addresses_count_to_add; i++) begin
134159
ipv6 = new[ipv6.size()+1](ipv6);
135160
ipv6[ipv6.size()-1].address = cfg.ipv6_addresses[i];
136161
ipv6[ipv6.size()-1].mask = 128;
137162
end
163+
164+
// Add MAC addresses
165+
for (int unsigned i = 0; i < cfg_mac_addresses_count_to_add; i++) begin
166+
mac = new[mac.size()+1](mac);
167+
mac[mac.size()-1].address = cfg.mac_addresses[i];
168+
mac[mac.size()-1].mask = 48;
169+
end
170+
171+
// Remove duplicates
172+
ipv4 = ipv4.unique() with (item.address);
173+
ipv6 = ipv6.unique() with (item.address);
174+
mac = mac .unique() with (item.address);
138175
endfunction
139176

140177
function string get_ipv4_addresses();
@@ -262,23 +299,21 @@ class sequence_flowtest #(int unsigned ITEM_WIDTH) extends uvm_common::sequence_
262299
task body;
263300
uvm_pcap::reader reader;
264301
byte unsigned data[];
302+
uvm_common::sequence_cfg state;
265303

266304
// Output configuration options
267-
string output_filepath = "output.pcap";
268-
string report_filepath = "report.txt";
305+
string output_filepath = { p_sequencer.get_full_name(), ".", "output.pcap" };
306+
string report_filepath = { p_sequencer.get_full_name(), ".", "report.txt" };
269307
bit skip_unknown = 0;
270308
bit no_collision_check = 1;
271309

272310
string generator_parameters;
273311
string generator_execute_command;
274312

275-
configure();
276313
generate_tools_configuration();
277314

278315
reader = new();
279-
if (!uvm_config_db #(string)::get(p_sequencer, "", "output_filepath", output_filepath)) begin
280-
output_filepath = { p_sequencer.get_full_name(), ".pcap" };
281-
end
316+
void'(uvm_config_db #(string)::get(p_sequencer, "", "output_filepath", output_filepath));
282317

283318
`uvm_info(get_full_name(), $sformatf("\n\tsequence_flowtest is running\n\t\tpcap_name%s", output_filepath), UVM_DEBUG);
284319

@@ -298,8 +333,24 @@ class sequence_flowtest #(int unsigned ITEM_WIDTH) extends uvm_common::sequence_
298333

299334
void'(reader.open(output_filepath)); // Try open an output pcap
300335

336+
void'(uvm_config_db #(uvm_common::sequence_cfg)::get(p_sequencer, "", "state", state));
337+
301338
req = uvm_logic_vector_array::sequence_item #(ITEM_WIDTH)::type_id::create("req", p_sequencer);
302339
while(reader.read(data) == uvm_pcap::RET_OK) begin
340+
if (data.size() > packet_size_max) begin
341+
continue;
342+
end
343+
344+
if (state != null) begin
345+
if (!state.next()) begin
346+
break;
347+
end
348+
end
349+
350+
if (data.size() < packet_size_min) begin
351+
data = new[packet_size_min](data);
352+
end
353+
303354
start_item(req);
304355
req.data = { >>{ data } };
305356
finish_item(req);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ lappend COMPONENTS \
1515
[ list "SV_LOGIC_VECTOR_ARRAY_MFB" "$SV_UVM_BASE/logic_vector_array_mfb" "FULL"] \
1616
[ list "SV_LOGIC_VECTOR_MVB" "$SV_UVM_BASE/logic_vector_mvb" "FULL"] \
1717
[ list "SV_LOGIC_VECTOR_ARRAY_AVST" "$SV_UVM_BASE/logic_vector_array_avst" "FULL"] \
18-
[ list "SV_LOGIC_VECTOR_ARRAY_INTEL_MAC_SEG" "$SV_UVM_BASE/logic_vector_array_intel_mac_seg" "FULL"]
18+
[ list "SV_LOGIC_VECTOR_ARRAY_INTEL_MAC_SEG" "$SV_UVM_BASE/logic_vector_array_intel_mac_seg" "FULL"] \
19+
[ list "SV_PACKET_GENERATORS_BASE" "$SV_UVM_BASE/packet_generators" "FULL"]
1920

2021
lappend COMPONENTS [ list "RX_MAC_LITE_SV" "$OFM_PATH/comp/nic/mac_lite/rx_mac_lite/uvm" "FULL"]
2122
lappend COMPONENTS [ list "TX_MAC_LITE_SV" "$OFM_PATH/comp/nic/mac_lite/tx_mac_lite/uvm" "FULL"]

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
@@ -220,6 +220,10 @@ class env #(
220220
m_sequencer.port[it].usr_tx_hdr = m_usr_tx_hdr[it].m_sequencer;
221221
end
222222
m_sequencer.tsu = m_tsu.m_sequencer;
223+
224+
for (int unsigned i = 0; i < ETH_PORTS; i++) begin
225+
m_scoreboard.set_model_rx_mac_regmodel(i, m_sequencer.port[i].regmodel);
226+
end
223227
endfunction
224228
endclass
225229

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

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ endclass
5151
class model #(string ETH_CORE_ARCH, int unsigned ETH_PORTS, int unsigned ETH_PORT_SPEED[ETH_PORTS-1:0], int unsigned ETH_PORT_CHAN[ETH_PORTS-1:0], REGIONS, ITEM_WIDTH, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH) extends uvm_component;
5252
`uvm_component_param_utils(uvm_network_mod_env::model #(ETH_CORE_ARCH, ETH_PORTS, ETH_PORT_SPEED, ETH_PORT_CHAN, REGIONS, ITEM_WIDTH, ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH));
5353

54+
localparam int unsigned RX_MAC_COUNT = 16;
55+
5456
uvm_tlm_analysis_fifo#(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) eth_rx_data[ETH_PORTS];
5557
uvm_tlm_analysis_fifo#(uvm_logic_vector::sequence_item#(6)) eth_rx_hdr [ETH_PORTS];
5658
uvm_analysis_port #(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) eth_tx_data[ETH_PORTS];
@@ -67,6 +69,8 @@ class model #(string ETH_CORE_ARCH, int unsigned ETH_PORTS, int unsigned ETH_POR
6769
protected int unsigned eth_recv[ETH_PORTS];
6870
protected int unsigned eth_drop[ETH_PORTS];
6971

72+
reg_model_port #(ETH_PORT_CHAN[0]) m_rx_mac_regmodel[ETH_PORTS];
73+
7074
// Constructor of environment.
7175
function new(string name, uvm_component parent);
7276
super.new(name, parent);
@@ -118,6 +122,10 @@ class model #(string ETH_CORE_ARCH, int unsigned ETH_PORTS, int unsigned ETH_POR
118122
end
119123
endfunction
120124

125+
function void set_rx_mac_regmodel(int unsigned port_index, reg_model_port #(ETH_PORT_CHAN[0]) regmodel);
126+
m_rx_mac_regmodel[port_index] = regmodel;
127+
endfunction
128+
121129
task automatic run_eth(int unsigned index);
122130
uvm_logic_vector::sequence_item#(6) hdr;
123131
uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) data;
@@ -173,17 +181,20 @@ class model #(string ETH_CORE_ARCH, int unsigned ETH_PORTS, int unsigned ETH_POR
173181
broadcast = dst_mac === '1;
174182
multicast = (dst_mac[48-8] === 1) && !broadcast;
175183

176-
//mac_hit_vld = 0;
177-
//mac_hit = 'X;
178-
mac_hit_vld = 0;
179-
mac_hit = 0;
184+
mac_hit_vld = check_mac_address(index, dst_mac, mac_hit);
180185

181186
timestamp_vld = 1'b0;
182187
timestamp = 'x;
183188

184189
drop_sync[index][channel].get(drop);
185190
drop |= error_frame | error_min_tu | error_max_tu | error_crc | error_mac;
186191

192+
case (get_mac_check_mode(index))
193+
2'h1: drop |= ~mac_hit_vld; // ONLY_VALID
194+
2'h2: drop |= ~(mac_hit_vld | broadcast); // VALID_AND_BCAST
195+
2'h3: drop |= ~(mac_hit_vld | multicast); // VALID_AND_MCAST
196+
endcase
197+
187198
msg = $sformatf("\n\thdr input time %s", hdr.time2string());
188199
msg = {msg, $sformatf("\n\tlength [%0d]" , length)};
189200
msg = {msg, $sformatf("\n\terror [0x%h]", error)};
@@ -282,4 +293,35 @@ class model #(string ETH_CORE_ARCH, int unsigned ETH_PORTS, int unsigned ETH_POR
282293
return !(|error_data);
283294
endfunction
284295

296+
function bit check_mac_address(int unsigned port_index, longint unsigned mac_address, output int unsigned mac_address_index);
297+
longint unsigned mac_addresses[$];
298+
int find_result[$];
299+
300+
get_mac_check_addresses(port_index, mac_addresses);
301+
find_result = mac_addresses.find_first_index with (item == mac_address);
302+
303+
if (find_result.size() > 0) begin
304+
mac_address_index = find_result.pop_front();
305+
return 1;
306+
end
307+
return 0;
308+
endfunction
309+
310+
function void get_mac_check_addresses(int unsigned port_index, output longint unsigned mac_addresses[$]);
311+
for (int unsigned i = 0; i < RX_MAC_COUNT; i++) begin
312+
bit valid;
313+
bit [48-1 : 0] address;
314+
315+
{ valid, address } = m_rx_mac_regmodel[port_index].channel[0].rx_mac.mac[i].get();
316+
317+
if (valid == 1'b1) begin
318+
mac_addresses.push_back(address);
319+
end
320+
end
321+
endfunction
322+
323+
function bit [2-1 : 0] get_mac_check_mode(int unsigned port_index);
324+
return m_rx_mac_regmodel[port_index].channel[0].rx_mac.mac_check.get();
325+
endfunction
326+
285327
endclass

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ package uvm_network_mod_env;
2525
`include "reg_sequence.sv"
2626
`include "sequence_eth.sv"
2727
`include "sequence_timestamp.sv"
28+
`include "sequence_mac_check_configuration.sv"
2829
`include "sequence.sv"
2930
endpackage
3031
`endif

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class reg_model_channel extends uvm_reg_block;
99
`uvm_object_param_utils(uvm_network_mod_env::reg_model_channel)
1010

11-
localparam RX_MAC_COUNT = 4;
11+
localparam int unsigned RX_MAC_COUNT = 16;
1212

1313
rand uvm_rx_mac_lite::regmodel#(RX_MAC_COUNT) rx_mac;
1414
rand uvm_tx_mac_lite::regmodel tx_mac;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class scoreboard #(ETH_CORE_ARCH, ETH_PORTS, int unsigned ETH_PORT_SPEED[ETH_POR
132132
end
133133
endfunction
134134

135+
function void set_model_rx_mac_regmodel(int unsigned port_index, reg_model_port #(ETH_PORT_CHAN[0]) regmodel);
136+
m_model.set_rx_mac_regmodel(port_index, regmodel);
137+
endfunction
138+
135139
function void report_phase(uvm_phase phase);
136140
string msg = "";
137141

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class virt_sequence_port#(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGION
99
`uvm_declare_p_sequencer(uvm_network_mod_env::sequencer_port#(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH));
1010

1111

12-
localparam RX_MAC_COUNT = 4;
12+
localparam int unsigned RX_MAC_COUNT = 16;
1313

1414
uvm_sequence#(uvm_reset::sequence_item) eth_rst;
1515
uvm_sequence#(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) usr_rx_data;
@@ -22,6 +22,8 @@ class virt_sequence_port#(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGION
2222

2323
protected uvm_logic_vector_array::config_sequence usr_rx_seq_cfg;
2424

25+
uvm_network_mod_env::sequence_mac_check_configuration #(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGIONS, REGION_SIZE, BLOCK_SIZE, ETH_PORT_CHAN, MI_DATA_WIDTH, MI_ADDR_WIDTH) m_sequence_mac_check_configuration;
26+
2527
rand int unsigned transactions_approx;
2628
constraint c_transactions {
2729
//transactions_approx inside {[30_000:40_000]};
@@ -42,6 +44,19 @@ class virt_sequence_port#(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGION
4244
this.usr_rx_seq_cfg = usr_rx_seq_cfg;
4345
endfunction
4446

47+
function void add_mac_check_addresses(uvm_packet_generators::config_sequence cfg);
48+
for (int unsigned i = 0; i < RX_MAC_COUNT; i++) begin
49+
bit valid;
50+
bit [48-1 : 0] address;
51+
52+
{ valid, address } = p_sequencer.regmodel.channel[0].rx_mac.mac[i].get();
53+
54+
if (valid == 1'b1) begin
55+
cfg.add_mac_address(address);
56+
end
57+
end
58+
endfunction
59+
4560
virtual task pre_body();
4661
int unsigned rst = 0;
4762
uvm_logic_vector_array::sequence_lib#(ITEM_WIDTH) lib_usr_rx_data;
@@ -85,6 +100,9 @@ class virt_sequence_port#(ETH_TX_HDR_WIDTH, ETH_RX_HDR_WIDTH, ITEM_WIDTH, REGION
85100
lib_usr_tx_hdr.max_random_count = 20;
86101
lib_usr_tx_hdr.min_random_count = 10;
87102

103+
// MAC Check configuration
104+
m_sequence_mac_check_configuration = uvm_network_mod_env::sequence_mac_check_configuration #(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::create("m_sequence_mac_check_configuration");
105+
88106
usr_rx_data = lib_usr_rx_data;
89107
usr_rx_meta = lib_usr_rx_meta;
90108
usr_tx_data = lib_usr_tx_data;

0 commit comments

Comments
 (0)