Skip to content

Commit

Permalink
Merge branch 'isa_uvm_refactorization' into 'devel'
Browse files Browse the repository at this point in the history
APP UVM: [BREAK] Change model_item to uvm_common::sequence_item

See merge request ndk/ndk-app-minimal!67
  • Loading branch information
jakubcabal committed Sep 3, 2024
2 parents 04cd474 + b05918b commit aa6dfce
Show file tree
Hide file tree
Showing 9 changed files with 714 additions and 305 deletions.
135 changes: 29 additions & 106 deletions app/uvm/env/model.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C
//LOCAL VARIABLES
localparam APP_RX_CHANNELS = DMA_RX_CHANNELS/(ETH_STREAMS/DMA_STREAMS);
protected uvm_channel_router::model#(ETH_CHANNELS, APP_RX_CHANNELS, 2, 1) eth_to_dma[ETH_STREAMS];
protected uvm_common::model_item#(uvm_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH)) dma_hdr_fifo[DMA_STREAMS][$];

function new(string name, uvm_component parent = null);
super.new(name, parent);
Expand Down Expand Up @@ -47,143 +46,67 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C
bit ret = 0;

ret |= super.used();

for (int unsigned it = 0; it < DMA_STREAMS; it++) begin
ret |= (dma_hdr_fifo[it].size() > 0);
end
endfunction

virtual function void reset();
super.reset();
for (int unsigned it = 0; it < ETH_STREAMS; it++) begin
eth_to_dma[it].reset();
end

for (int unsigned it = 0; it < DMA_STREAMS; it++) begin
dma_hdr_fifo[it].delete();
end
endfunction

task run_eth_mvb(int unsigned index);
logic [16-1:0] length;
logic [8-1:0] port;
logic [6-1:0] error;
logic [1-1:0] multicast;
logic [1-1:0] hitmac_vld;
logic [4-1:0] hitmac;
logic [1-1:0] timestamp_vld;
logic [64-1:0] timestamp;
uvm_common::model_item#(uvm_logic_vector::sequence_item#(ETH_RX_HDR_WIDTH)) item;
uvm_common::model_item#(uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU)) dma_hdr;
task run_eth(uvm_phase phase, int unsigned index);
uvm_app_core_top_agent::sequence_eth_item#(2**8, 16, ITEM_WIDTH) item;
uvm_app_core::packet #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU, ITEM_WIDTH) packet;

forever begin
eth_mvb_rx[index].get(item);
{timestamp, timestamp_vld, hitmac, hitmac_vld, multicast, error, port, length} = item.item.data;

dma_hdr = new();
dma_hdr.time_array_add(item.start);
dma_hdr.tag = item.tag;
dma_hdr.item = new();
dma_hdr.item.meta = '0;
if (DMA_STREAMS != ETH_STREAMS) begin
dma_hdr.item.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(port%ETH_CHANNELS);
end else begin
dma_hdr.item.channel = eth_to_dma[index].port_get(port%ETH_CHANNELS);
end
dma_hdr.item.packet_size = length;
dma_hdr.item.discard = 0;
//get item
eth_rx[index].get(item);

if (DMA_STREAMS == 1) begin
dma_mvb_tx[0].write(dma_hdr);
packet = uvm_app_core::packet #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU, ITEM_WIDTH)::type_id::create("packet", this);
packet.start = item.start;
packet.data = item.data;
packet.meta = '0;
if (DMA_STREAMS != ETH_STREAMS) begin
packet.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(item.channel%ETH_CHANNELS);
end else begin
dma_mvb_tx[index].write(dma_hdr);
packet.channel = eth_to_dma[index].port_get(item.channel%ETH_CHANNELS);
end
end
endtask

task run_eth_mfb(int unsigned index);
uvm_common::model_item#(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) packet;
//packet.packet_size = item.data.size();
packet.discard = 0;

forever begin
eth_mfb_rx[index].get(packet);
if (DMA_STREAMS == 1) begin
dma_mfb_tx[0].write(packet);
dma_tx[0].write(packet);
end else begin
dma_mfb_tx[index].write(packet);
dma_tx[index].write(packet);
end
end
endtask

task run_dma_mvb(int unsigned index);
logic [$clog2(DMA_PKT_MTU+1)-1:0] length;
logic [DMA_HDR_META_WIDTH-1:0] meta;
logic [$clog2(DMA_TX_CHANNELS)-1:0] channel;
task run_dma(uvm_phase phase, int unsigned index);
int unsigned eth_channel;
uvm_app_core_top_agent::sequence_dma_item#(DMA_RX_CHANNELS, $clog2(DMA_PKT_MTU+1), DMA_HDR_META_WIDTH, ITEM_WIDTH) item;

uvm_common::model_item#(uvm_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH)) header;
uvm_common::model_item#(uvm_app_core::packet_header #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1)) eth_hdr;
uvm_app_core::packet #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1, ITEM_WIDTH) packet;
//uvm_app_core::packet_header #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1) packet_hdr;
//uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) packet_data;

forever begin
dma_mvb_rx[index].get(header);

{channel, meta, length} = header.item.data;
eth_channel = ((index * DMA_TX_CHANNELS) + channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS));

//create DMA header
eth_hdr = new();
eth_hdr.tag = header.tag;
eth_hdr.time_array_add(header.start);
eth_hdr.item = new();
eth_hdr.item.packet_size = length;
eth_hdr.item.channel = eth_channel;
eth_hdr.item.discard = 1'b0;

dma_hdr_fifo[index].push_back(header);
eth_mvb_tx[eth_channel/ETH_CHANNELS].write(eth_hdr);
end
endtask

task run_dma_mfb(int unsigned index);
logic [$clog2(DMA_PKT_MTU+1)-1:0] length;
logic [DMA_HDR_META_WIDTH-1:0] meta;
logic [$clog2(DMA_TX_CHANNELS)-1:0] channel;
int unsigned eth_channel;
uvm_common::model_item#(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) packet;
uvm_common::model_item#(uvm_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH)) hdr;
dma_rx[index].get(item);

forever begin
dma_mfb_rx[index].get(packet);

wait(dma_hdr_fifo[index].size() != 0);
hdr = dma_hdr_fifo[index].pop_front();
{channel, meta, length} = hdr.item.data;
eth_channel = ((index * DMA_TX_CHANNELS) + channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS));
packet = uvm_app_core::packet #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1, ITEM_WIDTH)::type_id::create("packet", this);
packet.start = item.start;
eth_channel = ((index * DMA_TX_CHANNELS) + item.channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS));
packet.channel = eth_channel;
packet.discard = 1'b0;
packet.data = item.data;

if (length != packet.item.size()) begin
string msg;
eth_tx[eth_channel/ETH_CHANNELS].write(packet);

$sformat(msg, "\n\tDMA TO ETH[%0d] Header is desynchronize from packet\nHeader input time %0dns\n\t%s\nPacket input time %0dns\n\thdr length %0d\n\t%s", index, hdr.time_last()/1ns, hdr.item.convert2string(), packet.time_last()/1ns, length, packet.item.convert2string());
`uvm_fatal(this.get_full_name(), msg);
end

eth_mfb_tx[eth_channel/ETH_CHANNELS].write(packet);
end
endtask

task run_eth(uvm_phase phase, int unsigned index);
fork
run_eth_mfb(index);
run_eth_mvb(index);
join
endtask

task run_dma(uvm_phase phase, int unsigned index);
fork
run_dma_mfb(index);
run_dma_mvb(index);
join
endtask

function void report_phase(uvm_phase phase);
endfunction
endclass
1 change: 1 addition & 0 deletions app/uvm/signals.fdo
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ delete wave *
add_wave "-noupdate -color yellow -label CLK" "/testbench/APP_CLK"
add_wave "-noupdate -color yellow -label RESET" "/testbench/reset_app/RESET"

add_wave -noupdate -group "CONFIG" "/testbench/config_if/*"

for {set it 0} {$it < 4} {incr it} {

Expand Down
1 change: 1 addition & 0 deletions app/uvm/test_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ package test_pkg;
parameter int unsigned MFB_BLOCK_SIZE = 8;
parameter int unsigned MFB_ITEM_WIDTH = 8;
parameter int unsigned MEM_PORTS = 1;
parameter time MEM_CLK_PERIOD [MEM_PORTS-1:0] = '{MEM_PORTS{10ns}};
parameter int unsigned MEM_ADDR_WIDTH = 26;
parameter int unsigned MEM_BURST_WIDTH = 7;
parameter int unsigned MEM_DATA_WIDTH = 512;
Expand Down
88 changes: 62 additions & 26 deletions app/uvm/testbench.sv
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ module testbench;
test_pkg::REGIONS, test_pkg::MFB_REG_SIZE, test_pkg::MFB_BLOCK_SIZE, test_pkg::MFB_ITEM_WIDTH, test_pkg::MEM_PORTS, test_pkg::MEM_ADDR_WIDTH, test_pkg::MEM_BURST_WIDTH, test_pkg::MEM_DATA_WIDTH, test_pkg::MI_DATA_WIDTH, test_pkg::MI_ADDR_WIDTH)
test_full_speed;

typedef test::fifo#(test_pkg::ETH_STREAMS, test_pkg::ETH_CHANNELS, test_pkg::ETH_PKT_MTU, test_pkg::ETH_RX_HDR_WIDTH, test_pkg::ETH_TX_HDR_WIDTH, test_pkg::DMA_STREAMS, test_pkg::DMA_RX_CHANNELS, test_pkg::DMA_TX_CHANNELS, test_pkg::DMA_HDR_META_WIDTH, test_pkg::DMA_PKT_MTU,
test_pkg::REGIONS, test_pkg::MFB_REG_SIZE, test_pkg::MFB_BLOCK_SIZE, test_pkg::MFB_ITEM_WIDTH, test_pkg::MEM_PORTS, test_pkg::MEM_ADDR_WIDTH, test_pkg::MEM_BURST_WIDTH, test_pkg::MEM_DATA_WIDTH, test_pkg::MI_DATA_WIDTH, test_pkg::MI_ADDR_WIDTH)
test_fifo;


/////////////////////////
// DEFINE CLOCK
logic CLK_USER_X1 = 0;
Expand All @@ -35,9 +40,8 @@ module testbench;
logic DMA_CLK_X1;
logic DMA_CLK_X2;
logic APP_CLK;
logic MEM_CLK = '0;
logic [test_pkg::MEM_PORTS-1:0] clk_logic_mem;
//logic [test_pkg::MEM_PORTS-1:0] MEM_CLK = '0;
//logic MEM_CLK = '0;
logic [test_pkg::MEM_PORTS-1:0] MEM_CLK = '0;

/////////////////////////
// INTERFACESS
Expand All @@ -51,7 +55,6 @@ module testbench;
reset_if reset_dma_x1(DMA_CLK_X1);
reset_if reset_dma_x2(DMA_CLK_X2);
reset_if reset_app(APP_CLK);
reset_if reset_mem[test_pkg::MEM_PORTS](MEM_CLK);

// ETHERNET I/O INTERFACE
mvb_if #(test_pkg::REGIONS, test_pkg::ETH_RX_HDR_WIDTH) eth_rx_mvb[test_pkg::ETH_STREAMS](APP_CLK);
Expand All @@ -68,13 +71,16 @@ module testbench;
//CONFIGURE INTERFACE
mi_if#(test_pkg::MI_DATA_WIDTH, test_pkg::MI_ADDR_WIDTH) config_if(MI_CLK);

//TSU INTERFACE
mvb_if #(1, 64) m_tsu (APP_CLK);


/////////////////////////
// CLOCK GENERATION
always #(test_pkg::CLK_PERIOD/2) CLK_USER_X1 = ~CLK_USER_X1;
always #(test_pkg::CLK_PERIOD/4) CLK_USER_X2 = ~CLK_USER_X2;
always #(test_pkg::CLK_PERIOD/6) CLK_USER_X3 = ~CLK_USER_X3;
always #(test_pkg::CLK_PERIOD/8) CLK_USER_X4 = ~CLK_USER_X4;
//always #(test_pkg::CLK_MEM_PERIOD[mem_it]/2) MEM_CLK[mem_it] = ~MEM_CLK[mem_it];

/////////////////////////
// RESETS
Expand All @@ -93,15 +99,45 @@ module testbench;
logic [test_pkg::RESET_WIDTH-1:0] reset_logic_dma_x2;
logic [test_pkg::RESET_WIDTH-1:0] reset_logic_app;
logic [test_pkg::MEM_PORTS-1:0] reset_logic_mem;

logic [test_pkg::MEM_PORTS] mem_ready;
logic [test_pkg::MEM_PORTS] mem_read;
logic [test_pkg::MEM_PORTS] mem_write;
logic [test_pkg::MEM_PORTS*test_pkg::MEM_ADDR_WIDTH] mem_address;
logic [test_pkg::MEM_PORTS*test_pkg::MEM_BURST_WIDTH] mem_burstcount;
logic [test_pkg::MEM_PORTS*test_pkg::MEM_DATA_WIDTH ] mem_writedata;
logic [test_pkg::MEM_PORTS*test_pkg::MEM_DATA_WIDTH ] mem_readdata;
logic [test_pkg::MEM_PORTS] mem_readdatavalid;




assign reset_mi.RESET = reset_logic_mi[0];
assign reset_dma_x1.RESET = reset_logic_dma_x1[0];
assign reset_dma_x2.RESET = reset_logic_dma_x2[0];
assign reset_app.RESET = reset_logic_app[0];

for (genvar mem_it = 0; mem_it < test_pkg::MEM_PORTS; mem_it++) begin
assign reset_logic_mem[mem_it] = reset_mem[mem_it].RESET;
assign clk_logic_mem[mem_it] = MEM_CLK;
//always #(test_pkg::CLK_MEM_PERIOD[mem_it]/2) MEM_CLK[mem_it] = ~MEM_CLK[mem_it];
reset_if mem_reset(MEM_CLK[mem_it]);
avmm_if#(test_pkg::MEM_ADDR_WIDTH, test_pkg::MEM_DATA_WIDTH, test_pkg::MEM_BURST_WIDTH) mem (MEM_CLK[mem_it]);

assign reset_logic_mem[mem_it] = mem_reset.RESET;
assign mem_ready [mem_it] = mem.READY; // : in std_logic_vector(MEM_PORTS-1 downto 0);
assign mem.READ = mem_read [mem_it]; // : out std_logic_vector(MEM_PORTS-1 downto 0);
assign mem.WRITE = mem_write[mem_it]; // : out std_logic_vector(MEM_PORTS-1 downto 0);
assign mem.ADDRESS = mem_address [(mem_it+1)*test_pkg::MEM_ADDR_WIDTH-1 -: test_pkg::MEM_ADDR_WIDTH ]; // : out std_logic_vector(MEM_PORTS*MEM_ADDR_WIDTH-1 downto 0);
assign mem.BURSTCOUNT = mem_burstcount [(mem_it+1)*test_pkg::MEM_BURST_WIDTH-1 -: test_pkg::MEM_BURST_WIDTH]; // : out std_logic_vector(MEM_PORTS*MEM_BURST_WIDTH-1 downto 0);
assign mem.WRITEDATA = mem_writedata [(mem_it+1)*test_pkg::MEM_DATA_WIDTH -1 -: test_pkg::MEM_DATA_WIDTH ]; // : out std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
assign mem.READDATA = mem_readdata [(mem_it+1)*test_pkg::MEM_DATA_WIDTH -1 -: test_pkg::MEM_DATA_WIDTH ]; // : in std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
assign mem_readdatavalid[mem_it] = mem.READDATAVALID; // : in std_logic_vector(MEM_PORTS-1 downto 0);

always #(test_pkg::MEM_CLK_PERIOD[mem_it]/2) MEM_CLK[mem_it] = ~MEM_CLK[mem_it];

initial begin
//RESET
uvm_config_db#(virtual reset_if)::set(null, "", $sformatf("RESET_MEM_%0d", mem_it), mem_reset);
uvm_config_db#(virtual avmm_if#(test_pkg::MEM_ADDR_WIDTH, test_pkg::MEM_DATA_WIDTH, test_pkg::MEM_BURST_WIDTH))::set(null, "", $sformatf("MEM_%0d", mem_it), mem);
end
end

/////////////////////////
Expand Down Expand Up @@ -333,17 +369,22 @@ module testbench;
.DMA_TX_MFB_SRC_RDY (dma_rx_mfb_src_rdy), // : in std_logic_vector(DMA_STREAMS-1 downto 0);
.DMA_TX_MFB_DST_RDY (dma_rx_mfb_dst_rdy), // : out std_logic_vector(DMA_STREAMS-1 downto 0);

.MEM_CLK (clk_logic_mem), // : in std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_CLK (MEM_CLK), // : in std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_RST (reset_logic_mem), // : in std_logic_vector(MEM_PORTS-1 downto 0);

.MEM_AVMM_READY (), // : in std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_READ (), // : out std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_WRITE (), // : out std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_ADDRESS (), // : out std_logic_vector(MEM_PORTS*MEM_ADDR_WIDTH-1 downto 0);
.MEM_AVMM_BURSTCOUNT (), // : out std_logic_vector(MEM_PORTS*MEM_BURST_WIDTH-1 downto 0);
.MEM_AVMM_WRITEDATA (), // : out std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
.MEM_AVMM_READDATA (), // : in std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
.MEM_AVMM_READDATAVALID(), // : in std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_READY (mem_ready ), // : in std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_READ (mem_read ), // : out std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_WRITE (mem_write ), // : out std_logic_vector(MEM_PORTS-1 downto 0);
.MEM_AVMM_ADDRESS (mem_address ), // : out std_logic_vector(MEM_PORTS*MEM_ADDR_WIDTH-1 downto 0);
.MEM_AVMM_BURSTCOUNT (mem_burstcount ), // : out std_logic_vector(MEM_PORTS*MEM_BURST_WIDTH-1 downto 0);
.MEM_AVMM_WRITEDATA (mem_writedata ), // : out std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
.MEM_AVMM_READDATA (mem_readdata ), // : in std_logic_vector(MEM_PORTS*MEM_DATA_WIDTH-1 downto 0);
.MEM_AVMM_READDATAVALID(mem_readdatavalid), // : in std_logic_vector(MEM_PORTS-1 downto 0);

.TSU_CLK (APP_CLK), //: in std_logic
.TSU_RESET (1'b0), //: in std_logic;
.TSU_TS_NS (m_tsu.DATA[64-1 : 0]), //: in std_logic_vector(64-1 downto 0); -- Timestamp from TSU in nanoseconds format
.TSU_TS_VLD (m_tsu.SRC_RDY & m_tsu.VLD[0]), //: in std_logic;

.EMIF_RST_REQ (), // : out std_logic_vector(MEM_PORTS-1 downto 0);
.EMIF_RST_DONE (), // : in std_logic_vector(MEM_PORTS-1 downto 0);
Expand All @@ -360,7 +401,7 @@ module testbench;
.MI_DRD (config_if.DRD), // : out std_logic_vector(MI_DATA_WIDTH-1 downto 0);
.MI_DRDY (config_if.DRDY) // : out std_logic
);

assign m_tsu.SRC_RDY = 1'b1;

app_core_property #(
.ETH_STREAMS (test_pkg::ETH_STREAMS),
Expand Down Expand Up @@ -397,8 +438,6 @@ module testbench;
automatic virtual mfb_if #(test_pkg::REGIONS, test_pkg::MFB_REG_SIZE, test_pkg::MFB_BLOCK_SIZE, test_pkg::MFB_ITEM_WIDTH, 0) vir_dma_tx_mfb[test_pkg::DMA_STREAMS] = dma_tx_mfb;
automatic virtual mvb_if #(test_pkg::REGIONS, DMA_RX_MVB_WIDTH) vir_dma_rx_mvb[test_pkg::DMA_STREAMS] = dma_rx_mvb;
automatic virtual mfb_if #(test_pkg::REGIONS, test_pkg::MFB_REG_SIZE, test_pkg::MFB_BLOCK_SIZE, test_pkg::MFB_ITEM_WIDTH, 0) vir_dma_rx_mfb[test_pkg::DMA_STREAMS] = dma_rx_mfb;
//RESET
automatic virtual reset_if vir_reset_mem[test_pkg::MEM_PORTS] = reset_mem;


/////////////////////////////////////////////
Expand Down Expand Up @@ -431,16 +470,13 @@ module testbench;
uvm_config_db#(virtual reset_if)::set(null, "", "RESET_DMA_X1", reset_dma_x1);
uvm_config_db#(virtual reset_if)::set(null, "", "RESET_DMA_X2", reset_dma_x2);
uvm_config_db#(virtual reset_if)::set(null, "", "RESET_APP", reset_app);
for (int unsigned it = 0; it < test_pkg::MEM_PORTS; it++) begin
string it_num;
it_num.itoa(it);

uvm_config_db#(virtual reset_if)::set(null, "", {"RESET_MEM_", it_num}, vir_reset_mem[it]);
end

//CONFIGURE INF
uvm_config_db#(virtual mi_if#(test_pkg::MI_DATA_WIDTH, test_pkg::MI_ADDR_WIDTH))::set(null, "", "MI_INTERFACE", config_if);

//TSU
uvm_config_db#(virtual mvb_if #(1, 64))::set(null, "", "TSU_INTERFACE", m_tsu);

/////////////////////////////////////////////
// RUN TEST
m_root = uvm_root::get();
Expand Down
Loading

0 comments on commit aa6dfce

Please sign in to comment.