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 @@
+
\ 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()void2
+
+
+
\ 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