Skip to content

Commit

Permalink
Merge branch 'marushchenko-feat-uvm-network_module-cmac-add_verificat…
Browse files Browse the repository at this point in the history
…ion_support' into 'devel'

UVM NETWORK_MODULE CMAC [FEATURE]: add a support of the CMAC variant

See merge request ndk/ndk-fpga!94
  • Loading branch information
radek-isa committed Nov 7, 2024
2 parents 9251cc2 + c785cde commit d9a8476
Show file tree
Hide file tree
Showing 21 changed files with 1,477 additions and 127 deletions.
6 changes: 6 additions & 0 deletions core/comp/eth/network_mod/uvm/Modules.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ if {$ARCHGRP == "E_TILE"} {
lappend MOD "$ENTITY_BASE/tbench/f-tile/env/pkg.sv" \
"$ENTITY_BASE/tbench/f-tile/dut.sv" \
"$ENTITY_BASE/tbench/f-tile/testbench.sv"
} elseif {$ARCHGRP == "CMAC"} {
lappend COMPONENTS [ list "SV_LOGIC_VECTOR_ARRAY_LBUS" "$SV_UVM_BASE/logic_vector_array_lbus" "FULL"]
lappend MOD "$ENTITY_BASE/tbench/cmac/env/pkg.sv" \
"$ENTITY_BASE/tbench/cmac/dut.sv" \
"$ENTITY_BASE/tbench/cmac/property.sv" \
"$ENTITY_BASE/tbench/cmac/testbench.sv"
}
2 changes: 1 addition & 1 deletion core/comp/eth/network_mod/uvm/signals_sig.fdo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

set ETH_PORTS 2
set ETH_PORTS 4

add wave -divider "CLK"
add_wave "-noupdate -color yellow" /testbench/CLK_USR
Expand Down
4 changes: 4 additions & 0 deletions core/comp/eth/network_mod/uvm/tbench/base/env/env.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class env #(
return m_scoreboard.used();
endfunction

virtual function void eth_full_speed_set();
`uvm_fatal(this.get_full_name(), "\n\tIf you want to run full speed test you have to specified full speed sequece for ethernet");
endfunction

// Create base components of environment.
function void build_phase(uvm_phase phase);
uvm_reset::config_item cfg_rst;
Expand Down
180 changes: 180 additions & 0 deletions core/comp/eth/network_mod/uvm/tbench/cmac/dut.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// dut.sv: Xilinx CMAC DUT
// Copyright (C) 2024 CESNET z. s. p. o.
// Author(s): Yaroslav Marushchenko <[email protected]>

// SPDX-License-Identifier: BSD-3-Clause

module DUT #(
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],
int unsigned EHIP_PORT_TYPE [ETH_PORTS-1 : 0],
int unsigned ETH_PORT_RX_MTU[ETH_PORTS-1 : 0],
int unsigned ETH_PORT_TX_MTU[ETH_PORTS-1 : 0],

int unsigned LANES,

int unsigned QSFP_PORTS,
int unsigned QSFP_I2C_PORTS,
int unsigned QSFP_I2C_TRISTATE,

int unsigned ETH_TX_HDR_WIDTH,
int unsigned ETH_RX_HDR_WIDTH,

int unsigned REGIONS,
int unsigned REGION_SIZE,
int unsigned BLOCK_SIZE,
int unsigned ITEM_WIDTH,

int unsigned MI_DATA_WIDTH,
int unsigned MI_ADDR_WIDTH,

int unsigned MI_DATA_WIDTH_PHY,
int unsigned MI_ADDR_WIDTH_PHY,

int unsigned LANE_RX_POLARITY,
int unsigned LANE_TX_POLARITY,

int unsigned RESET_WIDTH,

string DEVICE,
string BOARD
)(
input wire logic CLK_ETH[ETH_PORTS],
input wire logic CLK_USR,
input wire logic CLK_MI,
input wire logic CLK_MI_PHY,
input wire logic CLK_MI_PMD,
input wire logic CLK_TSU,

reset_if.dut rst_usr,
reset_if.dut rst_eth[ETH_PORTS],
reset_if.dut rst_mi,
reset_if.dut rst_mi_phy,
reset_if.dut rst_mi_pmd,
reset_if.dut rst_tsu,

lbus_if.dut_tx eth_tx[ETH_PORTS],
lbus_if.dut_rx eth_rx[ETH_PORTS],

mfb_if.dut_rx usr_rx [ETH_PORTS],
mfb_if.dut_tx usr_tx_data[ETH_PORTS],
mvb_if.dut_tx usr_tx_hdr [ETH_PORTS],

mi_if.dut_slave mi,
mi_if.dut_slave mi_phy,
mi_if.dut_slave mi_pmd,

mvb_if.dut_rx tsu
);
DUT_BASE #(
.ETH_CORE_ARCH (ETH_CORE_ARCH ),
.ETH_PORTS (ETH_PORTS ),
.ETH_PORT_SPEED (ETH_PORT_SPEED ),
.ETH_PORT_CHAN (ETH_PORT_CHAN ),
.EHIP_PORT_TYPE (EHIP_PORT_TYPE ),
.ETH_PORT_RX_MTU (ETH_PORT_RX_MTU ),
.ETH_PORT_TX_MTU (ETH_PORT_TX_MTU ),
.LANES (LANES ),
.QSFP_PORTS (QSFP_PORTS ),
.QSFP_I2C_PORTS (QSFP_I2C_PORTS ),
.QSFP_I2C_TRISTATE(QSFP_I2C_TRISTATE),
.ETH_TX_HDR_WIDTH (ETH_TX_HDR_WIDTH ),
.ETH_RX_HDR_WIDTH (ETH_RX_HDR_WIDTH ),
.REGIONS (REGIONS ),
.REGION_SIZE (REGION_SIZE ),
.BLOCK_SIZE (BLOCK_SIZE ),
.ITEM_WIDTH (ITEM_WIDTH ),
.MI_DATA_WIDTH (MI_DATA_WIDTH ),
.MI_ADDR_WIDTH (MI_ADDR_WIDTH ),
.MI_DATA_WIDTH_PHY(MI_DATA_WIDTH_PHY),
.MI_ADDR_WIDTH_PHY(MI_ADDR_WIDTH_PHY),
.LANE_RX_POLARITY (LANE_RX_POLARITY ),
.LANE_TX_POLARITY (LANE_TX_POLARITY ),
.RESET_WIDTH (RESET_WIDTH ),
.DEVICE (DEVICE ),
.BOARD (BOARD )
) DUT_BASE_U (
.CLK_USR (CLK_USR ),
.CLK_MI (CLK_MI ),
.CLK_MI_PHY (CLK_MI_PHY),
.CLK_MI_PMD (CLK_MI_PMD),
.CLK_TSU (CLK_TSU ),

.rst_usr (rst_usr ),
.rst_eth (rst_eth ),
.rst_mi (rst_mi ),
.rst_mi_phy (rst_mi_phy),
.rst_mi_pmd (rst_mi_pmd),
.rst_tsu (rst_tsu ),

.usr_rx (usr_rx ),
.usr_tx_data (usr_tx_data),
.usr_tx_hdr (usr_tx_hdr ),

.mi (mi ),
.mi_phy (mi_phy),
.mi_pmd (mi_pmd),

.tsu (tsu)
);

generate;
for (genvar eth_it = 0; eth_it < ETH_PORTS; eth_it++) begin
localparam int unsigned ETH_PORT_CHAN_LOCAL = ETH_PORT_CHAN[eth_it];
initial assert(ETH_PORT_CHAN_LOCAL == 1);

wire logic [4*128-1 : 0] eth_rx_data;

// ------- //
// TX side //
// ------- //

for (genvar slice = 0; slice < 4; slice++) begin
initial begin
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
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];
end
end

initial begin
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;
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;
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;
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;
end

assign eth_tx[eth_it].RDY = 1'b1; // Always ready

// ------- //
// RX side //
// ------- //

assign eth_rx_data = {>>{DUT_BASE_U.VHDL_DUT_U.eth_core_g[eth_it].network_mod_core_i.cmac_tx_lbus_data}};
for (genvar segment = 0; segment < 4; segment++) begin
wire logic [128-1 : 0] segment_data;

assign segment_data = eth_rx_data[128*(segment+1)-1 -: 128];
assign eth_rx[eth_it].DATA[128*(segment+1)-1 -: 128] = {<<8{segment_data}}; // Byte reordering
end

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;
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;
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;
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;
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}};

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;

// ----- //
// Other //
// ----- //

// CLK connection
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];
end
endgenerate

endmodule
154 changes: 154 additions & 0 deletions core/comp/eth/network_mod/uvm/tbench/cmac/env/env.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// env.sv: Environment for the Xilinx CMAC device
// Copyright (C) 2024 CESNET z. s. p. o.
// Author(s): Yaroslav Marushchenko <[email protected]>

// SPDX-License-Identifier: BSD-3-Clause

class env #(
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],

int unsigned ETH_TX_HDR_WIDTH,
int unsigned ETH_RX_HDR_WIDTH,

int unsigned REGIONS,
int unsigned REGION_SIZE,
int unsigned BLOCK_SIZE,
int unsigned ITEM_WIDTH,

int unsigned MI_DATA_WIDTH,
int unsigned MI_ADDR_WIDTH
) extends uvm_network_mod_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
);
`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))

// BYTE ARRAY LBUS environments
protected uvm_logic_vector_array_lbus::env_tx m_eth_tx[ETH_PORTS];
protected uvm_logic_vector_array_lbus::env_rx m_eth_rx[ETH_PORTS];

tx_error_expander m_tx_error_expander[ETH_PORTS];

// Constructor
function new(string name = "env", uvm_component parent = null);
super.new(name, parent);
endfunction


virtual function void eth_full_speed_set();
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
uvm_logic_vector_array_lbus::sequence_library_tx::type_id::set_inst_override(
uvm_logic_vector_array_lbus::sequence_library_tx_fullspeed::get_type(),
$sformatf("m_eth_tx_%0d.*", it),
this
);

uvm_lbus::sequence_library_rx::type_id::set_inst_override(
uvm_lbus::sequence_library_rx_fullspeed::get_type(),
$sformatf("m_eth_rx_%0d.*", it),
this
);
end
endfunction

function void build_phase(uvm_phase phase);
// -------------------------------------- //
// Overriding the base components/objects //
// -------------------------------------- //

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(
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(),
"m_sequencer.*",
this
);

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(
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()
);
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(
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()
);
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(
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()
);
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(
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()
);

// Build of base environment
super.build_phase(phase);

// ------------------------- //
// Build of CMAC environment //
// ------------------------- //

for (int unsigned it = 0; it < ETH_PORTS; it++) begin
uvm_logic_vector_array_lbus::config_item cfg_eth_tx;
uvm_logic_vector_array_lbus::config_item cfg_eth_rx;

cfg_eth_tx = new();
cfg_eth_tx.active = UVM_ACTIVE;
cfg_eth_tx.interface_name = $sformatf("vif_eth_tx_%0d", it);
uvm_config_db #(uvm_logic_vector_array_lbus::config_item)::set(this, $sformatf("m_eth_tx_%0d", it), "m_config", cfg_eth_tx);
m_eth_tx[it] = uvm_logic_vector_array_lbus::env_tx::type_id::create($sformatf("m_eth_tx_%0d", it), this);

cfg_eth_rx = new();
cfg_eth_rx.active = UVM_ACTIVE;
cfg_eth_rx.interface_name = $sformatf("vif_eth_rx_%0d", it);
uvm_config_db #(uvm_logic_vector_array_lbus::config_item)::set(this, $sformatf("m_eth_rx_%0d", it), "m_config", cfg_eth_rx);
m_eth_rx[it] = uvm_logic_vector_array_lbus::env_rx::type_id::create($sformatf("m_eth_rx_%0d", it), this);

m_tx_error_expander[it] = tx_error_expander::type_id::create($sformatf("m_tx_error_expander_%0d", it), this);
end
endfunction

function void connect_phase(uvm_phase phase);
super.connect_phase(phase);

// Connection of resets
for (int unsigned it = 0; it < ETH_PORTS; it++) begin
m_eth_rst[it].sync_connect(m_eth_tx[it].reset_sync);
m_eth_rst[it].sync_connect(m_eth_rx[it].reset_sync);
end

for (int unsigned it = 0; it < ETH_PORTS; it++) begin
// TX packet
m_eth_tx[it].analysis_port_packet.connect(m_scoreboard.eth_rx_data[it]);
// TX error
m_eth_tx[it].analysis_port_error.connect(m_tx_error_expander[it].analysis_export);
m_tx_error_expander[it].analysis_port.connect(m_scoreboard.eth_rx_hdr[it]);

// RX packet
m_eth_rx[it].analysis_port_packet.connect(m_scoreboard.eth_tx_data[it]);
// RX error
m_eth_rx[it].analysis_port_error.connect(m_scoreboard.eth_tx_hdr[it]);
end

for (int unsigned it = 0; it < ETH_PORTS; it++) begin
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;
assert($cast(cast_sequencer_port, m_sequencer.port[it]))
else begin
`uvm_fatal(this.get_full_name(), $sformatf("\n\tCast failed: %s", m_sequencer.port[it].get_full_name()))
end

cast_sequencer_port.eth_tx_packet = m_eth_tx[it].m_sequencer.packet;
cast_sequencer_port.eth_tx_error = m_eth_tx[it].m_sequencer.error;
cast_sequencer_port.eth_rx = m_eth_rx[it].m_sequencer;
end
endfunction

endclass
22 changes: 22 additions & 0 deletions core/comp/eth/network_mod/uvm/tbench/cmac/env/pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// pkg.sv: Package for the Xilinx CMAC environment
// Copyright (C) 2024 CESNET z. s. p. o.
// Author(s): Yaroslav Marushchenko <[email protected]>

// SPDX-License-Identifier: BSD-3-Clause

`ifndef NETWORK_MOD_CMAC_ENV_SV
`define NETWORK_MOD_CMAC_ENV_SV

package uvm_network_mod_cmac_env;

`include "uvm_macros.svh"
import uvm_pkg::*;

`include "sequencer_port.sv"
`include "sequence.sv"
`include "tx_error_expander.sv"
`include "env.sv"

endpackage

`endif
Loading

0 comments on commit d9a8476

Please sign in to comment.