diff --git a/docs/library/drivers/common/scoreboard/index.rst b/docs/library/drivers/common/scoreboard/index.rst index d486a25b7..3047b2658 100644 --- a/docs/library/drivers/common/scoreboard/index.rst +++ b/docs/library/drivers/common/scoreboard/index.rst @@ -3,3 +3,107 @@ Scoreboard ================================================================================ +Overview +------------------------------------------------------------------------------- + +The scoreboard class is designed for transaction comparison in a verification +environment. This class extends adi_component and is parameterized by a +datatype data_type, which allows the verification of different datatypes without +the need of inheriting this class. The scoreboard class contains an inner class +subscriber_class which extends adi_subscriber and is responsible for receiving +and storing data streams. The scoreboard can operate in oneshot or in +cyclic mode, which allows the verification of repeating sequence verification. + +.. svg:: library/drivers/common/scoreboard/scoreboard.svg + :align: center + +Variables +------------------------------------------------------------------------------- + +The scoreboard class itself has two instances of subscriber_class, named +subscriber_source and subscriber_sink, which represent the source and sink of +the data streams. These are subscribed to a publisher, which calls the +respective functions when new data is available. + +Functions +------------------------------------------------------------------------------- + +function new(input string name, input adi_component parent = null); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates the scoreboard object. The name gives the scoreboard a name that is +relevant in the current environment it is instantiated in and the parent sets +the parent object in which it resides. + +task run(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enables the scoreboard and clears the data streams. + +task stop(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Disables the scoreboard and clears the data streams. + +function void set_sink_type(input bit sink_type); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Allows the setting of the sink type, which defines if the output data may or may +not repeat. If set to oneshot, then the source data is verified only once. If +set to cyclic, then the source data is verified against the sink data as long as +new data is coming in on the sink side. This value can only be set when the +scoreboard is disabled. + +function bit get_sink_type(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Get the sink type. + +protected function void clear_streams(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Clear the source and sink data streams. + +task wait_until_complete(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wait until the source and the sink datastreams are clear of data, which means +that all source data was verified against all sink data. + +virtual function void compare_transaction(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Compares the source and the sink datastreams against each other. This method is +called by the subscriber when new data arrives. If the scoreboard is disabled, +the comparison is ommited. + +Usage and recommendations +------------------------------------------------------------------------------- + +Basic usage of the scoreboard: + +* Declare the scoreboard +* Link the source and sink subscribers to the publishers where you want to + verify data +* Optional: set the sink type; default is oneshot +* Call the run function to start the verification +* Wait until the scoreboard completes verification +* Stop the scoreboard + +.. important:: + + * The scoreboard must be started before the data transmission begins, + otherwise, data will be lost and the verification will fail! + +Other use-cases: + +* The scoreboard can be dynamically reconfigured to use other inputs. Stop the + scoreboard, unsubscribe the subscribers from the publishers and subscribe them + to the other publisher where you want to verify data. + +.. important:: + + * The datatype cannot be changed during runtime, only the publisher, to which + they are subscribed to. + +.. include:: ../../../../common/support.rst diff --git a/docs/library/drivers/common/scoreboard/scoreboard.svg b/docs/library/drivers/common/scoreboard/scoreboard.svg new file mode 100755 index 000000000..581c3e9ae --- /dev/null +++ b/docs/library/drivers/common/scoreboard/scoreboard.svg @@ -0,0 +1,102 @@ +adi_reporteradi_componentadi_subscriberscoreboard+subscriber_source+subscriber_sink#sink_type#enabled#bytestream_empty_sig#byte_streams_empty#stop_scoreboard+run()void+stop()void+set_sink_type()void+get_sink_type()void#clear_streams()void+wait_until_complete()void+compare_transaction()void 2 + + + \ No newline at end of file diff --git a/docs/library/drivers/common/scoreboard/scoreboard.txt b/docs/library/drivers/common/scoreboard/scoreboard.txt new file mode 100644 index 000000000..39587c81a --- /dev/null +++ b/docs/library/drivers/common/scoreboard/scoreboard.txt @@ -0,0 +1,40 @@ +# Classes + +# Base +adi_reporter: {shape: class} +adi_component: {shape: class} + +# Component +adi_subscriber: {shape: class} + +# Scoreboard +scoreboard: { + shape: class + +subscriber_source + +subscriber_sink + \#sink_type + \#enabled + \#bytestream_empty_sig + \#byte_streams_empty + \#stop_scoreboard + +run() + +stop() + +set_sink_type() + +get_sink_type() + \#clear_streams() + +wait_until_complete() + +compare_transaction() +} + +# Inheritances + +# Base +adi_reporter <- adi_component: {shape: triangle; source-arrowhead.style.filled: false} + +# Scoreboard +adi_component <- scoreboard: {shape: triangle; source-arrowhead.style.filled: false} + +# Aggregations + +# Scoreboard +scoreboard <- adi_subscriber: {source-arrowhead: 2 {shape: diamond; style.filled: true}} diff --git a/docs/library/drivers/common/scoreboard_pack/index.rst b/docs/library/drivers/common/scoreboard_pack/index.rst new file mode 100644 index 000000000..ea4f50cfa --- /dev/null +++ b/docs/library/drivers/common/scoreboard_pack/index.rst @@ -0,0 +1,46 @@ +.. _scoreboard_pack: + +Scoreboard Pack +================================================================================ + +Overview +------------------------------------------------------------------------------- + +This class is a specialized version of a generic scoreboard class, parameterized +by the data type and packer mode. The scoreboard pack class is designed to +handle and compare data streams in a verification environment. + +.. svg:: library/drivers/common/scoreboard_pack/scoreboard_pack.svg + :align: center + +Variables +------------------------------------------------------------------------------- + +No additional variables are available for direct external access. + +Functions +------------------------------------------------------------------------------- + +function new(...); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates the scoreboard object. The name gives the scoreboard a name that is +relevant in the current environment it is instantiated in, the channels set the +number of channels that are present on the packer module, the sample value sets +the number of samples that are set in the converter, the width specifies the +width of one sample for one channel, the mode is set based on the current pack +module, which can be a packer or unpacker and the parent sets the parent object +in which it resides. + +virtual function void compare_transaction(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The compare module's base functionality is the same as the base class, but it +specifically verifies the input and output of the packer and unpacker modules. + +Usage and recommendations +------------------------------------------------------------------------------- + +Same as the base class. + +.. include:: ../../../../common/support.rst diff --git a/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.svg b/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.svg new file mode 100755 index 000000000..d1f4e3d44 --- /dev/null +++ b/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.svg @@ -0,0 +1,102 @@ +adi_reporteradi_componentadi_subscriberscoreboardscoreboard_pack#channels#samples#width#mode+compare_transaction()void 2 + + + \ No newline at end of file diff --git a/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.txt b/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.txt new file mode 100644 index 000000000..2f7440cde --- /dev/null +++ b/docs/library/drivers/common/scoreboard_pack/scoreboard_pack.txt @@ -0,0 +1,33 @@ +# Classes + +# Base +adi_reporter: {shape: class} +adi_component: {shape: class} + +# Component +adi_subscriber: {shape: class} + +# Scoreboard +scoreboard: {shape: class} +scoreboard_pack: { + shape: class + \#channels + \#samples + \#width + \#mode + +compare_transaction() +} + +# Inheritances + +# Base +adi_reporter <- adi_component: {shape: triangle; source-arrowhead.style.filled: false} + +# Scoreboard +adi_component <- scoreboard: {shape: triangle; source-arrowhead.style.filled: false} +scoreboard <- scoreboard_pack: {shape: triangle; source-arrowhead.style.filled: false} + +# Aggregations + +# Scoreboard +scoreboard_pack <- adi_subscriber: {source-arrowhead: 2 {shape: diamond; style.filled: true}} diff --git a/docs/testbenches/ip_based/scoreboard/index.rst b/docs/testbenches/ip_based/scoreboard/index.rst new file mode 100644 index 000000000..255ecc323 --- /dev/null +++ b/docs/testbenches/ip_based/scoreboard/index.rst @@ -0,0 +1,191 @@ +.. _scoreboard_tb: + +Scoreboard +================================================================================ + +Overview +------------------------------------------------------------------------------- + +The purpose of this testbench is to give engineers a sandbox testbench, where +they can test the scoreboard's functionalities. + +Block design +------------------------------------------------------------------------------- + +The block design is based on the test harness with the addition of two AXI4 +Stream VIPs from AMD. This testbench does not require the presence of the test +harness, as it can work without it, but since it was created based on the base +design, this was inherited. One of the VIPs is configured as master, while the +other one is configured as slave. The TREADY, TLAST and TKEEP signals are set to +be enabled for the VIPs. + +Block diagram +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: ../axis_sequencers/axis_sequencers_tb.svg + :width: 800 + :align: center + :alt: Scoreboard/Testbench block diagram + +Configuration parameters and modes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are no parameters that can be configured in the testbench configuration +files. + +Build parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are no build parameters for this testbench. + +Configuration files +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As this is a sandbox testbench, engineers are encouraged to change parameters +and see what happens in the simulation. Since there are no parameters available +for edit, the coniguration file's purpose is to give the testbench instance a +name. + +Tests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following test program file is available: + +============ ============================== +Test program Usage +============ ============================== +test_program Creates a basic test stimulus. +============ ============================== + +Available configurations & tests combinations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The test program is compatible with the configuration. + +CPU/Memory interconnects addresses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Irrelevant for this testbench. + +Interrupts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Irrelevant for this testbench. + +Test stimulus +------------------------------------------------------------------------------- + +The test program is responsible for configuring and running the sequencers, +while checking the data with a scoreboard. + +Environment Bringup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The steps of the environment bringup are: + +* Create the environment +* Start the environment +* Start the clocks +* Assert the resets + +Scoreboard testing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Before the resets are asserted, the master and slave sequencers are configured +* The scoreboard is subscribed to the master and slave sequencers' publisher +* The scoreboard is started +* The sequencers are started +* Scoreboard waits until the verification is complete + +.. warning:: + + Depending on the packet size and amount, the simulation may end before all of + the data is verified, which may cause runtime errors! + +Building the test bench +------------------------------------------------------------------------------- + +The testbench is built upon ADI's generic HDL reference design framework. +ADI does not distribute compiled files of these projects so they must be built +from the sources available :git-hdl:`here ` and :git-testbenches:`here `, +with the specified hierarchy described :ref:`build_tb set_up_tb_repo`. +To get the source you must +`clone `__ +the HDL repository, and then build the project as follows: + +**Linux/Cygwin/WSL** + +*Example 1* + +Building and simulating the testbench using only the command line. + +.. shell:: + :showuser: + + $cd testbenches/ip/scoreboard + $make + +*Example 2* + +Building and simulating the testbench using the Vivado GUI. This command will +launch Vivado, will run the simulation and display the waveforms. + +.. shell:: + :showuser: + + $cd testbenches/ip/scoreboard + $make MODE=gui + +*Example 3* + +Build a particular combination of test and configuration, using the Vivado GUI. +This command will launch Vivado, will run the simulation and display the +waveforms. + +.. shell:: + :showuser: + + $cd testbenches/ip/scoreboard + $make MODE=gui CFG=cfg1 TST=test_program + +The built project can be found in the ``runs`` folder, where each configuration +specific build has its own folder named after the configuration file's name. +Example: if the following command was run for a single configuration in the +clean folder (no runs folder available): + +``make CFG=cfg1`` + +Then the subfolder under ``runs`` name will be: + +``cfg1`` + +Resources +------------------------------------------------------------------------------- + +Testbenches related dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: ../../common/dependency_common.rst + +Testbench specific dependencies: + +.. list-table:: + :widths: 30 45 25 + :header-rows: 1 + + * - SV dependency name + - Source code link + - Documentation link + * - M_AXIS_SEQUENCER + - :git-testbenches:`library/vip/amd/m_axis_sequencer.sv` + - --- + * - S_AXIS_SEQUENCER + - :git-testbenches:`library/vip/amd/s_axis_sequencer.sv` + - --- + * - SCOREBOARD + - :git-testbenches:`library/drivers/common/scoreboard.sv` + - --- + +.. include:: ../../../common/more_information.rst + +.. include:: ../../../common/support.rst diff --git a/library/drivers/common/scoreboard.sv b/library/drivers/common/scoreboard.sv index a02ea7372..0d6a1c715 100644 --- a/library/drivers/common/scoreboard.sv +++ b/library/drivers/common/scoreboard.sv @@ -122,7 +122,7 @@ package scoreboard_pkg; // run task task run(); this.enabled = 1; - + this.clear_streams(); this.info($sformatf("Scoreboard enabled"), ADI_VERBOSITY_MEDIUM); endtask: run @@ -154,7 +154,7 @@ package scoreboard_pkg; // clear source and sink byte streams protected function void clear_streams(); this.subscriber_source.clear_stream(); - this.subscriber_source.clear_stream(); + this.subscriber_sink.clear_stream(); endfunction: clear_streams // wait until source and sink byte streams are empty, full check diff --git a/testbenches/ip/scoreboard/Makefile b/testbenches/ip/scoreboard/Makefile index e7925a696..fd72493a1 100644 --- a/testbenches/ip/scoreboard/Makefile +++ b/testbenches/ip/scoreboard/Makefile @@ -11,16 +11,7 @@ include $(TB_LIBRARY_PATH)/includes/Makeinclude_scoreboard.mk include $(TB_LIBRARY_PATH)/includes/Makeinclude_dmac.mk include $(TB_LIBRARY_PATH)/includes/Makeinclude_data_offload.mk -# Remaining test-bench dependencies except test programs -SV_DEPS += environment.sv - -LIB_DEPS := util_cdc -LIB_DEPS += util_axis_fifo -LIB_DEPS += axi_dmac -LIB_DEPS += data_offload -LIB_DEPS += util_do_ram - -# list of test programs +# default test program TP := $(notdir $(basename $(wildcard tests/*.sv))) # config files should have the following format @@ -29,7 +20,7 @@ CFG_FILES := $(notdir $(wildcard cfgs/cfg*.tcl)) # List of tests and configuration combinations that has to be run # Format is: : -TESTS := $(foreach cfg, $(basename $(CFG_FILES)), $(cfg):$(TP)) +TESTS := $(foreach cfg, $(basename $(CFG_FILES)), $(addprefix $(cfg):, $(TP))) include $(ADI_TB_DIR)/scripts/project-sim.mk diff --git a/testbenches/ip/scoreboard/cfgs/cfg1.tcl b/testbenches/ip/scoreboard/cfgs/cfg1.tcl index 2418b5b4f..d040d253a 100644 --- a/testbenches/ip/scoreboard/cfgs/cfg1.tcl +++ b/testbenches/ip/scoreboard/cfgs/cfg1.tcl @@ -1,19 +1 @@ global ad_project_params - -set ad_project_params(ADC_DATA_PATH_WIDTH) 16 ; ## -set ad_project_params(DAC_DATA_PATH_WIDTH) 16 ; ## - -set ad_project_params(ADC_PATH_TYPE) 0 ; ## RX -set ad_project_params(ADC_OFFLOAD_MEM_TYPE) 0 ; ## External storage -set ad_project_params(ADC_OFFLOAD_SIZE) 2048 ; ## Storage size in bytes -set ad_project_params(ADC_OFFLOAD_SRC_DWIDTH) 128 ; ## Source data width -set ad_project_params(ADC_OFFLOAD_DST_DWIDTH) 128 ; ## Destination data width - -set ad_project_params(DAC_PATH_TYPE) 0 ; ## TX -set ad_project_params(DAC_OFFLOAD_MEM_TYPE) 0 ; ## External storage -set ad_project_params(DAC_OFFLOAD_SIZE) 2048 ; ## Storage size in bytes -set ad_project_params(DAC_OFFLOAD_SRC_DWIDTH) 128 ; ## Source data width -set ad_project_params(DAC_OFFLOAD_DST_DWIDTH) 128 ; ## Destination data width - -set ad_project_params(PLDDR_OFFLOAD_DATA_WIDTH) 512 ; ## PLDDR's AXI4 interface data width - diff --git a/testbenches/ip/scoreboard/environment.sv b/testbenches/ip/scoreboard/environment.sv deleted file mode 100644 index c8cf74e82..000000000 --- a/testbenches/ip/scoreboard/environment.sv +++ /dev/null @@ -1,137 +0,0 @@ -// *************************************************************************** -// *************************************************************************** -// Copyright (C) 2024-2025 Analog Devices, Inc. All rights reserved. -// -// In this HDL repository, there are many different and unique modules, consisting -// of various HDL (Verilog or VHDL) components. The individual modules are -// developed independently, and may be accompanied by separate and unique license -// terms. -// -// The user should read each of these license terms, and understand the -// freedoms and responsibilities that he or she has by using this source/core. -// -// This core is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -// A PARTICULAR PURPOSE. -// -// Redistribution and use of source or resulting binaries, with or without modification -// of this file, are permitted under one of the following two license terms: -// -// 1. The GNU General Public License version 2 as published by the -// Free Software Foundation, which can be found in the top level directory -// of this repository (LICENSE_GPL2), and also online at: -// -// -// OR -// -// 2. An ADI specific BSD license, which can be found in the top level directory -// of this repository (LICENSE_ADIBSD), and also on-line at: -// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD -// This will allow to generate bit files and not release the source code, -// as long as it attaches to an ADI device. -// -// *************************************************************************** -// *************************************************************************** - -`include "utils.svh" -`include "axi_definitions.svh" -`include "axis_definitions.svh" - -package environment_pkg; - - import logger_pkg::*; - import adi_environment_pkg::*; - - import axi_vip_pkg::*; - import axi4stream_vip_pkg::*; - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import m_axis_sequencer_pkg::*; - import s_axis_sequencer_pkg::*; - import adi_axi_agent_pkg::*; - import adi_axis_agent_pkg::*; - import scoreboard_pkg::*; - import vip_agent_typedef_pkg::*; - - - class scoreboard_environment extends adi_environment; - - // Agents - adi_axis_agent_base adc_src_axis_agent; - adi_axis_agent_base dac_dst_axis_agent; - adi_axi_agent_base adc_dst_axi_pt_agent; - adi_axi_agent_base dac_src_axi_pt_agent; - - scoreboard #(logic [7:0]) scoreboard_tx; - scoreboard #(logic [7:0]) scoreboard_rx; - - //============================================================================ - // Constructor - //============================================================================ - function new ( - input string name, - input adi_environment parent = null); - - // creating the agents - super.new(name, parent); - - this.adc_src_axis_agent = new("ADC Source AXI Stream Agent", MASTER, this); - this.dac_dst_axis_agent = new("DAC Destination AXI Stream Agent", SLAVE, this); - this.adc_dst_axi_pt_agent = new("ADC Destination AXI Agent", PASSTHROUGH, this); - this.dac_src_axi_pt_agent = new("DAC Source AXI Agent", PASSTHROUGH, this); - - this.scoreboard_tx = new("Data Offload TX Scoreboard", this); - this.scoreboard_rx = new("Data Offload RX Scoreboard", this); - endfunction - - //============================================================================ - // Configure environment - // - Configure the sequencer VIPs with an initial configuration before starting them - //============================================================================ - task configure(int bytes_to_generate); - // ADC stub - this.adc_src_axis_agent.master_sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - this.adc_src_axis_agent.master_sequencer.add_xfer_descriptor_byte_count(bytes_to_generate, 0, 0); - - // DAC stub - this.dac_dst_axis_agent.slave_sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); - endtask - - //============================================================================ - // Start environment - // - Connect all the agents to the scoreboard - // - Start the agents - //============================================================================ - task start(); - this.adc_src_axis_agent.start_master(); - this.dac_dst_axis_agent.start_slave(); - - this.dac_dst_axis_agent.monitor.publisher.subscribe(this.scoreboard_tx.subscriber_sink); - - this.adc_src_axis_agent.monitor.publisher.subscribe(this.scoreboard_rx.subscriber_source); - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run(); - fork - this.adc_src_axis_agent.master_sequencer.start(); - this.dac_dst_axis_agent.slave_sequencer.start(); - - this.scoreboard_tx.run(); - this.scoreboard_rx.run(); - join_none - endtask - - //============================================================================ - // Stop subroutine - //============================================================================ - task stop(); - this.adc_src_axis_agent.stop_master(); - this.dac_dst_axis_agent.stop_slave(); - endtask - - endclass - -endpackage diff --git a/testbenches/ip/scoreboard/system_bd.tcl b/testbenches/ip/scoreboard/system_bd.tcl index a9929693c..ec2ae2c4b 100644 --- a/testbenches/ip/scoreboard/system_bd.tcl +++ b/testbenches/ip/scoreboard/system_bd.tcl @@ -35,143 +35,28 @@ global ad_project_params -source "$ad_hdl_dir/projects/common/xilinx/data_offload_bd.tcl" - -## DUT configuration - -set adc_data_path_width $ad_project_params(ADC_DATA_PATH_WIDTH) -set dac_data_path_width $ad_project_params(DAC_DATA_PATH_WIDTH) - -set adc_path_type $ad_project_params(ADC_PATH_TYPE) -set adc_offload_mem_type $ad_project_params(ADC_OFFLOAD_MEM_TYPE) -set adc_offload_size $ad_project_params(ADC_OFFLOAD_SIZE) -set adc_offload_src_dwidth $ad_project_params(ADC_OFFLOAD_SRC_DWIDTH) -set adc_offload_dst_dwidth $ad_project_params(ADC_OFFLOAD_DST_DWIDTH) - -set dac_path_type $ad_project_params(DAC_PATH_TYPE) -set dac_offload_mem_type $ad_project_params(DAC_OFFLOAD_MEM_TYPE) -set dac_offload_size $ad_project_params(DAC_OFFLOAD_SIZE) -set dac_offload_src_dwidth $ad_project_params(DAC_OFFLOAD_SRC_DWIDTH) -set dac_offload_dst_dwidth $ad_project_params(DAC_OFFLOAD_DST_DWIDTH) - -set plddr_offload_data_width $ad_project_params(PLDDR_OFFLOAD_DATA_WIDTH) - -ad_ip_instance xlconstant GND [list \ - CONST_VAL 0 \ +ad_ip_instance axi4stream_vip adc_src_axis [list \ + INTERFACE_MODE {MASTER} \ + TDATA_NUM_BYTES 2 \ + HAS_TREADY {1} \ + HAS_TKEEP {1} \ + HAS_TLAST {1} \ ] -ad_connect gnd GND/dout - -for {set i 0} {$i < 2} {incr i} { - ad_ip_instance axi_dmac i_rx_dmac_${i} [list \ - DMA_TYPE_SRC 1 \ - DMA_TYPE_DEST 0 \ - ID 0 \ - AXI_SLICE_SRC 1 \ - AXI_SLICE_DEST 1 \ - SYNC_TRANSFER_START 0 \ - DMA_LENGTH_WIDTH 24 \ - DMA_2D_TRANSFER 0 \ - MAX_BYTES_PER_BURST 4096 \ - CYCLIC 0 \ - DMA_DATA_WIDTH_SRC $adc_offload_dst_dwidth \ - DMA_DATA_WIDTH_DEST 64 \ - ] - - ad_ip_instance axi_dmac i_tx_dmac_${i} [list \ - DMA_TYPE_SRC 0 \ - DMA_TYPE_DEST 1 \ - ID 0 \ - AXI_SLICE_SRC 1 \ - AXI_SLICE_DEST 1 \ - SYNC_TRANSFER_START 0 \ - DMA_LENGTH_WIDTH 24 \ - DMA_2D_TRANSFER 0 \ - MAX_BYTES_PER_BURST 4096 \ - CYCLIC 1 \ - DMA_DATA_WIDTH_SRC 64 \ - DMA_DATA_WIDTH_DEST $dac_offload_src_dwidth \ - ] - - ad_data_offload_create RX_DUT_${i} \ - 0 \ - $adc_offload_mem_type \ - $adc_offload_size \ - $adc_offload_src_dwidth \ - $adc_offload_dst_dwidth \ - $plddr_offload_data_width - - ad_data_offload_create TX_DUT_${i} \ - 1 \ - $dac_offload_mem_type \ - $dac_offload_size \ - $dac_offload_src_dwidth \ - $dac_offload_dst_dwidth \ - $plddr_offload_data_width - - set BA 0x50000000 - ad_cpu_interconnect [expr ${BA} + 0x00000 + $i*0x40000] i_rx_dmac_${i} - ad_cpu_interconnect [expr ${BA} + 0x10000 + $i*0x40000] i_tx_dmac_${i} - ad_cpu_interconnect [expr ${BA} + 0x20000 + $i*0x40000] RX_DUT_${i} - ad_cpu_interconnect [expr ${BA} + 0x30000 + $i*0x40000] TX_DUT_${i} - - adi_sim_add_define "RX_DMA_BA_${i}=[format "%d" [expr ${BA} + 0x00000 + $i*0x40000]]" - adi_sim_add_define "TX_DMA_BA_${i}=[format "%d" [expr ${BA} + 0x10000 + $i*0x40000]]" - adi_sim_add_define "RX_DOFF_BA_${i}=[format "%d" [expr ${BA} + 0x20000 + $i*0x40000]]" - adi_sim_add_define "TX_DOFF_BA_${i}=[format "%d" [expr ${BA} + 0x30000 + $i*0x40000]]" +adi_sim_add_define "ADC_SRC_AXIS=adc_src_axis" - ad_ip_instance axi4stream_vip adc_src_axis_${i} [list \ - INTERFACE_MODE {MASTER} \ - HAS_TREADY {1} \ - HAS_TLAST {0} \ - TDATA_NUM_BYTES $adc_data_path_width \ - ] - adi_sim_add_define "ADC_SRC_AXIS_${i}=adc_src_axis_${i}" +ad_connect sys_dma_clk adc_src_axis/aclk +ad_connect sys_dma_resetn adc_src_axis/aresetn - ad_connect adc_src_axis_${i}/m_axis RX_DUT_${i}/s_axis - ad_connect RX_DUT_${i}/m_axis i_rx_dmac_${i}/s_axis - - ad_connect sys_dma_clk adc_src_axis_${i}/aclk - ad_connect sys_dma_resetn adc_src_axis_${i}/aresetn - - ad_connect sys_dma_clk RX_DUT_${i}/s_axis_aclk - ad_connect sys_dma_resetn RX_DUT_${i}/s_axis_aresetn - ad_connect sys_cpu_clk RX_DUT_${i}/m_axis_aclk - ad_connect sys_cpu_resetn RX_DUT_${i}/m_axis_aresetn - - ad_connect sys_cpu_clk i_rx_dmac_${i}/s_axis_aclk - ad_connect sys_mem_clk i_rx_dmac_${i}/m_dest_axi_aclk - ad_connect sys_mem_resetn i_rx_dmac_${i}/m_dest_axi_aresetn - - ad_connect i_rx_dmac_${i}/s_axis_xfer_req RX_DUT_${i}/init_req - ad_connect gnd RX_DUT_${i}/sync_ext - - ad_mem_hp0_interconnect sys_mem_clk i_rx_dmac_${i}/m_dest_axi - - ad_ip_instance axi4stream_vip dac_dst_axis_${i} [list \ - INTERFACE_MODE {SLAVE} \ - TDATA_NUM_BYTES $dac_data_path_width \ - HAS_TLAST {1} \ - HAS_TKEEP {0} \ - ] - adi_sim_add_define "DAC_DST_AXIS_${i}=dac_dst_axis_${i}" - - ad_connect sys_dma_clk dac_dst_axis_${i}/aclk - ad_connect sys_dma_resetn dac_dst_axis_${i}/aresetn - - ad_connect sys_dma_clk TX_DUT_${i}/m_axis_aclk - ad_connect sys_dma_resetn TX_DUT_${i}/m_axis_aresetn - ad_connect sys_cpu_clk TX_DUT_${i}/s_axis_aclk - ad_connect sys_cpu_resetn TX_DUT_${i}/s_axis_aresetn - - ad_connect sys_cpu_clk i_tx_dmac_${i}/m_axis_aclk - ad_connect sys_mem_clk i_tx_dmac_${i}/m_src_axi_aclk - ad_connect sys_mem_resetn i_tx_dmac_${i}/m_src_axi_aresetn - - ad_connect TX_DUT_${i}/m_axis dac_dst_axis_${i}/s_axis - ad_connect TX_DUT_${i}/s_axis i_tx_dmac_${i}/m_axis +ad_ip_instance axi4stream_vip dac_dst_axis [list \ + INTERFACE_MODE {SLAVE} \ + TDATA_NUM_BYTES 2 \ + HAS_TREADY {1} \ + HAS_TKEEP {1} \ + HAS_TLAST {1} \ +] +adi_sim_add_define "DAC_DST_AXIS=dac_dst_axis" - ad_connect i_tx_dmac_${i}/m_axis_xfer_req TX_DUT_${i}/init_req - ad_connect gnd TX_DUT_${i}/sync_ext +ad_connect sys_dma_clk dac_dst_axis/aclk +ad_connect sys_dma_resetn dac_dst_axis/aresetn - ad_mem_hp0_interconnect sys_mem_clk i_tx_dmac_${i}/m_src_axi -} +ad_connect adc_src_axis/m_axis dac_dst_axis/s_axis diff --git a/testbenches/ip/scoreboard/system_project.tcl b/testbenches/ip/scoreboard/system_project.tcl index 932901de9..945fcc6e5 100644 --- a/testbenches/ip/scoreboard/system_project.tcl +++ b/testbenches/ip/scoreboard/system_project.tcl @@ -18,12 +18,9 @@ adi_sim_project_xilinx $project_name "xcvu9p-flga2104-2L-e" source $ad_tb_dir/library/includes/sp_include_axis.tcl source $ad_tb_dir/library/includes/sp_include_scoreboard.tcl -source $ad_tb_dir/library/includes/sp_include_dmac.tcl -source $ad_tb_dir/library/includes/sp_include_data_offload.tcl # Add test files to the project adi_sim_project_files [list \ - "environment.sv" \ "tests/test_program.sv" \ ] diff --git a/testbenches/ip/scoreboard/tests/test_program.sv b/testbenches/ip/scoreboard/tests/test_program.sv index 74479215f..49395b672 100644 --- a/testbenches/ip/scoreboard/tests/test_program.sv +++ b/testbenches/ip/scoreboard/tests/test_program.sv @@ -39,22 +39,17 @@ import logger_pkg::*; import test_harness_env_pkg::*; -import environment_pkg::*; import adi_axi_agent_pkg::*; import adi_axis_agent_pkg::*; -import dmac_api_pkg::*; -import data_offload_api_pkg::*; +import axi4stream_vip_pkg::*; +import m_axis_sequencer_pkg::*; +import scoreboard_pkg::*; import `PKGIFY(test_harness, mng_axi_vip)::*; import `PKGIFY(test_harness, ddr_axi_vip)::*; -import `PKGIFY(test_harness, adc_src_axis_0)::*; -import `PKGIFY(test_harness, dac_dst_axis_0)::*; - -import `PKGIFY(test_harness, adc_src_axis_1)::*; -import `PKGIFY(test_harness, dac_dst_axis_1)::*; - -`define ADC_TRANSFER_LENGTH 32'h600 +import `PKGIFY(test_harness, adc_src_axis)::*; +import `PKGIFY(test_harness, dac_dst_axis)::*; program test_program(); @@ -64,30 +59,15 @@ program test_program(); // declare the class instances test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; - scoreboard_environment scb_env_0; - - adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; - - adi_axis_master_agent #(`AXIS_VIP_PARAMS(test_harness, adc_src_axis_0)) adc_src_axis_agent_0; - adi_axis_slave_agent #(`AXIS_VIP_PARAMS(test_harness, dac_dst_axis_0)) dac_dst_axis_agent_0; - - scoreboard_environment scb_env_1; + adi_axis_master_agent #(`AXIS_VIP_PARAMS(test_harness, adc_src_axis)) adc_src_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAMS(test_harness, dac_dst_axis)) dac_dst_axis_agent; - adi_axis_master_agent #(`AXIS_VIP_PARAMS(test_harness, adc_src_axis_1)) adc_src_axis_agent_1; - adi_axis_slave_agent #(`AXIS_VIP_PARAMS(test_harness, dac_dst_axis_1)) dac_dst_axis_agent_1; - - dmac_api dmac_tx_0; - dmac_api dmac_rx_0; - dmac_api dmac_tx_1; - dmac_api dmac_rx_1; - - data_offload_api do_tx_0; - data_offload_api do_rx_0; - data_offload_api do_tx_1; - data_offload_api do_rx_1; + scoreboard #(logic [7:0]) scoreboard; initial begin + setLoggerVerbosity(ADI_VERBOSITY_NONE); + // create environment base_env = new("Base Environment", `TH.`SYS_CLK.inst.IF, @@ -97,96 +77,38 @@ program test_program(); `TH.`MNG_AXI.inst.IF, `TH.`DDR_AXI.inst.IF); - ddr = base_env.ddr; + adc_src_axis_agent = new("Source", `TH.`ADC_SRC_AXIS.inst.IF); + dac_dst_axis_agent = new("Destination", `TH.`DAC_DST_AXIS.inst.IF); - scb_env_0 = new("Scoreboard Environment 0"); + scoreboard = new("Scoreboard"); - adc_src_axis_agent_0 = new("", `TH.`ADC_SRC_AXIS_0.inst.IF); - dac_dst_axis_agent_0 = new("", `TH.`DAC_DST_AXIS_0.inst.IF); + // configure the sequencers + adc_src_axis_agent.master_sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); + adc_src_axis_agent.master_sequencer.add_xfer_descriptor_byte_count(32'h100, 1, 0); - `LINK(adc_src_axis_agent_0, scb_env_0, adc_src_axis_agent) - `LINK(dac_dst_axis_agent_0, scb_env_0, dac_dst_axis_agent) - `LINK(ddr, scb_env_0, adc_dst_axi_pt_agent) - `LINK(ddr, scb_env_0, dac_src_axi_pt_agent) - - scb_env_1 = new("Scoreboard Environment 1"); - - adc_src_axis_agent_1 = new("", `TH.`ADC_SRC_AXIS_1.inst.IF); - dac_dst_axis_agent_1 = new("", `TH.`DAC_DST_AXIS_1.inst.IF); - - `LINK(adc_src_axis_agent_1, scb_env_1, adc_src_axis_agent) - `LINK(dac_dst_axis_agent_1, scb_env_1, dac_dst_axis_agent) - `LINK(ddr, scb_env_1, adc_dst_axi_pt_agent) - `LINK(ddr, scb_env_1, dac_src_axi_pt_agent) - - dmac_tx_0 = new("DMAC TX 0", base_env.mng.master_sequencer, `TX_DMA_BA_0); - dmac_rx_0 = new("DMAC RX 0", base_env.mng.master_sequencer, `RX_DMA_BA_0); - dmac_tx_1 = new("DMAC TX 1", base_env.mng.master_sequencer, `TX_DMA_BA_1); - dmac_rx_1 = new("DMAC RX 1", base_env.mng.master_sequencer, `RX_DMA_BA_1); - - do_tx_0 = new("Data Offload TX 0", base_env.mng.master_sequencer, `TX_DOFF_BA_0); - do_rx_0 = new("Data Offload RX 0", base_env.mng.master_sequencer, `RX_DOFF_BA_0); - do_tx_1 = new("Data Offload TX 1", base_env.mng.master_sequencer, `TX_DOFF_BA_1); - do_rx_1 = new("Data Offload RX 1", base_env.mng.master_sequencer, `RX_DOFF_BA_1); - - //========================================================================= - // Setup generator/monitor stubs - //========================================================================= - - setLoggerVerbosity(ADI_VERBOSITY_NONE); + dac_dst_axis_agent.slave_sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + // start the environment base_env.start(); - scb_env_0.start(); - scb_env_1.start(); - - base_env.ddr.monitor.publisher_rx.subscribe(scb_env_0.scoreboard_tx.subscriber_source); - base_env.ddr.monitor.publisher_tx.subscribe(scb_env_0.scoreboard_rx.subscriber_sink); - - base_env.ddr.monitor.publisher_rx.subscribe(scb_env_1.scoreboard_tx.subscriber_source); - base_env.ddr.monitor.publisher_tx.subscribe(scb_env_1.scoreboard_rx.subscriber_sink); - + adc_src_axis_agent.start_master(); + dac_dst_axis_agent.start_slave(); base_env.sys_reset(); - // configure environment sequencers - scb_env_0.configure(`ADC_TRANSFER_LENGTH); - scb_env_1.configure(`ADC_TRANSFER_LENGTH); - - `INFO(("Bring up IP from reset."), ADI_VERBOSITY_LOW); - systemBringUp(); - - //do_set_transfer_length(`ADC_TRANSFER_LENGTH); - do_set_transfer_length(`ADC_TRANSFER_LENGTH/64); - - // Start the ADC/DAC stubs - `INFO(("Start the sequencer"), ADI_VERBOSITY_LOW); - scb_env_0.adc_src_axis_agent.master_sequencer.start(); - scb_env_1.adc_src_axis_agent.master_sequencer.start(); + // subscribe and start the scoreboard + adc_src_axis_agent.monitor.publisher.subscribe(scoreboard.subscriber_source); + dac_dst_axis_agent.monitor.publisher.subscribe(scoreboard.subscriber_sink); - // Generate DMA transfers - `INFO(("Start RX DMA"), ADI_VERBOSITY_LOW); - rx_dma_transfer(dmac_rx_0, 32'h80000000, `ADC_TRANSFER_LENGTH); - rx_dma_transfer(dmac_rx_1, 32'h80000000, `ADC_TRANSFER_LENGTH); + scoreboard.run(); - fork - scb_env_0.scoreboard_rx.wait_until_complete(); - scb_env_1.scoreboard_rx.wait_until_complete(); - join - - `INFO(("Initialize the memory"), ADI_VERBOSITY_LOW); - init_mem_64(32'h80000000, 1024); - - `INFO(("Start TX DMA"), ADI_VERBOSITY_LOW); - tx_dma_transfer(dmac_tx_0, 32'h80000000, 1024); - tx_dma_transfer(dmac_tx_1, 32'h80000000, 1024); + // generate data + adc_src_axis_agent.master_sequencer.start(); + dac_dst_axis_agent.slave_sequencer.start(); #1us; - fork - scb_env_0.scoreboard_tx.wait_until_complete(); - scb_env_1.scoreboard_tx.wait_until_complete(); - join - scb_env_0.stop(); - scb_env_1.stop(); + // wait for scoreboard to be empty on both sides + scoreboard.wait_until_complete(); + base_env.stop(); `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); @@ -194,76 +116,4 @@ program test_program(); end - task systemBringUp(); - // bring up the Data Offload instances from reset - `INFO(("Bring up RX Data Offload 0"), ADI_VERBOSITY_LOW); - do_rx_0.deassert_reset(); - `INFO(("Bring up TX Data Offload 0"), ADI_VERBOSITY_LOW); - do_tx_0.deassert_reset(); - - `INFO(("Bring up RX Data Offload 1"), ADI_VERBOSITY_LOW); - do_rx_1.deassert_reset(); - `INFO(("Bring up TX Data Offload 1"), ADI_VERBOSITY_LOW); - do_tx_1.deassert_reset(); - - // Enable tx oneshot mode - do_tx_0.enable_oneshot_mode(); - do_tx_1.enable_oneshot_mode(); - - // bring up the DMAC instances from reset - `INFO(("Bring up RX DMAC 0"), ADI_VERBOSITY_LOW); - dmac_rx_0.enable_dma(); - `INFO(("Bring up TX DMAC 0"), ADI_VERBOSITY_LOW); - dmac_tx_0.enable_dma(); - - `INFO(("Bring up RX DMAC 1"), ADI_VERBOSITY_LOW); - dmac_rx_1.enable_dma(); - `INFO(("Bring up TX DMAC 1"), ADI_VERBOSITY_LOW); - dmac_tx_1.enable_dma(); - endtask - - task do_set_transfer_length(input int length); - do_rx_0.set_transfer_length(length); - do_rx_1.set_transfer_length(length); - endtask - - // RX DMA transfer generator - task rx_dma_transfer( - input dmac_api dmac, - input int xfer_addr, - input int xfer_length); - dmac.set_flags( - .cyclic(1'b0), - .tlast(1'b1), - .partial_reporting_en(1'b1)); - dmac.set_dest_addr(xfer_addr); - dmac.set_lengths(xfer_length - 1, 0); - dmac.transfer_start(); - endtask - - // TX DMA transfer generator - task tx_dma_transfer( - input dmac_api dmac, - input int xfer_addr, - input int xfer_length); - dmac.set_flags( - .cyclic(1'b0), - .tlast(1'b1), - .partial_reporting_en(1'b0)); - dmac.set_src_addr(xfer_addr); - dmac.set_lengths(xfer_length - 1, 0); - dmac.transfer_start(); - endtask - - // Memory initialization function for a 8byte DATA_WIDTH AXI4 bus - task init_mem_64( - input longint unsigned addr, - input int byte_length); - `INFO(("Initial address: %x", addr), ADI_VERBOSITY_LOW); - for (int i=0; i - - - - + + + + + + + - - - - - - + - - - - - - - - - + + - + - - - M_AXI - M_AXI + + + M_AXIS + M_AXIS - - RX - label - - - RX_DO - label - - - s_axis - s_axis - - - m_axis - m_axis - - - - RX_DMA - label - - - s_axis - s_axis - - - m_dest_axi - m_dest_axi - - - - TX - label - - - TX_DMA - label - - - m_src_axi - m_src_axi - - - m_axis - m_axis - - - - TX_DO - label - - - s_axis - s_axis - - - m_axis - m_axis - + + S_AXIS + S_AXIS