From 104b1db136695b09f760e572e0a577e362430d8e Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Thu, 15 Aug 2024 11:39:53 +0200 Subject: [PATCH 01/10] APP UVM: [MAITENANCE] add mi signals to wave --- app/uvm/signals.fdo | 1 + 1 file changed, 1 insertion(+) diff --git a/app/uvm/signals.fdo b/app/uvm/signals.fdo index 81d7b4e26..59e94299f 100644 --- a/app/uvm/signals.fdo +++ b/app/uvm/signals.fdo @@ -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} { From 4c0ea8dced69049019b728ef8f48cb04189a5975 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Thu, 15 Aug 2024 11:45:16 +0200 Subject: [PATCH 02/10] APP UVM: [BREAK] Change model_item to uvm_common::sequence_item This commit requires update OFM and CORE submodules --- app/uvm/env/model.sv | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/app/uvm/env/model.sv b/app/uvm/env/model.sv index c5a40c76a..32ab7dff4 100644 --- a/app/uvm/env/model.sv +++ b/app/uvm/env/model.sv @@ -14,7 +14,7 @@ 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][$]; + protected 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); @@ -73,25 +73,24 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C 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; + uvm_logic_vector::sequence_item#(ETH_RX_HDR_WIDTH) item; + uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU) dma_hdr; forever begin eth_mvb_rx[index].get(item); - {timestamp, timestamp_vld, hitmac, hitmac_vld, multicast, error, port, length} = item.item.data; + {timestamp, timestamp_vld, hitmac, hitmac_vld, multicast, error, port, length} = 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; + dma_hdr.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); + dma_hdr.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); + dma_hdr.channel = eth_to_dma[index].port_get(port%ETH_CHANNELS); end - dma_hdr.item.packet_size = length; - dma_hdr.item.discard = 0; + dma_hdr.packet_size = length; + dma_hdr.discard = 0; if (DMA_STREAMS == 1) begin dma_mvb_tx[0].write(dma_hdr); @@ -102,7 +101,7 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C endtask task run_eth_mfb(int unsigned index); - uvm_common::model_item#(uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)) packet; + uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) packet; forever begin eth_mfb_rx[index].get(packet); @@ -120,23 +119,22 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C logic [$clog2(DMA_TX_CHANNELS)-1:0] channel; int unsigned eth_channel; - 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_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH) header; + uvm_app_core::packet_header #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1) eth_hdr; forever begin dma_mvb_rx[index].get(header); - {channel, meta, length} = header.item.data; + {channel, meta, length} = header.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; + eth_hdr.packet_size = length; + eth_hdr.channel = eth_channel; + eth_hdr.discard = 1'b0; dma_hdr_fifo[index].push_back(header); eth_mvb_tx[eth_channel/ETH_CHANNELS].write(eth_hdr); @@ -148,21 +146,21 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C 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; + uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) packet; + uvm_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH) hdr; 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; + {channel, meta, length} = hdr.data; eth_channel = ((index * DMA_TX_CHANNELS) + channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS)); - if (length != packet.item.size()) begin + if (length != packet.size()) begin string msg; - $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()); + $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.convert2string(), packet.time_last()/1ns, length, packet.convert2string()); `uvm_fatal(this.get_full_name(), msg); end From 5c7308b1c05fcd7e398506f457e0140a6494083d Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Thu, 15 Aug 2024 11:48:30 +0200 Subject: [PATCH 03/10] APP UVM: [MAITENANCE] Start using virtual sequence instead run all sequences --- app/uvm/tests/base.sv | 140 +++++------------------------- app/uvm/tests/full_speed.sv | 166 ++++++++++++++++++++++++------------ 2 files changed, 133 insertions(+), 173 deletions(-) diff --git a/app/uvm/tests/base.sv b/app/uvm/tests/base.sv index 801f0374f..ba41adddb 100644 --- a/app/uvm/tests/base.sv +++ b/app/uvm/tests/base.sv @@ -26,8 +26,6 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH) m_env; logic event_reset; - logic event_eth_rx_end[ETH_STREAMS]; - logic event_dma_rx_end[DMA_STREAMS]; function new (string name, uvm_component parent = null); super.new(name, parent); @@ -50,78 +48,6 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR m_env.delay_max_set(1ms); endfunction - virtual task eth_tx_sequence(uvm_phase phase, int unsigned index); - uvm_mfb::sequence_lib_tx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH) mfb_seq; - - mfb_seq = uvm_mfb::sequence_lib_tx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH)::type_id::create("mfb_eth_tx_seq", this); - mfb_seq.init_sequence(); - mfb_seq.min_random_count = 50; - mfb_seq.max_random_count = 150; - - //RUN ETH - forever begin - mfb_seq.randomize(); - mfb_seq.start(m_env.m_eth_mfb_tx[index].m_sequencer); - end - endtask - - virtual task eth_rx_sequence(uvm_phase phase, int unsigned index); - uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH) packet_seq; - - packet_seq = uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH)::type_id::create("mfb_rx_seq", this); - - for (int unsigned it = 0; it < 10; it++) begin - assert(packet_seq.randomize()); - packet_seq.start(m_env.m_eth_rx[index].m_sequencer); - end - - - event_eth_rx_end[index] = 1'b0; - endtask - - virtual task dma_tx_sequence(uvm_phase phase, int unsigned index); - uvm_mfb::sequence_lib_tx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0) mfb_seq; - uvm_mvb::sequence_lib_tx#(REGIONS, DMA_TX_MVB_WIDTH) mvb_seq; - - mfb_seq = uvm_mfb::sequence_lib_tx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::create("mfb_dma_tx_seq", this); - mfb_seq.min_random_count = 50; - mfb_seq.max_random_count = 150; - mfb_seq.init_sequence(); - - mvb_seq = uvm_mvb::sequence_lib_tx#(REGIONS, DMA_TX_MVB_WIDTH)::type_id::create("mvb_dma_tx_seq", this); - mvb_seq.min_random_count = 50; - mvb_seq.max_random_count = 150; - mvb_seq.init_sequence(); - - //RUN ETH - fork - forever begin - //mvb_seq.set_starting_phase(phase); - void'(mvb_seq.randomize()); - mvb_seq.start(m_env.m_dma_mvb_tx[index].m_sequencer); - end - forever begin - //mfb_seq.set_starting_phase(phase); - void'(mfb_seq.randomize()); - mfb_seq.start(m_env.m_dma_mfb_tx[index].m_sequencer); - end - join_none; - endtask - - virtual task dma_rx_sequence(uvm_phase phase, int unsigned index); - uvm_app_core_top_agent::sequence_base#(sequence_item_dma_rx) packet_seq; - - packet_seq = uvm_app_core_top_agent::sequence_base#(sequence_item_dma_rx)::type_id::create("mfb_rx_seq", this); - - for (int unsigned it = 0; it < 10; it++) begin - assert(packet_seq.randomize()); - packet_seq.start(m_env.m_dma_rx[index].m_sequencer); - end - - //END sequence - event_dma_rx_end[index] = 1'b0; - endtask - virtual task run_reset(uvm_phase phase); uvm_reset::sequence_reset reset; uvm_reset::sequence_run run; @@ -159,24 +85,13 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR endtask virtual task run_phase(uvm_phase phase); + uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; + uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; time end_time; + main_seq = uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); phase.raise_objection(this); - //// RUN TX - for(int unsigned it = 0; it < ETH_STREAMS; it++) begin - fork - automatic int index = it; - eth_tx_sequence(phase, index); - join_none; - end - - //// RUN TX - for(int unsigned it = 0; it < DMA_STREAMS; it++) begin - fork - automatic int index = it; - dma_tx_sequence(phase, index); - join_none; - end // RUN RESET fork @@ -184,47 +99,32 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR join_none; ////configure egent + wait(event_reset == 1'b0); for (int unsigned it = 0; it < 3; it++) begin - event_eth_rx_end = '{ETH_STREAMS {1'b1}}; - event_dma_rx_end = '{DMA_STREAMS {1'b1}}; - //RUN RIVER SEQUENCE ONLY IF RESET IS NOT SET - wait(event_reset == 1'b0); - #(2000ns) dirver_sequence(); - #(200ns) - - //// RUN ETH - for(int unsigned it = 0; it < ETH_STREAMS; it++) begin - fork - automatic int index = it; - eth_rx_sequence(phase, index); - join_none; - end + #(200ns); - //// RUN DMA - for(int unsigned it = 0; it < DMA_STREAMS; it++) begin - fork - automatic int index = it; - dma_rx_sequence(phase, index); - join_none; + for (int unsigned it = 0; it < 5; it++) begin + assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + main_seq.start(m_env.m_sequencer); end - //////// - // wait for RX transactions - for (int unsigned it = 0; it < DMA_STREAMS; it++) begin - wait(event_dma_rx_end[it] == 1'b0); - end - for (int unsigned it = 0; it < ETH_STREAMS; it++) begin - wait(event_eth_rx_end[it] == 1'b0); + assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + end_time = $time() + 200us; + + fork + stop_seq.start(m_env.m_sequencer); + join_none; + + while (end_time > $time() && m_env.m_scoreboard.used() != 0) begin + #(500ns); end + stop_seq.done_set(); end - end_time = $time() + 20us; - while (end_time > $time() && m_env.m_scoreboard.used() != 0) begin - #(500ns); - end + phase.drop_objection(this); endtask diff --git a/app/uvm/tests/full_speed.sv b/app/uvm/tests/full_speed.sv index df871b921..18195716d 100644 --- a/app/uvm/tests/full_speed.sv +++ b/app/uvm/tests/full_speed.sv @@ -8,6 +8,75 @@ * SPDX-License-Identifier: BSD-3-Clause */ +class sequence_speed#( + int unsigned DMA_TX_CHANNELS, + int unsigned DMA_RX_CHANNELS, + int unsigned DMA_PKT_MTU, + int unsigned DMA_HDR_META_WIDTH, + int unsigned DMA_STREAMS, + int unsigned ETH_TX_HDR_WIDTH, + int unsigned MFB_ITEM_WIDTH, + int unsigned ETH_STREAMS, + int unsigned REGIONS, + int unsigned MFB_REG_SIZE, + int unsigned MFB_BLOCK_SIZE +) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); + `uvm_object_param_utils(test::sequence_speed#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + + // Constructor - creates new instance of this class + function new(string name = "sequence"); + super.new(name); + endfunction + + + virtual task eth_tx_sequence(int unsigned index); + uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH) mfb_seq; + + mfb_seq = uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH)::type_id::create("mfb_eth_tx_seq", p_sequencer.m_eth_tx[index]); + mfb_seq.init_sequence(); + mfb_seq.min_random_count = 10; + mfb_seq.max_random_count = 20; + + //RUN ETH + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_eth_tx[index], "", "state", tx_status); + while (!tx_status.stopped()) begin + mfb_seq.randomize(); + mfb_seq.start(p_sequencer.m_eth_tx[index]); + end + endtask + + virtual task dma_tx_sequence(int unsigned index); + uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0) mfb_seq; + uvm_mvb::sequence_lib_tx_speed#(REGIONS, DMA_TX_MVB_WIDTH) mvb_seq; + + mfb_seq = uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::create("mfb_dma_tx_seq", p_sequencer.m_dma_mfb_tx[index]); + mfb_seq.init_sequence(); + mfb_seq.min_random_count = 10; + mfb_seq.max_random_count = 20; + + mvb_seq = uvm_mvb::sequence_lib_tx_speed#(REGIONS, DMA_TX_MVB_WIDTH)::type_id::create("mvb_dma_tx_seq", p_sequencer.m_dma_mvb_tx[index]); + mvb_seq.init_sequence(); + mvb_seq.min_random_count = 10; + mvb_seq.max_random_count = 20; + + //RUN ETH + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_dma_mvb_tx[index], "", "state", tx_status); + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_dma_mfb_tx[index], "", "state", tx_status); + fork + while (!tx_status.stopped()) begin + //mfb_seq.set_starting_phase(phase); + void'(mfb_seq.randomize()); + mfb_seq.start(p_sequencer.m_dma_mfb_tx[index]); + end + while (!tx_status.stopped()) begin + //mvb_seq.set_starting_phase(phase); + void'(mvb_seq.randomize()); + mvb_seq.start(p_sequencer.m_dma_mvb_tx[index]); + end + join_none; + endtask +endclass + class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR_WIDTH, DMA_STREAMS, DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_HDR_META_WIDTH, DMA_PKT_MTU, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH) extends @@ -18,6 +87,17 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH), "test::full_speed") type_id; + function new (string name, uvm_component parent = null); + super.new(name, parent); + endfunction + + static function type_id get_type(); + return type_id::get(); + endfunction + + function string get_type_name(); + return get_type().get_type_name(); + endfunction function void build_phase(uvm_phase phase); for (int unsigned it = 0; it < ETH_STREAMS; it++) begin @@ -52,68 +132,48 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ m_env.delay_max_set(1ms); endfunction - static function type_id get_type(); - return type_id::get(); - endfunction - - function string get_type_name(); - return get_type().get_type_name(); - endfunction - - function new (string name, uvm_component parent = null); - super.new(name, parent); - endfunction + virtual task run_phase(uvm_phase phase); + test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; + uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; + time end_time; - virtual task eth_tx_sequence(uvm_phase phase, int unsigned index); - uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH) mfb_seq; + main_seq = test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); + phase.raise_objection(this); - mfb_seq = uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH)::type_id::create("mfb_eth_tx_seq", this); - mfb_seq.init_sequence(); - mfb_seq.min_random_count = 10; - mfb_seq.max_random_count = 20; + // RUN RESET + fork + run_reset(phase); + join_none; - //RUN ETH - forever begin - //mfb_seq.set_starting_phase(phase); - mfb_seq.randomize(); - mfb_seq.start(m_env.m_eth_mfb_tx[index].m_sequencer); - end - endtask + ////configure egent + wait(event_reset == 1'b0); + for (int unsigned it = 0; it < 3; it++) begin - virtual task eth_rx_sequence(uvm_phase phase, int unsigned index); - super.eth_rx_sequence(phase, index); - endtask + //RUN RIVER SEQUENCE ONLY IF RESET IS NOT SET + dirver_sequence(); + #(200ns); - virtual task dma_tx_sequence(uvm_phase phase, int unsigned index); - uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0) mfb_seq; - uvm_mvb::sequence_lib_tx_speed#(REGIONS, DMA_TX_MVB_WIDTH) mvb_seq; + end_time = $time() + 400us; + while (end_time > $time()) begin + //for (int unsigned it = 0; it < 10; it++) begin + assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + main_seq.start(m_env.m_sequencer); + end - mfb_seq = uvm_mfb::sequence_lib_tx_speed#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::create("mfb_dma_tx_seq", this); - mfb_seq.init_sequence(); - mfb_seq.min_random_count = 10; - mfb_seq.max_random_count = 20; + assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + end_time = $time() + 20us; - mvb_seq = uvm_mvb::sequence_lib_tx_speed#(REGIONS, DMA_TX_MVB_WIDTH)::type_id::create("mvb_dma_tx_seq", this); - mvb_seq.init_sequence(); - mvb_seq.min_random_count = 10; - mvb_seq.max_random_count = 20; + fork + stop_seq.start(m_env.m_sequencer); + join_none; - //RUN ETH - fork - forever begin - //mvb_seq.set_starting_phase(phase); - void'(mvb_seq.randomize()); - mvb_seq.start(m_env.m_dma_mvb_tx[index].m_sequencer); + while (end_time > $time() && m_env.m_scoreboard.used() != 0) begin + #(500ns); end - forever begin - //mfb_seq.set_starting_phase(phase); - void'(mfb_seq.randomize()); - mfb_seq.start(m_env.m_dma_mfb_tx[index].m_sequencer); - end - join_none; - endtask + stop_seq.done_set(); + end - virtual task dma_rx_sequence(uvm_phase phase, int unsigned index); - super.dma_rx_sequence(phase, index); + phase.drop_objection(this); endtask endclass From bc90dffd44d0d7b75802c382267f68857dfd5757 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Fri, 16 Aug 2024 08:59:00 +0200 Subject: [PATCH 04/10] CORE UVM: [MAITENANCE] Change interface from mfb and mvb to packet --- app/uvm/env/model.sv | 178 +++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 100 deletions(-) diff --git a/app/uvm/env/model.sv b/app/uvm/env/model.sv index 32ab7dff4..187c9eec8 100644 --- a/app/uvm/env/model.sv +++ b/app/uvm/env/model.sv @@ -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_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); @@ -47,10 +46,6 @@ 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(); @@ -58,129 +53,112 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C 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_logic_vector::sequence_item#(ETH_RX_HDR_WIDTH) 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; + //uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) packet_mfb; + //uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU) packet_hdr; forever begin - eth_mvb_rx[index].get(item); - {timestamp, timestamp_vld, hitmac, hitmac_vld, multicast, error, port, length} = item.data; - - dma_hdr = new(); - dma_hdr.time_array_add(item.start); - dma_hdr.tag = item.tag; - dma_hdr.meta = '0; + + //get item + eth_rx[index].get(item); + + 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 - dma_hdr.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(port%ETH_CHANNELS); + packet.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); end else begin - dma_hdr.channel = eth_to_dma[index].port_get(port%ETH_CHANNELS); + packet.channel = eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); end - dma_hdr.packet_size = length; - dma_hdr.discard = 0; - - if (DMA_STREAMS == 1) begin - dma_mvb_tx[0].write(dma_hdr); - end else begin - dma_mvb_tx[index].write(dma_hdr); - end - end - endtask - - task run_eth_mfb(int unsigned index); - 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 + //packet_mfb = uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)::type_id::create("packet_mfb", this); + //packet_mfb.start = item.start; + //packet_hdr = uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU)::type_id::create("packet_hdr", this); + //packet_hdr.start = item.start; + + //packet_mfb.data = item.data; + //packet_hdr.meta = '0; + //if (DMA_STREAMS != ETH_STREAMS) begin + // packet_hdr.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); + //end else begin + // packet_hdr.channel = eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); + //end + //packet_hdr.packet_size = item.data.size(); + //packet_hdr.discard = 0; + + //if (DMA_STREAMS == 1) begin + // dma_mvb_tx[0].write(packet_hdr); + // dma_mfb_tx[0].write(packet_mfb); + //end else begin + // dma_mvb_tx[index].write(packet_hdr); + // dma_mfb_tx[index].write(packet_mfb); + //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_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH) header; - 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.data; - eth_channel = ((index * DMA_TX_CHANNELS) + channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS)); + dma_rx[index].get(item); - //create DMA header - eth_hdr = new(); - eth_hdr.tag = header.tag; - eth_hdr.time_array_add(header.start); - eth_hdr.packet_size = length; - eth_hdr.channel = eth_channel; - eth_hdr.discard = 1'b0; + 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; - dma_hdr_fifo[index].push_back(header); - eth_mvb_tx[eth_channel/ETH_CHANNELS].write(eth_hdr); - end - endtask + eth_tx[eth_channel/ETH_CHANNELS].write(packet); - 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_logic_vector_array::sequence_item#(ITEM_WIDTH) packet; - uvm_logic_vector::sequence_item#(DMA_RX_MVB_WIDTH) hdr; - - forever begin - dma_mfb_rx[index].get(packet); + //packet_hdr = uvm_app_core::packet_header #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1)::type_id::create("packet_hdr", this); + //packet_hdr.start = item.start; + //packet_data = uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)::type_id::create("packet_data", this); + //packet_data.start = item.start; - wait(dma_hdr_fifo[index].size() != 0); - hdr = dma_hdr_fifo[index].pop_front(); - {channel, meta, length} = hdr.data; - eth_channel = ((index * DMA_TX_CHANNELS) + channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS)); + //eth_channel = ((index * DMA_TX_CHANNELS) + item.channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS)); + //packet_hdr.packet_size = item.data.size(); + //packet_hdr.channel = eth_channel; + //packet_hdr.discard = 1'b0; - if (length != packet.size()) begin - string msg; + //packet_data.data = item.data; - $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.convert2string(), packet.time_last()/1ns, length, packet.convert2string()); - `uvm_fatal(this.get_full_name(), msg); - end - - eth_mfb_tx[eth_channel/ETH_CHANNELS].write(packet); + //eth_mvb_tx[eth_channel/ETH_CHANNELS].write(packet_hdr); + //eth_mfb_tx[eth_channel/ETH_CHANNELS].write(packet_data); 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 + //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 From 76aec04c13282f8a7eca5cb1100bcf3aa428a554 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Wed, 28 Aug 2024 10:25:02 +0200 Subject: [PATCH 05/10] APP UVM: [MAITENANCE] Change input to model from MFB+MVB to packet. Unite MFB+MVB --- app/uvm/env/model.sv | 53 -------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/app/uvm/env/model.sv b/app/uvm/env/model.sv index 187c9eec8..14f017892 100644 --- a/app/uvm/env/model.sv +++ b/app/uvm/env/model.sv @@ -58,11 +58,8 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C 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; - //uvm_logic_vector_array::sequence_item#(ITEM_WIDTH) packet_mfb; - //uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU) packet_hdr; forever begin - //get item eth_rx[index].get(item); @@ -83,28 +80,6 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C end else begin dma_tx[index].write(packet); end - //packet_mfb = uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)::type_id::create("packet_mfb", this); - //packet_mfb.start = item.start; - //packet_hdr = uvm_app_core::packet_header #(DMA_HDR_META_WIDTH, DMA_RX_CHANNELS, DMA_PKT_MTU)::type_id::create("packet_hdr", this); - //packet_hdr.start = item.start; - - //packet_mfb.data = item.data; - //packet_hdr.meta = '0; - //if (DMA_STREAMS != ETH_STREAMS) begin - // packet_hdr.channel = (index*APP_RX_CHANNELS) + eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); - //end else begin - // packet_hdr.channel = eth_to_dma[index].port_get(item.channel%ETH_CHANNELS); - //end - //packet_hdr.packet_size = item.data.size(); - //packet_hdr.discard = 0; - - //if (DMA_STREAMS == 1) begin - // dma_mvb_tx[0].write(packet_hdr); - // dma_mfb_tx[0].write(packet_mfb); - //end else begin - // dma_mvb_tx[index].write(packet_hdr); - // dma_mfb_tx[index].write(packet_mfb); - //end end endtask @@ -129,37 +104,9 @@ class model #(ETH_STREAMS, ETH_CHANNELS, ETH_RX_HDR_WIDTH, DMA_STREAMS, DMA_RX_C eth_tx[eth_channel/ETH_CHANNELS].write(packet); - //packet_hdr = uvm_app_core::packet_header #(0, 2**ETH_TX_CHANNEL_WIDTH, 2**ETH_TX_LENGTH_WIDTH-1)::type_id::create("packet_hdr", this); - //packet_hdr.start = item.start; - //packet_data = uvm_logic_vector_array::sequence_item#(ITEM_WIDTH)::type_id::create("packet_data", this); - //packet_data.start = item.start; - - //eth_channel = ((index * DMA_TX_CHANNELS) + item.channel)/((DMA_STREAMS*DMA_TX_CHANNELS)/(ETH_STREAMS*ETH_CHANNELS)); - //packet_hdr.packet_size = item.data.size(); - //packet_hdr.channel = eth_channel; - //packet_hdr.discard = 1'b0; - - //packet_data.data = item.data; - - //eth_mvb_tx[eth_channel/ETH_CHANNELS].write(packet_hdr); - //eth_mfb_tx[eth_channel/ETH_CHANNELS].write(packet_data); 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 From 96f4472d315145ce70323d968fdfa1ea1bcf50cd Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Wed, 28 Aug 2024 10:35:26 +0200 Subject: [PATCH 06/10] APP UVM: [MAITENANCE] Write warning when reconfiguration start and some data is in DUT --- app/uvm/tests/base.sv | 9 +- app/uvm/tests/fifo.sv | 391 ++++++++++++++++++++++++++++++++++++ app/uvm/tests/full_speed.sv | 12 +- 3 files changed, 406 insertions(+), 6 deletions(-) create mode 100644 app/uvm/tests/fifo.sv diff --git a/app/uvm/tests/base.sv b/app/uvm/tests/base.sv index ba41adddb..437fcf490 100644 --- a/app/uvm/tests/base.sv +++ b/app/uvm/tests/base.sv @@ -112,19 +112,22 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR end assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); - end_time = $time() + 200us; fork stop_seq.start(m_env.m_sequencer); join_none; - while (end_time > $time() && m_env.m_scoreboard.used() != 0) begin + end_time = $time() + 400us; + while (end_time > $time() && m_env.used() != 0) begin #(500ns); end + if (m_env.used() != 0) begin + `uvm_warning(this.get_full_name(), $sformatf("\n\tUSED(%0d) sould be zero.\n\tDuring reconfiguration, There is some data in design", m_env.used())); + end + stop_seq.done_set(); end - phase.drop_objection(this); endtask diff --git a/app/uvm/tests/fifo.sv b/app/uvm/tests/fifo.sv new file mode 100644 index 000000000..726013d42 --- /dev/null +++ b/app/uvm/tests/fifo.sv @@ -0,0 +1,391 @@ +/* + * file : test.sv + * Copyright (C) 2021 CESNET z. s. p. o. + * description: base test + * date : 2021 + * author : Radek Iša + * + * SPDX-License-Identifier: BSD-3-Clause +*/ + + +class sequence_mfb_full_speed_rx #( + int unsigned REGIONS, + int unsigned REGION_SIZE, + int unsigned BLOCK_SIZE, + int unsigned ITEM_WIDTH, + int unsigned META_WIDTH +) extends uvm_logic_vector_array_mfb::sequence_full_speed_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH); + `uvm_object_param_utils(test::sequence_mfb_full_speed_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)) + + function new(string name = "test::sequence_mfb_full_speed_rx"); + super.new(name); + hl_transactions_min = 1000; + hl_transactions_max = 20000; + endfunction +endclass + + +class sequence_mfb_stop_rx #( + int unsigned REGIONS, + int unsigned REGION_SIZE, + int unsigned BLOCK_SIZE, + int unsigned ITEM_WIDTH, + int unsigned META_WIDTH +) extends uvm_logic_vector_array_mfb::sequence_stop_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH); + `uvm_object_param_utils(test::sequence_mfb_stop_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)) + + function new(string name = "test::sequence_mfb_stop_rx"); + super.new(name); + hl_transactions_min = 1000; + hl_transactions_max = 20000; + endfunction +endclass + + +class sequence_lib__mfb_rx_fifo #( + int unsigned REGIONS, + int unsigned REGION_SIZE, + int unsigned BLOCK_SIZE, + int unsigned ITEM_WIDTH, + int unsigned META_WIDTH +) extends uvm_logic_vector_array_mfb::sequence_lib_rx#(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH); + `uvm_object_param_utils( test::sequence_lib__mfb_rx_fifo#(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)) + `uvm_sequence_library_utils(test::sequence_lib__mfb_rx_fifo#(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)) + + function new(string name = "test::sequence_lib__mfb_rx_fifo"); + super.new(name); + init_sequence_library(); + endfunction + + // subclass can redefine and change run sequences + // can be useful in specific tests + virtual function void init_sequence(uvm_logic_vector_array_mfb::config_sequence param_cfg = null); + uvm_common::sequence_library::init_sequence(param_cfg); + this.add_sequence(test::sequence_mfb_full_speed_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)::get_type()); + this.add_sequence(test::sequence_mfb_stop_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)::get_type()); + endfunction +endclass + +class sequence_mvb_full_speed_rx #( + int unsigned ITEMS, + int unsigned ITEM_WIDTH +) extends uvm_logic_vector_mvb::sequence_full_speed_rx #(ITEMS, ITEM_WIDTH); + `uvm_object_param_utils(test::sequence_mvb_full_speed_rx #(ITEMS, ITEM_WIDTH)) + + function new(string name = "test::sequence_mvb_full_speed_rx"); + super.new(name); + hl_transactions_min = 1000; + hl_transactions_max = 20000; + endfunction +endclass + + +class sequence_mvb_stop_rx #( + int unsigned ITEMS, + int unsigned ITEM_WIDTH +) extends uvm_logic_vector_mvb::sequence_stop_rx #(ITEMS, ITEM_WIDTH); + `uvm_object_param_utils(test::sequence_mvb_stop_rx #(ITEMS, ITEM_WIDTH)) + + function new(string name = "test::sequence_mvb_stop_rx"); + super.new(name); + hl_transactions_min = 1000; + hl_transactions_max = 20000; + endfunction +endclass + + +class sequence_lib__mvb_rx_fifo #( + int unsigned ITEMS, + int unsigned ITEM_WIDTH +) extends uvm_logic_vector_mvb::sequence_lib_rx #(ITEMS, ITEM_WIDTH); + `uvm_object_param_utils( test::sequence_lib__mvb_rx_fifo#(ITEMS, ITEM_WIDTH)) + `uvm_sequence_library_utils(test::sequence_lib__mvb_rx_fifo#(ITEMS, ITEM_WIDTH)) + + function new(string name = "test::sequence_lib__mvb_rx_fifo"); + super.new(name); + init_sequence_library(); + endfunction + + // subclass can redefine and change run sequences + // can be useful in specific tests + virtual function void init_sequence(uvm_logic_vector_mvb::config_sequence param_cfg = null); + uvm_common::sequence_library::init_sequence(param_cfg); + this.add_sequence(test::sequence_mvb_full_speed_rx #(ITEMS, ITEM_WIDTH)::get_type()); + this.add_sequence(test::sequence_mvb_stop_rx #(ITEMS, ITEM_WIDTH)::get_type()); + endfunction +endclass + + + +class sequence_fifo#( + int unsigned DMA_TX_CHANNELS, + int unsigned DMA_RX_CHANNELS, + int unsigned DMA_PKT_MTU, + int unsigned DMA_HDR_META_WIDTH, + int unsigned DMA_STREAMS, + int unsigned ETH_TX_HDR_WIDTH, + int unsigned MFB_ITEM_WIDTH, + int unsigned ETH_STREAMS, + int unsigned REGIONS, + int unsigned MFB_REG_SIZE, + int unsigned MFB_BLOCK_SIZE +) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); + `uvm_object_param_utils(test::sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + + // Constructor - creates new instance of this class + function new(string name = "sequence"); + super.new(name); + endfunction + + virtual task eth_rx_sequence(int unsigned index); + uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH) packet_seq; + int unsigned it; + + packet_seq = uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH)::type_id::create("mfb_rx_seq", p_sequencer.m_eth_rx[index]); + + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_eth_rx[index], "", "state", rx_status); + it = 0; + while (it < 200 && !rx_status.stopped()) begin + assert(packet_seq.randomize()); + packet_seq.start(p_sequencer.m_eth_rx[index]); + it++; + end + + event_eth_rx_end[index] = 1'b0; + endtask + + + virtual task dma_rx_sequence(int unsigned index); + uvm_app_core_top_agent::sequence_base#(sequence_item_dma_rx) packet_seq; + int unsigned it; + + packet_seq = uvm_app_core_top_agent::sequence_base#(sequence_item_dma_rx)::type_id::create("mfb_rx_seq", p_sequencer.m_dma_rx[index]); + + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_dma_rx[index], "", "state", rx_status); + it = 0; + while (it < 200 && !rx_status.stopped()) begin + assert(packet_seq.randomize()); + packet_seq.start(p_sequencer.m_dma_rx[index]); + it++; + end + + event_dma_rx_end[index] = 1'b0; + endtask + + + virtual task eth_tx_sequence(int unsigned index); + uvm_mfb::sequence_full_speed_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH) seq_mfb_one; + uvm_mfb::sequence_stop_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH) seq_mfb_zero; + + seq_mfb_one = uvm_mfb::sequence_full_speed_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH)::type_id::create("seq_mfb_one", p_sequencer.m_eth_tx[index]); + seq_mfb_one.min_transaction_count = 1000; + seq_mfb_one.max_transaction_count = 20000; + seq_mfb_zero = uvm_mfb::sequence_stop_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, ETH_TX_HDR_WIDTH)::type_id::create("seq_mfb_zero", p_sequencer.m_eth_tx[index]); + seq_mfb_zero.min_transaction_count = 1000; + seq_mfb_zero.max_transaction_count = 20000; + + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_eth_tx[index], "", "state", tx_status); + while (!tx_status.stopped()) begin + //mfb_seq.set_starting_phase(phase); + void'(seq_mfb_one.randomize()); + seq_mfb_one.start(p_sequencer.m_eth_tx[index]); + void'(seq_mfb_zero.randomize()); + seq_mfb_zero.start(p_sequencer.m_eth_tx[index]); + end + endtask + + + virtual task dma_tx_sequence(int unsigned index); + uvm_mfb::sequence_full_speed_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0) seq_mfb_one; + uvm_mfb::sequence_stop_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0) seq_mfb_zero; + uvm_mvb::sequence_full_speed_tx #(REGIONS, DMA_TX_MVB_WIDTH) seq_mvb_one; + uvm_mvb::sequence_stop_tx #(REGIONS, DMA_TX_MVB_WIDTH) seq_mvb_zero; + + + seq_mfb_one = uvm_mfb::sequence_full_speed_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::create("seq_mfb_one", p_sequencer.m_dma_mfb_tx[index]); + seq_mfb_one.min_transaction_count = 1000; + seq_mfb_one.max_transaction_count = 20000; + seq_mfb_zero = uvm_mfb::sequence_stop_tx #(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::create("seq_mfb_zero", p_sequencer.m_dma_mfb_tx[index]); + seq_mfb_zero.min_transaction_count = 1000; + seq_mfb_zero.max_transaction_count = 20000; + + + seq_mvb_one = uvm_mvb::sequence_full_speed_tx #(REGIONS, DMA_TX_MVB_WIDTH)::type_id::create("seq_mvb_one", p_sequencer.m_dma_mvb_tx[index]); + seq_mvb_one.min_transaction_count = 1000; + seq_mvb_one.max_transaction_count = 20000; + seq_mvb_zero = uvm_mvb::sequence_stop_tx #(REGIONS, DMA_TX_MVB_WIDTH)::type_id::create("seq_mvb_zero", p_sequencer.m_dma_mvb_tx[index]); + seq_mvb_zero.min_transaction_count = 1000; + seq_mvb_zero.max_transaction_count = 20000; + + + //RUN ETH + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_dma_mvb_tx[index], "", "state", tx_status); + uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_dma_mfb_tx[index], "", "state", tx_status); + fork + while (!tx_status.stopped()) begin + //mfb_seq.set_starting_phase(phase); + void'(seq_mfb_one.randomize()); + seq_mfb_one.start(p_sequencer.m_dma_mfb_tx[index]); + void'(seq_mfb_zero.randomize()); + seq_mfb_zero.start(p_sequencer.m_dma_mfb_tx[index]); + end + while (!tx_status.stopped()) begin + //mvb_seq.set_starting_phase(phase); + void'(seq_mvb_one.randomize()); + seq_mvb_one.start(p_sequencer.m_dma_mvb_tx[index]); + void'(seq_mvb_zero.randomize()); + seq_mvb_zero.start(p_sequencer.m_dma_mvb_tx[index]); + end + join; + endtask +endclass + + +class sequence_fifo_stop#( + int unsigned DMA_TX_CHANNELS, + int unsigned DMA_RX_CHANNELS, + int unsigned DMA_PKT_MTU, + int unsigned DMA_HDR_META_WIDTH, + int unsigned DMA_STREAMS, + int unsigned ETH_TX_HDR_WIDTH, + int unsigned MFB_ITEM_WIDTH, + int unsigned ETH_STREAMS, + int unsigned REGIONS, + int unsigned MFB_REG_SIZE, + int unsigned MFB_BLOCK_SIZE +) extends sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); + `uvm_object_param_utils(test::sequence_fifo_stop#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + + + // Constructor - creates new instance of this class + function new(string name = "sequence"); + super.new(name); + endfunction + + function void done_set(); + tx_status.send_stop(); + endfunction + + task body; + tx_status.clear(); + for (int unsigned it = 0; it < DMA_STREAMS; it++) begin + fork + automatic int index = it; + dma_tx_sequence(index); + join_none; + end + + for (int unsigned it = 0; it < ETH_STREAMS; it++) begin + fork + automatic int index = it; + eth_tx_sequence(index); + join_none; + end + + while (tx_status.stopped() == 0) begin + #(30ns); + end + endtask + +endclass + + +class fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR_WIDTH, DMA_STREAMS, DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_HDR_META_WIDTH, DMA_PKT_MTU, + REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH) extends + base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR_WIDTH, DMA_STREAMS, DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_HDR_META_WIDTH, DMA_PKT_MTU, + REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH); + + typedef uvm_component_registry#(test::fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR_WIDTH, DMA_STREAMS, DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_HDR_META_WIDTH, DMA_PKT_MTU, + REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, MEM_PORTS, MEM_ADDR_WIDTH, MEM_BURST_WIDTH, MEM_DATA_WIDTH, MI_DATA_WIDTH, MI_ADDR_WIDTH), + "test::fifo") type_id; + + function new (string name, uvm_component parent = null); + super.new(name, parent); + endfunction + + static function type_id get_type(); + return type_id::get(); + endfunction + + function string get_type_name(); + return get_type().get_type_name(); + endfunction + + function void build_phase(uvm_phase phase); + for (int unsigned it = 0; it < ETH_STREAMS; it++) begin + string it_num; + it_num.itoa(it); + + uvm_logic_vector_array_mfb::sequence_lib_rx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::set_inst_override(test::sequence_lib__mfb_rx_fifo#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::get_type(), + {this.get_full_name(), ".m_env.m_eth_mfb_rx_", it_num ,".*"}); + + uvm_logic_vector_mvb::sequence_lib_rx#(REGIONS, ETH_RX_HDR_WIDTH)::type_id::set_inst_override(test::sequence_lib__mvb_rx_fifo#(REGIONS, ETH_RX_HDR_WIDTH)::get_type(), + {this.get_full_name(), ".m_env.m_eth_mvb_rx_", it_num,".*"}); + end + + for (int unsigned it = 0; it < DMA_STREAMS; it++) begin + string it_num; + it_num.itoa(it); + + uvm_logic_vector_array_mfb::sequence_lib_rx#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::type_id::set_inst_override(test::sequence_lib__mfb_rx_fifo#(REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MFB_ITEM_WIDTH, 0)::get_type(), + {this.get_full_name(), ".m_env.m_dma_mfb_rx_", it_num,".*"}); + + uvm_logic_vector_mvb::sequence_lib_rx#(REGIONS, DMA_RX_MVB_WIDTH)::type_id::set_inst_override(test::sequence_lib__mvb_rx_fifo#(REGIONS, DMA_RX_MVB_WIDTH)::get_type(), + {this.get_full_name(), ".m_env.m_dma_mvb_rx_", it_num,".*"}); + + //.mfb_seq + end + + super.build_phase(phase); + endfunction + + function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + m_env.delay_max_set(1ms); + endfunction + + virtual task run_phase(uvm_phase phase); + test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; + test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; + time end_time; + + main_seq = test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); + phase.raise_objection(this); + + // RUN RESET + fork + run_reset(phase); + join_none; + + ////configure egent + wait(event_reset == 1'b0); + for (int unsigned it = 0; it < 2; it++) begin + + //RUN RIVER SEQUENCE ONLY IF RESET IS NOT SET + dirver_sequence(); + #(200ns); + + assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + main_seq.start(m_env.m_sequencer); + + assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + fork + stop_seq.start(m_env.m_sequencer); + join_none; + + end_time = $time() + 400us; + while (end_time > $time() && m_env.used() != 0) begin + #(500ns); + end + if (m_env.used() != 0) begin + `uvm_warning(this.get_full_name(), $sformatf("\n\tUSED(%0d) sould be zero.\n\tDuring reconfiguration, There is some data in design", m_env.used())); + end + + stop_seq.done_set(); + end + + phase.drop_objection(this); + endtask +endclass diff --git a/app/uvm/tests/full_speed.sv b/app/uvm/tests/full_speed.sv index 18195716d..5842ad82d 100644 --- a/app/uvm/tests/full_speed.sv +++ b/app/uvm/tests/full_speed.sv @@ -73,7 +73,8 @@ class sequence_speed#( void'(mvb_seq.randomize()); mvb_seq.start(p_sequencer.m_dma_mvb_tx[index]); end - join_none; + //join_none; + join; endtask endclass @@ -162,15 +163,20 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ end assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); - end_time = $time() + 20us; fork stop_seq.start(m_env.m_sequencer); join_none; - while (end_time > $time() && m_env.m_scoreboard.used() != 0) begin + end_time = $time() + 200us; + while (end_time > $time() && m_env.used() != 0) begin #(500ns); end + + if (m_env.used() != 0) begin + `uvm_warning(this.get_full_name(), $sformatf("\n\tUSED(%0d) sould be zero.\n\tDuring reconfiguration, There is some data in design", m_env.used())); + end + stop_seq.done_set(); end From 41de5f6d0d65fecaae7560f458081017cf5a0ac0 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Wed, 28 Aug 2024 10:41:24 +0200 Subject: [PATCH 07/10] APP UVM: [MAITENANCE] Add test fifo. This test randomly switch between full speed and stop seqences. To Fill and empties fifos --- app/uvm/testbench.sv | 5 +++++ app/uvm/tests/pkg.sv | 1 + 2 files changed, 6 insertions(+) diff --git a/app/uvm/testbench.sv b/app/uvm/testbench.sv index 0761dc75b..3a8376f17 100644 --- a/app/uvm/testbench.sv +++ b/app/uvm/testbench.sv @@ -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; diff --git a/app/uvm/tests/pkg.sv b/app/uvm/tests/pkg.sv index bb2b184e0..673d84d25 100644 --- a/app/uvm/tests/pkg.sv +++ b/app/uvm/tests/pkg.sv @@ -15,4 +15,5 @@ package test; `include "base.sv" `include "full_speed.sv" + `include "fifo.sv" endpackage From f854fb12799703dac61374b28beab71dcd0960b7 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Fri, 30 Aug 2024 14:52:50 +0200 Subject: [PATCH 08/10] APP UVM: [MAITENANCE] Add support for RAM on chip --- app/uvm/test_pkg.sv | 1 + app/uvm/testbench.sv | 69 +++++++++++++++++++++++-------------- app/uvm/tests/base.sv | 30 +++++++++++++--- app/uvm/tests/fifo.sv | 36 +++++++++++++------ app/uvm/tests/full_speed.sv | 24 +++++++++---- 5 files changed, 114 insertions(+), 46 deletions(-) diff --git a/app/uvm/test_pkg.sv b/app/uvm/test_pkg.sv index f1bb57a6c..3462b7a91 100644 --- a/app/uvm/test_pkg.sv +++ b/app/uvm/test_pkg.sv @@ -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; diff --git a/app/uvm/testbench.sv b/app/uvm/testbench.sv index 3a8376f17..b2e01015f 100644 --- a/app/uvm/testbench.sv +++ b/app/uvm/testbench.sv @@ -40,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 @@ -56,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); @@ -79,7 +77,6 @@ module testbench; 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 @@ -98,15 +95,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 ///////////////////////// @@ -338,17 +365,17 @@ 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); .EMIF_RST_REQ (), // : out std_logic_vector(MEM_PORTS-1 downto 0); .EMIF_RST_DONE (), // : in std_logic_vector(MEM_PORTS-1 downto 0); @@ -402,8 +429,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; ///////////////////////////////////////////// @@ -436,12 +461,6 @@ 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); diff --git a/app/uvm/tests/base.sv b/app/uvm/tests/base.sv index 437fcf490..2a5011adb 100644 --- a/app/uvm/tests/base.sv +++ b/app/uvm/tests/base.sv @@ -75,6 +75,24 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR end endtask + task run_mem(); + uvm_avmm::sequence_library_master #(MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) mem_seq[MEM_PORTS]; + + for (int unsigned it = 0; it < MEM_PORTS; it ++) begin + mem_seq[it] = uvm_avmm::sequence_library_master #(MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create($sformatf("mem_seq_%0d", it), this);; + end + + for (int unsigned it = 0; it < MEM_PORTS; it ++) begin + fork + automatic int unsigned index = it; + forever begin + assert(mem_seq[index].randomize()) else begin `uvm_fatal(this.get_full_name(), $sfomratf("Cannot randomize memory sequence %0d", index)) end + mem_seq[index].start(m_env.m_sequencer.m_memory[index]); + end + join_none + end + endtask + virtual task dirver_sequence(); uvm_app_core_minimal::reg_sequence#(ETH_STREAMS, ETH_CHANNELS, DMA_STREAMS, DMA_RX_CHANNELS) seq; @@ -85,12 +103,16 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR endtask virtual task run_phase(uvm_phase phase); - uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; - uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; + uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; + uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) stop_seq; time end_time; - main_seq = uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); - stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); + main_seq = uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("stop_seq", m_env.m_sequencer); phase.raise_objection(this); // RUN RESET diff --git a/app/uvm/tests/fifo.sv b/app/uvm/tests/fifo.sv index 726013d42..6bb530be2 100644 --- a/app/uvm/tests/fifo.sv +++ b/app/uvm/tests/fifo.sv @@ -129,9 +129,15 @@ class sequence_fifo#( int unsigned ETH_STREAMS, int unsigned REGIONS, int unsigned MFB_REG_SIZE, - int unsigned MFB_BLOCK_SIZE -) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); - `uvm_object_param_utils(test::sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + int unsigned MFB_BLOCK_SIZE, + int unsigned MEM_PORTS, + int unsigned MEM_ADDR_WIDTH, + int unsigned MEM_DATA_WIDTH, + int unsigned MEM_BURST_WIDTH +) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH); + `uvm_object_param_utils(test::sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)) // Constructor - creates new instance of this class function new(string name = "sequence"); @@ -253,9 +259,15 @@ class sequence_fifo_stop#( int unsigned ETH_STREAMS, int unsigned REGIONS, int unsigned MFB_REG_SIZE, - int unsigned MFB_BLOCK_SIZE -) extends sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); - `uvm_object_param_utils(test::sequence_fifo_stop#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + int unsigned MFB_BLOCK_SIZE, + int unsigned MEM_PORTS, + int unsigned MEM_ADDR_WIDTH, + int unsigned MEM_DATA_WIDTH, + int unsigned MEM_BURST_WIDTH +) extends sequence_fifo#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH); + `uvm_object_param_utils(test::sequence_fifo_stop#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)) // Constructor - creates new instance of this class @@ -346,12 +358,16 @@ class fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR endfunction virtual task run_phase(uvm_phase phase); - test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; - test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; + test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; + test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) stop_seq; time end_time; - main_seq = test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); - stop_seq = test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); + main_seq = test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("stop_seq", m_env.m_sequencer); phase.raise_objection(this); // RUN RESET diff --git a/app/uvm/tests/full_speed.sv b/app/uvm/tests/full_speed.sv index 5842ad82d..3c719ca31 100644 --- a/app/uvm/tests/full_speed.sv +++ b/app/uvm/tests/full_speed.sv @@ -19,9 +19,15 @@ class sequence_speed#( int unsigned ETH_STREAMS, int unsigned REGIONS, int unsigned MFB_REG_SIZE, - int unsigned MFB_BLOCK_SIZE -) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE); - `uvm_object_param_utils(test::sequence_speed#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)) + int unsigned MFB_BLOCK_SIZE, + int unsigned MEM_PORTS, + int unsigned MEM_ADDR_WIDTH, + int unsigned MEM_DATA_WIDTH, + int unsigned MEM_BURST_WIDTH +) extends uvm_app_core::sequence_main#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH); + `uvm_object_param_utils(test::sequence_speed#(DMA_TX_CHANNELS, DMA_RX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)) // Constructor - creates new instance of this class function new(string name = "sequence"); @@ -134,12 +140,16 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ endfunction virtual task run_phase(uvm_phase phase); - test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) main_seq; - uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE) stop_seq; + test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; + uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) stop_seq; time end_time; - main_seq = test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("main_seq", m_env.m_sequencer); - stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE)::type_id::create("stop_seq", m_env.m_sequencer); + main_seq = test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("main_seq", m_env.m_sequencer); + stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, + ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("stop_seq", m_env.m_sequencer); phase.raise_objection(this); // RUN RESET From a80ca96a22dbd1d8f7f5f9b495aeb0399e967325 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Fri, 30 Aug 2024 15:02:25 +0200 Subject: [PATCH 09/10] APP UVM: [MAITENANCE] Add fifo testing into automatic verification --- app/uvm/ver_settings.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/uvm/ver_settings.py b/app/uvm/ver_settings.py index 4813c93d1..8f2d9127a 100644 --- a/app/uvm/ver_settings.py +++ b/app/uvm/ver_settings.py @@ -65,12 +65,18 @@ "__core_params__" : {"UVM_TEST" : "test::full_speed"}, }, + "test_fifo" : { + "__core_params__" : {"UVM_TEST" : "test::fifo"}, + }, + "_combinations_" : ( ("default",), # Works the same as '("default",),' as the "default" is applied in every combination - ("default", "test_speed", ), + ("default", "test_speed", ), + ("default", "test_fifo", ), ("eth_1", "dma_1", "mfb",), ("dma_1", "eth_ch1", "mfb_1",), ("dma_1", "eth_ch1",), ("eth_1", "dma_1", "mfb", "test_speed", ), + ("eth_1", "dma_1", "mfb", "test_fifo", ), ), } From b05918b0417dabb5abca7126b46e2ce5a494bec4 Mon Sep 17 00:00:00 2001 From: Radek Isa Date: Tue, 3 Sep 2024 14:05:37 +0200 Subject: [PATCH 10/10] APP UVM: [MAITENANCE] Add tsu agent and interface to generate better timestamps --- app/uvm/testbench.sv | 14 +++++++++++++- app/uvm/tests/base.sv | 11 +++++++++++ app/uvm/tests/fifo.sv | 17 +++++++++++++++-- app/uvm/tests/full_speed.sv | 9 +++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/uvm/testbench.sv b/app/uvm/testbench.sv index b2e01015f..cdbe0f190 100644 --- a/app/uvm/testbench.sv +++ b/app/uvm/testbench.sv @@ -71,6 +71,10 @@ 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; @@ -377,6 +381,11 @@ module testbench; .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); .EMIF_ECC_USR_INT (), // : in std_logic_vector(MEM_PORTS-1 downto 0); @@ -392,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), @@ -465,6 +474,9 @@ module testbench; //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(); diff --git a/app/uvm/tests/base.sv b/app/uvm/tests/base.sv index 2a5011adb..e519b1607 100644 --- a/app/uvm/tests/base.sv +++ b/app/uvm/tests/base.sv @@ -103,6 +103,7 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR endtask virtual task run_phase(uvm_phase phase); + uvm_app_core::sequence_tsu tsu_seq; uvm_app_core::sequence_main#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, @@ -113,6 +114,7 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("main_seq", m_env.m_sequencer); stop_seq = uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH)::type_id::create("stop_seq", m_env.m_sequencer); + phase.raise_objection(this); // RUN RESET @@ -120,6 +122,14 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR run_reset(phase); join_none; + + // RUN TSU + tsu_seq = uvm_app_core::sequence_tsu::type_id::create("tsu_seq", m_env.m_tsu.m_sequencer); + tsu_seq.randomize(); + fork + tsu_seq.start(m_env.m_tsu.m_sequencer); + join_none; + ////configure egent wait(event_reset == 1'b0); for (int unsigned it = 0; it < 3; it++) begin @@ -130,6 +140,7 @@ class base#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR for (int unsigned it = 0; it < 5; it++) begin assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); + main_seq.time_start = tsu_seq.time_start; main_seq.start(m_env.m_sequencer); end diff --git a/app/uvm/tests/fifo.sv b/app/uvm/tests/fifo.sv index 6bb530be2..77eb8c4ab 100644 --- a/app/uvm/tests/fifo.sv +++ b/app/uvm/tests/fifo.sv @@ -145,10 +145,14 @@ class sequence_fifo#( endfunction virtual task eth_rx_sequence(int unsigned index); - uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH) packet_seq; + uvm_app_core::sequence_library_eth#(2**8, 16, MFB_ITEM_WIDTH) packet_seq; + uvm_app_core::config_sequence_eth seq_cfg; int unsigned it; - packet_seq = uvm_app_core::sequence_eth#(2**8, 16, MFB_ITEM_WIDTH)::type_id::create("mfb_rx_seq", p_sequencer.m_eth_rx[index]); + seq_cfg = new(); + seq_cfg.time_start = time_start; + packet_seq = uvm_app_core::sequence_library_eth#(2**8, 16, MFB_ITEM_WIDTH)::type_id::create("mfb_rx_seq", p_sequencer.m_eth_rx[index]); + packet_seq.init_sequence(seq_cfg); uvm_config_db#(uvm_common::sequence_cfg)::set(p_sequencer.m_eth_rx[index], "", "state", rx_status); it = 0; @@ -358,6 +362,7 @@ class fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR endfunction virtual task run_phase(uvm_phase phase); + uvm_app_core::sequence_tsu tsu_seq; test::sequence_fifo#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; test::sequence_fifo_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, @@ -375,6 +380,13 @@ class fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR run_reset(phase); join_none; + // RUN TSU + tsu_seq = uvm_app_core::sequence_tsu::type_id::create("tsu_seq", m_env.m_tsu.m_sequencer); + tsu_seq.randomize(); + fork + tsu_seq.start(m_env.m_tsu.m_sequencer); + join_none; + ////configure egent wait(event_reset == 1'b0); for (int unsigned it = 0; it < 2; it++) begin @@ -385,6 +397,7 @@ class fifo#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_TX_HDR assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); main_seq.start(m_env.m_sequencer); + main_seq.time_start = tsu_seq.time_start; assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); fork diff --git a/app/uvm/tests/full_speed.sv b/app/uvm/tests/full_speed.sv index 3c719ca31..ac456a460 100644 --- a/app/uvm/tests/full_speed.sv +++ b/app/uvm/tests/full_speed.sv @@ -140,6 +140,7 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ endfunction virtual task run_phase(uvm_phase phase); + uvm_app_core::sequence_tsu tsu_seq; test::sequence_speed#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, ETH_STREAMS, REGIONS, MFB_REG_SIZE, MFB_BLOCK_SIZE, MEM_PORTS, MEM_ADDR_WIDTH, MEM_DATA_WIDTH, MEM_BURST_WIDTH) main_seq; uvm_app_core::sequence_stop#(DMA_RX_CHANNELS, DMA_TX_CHANNELS, DMA_PKT_MTU, DMA_HDR_META_WIDTH, DMA_STREAMS, ETH_TX_HDR_WIDTH, MFB_ITEM_WIDTH, @@ -157,6 +158,13 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ run_reset(phase); join_none; + // RUN TSU + tsu_seq = uvm_app_core::sequence_tsu::type_id::create("tsu_seq", m_env.m_tsu.m_sequencer); + tsu_seq.randomize(); + fork + tsu_seq.start(m_env.m_tsu.m_sequencer); + join_none; + ////configure egent wait(event_reset == 1'b0); for (int unsigned it = 0; it < 3; it++) begin @@ -170,6 +178,7 @@ class full_speed#(ETH_STREAMS, ETH_CHANNELS, ETH_PKT_MTU, ETH_RX_HDR_WIDTH, ETH_ //for (int unsigned it = 0; it < 10; it++) begin assert(main_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence"); main_seq.start(m_env.m_sequencer); + main_seq.time_start = tsu_seq.time_start; end assert(stop_seq.randomize()) else `uvm_fatal(m_env.m_sequencer.get_full_name(), "\n\tCannot randomize main sequence");