diff --git a/docs/library/utilities/index.rst b/docs/library/utilities/index.rst index 5caf4775..316ca78c 100644 --- a/docs/library/utilities/index.rst +++ b/docs/library/utilities/index.rst @@ -8,5 +8,6 @@ Contents .. toctree:: :maxdepth: 1 + :glob: - Test Harness + */index diff --git a/docs/library/utilities/irq_handler/index.rst b/docs/library/utilities/irq_handler/index.rst new file mode 100644 index 00000000..b459237e --- /dev/null +++ b/docs/library/utilities/irq_handler/index.rst @@ -0,0 +1,67 @@ +.. _irq_handler: + +IRQ Handler +================================================================================ + +Overview +------------------------------------------------------------------------------- + +The purpose of this class is to provide an object that can simulate a processor +interrupt handler. The class relies on the AXI Interrupt Controller from AMD and +it uses an IO VIP to monitor the IRQ pin. + +.. svg:: library/utilities/irq_handler/irq_handler.svg + :align: center + +Variables +------------------------------------------------------------------------------- + +None are available for direct external access. + +Functions +------------------------------------------------------------------------------- + +function new(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates the irq_handler object. It requires a name, a master AXI sequencer +reference object with which it accesses the interrupt controller, the address of +the controller, the IO VIP interface handler and a parent if it's the case. + +function void enable_software_testing(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Enables software testing. + +task software_irq_testing(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Triggeres a software interrupt test, which can be used to verify certain +functions at system powerup. + +task start(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Starts the IRQ handler, which configures and enables the interrupt controller. +After that, it monitors the IO VIP, waiting for the arrival of interrupts. Once +triggered, it goes over the list of triggered interrupts and signals the +responsible classes to handle their respective interrupt. If software testing is +enabled, it will automatically trigger a software interrupt after starting the +monitor. + +function event register_device(input int position); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Registers an event reference for an object, that has an interrupt signal +connected to the controller. Gives a fatal error if a device is already +registered in the same location. + +Usage +------------------------------------------------------------------------------- + +* Declare the irq handler, set up with the required parameters +* Registers all devices that are connected to the interrupt controller +* Optionally enable software interrupt +* Start the irq handler + +.. include:: ../../../common/support.rst diff --git a/docs/library/utilities/irq_handler/irq_handler.svg b/docs/library/utilities/irq_handler/irq_handler.svg new file mode 100755 index 00000000..a07536f0 --- /dev/null +++ b/docs/library/utilities/irq_handler/irq_handler.svg @@ -0,0 +1,95 @@ +adi_reporteradi_componentm_axi_sequencerio_vipirq_handler#irq_vip_if#irq_event_list#irq_valid_list#software_testing+enable_software_testing()void+software_irq_testing()void+start()void+register_device()void + + + \ No newline at end of file diff --git a/docs/library/utilities/irq_handler/irq_handler.txt b/docs/library/utilities/irq_handler/irq_handler.txt new file mode 100644 index 00000000..d1dc0634 --- /dev/null +++ b/docs/library/utilities/irq_handler/irq_handler.txt @@ -0,0 +1,30 @@ +# Classes + +# Base +adi_reporter: {shape: class} +adi_component: {shape: class} +m_axi_sequencer: {shape: class} +io_vip: {shape: class} + +# Scoreboard +irq_handler: { + shape: class + \#irq_vip_if + \#irq_event_list + \#irq_valid_list + \#software_testing + +enable_software_testing() + +software_irq_testing() + +start() + +register_device() +} + +# Inheritances + +adi_reporter <- adi_component: {shape: triangle; source-arrowhead.style.filled: false} +adi_component <- irq_handler: {shape: triangle; source-arrowhead.style.filled: false} + +# Aggregations + +irq_handler <- m_axi_sequencer: {source-arrowhead: {shape: diamond; style.filled: false}} +irq_handler <- io_vip: {source-arrowhead: {shape: diamond; style.filled: true}} diff --git a/docs/testbenches/common/dependency_common.rst b/docs/testbenches/common/dependency_common.rst index 667f161d..4a7d05bb 100644 --- a/docs/testbenches/common/dependency_common.rst +++ b/docs/testbenches/common/dependency_common.rst @@ -7,6 +7,9 @@ Common with most testbenches: * - SV dependency name - Source code link - Documentation link + * - IRQ_HANDLER + - :git-testbenches:`library/utilities/irq_handler_pkg.sv` + - --- * - LOGGER_PKG - :git-testbenches:`library/utilities/logger_pkg.sv` - --- diff --git a/docs/testbenches/ip_based/irq_handler/index.rst b/docs/testbenches/ip_based/irq_handler/index.rst new file mode 100644 index 00000000..73474155 --- /dev/null +++ b/docs/testbenches/ip_based/irq_handler/index.rst @@ -0,0 +1,188 @@ +.. _irq_handler_tb: + +IRQ handler +================================================================================ + +Overview +------------------------------------------------------------------------------- + +The purpose of this testbench is to give engineers a sandbox testbench, where +they can test the interrupt request handler class. + +Block design +------------------------------------------------------------------------------- + +The block design is based on the test harness with the addition of an IO VIP. +The VIP is configure to be in master mode and connected to the interrupt +controller's bit 0 position. + +Block diagram +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. image:: ./irq_handler_tb.svg + :width: 800 + :align: center + :alt: IRQ_Handler/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 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Below are the CPU/Memory interconnect addresses used in this project: + +======== =========== +Instance Address +======== =========== +axi_intc 0x4120_0000 +======== =========== + +Interrupts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Below are the Programmable Logic interrupts used in this project: + +============= === +Instance name HDL +============= === +irq_test_vip 0 +============= === + +Test stimulus +------------------------------------------------------------------------------- + +The test program is responsible for configuring and running the sequencers. + +Environment Bringup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The steps of the environment bringup are: + +* Create the environment +* Link the agents +* Instantiate the IRQ handler class +* Start the environment +* Start the clocks +* Assert the resets + +IRQ handler testing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Register the IO VIP device event to the IRQ handler +* Start the IRQ handler class +* Create a subthread to catch the triggered event from IRQ handler +* Generate an IRQ and see if the subthread is triggered + +Priority packet generation testing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Create 10 priority and 10 non-priority packets at the same time and check if + the priority packets are processed first. + +.. note:: + + Priority packet processing order is checked manually. + +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/irq_handler + $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/irq_handler + $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/irq_handler + $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: None + +.. include:: ../../../common/more_information.rst + +.. include:: ../../../common/support.rst diff --git a/docs/testbenches/ip_based/irq_handler/irq_handler_tb.svg b/docs/testbenches/ip_based/irq_handler/irq_handler_tb.svg new file mode 100644 index 00000000..8fa17922 --- /dev/null +++ b/docs/testbenches/ip_based/irq_handler/irq_handler_tb.svg @@ -0,0 +1,673 @@ + + + + + + + + + + + + + Test module + + + + + + Top module + + + + + + IRQ Test + + + + + + Test program + + + + + + Test Harness + + + + + + PS AXI VIP + + + + + + PSInterconnect + + + + + + DDRInterconnect + + + + + + DDR AXI VIP + + + + + + IRQ Controller + + + + + + IRQ IO VIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/drivers/common/mailbox.sv b/library/drivers/common/mailbox.sv deleted file mode 100644 index 4f468bc2..00000000 --- a/library/drivers/common/mailbox.sv +++ /dev/null @@ -1,67 +0,0 @@ -`include "utils.svh" - -package mailbox_pkg; - - import logger_pkg::*; - - class mailbox_c #(type T) extends adi_component; - - T queue[$]; - - int size_max; - - event q_event; - - // constructor - function new( - input string name, - input int size_max = 0, - input adi_component parent = null); - - super.new(name, parent); - - this.size_max = size_max; - endfunction - - function int num(); - return this.queue.size(); - endfunction - - task get(ref T element); - if (this.num() == 0) - @this.q_event; - element = this.queue.pop_back(); - ->this.q_event; - endtask - - function int try_get(ref T element); - if (this.num() == 0) - return 0; - element = this.queue.pop_back(); - ->this.q_event; - return 1; - endfunction - - task put(input T element); - if (this.size_max == this.num() && this.size_max != 0) - @this.q_event; - this.queue.push_front(element); - ->this.q_event; - endtask - - function int try_put(input T element); - if (this.size_max == this.num() && this.size_max != 0) - return 0; - this.queue.push_front(element); - ->this.q_event; - return 1; - endfunction - - task flush(); - T element; - while(this.try_get(element)); - endtask - - endclass - -endpackage diff --git a/library/drivers/common/scoreboard.sv b/library/drivers/common/scoreboard.sv index 640dabab..b2d54f43 100644 --- a/library/drivers/common/scoreboard.sv +++ b/library/drivers/common/scoreboard.sv @@ -1,28 +1,99 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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" package scoreboard_pkg; - import xil_common_vip_pkg::*; - import axi4stream_vip_pkg::*; - import axi_vip_pkg::*; import logger_pkg::*; - import x_monitor_pkg::*; - import mailbox_pkg::*; + import adi_common_pkg::*; + import pub_sub_pkg::*; - class scoreboard extends adi_component; + class scoreboard #(type data_type = int) extends adi_component; - typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t; - protected sink_type_t sink_type; + class subscriber_class extends adi_subscriber #(data_type); + + protected scoreboard #(data_type) scoreboard_ref; + + protected data_type byte_stream [$]; + + function new( + input string name, + input scoreboard #(data_type) scoreboard_ref, + input adi_component parent = null); + + super.new(name, parent); + + this.scoreboard_ref = scoreboard_ref; + endfunction: new + + virtual function void update(input data_type data [$]); + this.info($sformatf("Data received: %d", data.size()), ADI_VERBOSITY_MEDIUM); + while (data.size()) begin + this.byte_stream.push_back(data.pop_front()); + end + + if (this.scoreboard_ref.get_enabled()) begin + this.scoreboard_ref.compare_transaction(); + end + endfunction: update + + function data_type get_data(); + return this.byte_stream.pop_front(); + endfunction: get_data - // List of analysis ports from the monitors - protected x_monitor source_monitor; - protected x_monitor sink_monitor; + function void put_data(data_type data); + this.byte_stream.push_back(data); + endfunction: put_data - protected logic [7:0] source_byte_stream [$]; - protected logic [7:0] sink_byte_stream [$]; + function int get_size(); + return this.byte_stream.size(); + endfunction: get_size - protected int source_byte_stream_size; - protected int sink_byte_stream_size; + function void clear_stream(); + this.byte_stream.delete(); + endfunction: clear_stream + + endclass: subscriber_class + + + subscriber_class subscriber_source; + subscriber_class subscriber_sink; + + typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t; + protected sink_type_t sink_type; // counters and synchronizers protected bit enabled; @@ -31,8 +102,6 @@ package scoreboard_pkg; // protected event end_of_first_cycle; protected event byte_streams_empty; protected event stop_scoreboard; - protected event source_transaction_event; - protected event sink_transaction_event; // constructor function new( @@ -41,186 +110,86 @@ package scoreboard_pkg; super.new(name, parent); + this.subscriber_source = new("Subscriber Source", this); + this.subscriber_sink = new("Subscriber Sink", this); + this.enabled = 0; this.sink_type = ONESHOT; - this.source_byte_stream_size = 0; - this.sink_byte_stream_size = 0; this.byte_streams_empty_sig = 1; - endfunction: new - // connect the analysis ports of the monitor to the scoreboard - function void set_source_stream( - x_monitor source_monitor); - - this.source_monitor = source_monitor; - - endfunction: set_source_stream - - function void set_sink_stream( - x_monitor sink_monitor); - - this.sink_monitor = sink_monitor; - - endfunction: set_sink_stream - // run task task run(); - - fork - this.enabled = 1; - this.get_source_transaction(); - this.get_sink_transaction(); - this.compare_transaction(); - join_none - + this.enabled = 1; + + this.info($sformatf("Scoreboard enabled"), ADI_VERBOSITY_MEDIUM); endtask: run // stop scoreboard task stop(); this.enabled = 0; - ->>stop_scoreboard; this.clear_streams(); - #1step; + this.byte_streams_empty_sig = 1; endtask: stop + function bit get_enabled(); + return this.enabled; + endfunction: get_enabled + // set sink type function void set_sink_type(input bit sink_type); - if (!this.enabled) begin this.sink_type = sink_type_t'(sink_type); end else begin this.error($sformatf("Can not configure sink_type while scoreboard is running.")); end - endfunction: set_sink_type - // clear source and sink byte streams - function void clear_streams(); - this.source_byte_stream.delete(); - this.sink_byte_stream.delete(); - - this.source_byte_stream_size = 0; - this.sink_byte_stream_size = 0; - endfunction: clear_streams - // get sink type function bit get_sink_type(); return this.sink_type; - endfunction + endfunction: get_sink_type + + // clear source and sink byte streams + protected function void clear_streams(); + this.subscriber_source.clear_stream(); + this.subscriber_source.clear_stream(); + endfunction: clear_streams // wait until source and sink byte streams are empty, full check task wait_until_complete(); if (this.byte_streams_empty_sig) return; - @byte_streams_empty; - endtask - - // get transaction data from source monitor - task get_source_transaction(); - - logic [7:0] source_byte; - - forever begin - fork begin - fork - this.source_monitor.wait_for_transaction_event(); - @stop_scoreboard; - join_any - disable fork; - end join - if (this.enabled == 0) - break; - - this.source_monitor.get_key(); - for (int i=0; i>source_transaction_event; - this.source_monitor.put_key(); - end - - endtask: get_source_transaction - - // get transaction data from sink monitor - task get_sink_transaction(); - - logic [7:0] sink_byte; - - forever begin - fork begin - fork - this.sink_monitor.wait_for_transaction_event(); - @stop_scoreboard; - join_any - disable fork; - end join - - if (this.enabled == 0) - break; - - this.sink_monitor.get_key(); - for (int i=0; i>sink_transaction_event; - this.sink_monitor.put_key(); - end - - endtask: get_sink_transaction + @this.byte_streams_empty; + endtask: wait_until_complete // compare the collected data - virtual task compare_transaction(); - - logic [7:0] source_byte; - logic [7:0] sink_byte; - - this.info($sformatf("Started"), ADI_VERBOSITY_MEDIUM); - - forever begin : tx_path - if (this.enabled == 0) - break; - if ((this.source_byte_stream_size > 0) && - (this.sink_byte_stream_size > 0)) begin - byte_streams_empty_sig = 0; - source_byte = this.source_byte_stream.pop_back(); - if (this.sink_type == CYCLIC) - this.source_byte_stream.push_front(source_byte); - else - this.source_byte_stream_size--; - sink_byte = this.sink_byte_stream.pop_back(); - this.sink_byte_stream_size--; - this.info($sformatf("Source-sink data: exp %h - rcv %h", source_byte, sink_byte), ADI_VERBOSITY_MEDIUM); - if (source_byte != sink_byte) begin - this.error($sformatf("Failed at: exp %h - rcv %h", source_byte, sink_byte)); - end - end else begin - if ((this.source_byte_stream_size == 0) && - (this.sink_byte_stream_size == 0)) begin - byte_streams_empty_sig = 1; - ->>byte_streams_empty; - end - fork begin - fork - @source_transaction_event; - @sink_transaction_event; - @stop_scoreboard; - join_any - byte_streams_empty_sig = 0; - disable fork; - end join + virtual function void compare_transaction(); + data_type source_byte; + data_type sink_byte; + + if (this.enabled == 0) + return; + + while ((this.subscriber_source.get_size() > 0) && + (this.subscriber_sink.get_size() > 0)) begin + byte_streams_empty_sig = 0; + source_byte = this.subscriber_source.get_data(); + if (this.sink_type == CYCLIC) + this.subscriber_source.put_data(source_byte); + sink_byte = this.subscriber_sink.get_data(); + this.info($sformatf("Source-sink data: exp %h - rcv %h", source_byte, sink_byte), ADI_VERBOSITY_MEDIUM); + if (source_byte != sink_byte) begin + this.error($sformatf("Failed at: exp %h - rcv %h", source_byte, sink_byte)); end end - endtask /* compare_transaction */ + if ((this.subscriber_source.get_size() == 0) && + (this.subscriber_sink.get_size() == 0)) begin + this.byte_streams_empty_sig = 1; + ->this.byte_streams_empty; + end + endfunction: compare_transaction endclass diff --git a/library/drivers/common/scoreboard_pack.sv b/library/drivers/common/scoreboard_pack.sv index 7a7b151d..25b3c15c 100644 --- a/library/drivers/common/scoreboard_pack.sv +++ b/library/drivers/common/scoreboard_pack.sv @@ -1,13 +1,44 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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" package scoreboard_pack_pkg; - import xil_common_vip_pkg::*; - import axi4stream_vip_pkg::*; - import axi_vip_pkg::*; import logger_pkg::*; - import x_monitor_pkg::*; - import mailbox_pkg::*; + import adi_common_pkg::*; import scoreboard_pkg::*; typedef enum { @@ -15,7 +46,7 @@ package scoreboard_pack_pkg; UPACK } pack_type; - class scoreboard_pack extends scoreboard; + class scoreboard_pack #(type data_type = int) extends scoreboard#(.data_type(data_type)); protected int channels; protected int samples; @@ -42,62 +73,46 @@ package scoreboard_pack_pkg; endfunction: new // compare the collected data - virtual task compare_transaction(); + virtual function void compare_transaction(); logic [7:0] source_byte; logic [7:0] sink_byte; - logic [7:0] sink_byte_stream_block [int]; + data_type sink_byte_stream_block [int]; int outer_loop = (this.mode == CPACK) ? this.channels : this.samples; int inner_loop = (this.mode == CPACK) ? this.samples : this.channels; - this.info($sformatf("Scoreboard started"), 100); - - forever begin : tx_path - if (this.enabled == 0) - break; - if ((this.source_byte_stream_size > 0) && - (this.sink_byte_stream_size >= this.channels*this.samples*this.width/8)) begin - byte_streams_empty_sig = 0; - for (int i=0; i 0) && + (this.subscriber_sink.get_size() >= this.channels*this.samples*this.width/8)) begin + byte_streams_empty_sig = 0; + for (int i=0; i>byte_streams_empty; - end - fork begin - fork - @source_transaction_event; - @sink_transaction_event; - @stop_scoreboard; - join_any - byte_streams_empty_sig = 0; - disable fork; - end join end - end + end - endtask /* compare_transaction */ + if ((this.subscriber_source.get_size() == 0) && + (this.subscriber_sink.get_size() == 0)) begin + this.byte_streams_empty_sig = 1; + ->this.byte_streams_empty; + end + endfunction: compare_transaction endclass diff --git a/library/drivers/common/watchdog.sv b/library/drivers/common/watchdog.sv index 917f3a32..94f270cb 100644 --- a/library/drivers/common/watchdog.sv +++ b/library/drivers/common/watchdog.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2021 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -26,17 +26,19 @@ // // 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/master/LICENSE_ADIBSD +// 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" package watchdog_pkg; import logger_pkg::*; + import adi_common_pkg::*; class watchdog extends adi_component; @@ -81,7 +83,7 @@ package watchdog_pkg; fork begin #(this.timer*1ns); - this.error($sformatf("Watchdog timer timed out! %s", this.message)); + this.fatal($sformatf("Watchdog timer timed out! %s", this.message)); end @this.stop_event; join_any diff --git a/library/drivers/common/x_monitor.sv b/library/drivers/common/x_monitor.sv deleted file mode 100644 index 2852b789..00000000 --- a/library/drivers/common/x_monitor.sv +++ /dev/null @@ -1,227 +0,0 @@ -`include "utils.svh" - -package x_monitor_pkg; - - import xil_common_vip_pkg::*; - import axi4stream_vip_pkg::*; - import axi_vip_pkg::*; - import logger_pkg::*; - import mailbox_pkg::*; - - class x_monitor extends adi_component; - - mailbox_c #(logic [7:0]) mailbox; - protected semaphore semaphore_key; - protected event transaction_event; - - protected bit enabled; - - // constructor - function new( - input string name, - input adi_component parent = null); - - super.new(name, parent); - - this.mailbox = new("Mailbox", 0, this); - this.semaphore_key = new(1); - endfunction - - // semaphore functions - task get_key(); - this.semaphore_key.get(); - endtask - - task put_key(); - this.semaphore_key.put(); - endtask - - // event functions - task transaction_captured(); - ->>this.transaction_event; - endtask - - task wait_for_transaction_event(); - @this.transaction_event; - endtask - - // run task - task run(); - - fork - this.enabled = 1; - get_transaction(); - join_none - - endtask /* run */ - - // virtual functions - virtual function void set_sink_type(input bit sink_type); - endfunction - - virtual function bit get_sink_type(); - endfunction - - virtual task get_transaction(); - endtask - - endclass - - typedef enum bit { - READ_OP = 1'b0, - WRITE_OP = 1'b1 - } operation_type_t; - - class x_axi_monitor #( type T, operation_type_t operation_type ) extends x_monitor; - // operation type: 1 - write - // 0 - read - - // analysis port from the monitor - protected xil_analysis_port #(axi_monitor_transaction) axi_ap; - - protected T agent; - - protected int axi_byte_stream_size; - - // constructor - function new( - input string name, - input T agent, - input adi_component parent = null); - - super.new(name, parent); - - this.enabled = 0; - - this.agent = agent; - this.axi_ap = this.agent.monitor.item_collected_port; - - this.axi_byte_stream_size = 0; - - endfunction /* new */ - - // collect data from the DDR interface, all WRITE transaction are coming - // from the ADC and all READ transactions are going to the DAC - virtual task get_transaction(); - - axi_monitor_transaction transaction; - xil_axi_data_beat data_beat; - xil_axi_strb_beat strb_beat; - int num_bytes; - logic [7:0] axi_byte; - - forever begin - this.get_key(); - this.axi_ap.get(transaction); - if (bit'(transaction.get_cmd_type()) == operation_type) begin - this.put_key(); - num_bytes = transaction.get_data_width()/8; - for (int i=0; i<(transaction.get_len()+1); i++) begin - data_beat = transaction.get_data_beat(i); - strb_beat = transaction.get_strb_beat(i); - for (int j=0; j +// +// 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" + +package adi_datatypes_pkg; + + import logger_pkg::*; + import adi_common_pkg::*; + + class adi_fifo #(type data_type = int) extends adi_component; + + local data_type adi_fifo [$]; + local int depth; + + function new( + input string name, + input int depth, + input adi_component parent = null); + + super.new(name, parent); + + this.depth = depth; + endfunction: new + + function bit push(input data_type data); + if (this.adi_fifo.size() == this.depth && this.depth != 0) begin + return 1'b0; + end else begin + this.adi_fifo.push_back(data); + return 1'b1; + end + endfunction: push + + function data_type pop(); + if (this.adi_fifo.size() == 0) begin + return null; + end else begin + return this.adi_fifo.pop_front(); + end + endfunction: pop + + function int room(); + return depth-this.adi_fifo.size(); + endfunction: room + + function int size(); + return this.adi_fifo.size(); + endfunction: room + + function void clear(); + this.adi_fifo.delete(); + endfunction: clear + + function bit insert( + input int index, + input data_type data); + + if (this.adi_fifo.size() == this.depth && this.depth != 0) begin + return 1'b0; + end else begin + this.adi_fifo.insert(index, data); + return 1'b1; + end + endfunction: clear + + endclass: adi_fifo + + + class adi_lifo #(type data_type = int) extends adi_component; + + local data_type adi_fifo [$]; + local int depth; + + function new( + input string name, + input int depth, + input adi_component parent = null); + + super.new(name, parent); + + this.depth = depth; + endfunction: new + + function bit push(input data_type data); + if (this.adi_fifo.size() == this.depth && this.depth != 0) begin + return 1'b0; + end else begin + this.adi_fifo.push_front(data); + return 1'b1; + end + endfunction: push + + function data_type pop(); + if (this.adi_fifo.size() == 0) begin + return null; + end else begin + return this.adi_fifo.pop_front(); + end + endfunction: pop + + function int room(); + return depth-this.adi_fifo.size(); + endfunction: room + + function int size(); + return this.adi_fifo.size(); + endfunction: room + + function void clear(); + this.adi_fifo.delete(); + endfunction: clear + + function bit insert( + input int index, + input data_type data); + + if (this.adi_fifo.size() == this.depth && this.depth != 0) begin + return 1'b0; + end else begin + this.adi_fifo.insert(index, data); + return 1'b1; + end + endfunction: clear + + endclass: adi_lifo + +endpackage: adi_datatypes_pkg diff --git a/library/regmaps/reg_accessor.sv b/library/utilities/adi_environment_pkg.sv similarity index 67% rename from library/regmaps/reg_accessor.sv rename to library/utilities/adi_environment_pkg.sv index 519e0689..c57ab8e9 100644 --- a/library/regmaps/reg_accessor.sv +++ b/library/utilities/adi_environment_pkg.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 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 @@ -26,39 +26,28 @@ // // 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/master/LICENSE_ADIBSD +// 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. // // *************************************************************************** // *************************************************************************** -package reg_accessor_pkg; +`include "utils.svh" - import axi_vip_pkg::*; - import logger_pkg::*; +package adi_environment_pkg; - class reg_accessor extends adi_component; + import logger_pkg::*; + import adi_common_pkg::*; + import adi_environment_pkg::*; + class adi_environment extends adi_component; function new( input string name, - input adi_component parent = null); - - super.new(name, parent); - endfunction - - virtual task automatic RegWrite32(input xil_axi_ulong addr =0, - input bit [31:0] data); - endtask: RegWrite32 + input adi_environment parent = null); - virtual task automatic RegRead32(input xil_axi_ulong addr =0, - output bit [31:0] data); - endtask: RegRead32 - - virtual task automatic RegReadVerify32(input xil_axi_ulong addr =0, - input bit [31:0] data); - endtask: RegReadVerify32 - - endclass + super.new(name, parent); + endfunction: new + endclass: adi_environment -endpackage +endpackage: adi_environment_pkg diff --git a/library/utilities/adi_vip_pkg.sv b/library/utilities/adi_vip_pkg.sv new file mode 100644 index 00000000..b33cca46 --- /dev/null +++ b/library/utilities/adi_vip_pkg.sv @@ -0,0 +1,83 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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" + +package adi_vip_pkg; + + import logger_pkg::*; + import adi_common_pkg::*; + import adi_environment_pkg::*; + + class adi_agent extends adi_component; + function new( + input string name, + input adi_environment parent = null); + + super.new(name, parent); + endfunction: new + endclass: adi_agent + + + class adi_driver extends adi_component; + function new( + input string name, + input adi_agent parent = null); + + super.new(name, parent); + endfunction: new + endclass: adi_driver + + + class adi_sequencer extends adi_component; + function new( + input string name, + input adi_agent parent = null); + + super.new(name, parent); + endfunction: new + endclass: adi_sequencer + + + class adi_monitor extends adi_component; + function new( + input string name, + input adi_agent parent = null); + + super.new(name, parent); + endfunction: new + endclass: adi_monitor + +endpackage: adi_vip_pkg diff --git a/library/utilities/irq_handler_pkg.sv b/library/utilities/irq_handler_pkg.sv new file mode 100644 index 00000000..24eb4368 --- /dev/null +++ b/library/utilities/irq_handler_pkg.sv @@ -0,0 +1,143 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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" + +package irq_handler_pkg; + + import logger_pkg::*; + import adi_common_pkg::*; + import adi_api_pkg::*; + import m_axi_sequencer_pkg::*; + import io_vip_if_base_pkg::*; + + class irq_handler_class extends adi_api; + + protected io_vip_if_base irq_vip_if; + + protected event irq_event_list [31:0]; + protected bit [31:0] irq_valid_list; + + protected bit software_testing; + + // constructor + function new( + input string name, + input m_axi_sequencer_base bus, + input bit [31:0] base_address, + input io_vip_if_base irq_vip_if, + input adi_component parent = null); + + super.new(name, bus, base_address, parent); + + this.irq_vip_if = irq_vip_if; + this.irq_valid_list = 'h0; + this.software_testing = 1'b0; + endfunction: new + + // enable software testing at startup + function void enable_software_testing(); + this.software_testing = 1'b1; + endfunction: enable_software_testing + + // software IRQ test-phase + task software_irq_testing(); + logic [31:0] enable_irq = 'h0; + + for (int i=0; i<32; ++i) begin + enable_irq = enable_irq | (this.irq_valid_list[i] << i); + end + this.info($sformatf("Enables: %d", enable_irq), ADI_VERBOSITY_HIGH); + this.axi_write('h00, enable_irq, 1); // software trigger IRQ + + // negative edge detection + if (this.irq_vip_if.get_io() == 1'b0) begin + this.irq_vip_if.wait_io_change(); + end + this.irq_vip_if.wait_io_change(); + endtask: software_irq_testing + + // IRQ event handler + task start(); + logic [31:0] irq_triggered; + logic [31:0] enable_irq = 'h0; + + for (int i=0; i<32; ++i) begin + enable_irq = enable_irq | (this.irq_valid_list[i] << i); + end + + this.axi_write('h10, enable_irq, 1); // enable all IRQ handles + this.axi_write('h1C, 'b01, 1); // enable IRQ controller / software interrupt disabled + + fork forever begin + if (this.irq_vip_if.get_io() == 1'b0) begin + this.irq_vip_if.wait_io_change(); + end + + this.info($sformatf("IRQ controller triggered"), ADI_VERBOSITY_HIGH); + + this.axi_read('h04, irq_triggered, 1); // check pending IRQ (status + enable) + + for (int i=0; i<32; ++i) begin + if (irq_triggered[i]) begin + if (this.irq_valid_list[i] == 1'b0) begin + this.fatal($sformatf("IRQ triggered on a non-registered device!")); + end + ->this.irq_event_list[i]; + @(this.irq_event_list[i]); + this.axi_write('h0C, 'h1 << i, 1); // acknowledge IRQ + end + end + end join_none + + if (this.software_testing) begin + this.software_irq_testing(); + end + + this.axi_write('h1C, 'b11, 1); // enable IRQ controller + software interrupt enabled + endtask: start + + // register IRQ device + function event register_device(input int position); + if (this.irq_valid_list[position]) begin + this.fatal($sformatf("An interrupt handler is already assigned to position %0d!", position)); + end + this.irq_valid_list[position] = 1'b1; + return this.irq_event_list[position]; + endfunction: register_device + + endclass: irq_handler_class + +endpackage: irq_handler_pkg diff --git a/library/utilities/logger_pkg.sv b/library/utilities/logger_pkg.sv index 0b2b64d2..0f610791 100644 --- a/library/utilities/logger_pkg.sv +++ b/library/utilities/logger_pkg.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -71,54 +71,4 @@ package logger_pkg; verbosity = value; endfunction: setLoggerVerbosity - - class adi_reporter; - string name; - adi_reporter parent; - - function new( - input string name, - input adi_reporter parent = null); - - this.name = name; - this.parent = parent; - endfunction - - function string get_path(); - if (this.parent == null) - return this.name; - else - return $sformatf("%s.%s", this.parent.get_path(), this.name); - endfunction: get_path - - function void info( - input string message, - input adi_verbosity_t verbosity); - - PrintInfo($sformatf("[%s] %s", this.get_path(), message), verbosity); - endfunction: info - - function void warning(input string message); - PrintWarning($sformatf("[%s] %s", this.get_path(), message)); - endfunction: warning - - function void error(input string message); - PrintError($sformatf("[%s] %s", this.get_path(), message)); - endfunction: error - - function void fatal(input string message); - PrintFatal($sformatf("[%s] %s", this.get_path(), message)); - endfunction: fatal - endclass: adi_reporter - - - class adi_component extends adi_reporter; - function new( - input string name, - input adi_component parent = null); - - super.new(name, parent); - endfunction: new - endclass: adi_component - endpackage diff --git a/library/utilities/pub_sub_pkg.sv b/library/utilities/pub_sub_pkg.sv new file mode 100644 index 00000000..96044b7f --- /dev/null +++ b/library/utilities/pub_sub_pkg.sv @@ -0,0 +1,97 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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" + +package pub_sub_pkg; + + import logger_pkg::*; + import adi_common_pkg::*; + + class adi_subscriber #(type data_type = int) extends adi_component; + + protected static bit [15:0] last_id = 'd0; + bit [15:0] id; + + function new( + input string name, + input adi_component parent = null); + + super.new(name, parent); + + this.last_id++; + this.id = this.last_id; + endfunction: new + + virtual function void update(input data_type data [$]); + this.fatal($sformatf("This function is not implemented!")); + endfunction: update + + endclass: adi_subscriber + + + class adi_publisher #(type data_type = int) extends adi_component; + + protected adi_subscriber #(data_type) subscriber_list[bit[15:0]]; + + function new( + input string name, + input adi_component parent = null); + + super.new(name, parent); + endfunction: new + + function void subscribe(input adi_subscriber #(data_type) subscriber); + if (this.subscriber_list.exists(subscriber.id)) + this.error($sformatf("Subscriber already on the list!")); + else + this.subscriber_list[subscriber.id] = subscriber; + endfunction: subscribe + + function void unsubscribe(input adi_subscriber #(data_type) subscriber); + if (!this.subscriber_list.exists(subscriber.id)) + this.error($sformatf("Subscriber does not exist on list!")); + else + this.subscriber_list.delete(subscriber.id); + endfunction: unsubscribe + + function void notify(input data_type data [$]); + foreach (this.subscriber_list[i]) + this.subscriber_list[i].update(data); + endfunction: notify + + endclass: adi_publisher + +endpackage diff --git a/library/utilities/test_harness_env.sv b/library/utilities/test_harness_env.sv index 2850c1b0..e427fd37 100644 --- a/library/utilities/test_harness_env.sv +++ b/library/utilities/test_harness_env.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -34,29 +34,23 @@ // *************************************************************************** `include "utils.svh" +`include "axi_definitions.svh" package test_harness_env_pkg; import logger_pkg::*; - import axi_vip_pkg::*; - import axi4stream_vip_pkg::*; - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; + import adi_environment_pkg::*; + import adi_axi_agent_pkg::*; + import irq_handler_pkg::*; + import io_vip_if_base_pkg::*; - class test_harness_env extends adi_component; + class test_harness_env extends adi_environment; // Agents - `AGENT(test_harness, mng_axi_vip, mst_t) mng_agent; - `AGENT(test_harness, ddr_axi_vip, slv_mem_t) ddr_axi_agent; + adi_axi_agent_base mng; + adi_axi_agent_base ddr; - // Sequencers - m_axi_sequencer #(`AGENT(test_harness, mng_axi_vip, mst_t)) mng; - s_axi_sequencer #(`AGENT(test_harness, ddr_axi_vip, slv_mem_t)) ddr_axi_seq; - - // Register accessors - bit done = 0; + irq_handler_class irq_handler; virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if; virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if; @@ -69,18 +63,13 @@ package test_harness_env_pkg; //============================================================================ function new( input string name, + input virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, + input virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, + input virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, + input virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, + input adi_environment parent = null); - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if - ); - - super.new(name); + super.new(name, parent); this.sys_clk_vip_if = sys_clk_vip_if; this.dma_clk_vip_if = dma_clk_vip_if; @@ -88,13 +77,8 @@ package test_harness_env_pkg; this.sys_rst_vip_if = sys_rst_vip_if; // Creating the agents - mng_agent = new("AXI Manager agent", mng_vip_if); - ddr_axi_agent = new("AXI DDR stub agent", ddr_vip_if); - - // Creating the sequencers - mng = new("AXI Manager sequencer", mng_agent, this); - ddr_axi_seq = new("AXI DDR stub sequencer", ddr_axi_agent, this); - + this.mng = new("AXI Manager agent", adi_axi_agent_pkg::MASTER, this); + this.ddr = new("AXI DDR stub agent", adi_axi_agent_pkg::SLAVE, this); endfunction //============================================================================ @@ -103,77 +87,35 @@ package test_harness_env_pkg; // - Start the agents //============================================================================ task start(); - mng_agent.start_master(); - ddr_axi_agent.start_slave(); - - sys_clk_vip_if.start_clock; - dma_clk_vip_if.start_clock; - ddr_clk_vip_if.start_clock; - endtask - - //============================================================================ - // Start the test - // - start the scoreboard - // - start the sequencers - //============================================================================ - task test(); - fork + this.mng.start_master(); + this.ddr.start_slave(); - join_none - endtask - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - // wait until done - wait_done(); - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run; - test(); - post_test(); + this.sys_clk_vip_if.start_clock(); + this.dma_clk_vip_if.start_clock(); + this.ddr_clk_vip_if.start_clock(); endtask //============================================================================ // Stop subroutine //============================================================================ - task stop; - mng_agent.stop_master(); - ddr_axi_agent.stop_slave(); - - sys_clk_vip_if.stop_clock; - dma_clk_vip_if.stop_clock; - ddr_clk_vip_if.stop_clock; - endtask + task stop(); + this.mng.stop_master(); + this.ddr.stop_slave(); - //============================================================================ - // Wait until all component are done - //============================================================================ - task wait_done; - wait (done == 1); - //`INFO(("Shutting down")); - endtask - - //============================================================================ - // Test controller routine - //============================================================================ - task test_c_run(); - done = 1; + this.sys_clk_vip_if.stop_clock(); + this.dma_clk_vip_if.stop_clock(); + this.ddr_clk_vip_if.stop_clock(); endtask //============================================================================ // System reset routine //============================================================================ - task sys_reset; + task sys_reset(); //asserts all the resets for 100 ns - sys_rst_vip_if.assert_reset; - #200; - sys_rst_vip_if.deassert_reset; - #800; + this.sys_rst_vip_if.assert_reset(); + #200ns; + this.sys_rst_vip_if.deassert_reset(); + #800ns; endtask endclass diff --git a/library/utilities/test_harness_system_bd.tcl b/library/utilities/test_harness_system_bd.tcl index 13e8337d..83f80c8e 100644 --- a/library/utilities/test_harness_system_bd.tcl +++ b/library/utilities/test_harness_system_bd.tcl @@ -49,6 +49,13 @@ ad_ip_instance axi_intc axi_intc [list \ C_HAS_FAST 0 \ ] +# create IRQ VIP +ad_ip_instance io_vip irq_vip [ list \ + ASYNC {true} \ + MODE {0} \ +] +adi_sim_add_define "IRQ=irq_vip" + ad_ip_instance xlconcat sys_concat_intc ad_ip_parameter sys_concat_intc CONFIG.NUM_PORTS 16 @@ -63,7 +70,6 @@ ad_ip_instance clk_vip sys_clk_vip [ list \ ] adi_sim_add_define "SYS_CLK=sys_clk_vip" - # DMA clock ad_ip_instance clk_vip dma_clk_vip [ list \ INTERFACE_MODE {MASTER} \ @@ -160,7 +166,9 @@ ad_connect sys_concat_intc/In15 GND # interconnect - processor -ad_cpu_interconnect 0x41200000 axi_intc +set IRQ_C_BASE 0x41200000 +ad_cpu_interconnect $IRQ_C_BASE axi_intc +adi_sim_add_define "IRQ_C_BA=[format "%d" ${IRQ_C_BASE}]" # interconnect - memory @@ -189,10 +197,8 @@ incr sys_cpu_interconnect_index global sys_mem_interconnect_index incr sys_mem_interconnect_index -# create external port for IRQ -create_bd_port -dir O -type intr irq - -ad_connect irq axi_intc/irq +# connect the IRQ controller to the IRQ VIP +ad_connect axi_intc/irq irq_vip/i # Set DDR VIP to a range of 2G set DDR_BASE 0x80000000 diff --git a/library/utilities/utils.svh b/library/utilities/utils.svh index a14e3493..1bda6ee5 100644 --- a/library/utilities/utils.svh +++ b/library/utilities/utils.svh @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -48,144 +48,11 @@ // Help build VIP parameter name e.g. test_harness_dst_axis_vip_0_VIP_DATA_WIDTH `define GETPARAM(th,vip,param) th``_``vip``_0_``param -`define DMAC_PARAMS(th,vip) th``_``vip``_0_ID, \ - th``_``vip``_0_DMA_DATA_WIDTH_SRC, \ - th``_``vip``_0_DMA_DATA_WIDTH_DEST, \ - th``_``vip``_0_DMA_LENGTH_WIDTH, \ - th``_``vip``_0_DMA_2D_TRANSFER, \ - th``_``vip``_0_DMA_2D_TLAST_MODE, \ - th``_``vip``_0_ASYNC_CLK_REQ_SRC, \ - th``_``vip``_0_ASYNC_CLK_SRC_DEST, \ - th``_``vip``_0_ASYNC_CLK_DEST_REQ, \ - th``_``vip``_0_AXI_SLICE_DEST, \ - th``_``vip``_0_AXI_SLICE_SRC, \ - th``_``vip``_0_SYNC_TRANSFER_START, \ - th``_``vip``_0_CYCLIC, \ - th``_``vip``_0_DMA_AXI_PROTOCOL_DEST, \ - th``_``vip``_0_DMA_AXI_PROTOCOL_SRC, \ - th``_``vip``_0_DMA_TYPE_DEST, \ - th``_``vip``_0_DMA_TYPE_SRC, \ - th``_``vip``_0_DMA_AXI_ADDR_WIDTH, \ - th``_``vip``_0_MAX_BYTES_PER_BURST, \ - th``_``vip``_0_FIFO_SIZE, \ - th``_``vip``_0_AXI_ID_WIDTH_SRC, \ - th``_``vip``_0_AXI_ID_WIDTH_DEST, \ - th``_``vip``_0_DISABLE_DEBUG_REGISTERS, \ - th``_``vip``_0_ENABLE_DIAGNOSTICS_IF, \ - th``_``vip``_0_ENABLE_FRAME_LOCK, \ - th``_``vip``_0_MAX_NUM_FRAMES_WIDTH, \ - th``_``vip``_0_USE_EXT_SYNC, \ - th``_``vip``_0_HAS_AUTORUN - -// Help build VIP Interface parameters name -`define AXI_VIP_IF_PARAMS(th,vip) th``_``vip``_0_VIP_PROTOCOL,\ - th``_``vip``_0_VIP_ADDR_WIDTH,\ - th``_``vip``_0_VIP_DATA_WIDTH,\ - th``_``vip``_0_VIP_DATA_WIDTH,\ - th``_``vip``_0_VIP_ID_WIDTH,\ - th``_``vip``_0_VIP_ID_WIDTH,\ - th``_``vip``_0_VIP_AWUSER_WIDTH,\ - th``_``vip``_0_VIP_WUSER_WIDTH,\ - th``_``vip``_0_VIP_BUSER_WIDTH,\ - th``_``vip``_0_VIP_ARUSER_WIDTH,\ - th``_``vip``_0_VIP_RUSER_WIDTH,\ - th``_``vip``_0_VIP_SUPPORTS_NARROW,\ - th``_``vip``_0_VIP_HAS_BURST,\ - th``_``vip``_0_VIP_HAS_LOCK,\ - th``_``vip``_0_VIP_HAS_CACHE,\ - th``_``vip``_0_VIP_HAS_REGION,\ - th``_``vip``_0_VIP_HAS_PROT,\ - th``_``vip``_0_VIP_HAS_QOS,\ - th``_``vip``_0_VIP_HAS_WSTRB,\ - th``_``vip``_0_VIP_HAS_BRESP,\ - th``_``vip``_0_VIP_HAS_RRESP,\ - th``_``vip``_0_VIP_HAS_ARESETN - -`define AXIS_VIP_IF_PARAMS(th,vip) th``_``vip``_0_VIP_SIGNAL_SET,\ - th``_``vip``_0_VIP_DEST_WIDTH,\ - th``_``vip``_0_VIP_DATA_WIDTH,\ - th``_``vip``_0_VIP_ID_WIDTH,\ - th``_``vip``_0_VIP_USER_WIDTH,\ - th``_``vip``_0_VIP_USER_BITS_PER_BYTE,\ - th``_``vip``_0_VIP_HAS_ARESETN - -`define AXI_VIP_PARAM_DECL int AXI_VIP_PROTOCOL=0,\ - AXI_VIP_ADDR_WIDTH=32,\ - AXI_VIP_WDATA_WIDTH=32,\ - AXI_VIP_RDATA_WIDTH=32,\ - AXI_VIP_WID_WIDTH = 0,\ - AXI_VIP_RID_WIDTH = 0,\ - AXI_VIP_AWUSER_WIDTH=0,\ - AXI_VIP_WUSER_WIDTH=0,\ - AXI_VIP_BUSER_WIDTH=0,\ - AXI_VIP_ARUSER_WIDTH=0,\ - AXI_VIP_RUSER_WIDTH=0,\ - AXI_VIP_SUPPORTS_NARROW = 1,\ - AXI_VIP_HAS_BURST = 1,\ - AXI_VIP_HAS_LOCK = 1,\ - AXI_VIP_HAS_CACHE= 1,\ - AXI_VIP_HAS_REGION = 1,\ - AXI_VIP_HAS_PROT= 1,\ - AXI_VIP_HAS_QOS= 1,\ - AXI_VIP_HAS_WSTRB= 1,\ - AXI_VIP_HAS_BRESP= 1,\ - AXI_VIP_HAS_RRESP= 1,\ - AXI_VIP_HAS_ARESETN = 1 - -`define AXI_VIP_PARAM_ORDER AXI_VIP_PROTOCOL,\ - AXI_VIP_ADDR_WIDTH,\ - AXI_VIP_WDATA_WIDTH,\ - AXI_VIP_RDATA_WIDTH,\ - AXI_VIP_WID_WIDTH,\ - AXI_VIP_RID_WIDTH,\ - AXI_VIP_AWUSER_WIDTH,\ - AXI_VIP_WUSER_WIDTH,\ - AXI_VIP_BUSER_WIDTH,\ - AXI_VIP_ARUSER_WIDTH,\ - AXI_VIP_RUSER_WIDTH,\ - AXI_VIP_SUPPORTS_NARROW,\ - AXI_VIP_HAS_BURST,\ - AXI_VIP_HAS_LOCK,\ - AXI_VIP_HAS_CACHE,\ - AXI_VIP_HAS_REGION,\ - AXI_VIP_HAS_PROT,\ - AXI_VIP_HAS_QOS,\ - AXI_VIP_HAS_WSTRB,\ - AXI_VIP_HAS_BRESP,\ - AXI_VIP_HAS_RRESP,\ - AXI_VIP_HAS_ARESETN - -`define AXIS_VIP_PARAM_DECL int AXIS_VIP_INTERFACE_MODE = 2,\ - AXIS_VIP_SIGNAL_SET = 8'b00000011,\ - AXIS_VIP_DATA_WIDTH = 8,\ - AXIS_VIP_ID_WIDTH = 0,\ - AXIS_VIP_DEST_WIDTH = 0,\ - AXIS_VIP_USER_WIDTH = 0,\ - AXIS_VIP_USER_BITS_PER_BYTE = 0,\ - AXIS_VIP_HAS_TREADY = 1,\ - AXIS_VIP_HAS_TSTRB = 0,\ - AXIS_VIP_HAS_TKEEP = 0,\ - AXIS_VIP_HAS_TLAST = 0,\ - AXIS_VIP_HAS_ACLKEN = 0,\ - AXIS_VIP_HAS_ARESETN = 1 - -`define AXIS_VIP_PARAMS(th,vip) th``_``vip``_0_VIP_INTERFACE_MODE,\ - th``_``vip``_0_VIP_SIGNAL_SET,\ - th``_``vip``_0_VIP_DATA_WIDTH,\ - th``_``vip``_0_VIP_ID_WIDTH,\ - th``_``vip``_0_VIP_DEST_WIDTH,\ - th``_``vip``_0_VIP_USER_WIDTH,\ - th``_``vip``_0_VIP_USER_BITS_PER_BYTE,\ - th``_``vip``_0_VIP_HAS_TREADY,\ - th``_``vip``_0_VIP_HAS_TSTRB,\ - th``_``vip``_0_VIP_HAS_TKEEP,\ - th``_``vip``_0_VIP_HAS_TLAST,\ - th``_``vip``_0_VIP_HAS_ACLKEN,\ - th``_``vip``_0_VIP_HAS_ARESETN - -`define AXI 0 -`define AXIS 1 -`define FIFO 2 +// Help link AMD AXI and AXIS VIPs to ADI Environment VIPs +`define LINK(top,env,inst) \ + top``.pre_link_agent(``env``.``inst``); \ + env``.``inst`` = ``top``; \ + top``.post_link_agent(``env``.``inst``); // Macros used in Simulation files during simulation `define INFO(m,v) \ diff --git a/library/vip/adi/io_vip/Makefile b/library/vip/adi/io_vip/Makefile index 8e61c693..cc672cf7 100644 --- a/library/vip/adi/io_vip/Makefile +++ b/library/vip/adi/io_vip/Makefile @@ -1,5 +1,5 @@ #################################################################################### -## Copyright (c) 2018 - 2024 Analog Devices, Inc. +## Copyright (C) 2018 - 2024 Analog Devices, Inc. ## Auto-generated, do not modify! #################################################################################### @@ -9,9 +9,10 @@ include ../../../../scripts/make_tb_path.mk LIBRARY_NAME := io_vip GENERIC_DEPS += io_vip.sv +GENERIC_DEPS += io_vip_top.v GENERIC_DEPS += io_vip_if.sv +GENERIC_DEPS += io_vip_if_base_pkg.sv XILINX_DEPS += io_vip_ip.tcl -XILINX_DEPS += io_vip_pkg.ttcl include $(HDL_LIBRARY_PATH)/scripts/library.mk diff --git a/library/vip/adi/io_vip/io_vip.sv b/library/vip/adi/io_vip/io_vip.sv index 62eb8f65..46ee6f9a 100644 --- a/library/vip/adi/io_vip/io_vip.sv +++ b/library/vip/adi/io_vip/io_vip.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -34,25 +34,75 @@ // *************************************************************************** module io_vip #( - parameter MODE = 1, // 1 - master, 0 - slave - parameter WIDTH = 1 + parameter MODE = 1, // 1 - master, 0 - slave, 2 - passthrough + parameter WIDTH = 1, // bitwidth + parameter ASYNC = 0 // clock synchronous )( input clk, - input [WIDTH-1:0] in, - output [WIDTH-1:0] out + input [WIDTH-1:0] i, + output [WIDTH-1:0] o ); + wire intf_clk; + + logic master_mode = 0; + logic slave_mode = 0; + io_vip_if #( .MODE (MODE), - .WIDTH (WIDTH) + .WIDTH (WIDTH), + .ASYNC (ASYNC) ) IF ( - .clk(clk) - ); + .clk(intf_clk)); + + assign o = (master_mode) ? IF.IO : {WIDTH{1'b0}}; + + assign IF.IO = (slave_mode) ? i : {WIDTH{1'bz}}; + + assign intf_clk = (ASYNC == 0) ? clk : 1'b0; - assign out = IF.io; - generate if (~MODE) begin - assign IF.io = in; - end + generate + initial begin + if (MODE == 1) begin + master_mode = 1; + IF.set_intf_master(); + end else if (MODE == 0) begin + slave_mode = 1; + IF.set_intf_slave(); + end else if (MODE == 2) begin + IF.set_intf_monitor(); + end else begin + $fatal(0, "This VIP mode does not exist"); + end + end endgenerate -endmodule + function void set_master_mode(); + if (MODE == 2) begin + master_mode = 1; + IF.set_intf_master(); + end else begin + $fatal(0, "VIP mode cannot be set, unless it is configured to passthrough mode"); + end + endfunction: set_master_mode + + function void set_slave_mode(); + if (MODE == 2) begin + slave_mode = 1; + IF.set_intf_slave(); + end else begin + $fatal(0, "VIP mode cannot be set, unless it is configured to passthrough mode"); + end + endfunction: set_slave_mode + + function void set_passthrough_mode(); + if (MODE == 2) begin + master_mode = 0; + slave_mode = 0; + IF.set_intf_monitor(); + end else begin + $fatal(0, "VIP mode cannot be set, unless it is configured to passthrough mode"); + end + endfunction: set_passthrough_mode + +endmodule: io_vip diff --git a/library/vip/adi/io_vip/io_vip_if.sv b/library/vip/adi/io_vip/io_vip_if.sv index c9fb7dac..564d5cbb 100644 --- a/library/vip/adi/io_vip/io_vip_if.sv +++ b/library/vip/adi/io_vip/io_vip_if.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -34,42 +34,89 @@ // *************************************************************************** interface io_vip_if #( - int MODE = 0, // 1 - master, 0 - slave - WIDTH = 1 + int MODE = 1, // 1 - master, 0 - slave, 2 - passthrough + WIDTH = 1, // bitwidth + ASYNC = 0 // clock synchronous ) ( input bit clk ); - logic [WIDTH-1:0] io = 0; - - // Master functions - function void set_io(int o); - if (MODE === 0) begin - $display("[ERROR] %0t Unsupported in slave mode", $time); - $finish; - end else begin - io <= o[WIDTH-1:0]; - end - endfunction - - // Wait and set - task setw_io(int o, int w=1); - repeat(w) wait_posedge_clk(); - set_io(o); - endtask - - // Slave functions - function int get_io(); - return io; - endfunction - - task wait_posedge_clk(); - @(cb); - endtask + import io_vip_if_base_pkg::*; + + wire [WIDTH-1:0] IO; + + logic [WIDTH-1:0] io = {WIDTH{1'b0}}; + + logic intf_is_master = 0; + logic intf_is_slave = 0; + + function void set_intf_master(); + intf_is_master = 1; + intf_is_slave = 0; + endfunction: set_intf_master + + function void set_intf_slave(); + intf_is_master = 0; + intf_is_slave = 1; + endfunction: set_intf_slave + + function void set_intf_monitor(); + intf_is_master = 0; + intf_is_slave = 0; + endfunction: set_intf_monitor + + assign IO = (intf_is_master) ? io : {WIDTH{1'bz}}; + + class io_vip_if_class #(int WIDTH = 1) extends io_vip_if_base; + + function new(); + endfunction + + virtual function void set_io(logic [1023:0] o); + if (intf_is_master) begin + io <= o[WIDTH-1:0]; + end else begin + $fatal(0, "Supported only in runtime master mode"); + end + endfunction: set_io + + virtual function logic [1023:0] get_io(); + if (intf_is_slave) begin + get_io = {{1024-WIDTH{1'b0}}, IO}; + end else begin + $fatal(0, "Supported only in runtime slave mode"); + end + endfunction: get_io + + virtual task wait_io_change(); + @(IO); + endtask: wait_io_change + + virtual task wait_posedge_clk(); + if (ASYNC == 1) begin + $fatal(0, "Unsupported in async mode"); + end + @(posedge clk); + endtask: wait_posedge_clk + + virtual task wait_negedge_clk(); + if (ASYNC == 1) begin + $fatal(0, "Unsupported in async mode"); + end + @(negedge clk); + endtask: wait_negedge_clk + + virtual function int get_width(); + get_width = WIDTH; + endfunction: get_width + + endclass: io_vip_if_class + + io_vip_if_class vif = new(); default clocking cb @(posedge clk); default input #1step output #1ps; - inout io; + inout IO; endclocking : cb -endinterface +endinterface: io_vip_if diff --git a/library/vip/adi/io_vip/io_vip_if_base_pkg.sv b/library/vip/adi/io_vip/io_vip_if_base_pkg.sv new file mode 100644 index 00000000..ecbf5343 --- /dev/null +++ b/library/vip/adi/io_vip/io_vip_if_base_pkg.sv @@ -0,0 +1,51 @@ +// *************************************************************************** +// Copyright (C) 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 responsabilities 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. +// +// *************************************************************************** +// *************************************************************************** + +package io_vip_if_base_pkg; + + virtual class io_vip_if_base; + + function new(); + endfunction + + pure virtual function void set_io(input logic [1023:0] o); + pure virtual function logic [1023:0] get_io(); + pure virtual task wait_io_change(); + pure virtual task wait_posedge_clk(); + pure virtual task wait_negedge_clk(); + pure virtual function int get_width(); + + endclass: io_vip_if_base + +endpackage: io_vip_if_base_pkg diff --git a/library/vip/adi/io_vip/io_vip_ip.tcl b/library/vip/adi/io_vip/io_vip_ip.tcl index 46f5fcad..21fc0ace 100644 --- a/library/vip/adi/io_vip/io_vip_ip.tcl +++ b/library/vip/adi/io_vip/io_vip_ip.tcl @@ -3,43 +3,66 @@ ### SPDX short identifier: ADIBSD ############################################################################### -source ../../../../../scripts/adi_env.tcl +source ../../../../scripts/adi_tb_env.tcl source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl adi_ip_create io_vip -adi_ip_files io_vip [list \ +adi_ip_files io_vip_top [list \ "io_vip.sv" \ + "io_vip_top.v" \ "io_vip_if.sv" \ + "io_vip_if_base_pkg.sv" \ ] adi_ip_properties_lite io_vip -adi_ip_sim_ttcl io_vip "io_vip_pkg.ttcl" + +set cc [ipx::current_core] + +set_property company_url {https://www.analog.com/en/index.html} $cc + +set_property display_name "ADI IO VIP" $cc +set_property description "ADI IO VIP" $cc # Remove all inferred interfaces -ipx::remove_all_bus_interface [ipx::current_core] +ipx::remove_all_bus_interface $cc ## Interface definitions -adi_set_ports_dependency "in" \ - "(spirit:decode(id('MODELPARAM_VALUE.MODE')) = 0)" +adi_set_ports_dependency "i" \ + "(spirit:decode(id('MODELPARAM_VALUE.MODE')) != 1)" -set cc [ipx::current_core] +adi_set_ports_dependency "o" \ + "(spirit:decode(id('MODELPARAM_VALUE.MODE')) != 0)" + +adi_set_ports_dependency "clk" \ + "(spirit:decode(id('MODELPARAM_VALUE.ASYNC')) = 0)" ## MODE set_property -dict [list \ "value_validation_type" "pairs" \ - "value_validation_pairs" {"Monitor" 0 "Driver" 1} \ + "value_validation_pairs" {"Slave" 0 "Master" 1 "Passthrough" 2} \ ] \ [ipx::get_user_parameters MODE -of_objects $cc] +set_property -dict [list \ + "value_format" "bool" \ + "value" "false" \ +] \ +[ipx::get_user_parameters ASYNC -of_objects $cc] +set_property -dict [list \ + "value_format" "bool" \ + "value" "false" \ + ] [ipx::get_hdl_parameters ASYNC -of_objects $cc] + +set_property driver_value 0 [ipx::get_ports i -of_objects $cc] + ## Customize IP Layout ## Remove the automatically generated GUI page ipgui::remove_page -component $cc [ipgui::get_pagespec -name "Page 0" -component $cc] -ipx::save_core [ipx::current_core] - +ipx::save_core $cc ## Create general configuration page -ipgui::add_page -name {IO VIP} -component [ipx::current_core] -display_name {IO VIP} +ipgui::add_page -name {IO VIP} -component $cc -display_name {IO VIP} set page0 [ipgui::get_pagespec -name "IO VIP" -component $cc] set general_group [ipgui::add_group -name "General Configuration" -component $cc \ @@ -55,9 +78,15 @@ set_property -dict [list \ ipgui::add_param -name "MODE" -component $cc -parent $general_group set_property -dict [list \ "display_name" "Mode" \ - "tooltip" "\[MODE\] Set as output or input" \ + "tooltip" "\[MODE\] Set as master, slave or passthrough" \ ] [ipgui::get_guiparamspec -name "MODE" -component $cc] +ipgui::add_param -name "ASYNC" -component $cc -parent $general_group +set_property -dict [list \ + "display_name" "Asynchronous clock" \ + "tooltip" "\[ASYNC\] Set clock mode" \ +] [ipgui::get_guiparamspec -name "ASYNC" -component $cc] + ## Create and save the XGUI file ipx::create_xgui_files $cc ipx::save_core $cc diff --git a/library/vip/adi/io_vip/io_vip_pkg.ttcl b/library/vip/adi/io_vip/io_vip_pkg.ttcl deleted file mode 100644 index 38b81bce..00000000 --- a/library/vip/adi/io_vip/io_vip_pkg.ttcl +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -## Copyright (C) 2024 Analog Devices, Inc. All rights reserved. -# SPDX short identifier: ADIBSD -############################################################################### - -<: :> -<: set ComponentName [getComponentNameString] :> -<: setOutputDirectory "./sim/" :> -<: setFileName ${ComponentName}_pkg :> -<: setFileExtension ".sv" :> -<: set mode [get_property MODELPARAM_VALUE.MODE] :> -<: set width [get_property MODELPARAM_VALUE.WIDTH] :> - -<: proc b2i {b} { if {$b==true} {return 1} else {return 0}} :> -/////////////////////////////////////////////////////////////////////////// -//NOTE: This file has been automatically generated by Vivado. -/////////////////////////////////////////////////////////////////////////// - -package <=: ComponentName :>_pkg; - - -/////////////////////////////////////////////////////////////////////////// -// These parameters are named after the component for use in your verification -// environment. -/////////////////////////////////////////////////////////////////////////// - parameter <=: ComponentName :>_VIP_MODE = <=: b2i $mode :>; - parameter <=: ComponentName :>_VIP_WIDTH = <=: $width :>; -////////////////////////////////////////////////////////////////////////// - -endpackage : <=: ComponentName :>_pkg diff --git a/library/vip/adi/io_vip/io_vip_top.v b/library/vip/adi/io_vip/io_vip_top.v new file mode 100644 index 00000000..5fba3b56 --- /dev/null +++ b/library/vip/adi/io_vip/io_vip_top.v @@ -0,0 +1,55 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2024 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. +// +// *************************************************************************** +// *************************************************************************** + +module io_vip_top #( + parameter MODE = 1, // 1 - master, 0 - slave, 2 - passthrough + parameter WIDTH = 1, // bitwidth + parameter ASYNC = 0 // clock synchronous +)( + input clk, + input [WIDTH-1:0] i, + output [WIDTH-1:0] o +); + + io_vip #( + .MODE(MODE), + .WIDTH(WIDTH), + .ASYNC(ASYNC) + ) inst ( + .clk(clk), + .i(i), + .o(o)); + +endmodule diff --git a/library/vip/adi/spi_vip/Makefile b/library/vip/adi/spi_vip/Makefile index 890ed530..049e237a 100644 --- a/library/vip/adi/spi_vip/Makefile +++ b/library/vip/adi/spi_vip/Makefile @@ -1,5 +1,5 @@ #################################################################################### -## Copyright (c) 2024 Analog Devices, Inc. +## Copyright (C) 2024 Analog Devices, Inc. ### SPDX short identifier: BSD-1-Clause ## Auto-generated, do not modify! #################################################################################### @@ -9,13 +9,11 @@ include ../../../../scripts/make_tb_path.mk LIBRARY_NAME := adi_spi_vip -GENERIC_DEPS += $(TB_LIBRARY_PATH)/utilities/utils.svh GENERIC_DEPS += adi_spi_vip_pkg.sv GENERIC_DEPS += spi_vip_if.sv GENERIC_DEPS += adi_spi_vip.sv XILINX_DEPS += adi_spi_vip_ip.tcl -XILINX_DEPS += adi_spi_vip_pkg.ttcl #TODO: INTEL_DEPS += adi_spi_vip_hw.tcl diff --git a/library/vip/adi/spi_vip/adi_spi_vip.sv b/library/vip/adi/spi_vip/adi_spi_vip.sv index fd3ec55c..40bcc7a1 100644 --- a/library/vip/adi/spi_vip/adi_spi_vip.sv +++ b/library/vip/adi/spi_vip/adi_spi_vip.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2024 Analog Devices, Inc. All rights reserved. +// 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 @@ -33,8 +33,6 @@ // *************************************************************************** // *************************************************************************** -`include "utils.svh" - module adi_spi_vip #( parameter MODE = 0, // SLAVE=0 parameter CPOL = 0, @@ -49,11 +47,11 @@ module adi_spi_vip #( parameter DEFAULT_MISO_DATA = 'hCAFE ) ( input logic s_spi_sclk, - input wire s_spi_mosi, + input logic s_spi_mosi, output wire s_spi_miso, input logic s_spi_cs, output logic m_spi_sclk, - output wire m_spi_mosi, + output logic m_spi_mosi, input wire m_spi_miso, output logic m_spi_cs ); @@ -76,41 +74,33 @@ module adi_spi_vip #( .DEFAULT_MISO_DATA (DEFAULT_MISO_DATA) ) IF (); - initial begin : ASSERT_PARAMETERS - assert (MODE == MODE_SLAVE) - else begin - $error("Unsupported mode %s. Valid values are 0=SLAVE, 1=MASTER, 2=MONITOR. Only 0(SLAVE) is currently supported.", MODE); - end - end : ASSERT_PARAMETERS + if (MODE != MODE_SLAVE) begin + $error("Unsupported mode %s. Valid values are 0=SLAVE, 1=MASTER, 2=MONITOR. Only 0(SLAVE) is currently supported.", MODE); + end generate + + assign s_spi_miso = IF.s_miso; + assign IF.s_mosi = s_spi_mosi; + assign IF.s_cs = s_spi_cs; + assign IF.s_sclk = s_spi_sclk; + + assign IF.m_miso = m_spi_miso; + assign m_spi_mosi = IF.m_mosi; + assign m_spi_sclk = IF.m_sclk; + assign m_spi_cs = IF.m_cs; + if (MODE == MODE_SLAVE) begin - assign s_spi_miso = IF.miso; - assign IF.mosi = s_spi_mosi; - assign IF.sclk = s_spi_sclk; - assign IF.cs = s_spi_cs; initial begin IF.set_slave_mode(); end end else if (MODE == MODE_MASTER) begin - assign IF.miso = m_spi_miso; - assign m_spi_mosi = IF.mosi; - assign m_spi_sclk = IF.sclk; - assign m_spi_cs = IF.cs; initial begin IF.set_master_mode(); end end else if (MODE == MODE_MONITOR) begin - assign IF.miso = m_spi_miso; - assign IF.mosi = s_spi_mosi; - assign IF.miso = s_spi_miso; - assign IF.cs = s_spi_cs; - assign s_spi_miso = m_spi_miso; - assign m_spi_mosi = s_spi_mosi; - assign m_spi_sclk = s_spi_sclk; - assign m_spi_cs = s_spi_cs; initial begin - IF.intf_monitor_mode(); + IF.set_monitor_mode(); end end endgenerate diff --git a/library/vip/adi/spi_vip/adi_spi_vip_if_base_pkg.sv b/library/vip/adi/spi_vip/adi_spi_vip_if_base_pkg.sv new file mode 100644 index 00000000..05454939 --- /dev/null +++ b/library/vip/adi/spi_vip/adi_spi_vip_if_base_pkg.sv @@ -0,0 +1,90 @@ +// *************************************************************************** +// Copyright (C) 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 responsabilities 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. +// +// *************************************************************************** +// *************************************************************************** + +package adi_spi_vip_if_base_pkg; + + typedef enum {SPI_MODE_SLAVE, SPI_MODE_MASTER, SPI_MODE_MONITOR} spi_mode_t; + + virtual class adi_spi_vip_if_base; + + function new(); + endfunction + + pure virtual function int get_param_MODE(); + + pure virtual function int get_param_CPOL(); + + pure virtual function int get_param_CPHA(); + + pure virtual function int get_param_INV_CS(); + + pure virtual function int get_param_DATA_DLENGTH(); + + pure virtual function int get_param_SLAVE_TIN(); + + pure virtual function int get_param_SLAVE_TOUT(); + + pure virtual function int get_param_MASTER_TIN(); + + pure virtual function int get_param_MASTER_TOUT(); + + pure virtual function int get_param_CS_TO_MISO(); + + pure virtual function int get_param_DEFAULT_MISO_DATA(); + + pure virtual function spi_mode_t get_mode(); + + pure virtual function logic get_cs_active(); + + pure virtual task wait_cs_active(); + + pure virtual task wait_cs_inactive(); + + pure virtual task wait_for_sample_edge(); + + pure virtual function logic get_mosi_delayed(); + + pure virtual task set_miso_drive(bit val); + + pure virtual task set_miso_drive_instantaneous(bit val); + + pure virtual task wait_for_drive_edge(); + + pure virtual task wait_cs(); + + pure virtual task set_miso_oen(bit val); + + endclass + +endpackage diff --git a/library/vip/adi/spi_vip/adi_spi_vip_ip.tcl b/library/vip/adi/spi_vip/adi_spi_vip_ip.tcl index d6748352..4744ead2 100644 --- a/library/vip/adi/spi_vip/adi_spi_vip_ip.tcl +++ b/library/vip/adi/spi_vip/adi_spi_vip_ip.tcl @@ -3,26 +3,27 @@ ### SPDX short identifier: ADIBSD ############################################################################### -source ../../../../../scripts/adi_env.tcl +source ../../../../scripts/adi_tb_env.tcl source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl adi_ip_create adi_spi_vip adi_ip_files adi_spi_vip [list \ - "adi_spi_vip_pkg.sv" \ "adi_spi_vip.sv" \ "spi_vip_if.sv" \ - "adi_spi_vip_pkg.ttcl" \ - "$ad_hdl_dir/testbenches/library/utilities/utils.svh" \ - "$ad_hdl_dir/testbenches/library/utilities/logger_pkg.sv" \ + "adi_spi_vip_if_base_pkg.sv" \ ] adi_ip_properties_lite adi_spi_vip -adi_ip_sim_ttcl adi_spi_vip "adi_spi_vip_pkg.ttcl" -set_property company_url {https://wiki.analog.com/resources/fpga/peripherals/spi_engine} [ipx::current_core] +set cc [ipx::current_core] + +set_property company_url {Unavailable} $cc + +set_property display_name "ADI SPI VIP" $cc +set_property description "ADI SPI Verification IP" $cc # Remove all inferred interfaces -ipx::remove_all_bus_interface [ipx::current_core] +ipx::remove_all_bus_interface $cc ## Interface definitions @@ -52,8 +53,6 @@ adi_add_bus "m_spi" "master" \ ## Parameter validations -set cc [ipx::current_core] - ## MODE set_property -dict [list \ "value_validation_type" "pairs" \ @@ -157,7 +156,7 @@ set_property -dict [list \ ## DEFAULT_MISO_DATA set_property -dict [list \ "value_bit_string_length" "32" \ - "value_format" "bit_string" \ + "value_format" "bitString" \ "enablement_tcl_expr" "\$MODE==0" \ ] \ [ipx::get_user_parameters DEFAULT_MISO_DATA -of_objects $cc] diff --git a/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv b/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv index b403a0ba..20c0edd3 100644 --- a/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv +++ b/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2024 Analog Devices, Inc. All rights reserved. +// 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 @@ -38,54 +38,36 @@ package adi_spi_vip_pkg; import logger_pkg::*; + import adi_vip_pkg::*; + import adi_environment_pkg::*; + import adi_spi_vip_if_base_pkg::*; - `define SPI_VIP_PARAM_ORDER SPI_VIP_MODE ,\ - SPI_VIP_CPOL ,\ - SPI_VIP_CPHA ,\ - SPI_VIP_INV_CS ,\ - SPI_VIP_DATA_DLENGTH ,\ - SPI_VIP_SLAVE_TIN ,\ - SPI_VIP_SLAVE_TOUT ,\ - SPI_VIP_MASTER_TIN ,\ - SPI_VIP_MASTER_TOUT ,\ - SPI_VIP_CS_TO_MISO ,\ - SPI_VIP_DEFAULT_MISO_DATA - - `define SPI_VIP_PARAMS(th,vip) th``_``vip``_0_VIP_MODE,\ - th``_``vip``_0_VIP_CPOL,\ - th``_``vip``_0_VIP_CPHA,\ - th``_``vip``_0_VIP_INV_CS,\ - th``_``vip``_0_VIP_DATA_DLENGTH,\ - th``_``vip``_0_VIP_SLAVE_TIN,\ - th``_``vip``_0_VIP_SLAVE_TOUT,\ - th``_``vip``_0_VIP_MASTER_TIN,\ - th``_``vip``_0_VIP_MASTER_TOUT,\ - th``_``vip``_0_VIP_CS_TO_MISO,\ - th``_``vip``_0_VIP_DEFAULT_MISO_DATA - - class adi_spi_driver #(int `SPI_VIP_PARAM_ORDER) extends adi_component; - - typedef mailbox #(logic [SPI_VIP_DATA_DLENGTH-1:0]) spi_mbx_t; - protected spi_mbx_t mosi_mbx; - spi_mbx_t miso_mbx; + // forward declaration to avoid errors + typedef class adi_spi_agent; + + class adi_spi_driver extends adi_driver; + + typedef bit bitqueue_t [$]; + protected mailbox mosi_mbx; + mailbox miso_mbx; protected bit active; protected bit stop_flag; - protected bit [SPI_VIP_DATA_DLENGTH-1:0] miso_reg; - protected bit [SPI_VIP_DATA_DLENGTH-1:0] default_miso_data; + protected int default_miso_data; protected event tx_mbx_updated; - virtual spi_vip_if #(`SPI_VIP_PARAM_ORDER) vif; + + adi_spi_vip_if_base vif; function new( input string name, - virtual spi_vip_if #(`SPI_VIP_PARAM_ORDER) intf, - input adi_component parent = null); + input adi_spi_vip_if_base intf, + input adi_spi_agent parent = null); super.new(name, parent); - + this.vif = intf; this.active = 0; this.stop_flag = 0; - this.default_miso_data = SPI_VIP_DEFAULT_MISO_DATA; + this.default_miso_data = vif.get_param_DEFAULT_MISO_DATA(); this.miso_mbx = new(); this.mosi_mbx = new(); endfunction @@ -104,19 +86,27 @@ package adi_spi_vip_pkg; endfunction : clear_active protected task rx_mosi(); - static logic [SPI_VIP_DATA_DLENGTH-1:0] mosi_data; + bitqueue_t mosi_bits; + logic mosi_logic; + bit mosi_bit; forever begin - if (vif.intf_slave_mode) begin - wait (vif.cs_active); - while (vif.cs_active) begin - for (int i = 0; itx_mbx_updated; endtask task get_rx_data( output int unsigned data); - bit [SPI_VIP_DATA_DLENGTH-1:0] rxdata; - mosi_mbx.get(rxdata); - data = rxdata; + mosi_mbx.get(data); endtask task flush_tx(); @@ -276,34 +265,93 @@ package adi_spi_vip_pkg; end endtask + automatic function int bitqueue_to_int(bitqueue_t bitq); + int idx = 0; + int data = 0; + while (bitq.size() != 0) begin + data |= (bitq.pop_front() << idx); + idx++; + end + return data; + endfunction + + automatic function bitqueue_t int_to_bitqueue(int data, int n_bits); + bitqueue_t bitq; + for (int i =0; i>i) & 1'b1); + end + return bitq; + endfunction + + automatic function bit bitqueue_pop_msb(ref bitqueue_t bitq); + bit data; + data = bitq.pop_back(); + return data; + endfunction + + automatic function void bitqueue_push_lsb(ref bitqueue_t bitq, bit lsb); + bitq.push_front(lsb); + endfunction endclass - class adi_spi_agent #(int `SPI_VIP_PARAM_ORDER) extends adi_component; + + class adi_spi_sequencer extends adi_sequencer; - protected adi_spi_driver #(`SPI_VIP_PARAM_ORDER) driver; + protected adi_spi_driver driver; function new( input string name, - virtual spi_vip_if #(`SPI_VIP_PARAM_ORDER) intf, - input adi_component parent = null); + input adi_spi_driver driver, + input adi_spi_agent parent = null); super.new(name, parent); - this.driver = new("Driver", intf, this); - endfunction + this.driver = driver; + endfunction: new - virtual task send_data(input int unsigned data); + virtual task automatic send_data(input int unsigned data); this.driver.put_tx_data(data); endtask : send_data - virtual task receive_data(output int unsigned data); + virtual task automatic receive_data(output int unsigned data); this.driver.get_rx_data(data); endtask : receive_data + virtual task automatic receive_data_verify(input int unsigned expected); + int unsigned received; + this.driver.get_rx_data(received); + if (received !== expected) begin + this.error($sformatf("Data mismatch. Received : %h; expected %h", received, expected)); + end + endtask : receive_data_verify + virtual task flush_send(); this.driver.flush_tx(); endtask : flush_send + virtual function void set_default_miso_data(input int unsigned data); + this.driver.set_default_miso_data(data); + endfunction : set_default_miso_data + + endclass + + + class adi_spi_agent extends adi_agent; + + protected adi_spi_driver driver; + adi_spi_sequencer sequencer; + + function new( + input string name, + input adi_spi_vip_if_base intf, + input adi_environment parent = null); + + super.new(name, parent); + + this.driver = new("Driver", intf, this); + this.sequencer = new("Sequencer", this.driver, this); + endfunction + virtual task start(); fork this.driver.start(); @@ -314,10 +362,6 @@ package adi_spi_vip_pkg; this.driver.stop(); endtask : stop - virtual function void set_default_miso_data(input int unsigned data); - this.driver.set_default_miso_data(data); - endfunction : set_default_miso_data - endclass endpackage diff --git a/library/vip/adi/spi_vip/adi_spi_vip_pkg.ttcl b/library/vip/adi/spi_vip/adi_spi_vip_pkg.ttcl deleted file mode 100644 index 5d9abd2f..00000000 --- a/library/vip/adi/spi_vip/adi_spi_vip_pkg.ttcl +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################### -## Copyright (C) 2024 Analog Devices, Inc. All rights reserved. -# SPDX short identifier: ADIBSD -############################################################################### - -<: :> -<: set ComponentName [getComponentNameString] :> -<: setOutputDirectory "./sim/" :> -<: setFileName ${ComponentName}_pkg :> -<: setFileExtension ".sv" :> -<: set mode [get_property MODELPARAM_VALUE.MODE] :> -<: set cpol [get_property MODELPARAM_VALUE.CPOL] :> -<: set cpha [get_property MODELPARAM_VALUE.CPHA] :> -<: set inv_cs [get_property MODELPARAM_VALUE.INV_CS] :> -<: set slave_tin [get_property MODELPARAM_VALUE.SLAVE_TIN] :> -<: set slave_tout [get_property MODELPARAM_VALUE.SLAVE_TOUT] :> -<: set master_tin [get_property MODELPARAM_VALUE.MASTER_TIN] :> -<: set master_tout [get_property MODELPARAM_VALUE.MASTER_TOUT] :> -<: set cs_to_miso [get_property MODELPARAM_VALUE.CS_TO_MISO] :> -<: set data_dlength [get_property MODELPARAM_VALUE.DATA_DLENGTH] :> -<: set default_miso_data [get_property MODELPARAM_VALUE.DEFAULT_MISO_DATA] :> - -<: proc b2i {b} { if {$b==true} {return 1} else {return 0}} :> -<: proc h2i {h} { return [format "%d" $h]} :> -/////////////////////////////////////////////////////////////////////////// -//NOTE: This file has been automatically generated by Vivado. -/////////////////////////////////////////////////////////////////////////// - -package <=: ComponentName :>_pkg; - - -/////////////////////////////////////////////////////////////////////////// -// These parameters are named after the component for use in your verification -// environment. -/////////////////////////////////////////////////////////////////////////// - parameter <=: ComponentName :>_VIP_MODE = <=: $mode :>; - parameter <=: ComponentName :>_VIP_CPOL = <=: b2i $cpol :>; - parameter <=: ComponentName :>_VIP_CPHA = <=: b2i $cpha :>; - parameter <=: ComponentName :>_VIP_INV_CS = <=: b2i $inv_cs :>; - parameter <=: ComponentName :>_VIP_SLAVE_TIN = <=: $slave_tin :>; - parameter <=: ComponentName :>_VIP_SLAVE_TOUT = <=: $slave_tout :>; - parameter <=: ComponentName :>_VIP_MASTER_TIN = <=: $master_tin :>; - parameter <=: ComponentName :>_VIP_MASTER_TOUT = <=: $master_tout :>; - parameter <=: ComponentName :>_VIP_CS_TO_MISO = <=: $cs_to_miso :>; - parameter <=: ComponentName :>_VIP_DATA_DLENGTH = <=: $data_dlength :>; - parameter <=: ComponentName :>_VIP_DEFAULT_MISO_DATA = <=: h2i $default_miso_data :>; -////////////////////////////////////////////////////////////////////////// - -endpackage : <=: ComponentName :>_pkg \ No newline at end of file diff --git a/library/vip/adi/spi_vip/spi_vip_if.sv b/library/vip/adi/spi_vip/spi_vip_if.sv index 3098778b..eb453024 100644 --- a/library/vip/adi/spi_vip/spi_vip_if.sv +++ b/library/vip/adi/spi_vip/spi_vip_if.sv @@ -32,8 +32,6 @@ // *************************************************************************** // *************************************************************************** -`include "utils.svh" - interface spi_vip_if #( int MODE = 0, CPOL = 0, @@ -47,52 +45,166 @@ interface spi_vip_if #( CS_TO_MISO = 0, DEFAULT_MISO_DATA = 'hCAFE ) (); - logic sclk; - wire miso; // need net types here in case tb wants to tristate this - wire mosi; // need net types here in case tb wants to tristate this - logic cs; + import adi_spi_vip_if_base_pkg::*; + + logic s_sclk; + wire s_miso; // need net types here in case tb wants to tristate this + logic s_mosi; + logic s_cs; + + logic m_sclk; + wire m_miso; // need net types here in case tb wants to tristate this + logic m_mosi; + logic m_cs; // internal - logic intf_slave_mode; - logic intf_master_mode; - logic intf_monitor_mode; + spi_mode_t spi_mode; logic miso_oen; logic miso_drive; + logic mosi_drive = 1'b0; + logic cs_drive = 1'b0; + logic sclk_drive = 1'b0; logic cs_active; - logic mosi_delayed; + logic s_mosi_delayed; + wire sclk; + wire cs; localparam CS_ACTIVE_LEVEL = (INV_CS) ? 1'b1 : 1'b0; + // cs, sclk sources + assign cs = (spi_mode != SPI_MODE_SLAVE) ? m_cs : s_cs; + assign sclk = (spi_mode != SPI_MODE_SLAVE) ? m_sclk : s_sclk; + // hack for parameterized edge. TODO: improve this logic sample_edge, drive_edge; assign sample_edge = (CPOL^CPHA) ? !sclk : sclk; assign drive_edge = (CPOL^CPHA) ? sclk : !sclk; assign cs_active = (cs == CS_ACTIVE_LEVEL); - // miso tri-state handling - assign miso = (!intf_slave_mode) ? 'z - : (miso_oen) ? miso_drive + // miso drive handling + assign s_miso = (spi_mode != SPI_MODE_SLAVE) ? m_miso + : (miso_oen) ? miso_drive /*default*/ : 'z; + // mosi drive handling + assign m_mosi = (spi_mode != SPI_MODE_MASTER) ? s_mosi : mosi_drive; + + // cs drive handling + assign m_cs = (spi_mode != SPI_MODE_MASTER) ? s_cs : cs_drive; + + // sclk drive handling + assign m_sclk = (spi_mode != SPI_MODE_MASTER) ? s_sclk : sclk_drive; + // mosi delay - assign #(SLAVE_TIN*1ns) mosi_delayed = mosi; + assign #(SLAVE_TIN*1ns) s_mosi_delayed = s_mosi; + + class adi_spi_vip_if #(int dummy = 10) extends adi_spi_vip_if_base; + + function new(); + endfunction + + virtual function int get_param_MODE(); + return MODE; + endfunction + + virtual function int get_param_CPOL(); + return CPOL; + endfunction + + virtual function int get_param_CPHA(); + return CPHA; + endfunction + + virtual function int get_param_INV_CS(); + return INV_CS; + endfunction + + virtual function int get_param_DATA_DLENGTH(); + return DATA_DLENGTH; + endfunction + + virtual function int get_param_SLAVE_TIN(); + return SLAVE_TIN; + endfunction + + virtual function int get_param_SLAVE_TOUT(); + return SLAVE_TOUT; + endfunction + + virtual function int get_param_MASTER_TIN(); + return MASTER_TIN; + endfunction + + virtual function int get_param_MASTER_TOUT(); + return MASTER_TOUT; + endfunction + + virtual function int get_param_CS_TO_MISO(); + return CS_TO_MISO; + endfunction + + virtual function int get_param_DEFAULT_MISO_DATA(); + return DEFAULT_MISO_DATA; + endfunction + + virtual function spi_mode_t get_mode(); + return spi_mode; + endfunction + + virtual function logic get_mosi_delayed(); + return s_mosi_delayed; + endfunction + + virtual function logic get_cs_active(); + return cs_active; + endfunction + + virtual task set_miso_drive(bit val); + miso_drive <= #(SLAVE_TOUT) val; + endtask + + virtual task set_miso_drive_instantaneous(bit val); + miso_drive <= val; + endtask + + virtual task wait_cs_active(); + wait(cs_active); + endtask + + virtual task wait_cs_inactive(); + wait(!cs_active); + endtask + + virtual task wait_for_sample_edge(); + @(posedge sample_edge); + endtask + + virtual task wait_for_drive_edge(); + @(posedge drive_edge); + endtask + + virtual task wait_cs(); + @(cs); + endtask + + virtual task set_miso_oen(bit val); + miso_oen <= #(CS_TO_MISO*1ns) val; + endtask + + endclass: adi_spi_vip_if + + adi_spi_vip_if vif = new(); function void set_slave_mode(); - intf_slave_mode = 1; - intf_master_mode = 0; - intf_monitor_mode = 0; + spi_mode = SPI_MODE_SLAVE; endfunction : set_slave_mode function void set_master_mode(); - intf_slave_mode = 0; - intf_master_mode = 1; - intf_monitor_mode = 0; + spi_mode = SPI_MODE_MASTER; $error("Unsupported mode master"); //TODO endfunction : set_master_mode function void set_monitor_mode(); - intf_slave_mode = 0; - intf_master_mode = 0; - intf_monitor_mode = 1; + spi_mode = SPI_MODE_MONITOR; $error("Unsupported mode monitor"); //TODO endfunction : set_monitor_mode diff --git a/library/vip/amd/axi/adi_axi_agent.sv b/library/vip/amd/axi/adi_axi_agent.sv new file mode 100644 index 00000000..0bd88f1f --- /dev/null +++ b/library/vip/amd/axi/adi_axi_agent.sv @@ -0,0 +1,259 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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" + +package adi_axi_agent_pkg; + + import logger_pkg::*; + import adi_vip_pkg::*; + import adi_environment_pkg::*; + import axi_vip_pkg::*; + import m_axi_sequencer_pkg::*; + import s_axi_sequencer_pkg::*; + import adi_axi_monitor_pkg::*; + + typedef enum {MASTER, SLAVE, PASSTHROUGH} axi_agent_typedef; + + class adi_axi_agent_base extends adi_agent; + + m_axi_sequencer_base master_sequencer; + s_axi_sequencer_base slave_sequencer; + adi_axi_monitor_base monitor; + + local axi_agent_typedef agent_type; + + function new( + input string name, + input axi_agent_typedef agent_type, + input adi_environment parent = null); + + super.new(name, parent); + + this.agent_type = agent_type; + endfunction: new + + virtual task start_master(); + if (agent_type == SLAVE) begin + this.fatal($sformatf("Agent is in slave mode!")); + end + this.monitor.start(); + endtask: start_master + + virtual task start_slave(); + if (agent_type == MASTER) begin + this.fatal($sformatf("Agent is in master mode!")); + end + this.monitor.start(); + endtask: start_slave + + virtual task start_monitor(); + if (agent_type != PASSTHROUGH) begin + this.fatal($sformatf("Agent is not in passthrough mode!")); + end + this.monitor.start(); + endtask: start_monitor + + virtual task stop_master(); + if (agent_type == SLAVE) begin + this.fatal($sformatf("Agent is in slave mode!")); + end + this.monitor.stop(); + endtask: stop_master + + virtual task stop_slave(); + if (agent_type == MASTER) begin + this.fatal($sformatf("Agent is in master mode!")); + end + this.monitor.stop(); + endtask: stop_slave + + virtual task stop_monitor(); + if (agent_type != PASSTHROUGH) begin + this.fatal($sformatf("Agent is not in passthrough mode!")); + end + this.monitor.stop(); + endtask: stop_monitor + + endclass: adi_axi_agent_base + + + class adi_axi_master_agent #(int `AXI_VIP_PARAM_ORDER(master)) extends adi_axi_agent_base; + + axi_mst_agent #(`AXI_VIP_PARAM_ORDER(master)) agent; + m_axi_sequencer #(`AXI_VIP_PARAM_ORDER(master)) master_sequencer; + adi_axi_monitor #(`AXI_VIP_PARAM_ORDER(master)) monitor; + + function new( + input string name, + virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(master)) master_vip_if, + input adi_environment parent = null); + + super.new(name, MASTER, parent); + + this.agent = new("Agent", master_vip_if); + this.master_sequencer = new("Master Sequencer", this.agent.wr_driver, this.agent.rd_driver, this); + this.monitor = new("Monitor", this.agent.monitor, this); + endfunction: new + + function void pre_link_agent(adi_axi_agent_base adi_axi_agent); + this.name = adi_axi_agent.name; + this.parent = adi_axi_agent.parent; + endfunction: pre_link_agent + + function void post_link_agent(adi_axi_agent_base adi_axi_agent); + adi_axi_agent.master_sequencer = this.master_sequencer; + adi_axi_agent.monitor = this.monitor; + endfunction: post_link_agent + + virtual task start_master(); + super.start_master(); + this.agent.start_master(); + endtask: start_master + + virtual task stop_master(); + super.stop_master(); + this.agent.stop_master(); + endtask: stop_master + + endclass: adi_axi_master_agent + + + class adi_axi_slave_mem_agent #(int `AXI_VIP_PARAM_ORDER(slave)) extends adi_axi_agent_base; + + axi_slv_mem_agent #(`AXI_VIP_PARAM_ORDER(slave)) agent; + s_axi_sequencer #(`AXI_VIP_PARAM_ORDER(slave)) slave_sequencer; + adi_axi_monitor #(`AXI_VIP_PARAM_ORDER(slave)) monitor; + + function new( + input string name, + virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(slave)) slave_vip_if, + input adi_environment parent = null); + + super.new(name, SLAVE, parent); + + this.agent = new("Agent", slave_vip_if); + this.slave_sequencer = new("Slave Sequencer", this.agent.mem_model, this); + this.monitor = new("Monitor", this.agent.monitor, this); + endfunction: new + + function void pre_link_agent(adi_axi_agent_base adi_axi_agent); + this.name = adi_axi_agent.name; + this.parent = adi_axi_agent.parent; + endfunction: pre_link_agent + + function void post_link_agent(adi_axi_agent_base adi_axi_agent); + adi_axi_agent.slave_sequencer = this.slave_sequencer; + adi_axi_agent.monitor = this.monitor; + endfunction: post_link_agent + + virtual task start_slave(); + super.start_slave(); + this.agent.start_slave(); + endtask: start_slave + + virtual task stop_slave(); + super.stop_slave(); + this.agent.stop_slave(); + endtask: stop_slave + + endclass: adi_axi_slave_mem_agent + + + class adi_axi_passthrough_mem_agent #(int `AXI_VIP_PARAM_ORDER(passthrough)) extends adi_axi_agent_base; + + axi_passthrough_mem_agent #(`AXI_VIP_PARAM_ORDER(passthrough)) agent; + m_axi_sequencer #(`AXI_VIP_PARAM_ORDER(passthrough)) master_sequencer; + s_axi_sequencer #(`AXI_VIP_PARAM_ORDER(passthrough)) slave_sequencer; + adi_axi_monitor #(`AXI_VIP_PARAM_ORDER(passthrough)) monitor; + + function new( + input string name, + virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(passthrough)) passthrough_vip_if, + input adi_environment parent = null); + + super.new(name, PASSTHROUGH, parent); + + this.agent = new("Agent", passthrough_vip_if); + this.master_sequencer = new("Master Sequencer", this.agent.mst_wr_driver, this.agent.mst_rd_driver, this); + this.slave_sequencer = new("Slave Sequencer", this.agent.mem_model, this); + this.monitor = new("Monitor", this.agent.monitor, this); + endfunction: new + + function void pre_link_agent(adi_axi_agent_base adi_axi_agent); + this.name = adi_axi_agent.name; + this.parent = adi_axi_agent.parent; + endfunction: pre_link_agent + + function void post_link_agent(adi_axi_agent_base adi_axi_agent); + adi_axi_agent.master_sequencer = this.master_sequencer; + adi_axi_agent.slave_sequencer = this.slave_sequencer; + adi_axi_agent.monitor = this.monitor; + endfunction: post_link_agent + + virtual task start_master(); + super.start_master(); + this.agent.start_master(); + endtask: start_master + + virtual task start_slave(); + super.start_slave(); + this.agent.start_slave(); + endtask: start_slave + + virtual task start_monitor(); + super.start_monitor(); + this.agent.start_monitor(); + endtask: start_monitor + + virtual task stop_master(); + super.stop_master(); + this.agent.stop_master(); + endtask: stop_master + + virtual task stop_slave(); + super.stop_slave(); + this.agent.stop_slave(); + endtask: stop_slave + + virtual task stop_monitor(); + super.stop_monitor(); + this.agent.stop_monitor(); + endtask: stop_monitor + + endclass: adi_axi_passthrough_mem_agent + +endpackage: adi_axi_agent_pkg diff --git a/library/vip/amd/axi/adi_axi_monitor.sv b/library/vip/amd/axi/adi_axi_monitor.sv new file mode 100644 index 00000000..afcfb044 --- /dev/null +++ b/library/vip/amd/axi/adi_axi_monitor.sv @@ -0,0 +1,154 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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" + +package adi_axi_monitor_pkg; + + import axi_vip_pkg::*; + import logger_pkg::*; + import adi_vip_pkg::*; + import pub_sub_pkg::*; + + + class adi_axi_monitor_base extends adi_monitor; + + adi_publisher #(logic [7:0]) publisher_tx; + adi_publisher #(logic [7:0]) publisher_rx; + + protected bit enabled; + protected event enable_ev; + + // constructor + function new( + input string name, + input adi_agent parent = null); + + super.new(name, parent); + + this.publisher_tx = new("Publisher TX", this); + this.publisher_rx = new("Publisher RX", this); + + this.enabled = 0; + endfunction + + task start(); + if (this.enabled) begin + this.error($sformatf("Monitor is already running!")); + return; + end + + this.enabled = 1; + this.info($sformatf("Monitor enabled"), ADI_VERBOSITY_MEDIUM); + + fork + begin + this.get_transaction(); + end + begin + if (this.enabled == 1) begin + @enable_ev; + end + disable fork; + end + join_none + endtask: start + + function void stop(); + this.enabled = 0; + -> enable_ev; + endfunction: stop + + virtual task get_transaction(); + endtask: get_transaction + + endclass: adi_axi_monitor_base + + + class adi_axi_monitor #(int `AXI_VIP_PARAM_ORDER(axi)) extends adi_axi_monitor_base; + + // analysis port from the monitor + protected axi_monitor #(`AXI_VIP_PARAM_ORDER(axi)) monitor; + + // constructor + function new( + input string name, + input axi_monitor #(`AXI_VIP_PARAM_ORDER(axi)) monitor, + input adi_agent parent = null); + + super.new(name, parent); + + this.monitor = monitor; + endfunction + + // collect data from the DDR interface, all WRITE transaction are coming + // from the ADC and all READ transactions are going to the DAC + virtual task get_transaction(); + axi_monitor_transaction transaction; + xil_axi_data_beat data_beat; + xil_axi_strb_beat strb_beat; + int num_bytes; + logic [7:0] axi_byte; + logic [7:0] data_queue [$]; + + forever begin + this.monitor.item_collected_port.get(transaction); + num_bytes = transaction.get_data_width()/8; + for (int i=0; i<(transaction.get_len()+1); i++) begin + data_beat = transaction.get_data_beat(i); + strb_beat = transaction.get_strb_beat(i); + for (int j=0; j +// +// 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. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +`ifndef _AXI_DEFINITIONS_SVH_ +`define _AXI_DEFINITIONS_SVH_ + +// Help build VIP Interface parameters name +`define AXI_VIP_PARAM_DECL(n) int n``_VIP_PROTOCOL,\ + n``_VIP_ADDR_WIDTH,\ + n``_VIP_WDATA_WIDTH,\ + n``_VIP_RDATA_WIDTH,\ + n``_VIP_WID_WIDTH,\ + n``_VIP_RID_WIDTH,\ + n``_VIP_AWUSER_WIDTH,\ + n``_VIP_WUSER_WIDTH,\ + n``_VIP_BUSER_WIDTH,\ + n``_VIP_ARUSER_WIDTH,\ + n``_VIP_RUSER_WIDTH,\ + n``_VIP_SUPPORTS_NARROW,\ + n``_VIP_HAS_BURST,\ + n``_VIP_HAS_LOCK,\ + n``_VIP_HAS_CACHE,\ + n``_VIP_HAS_REGION,\ + n``_VIP_HAS_PROT,\ + n``_VIP_HAS_QOS,\ + n``_VIP_HAS_WSTRB,\ + n``_VIP_HAS_BRESP,\ + n``_VIP_HAS_RRESP,\ + n``_VIP_HAS_ARESETN + +`define AXI_VIP_PARAM_ORDER(n) n``_VIP_PROTOCOL,\ + n``_VIP_ADDR_WIDTH,\ + n``_VIP_WDATA_WIDTH,\ + n``_VIP_RDATA_WIDTH,\ + n``_VIP_WID_WIDTH,\ + n``_VIP_RID_WIDTH,\ + n``_VIP_AWUSER_WIDTH,\ + n``_VIP_WUSER_WIDTH,\ + n``_VIP_BUSER_WIDTH,\ + n``_VIP_ARUSER_WIDTH,\ + n``_VIP_RUSER_WIDTH,\ + n``_VIP_SUPPORTS_NARROW,\ + n``_VIP_HAS_BURST,\ + n``_VIP_HAS_LOCK,\ + n``_VIP_HAS_CACHE,\ + n``_VIP_HAS_REGION,\ + n``_VIP_HAS_PROT,\ + n``_VIP_HAS_QOS,\ + n``_VIP_HAS_WSTRB,\ + n``_VIP_HAS_BRESP,\ + n``_VIP_HAS_RRESP,\ + n``_VIP_HAS_ARESETN + +`define AXI_VIP_IF_PARAMS(n) n``_VIP_PROTOCOL,\ + n``_VIP_ADDR_WIDTH,\ + n``_VIP_WDATA_WIDTH,\ + n``_VIP_RDATA_WIDTH,\ + n``_VIP_WID_WIDTH,\ + n``_VIP_RID_WIDTH,\ + n``_VIP_AWUSER_WIDTH,\ + n``_VIP_WUSER_WIDTH,\ + n``_VIP_BUSER_WIDTH,\ + n``_VIP_ARUSER_WIDTH,\ + n``_VIP_RUSER_WIDTH,\ + n``_VIP_SUPPORTS_NARROW,\ + n``_VIP_HAS_BURST,\ + n``_VIP_HAS_LOCK,\ + n``_VIP_HAS_CACHE,\ + n``_VIP_HAS_REGION,\ + n``_VIP_HAS_PROT,\ + n``_VIP_HAS_QOS,\ + n``_VIP_HAS_WSTRB,\ + n``_VIP_HAS_BRESP,\ + n``_VIP_HAS_RRESP,\ + n``_VIP_HAS_ARESETN + +`define AXI_VIP_PARAMS(th,vip) th``_``vip``_0_VIP_PROTOCOL,\ + th``_``vip``_0_VIP_ADDR_WIDTH,\ + th``_``vip``_0_VIP_DATA_WIDTH,\ + th``_``vip``_0_VIP_DATA_WIDTH,\ + th``_``vip``_0_VIP_ID_WIDTH,\ + th``_``vip``_0_VIP_ID_WIDTH,\ + th``_``vip``_0_VIP_AWUSER_WIDTH,\ + th``_``vip``_0_VIP_WUSER_WIDTH,\ + th``_``vip``_0_VIP_BUSER_WIDTH,\ + th``_``vip``_0_VIP_ARUSER_WIDTH,\ + th``_``vip``_0_VIP_RUSER_WIDTH,\ + th``_``vip``_0_VIP_SUPPORTS_NARROW,\ + th``_``vip``_0_VIP_HAS_BURST,\ + th``_``vip``_0_VIP_HAS_LOCK,\ + th``_``vip``_0_VIP_HAS_CACHE,\ + th``_``vip``_0_VIP_HAS_REGION,\ + th``_``vip``_0_VIP_HAS_PROT,\ + th``_``vip``_0_VIP_HAS_QOS,\ + th``_``vip``_0_VIP_HAS_WSTRB,\ + th``_``vip``_0_VIP_HAS_BRESP,\ + th``_``vip``_0_VIP_HAS_RRESP,\ + th``_``vip``_0_VIP_HAS_ARESETN + +`endif diff --git a/library/vip/amd/axi/m_axi_sequencer.sv b/library/vip/amd/axi/m_axi_sequencer.sv new file mode 100644 index 00000000..f745528f --- /dev/null +++ b/library/vip/amd/axi/m_axi_sequencer.sv @@ -0,0 +1,282 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2014 - 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 responsabilities 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" + +package m_axi_sequencer_pkg; + + import axi_vip_pkg::*; + import logger_pkg::*; + import adi_vip_pkg::*; + + + class m_axi_sequencer_base extends adi_sequencer; + + local semaphore reader_s; + local semaphore writer_s; + + local int reader_priority_counter; + local int writer_priority_counter; + + local event reader_event; + local event writer_event; + + function new( + input string name, + input adi_agent parent = null); + + super.new(name, parent); + + this.reader_s = new(1); + this.writer_s = new(1); + + this.reader_priority_counter = 0; + this.writer_priority_counter = 0; + endfunction: new + + + // Generic tasks + task automatic RegWrite32( + input xil_axi_ulong addr = 0, + input bit [31:0] data, + input bit priority_packet = 0); + + static xil_axi_uint id = 0; + + if (priority_packet) begin + this.writer_priority_counter++; + end else begin + while (this.writer_priority_counter) begin + @this.writer_event; + end + end + this.writer_s.get(1); + this.info($sformatf("Writing to address 0x%h, value %h with priority %0x", addr , data, priority_packet), ADI_VERBOSITY_HIGH); + + single_write_transaction_readback_api( + .id(id), + .addr(addr), + .len(0), + .size(XIL_AXI_SIZE_4BYTE), + .burst(XIL_AXI_BURST_TYPE_INCR), + .data(data)); + + id++; + if (priority_packet) begin + this.writer_priority_counter--; + -> this.writer_event; + end + this.writer_s.put(1); + endtask: RegWrite32 + + task automatic RegRead32( + input xil_axi_ulong addr = 0, + output bit [31:0] data, + input bit priority_packet = 0); + + xil_axi_data_beat DataBeat_for_read[]; + static xil_axi_uint id = 0; + + if (priority_packet) begin + this.reader_priority_counter++; + end else begin + while (this.reader_priority_counter) begin + @this.reader_event; + end + end + this.reader_s.get(1); + + single_read_transaction_readback_api( + .id(id), + .addr(addr), + .len(0), + .size(XIL_AXI_SIZE_4BYTE), + .burst(XIL_AXI_BURST_TYPE_INCR), + .Rdatabeat(DataBeat_for_read)); + + id++; + if (priority_packet) begin + this.reader_priority_counter--; + -> this.reader_event; + end + this.reader_s.put(1); + + data = DataBeat_for_read[0][0+:32]; + this.info($sformatf(" Reading data %h from 0x%h with priority %0x", data, addr, priority_packet), ADI_VERBOSITY_HIGH); + endtask: RegRead32 + + task automatic RegReadVerify32( + input xil_axi_ulong addr = 0, + input bit [31:0] data, + input bit priority_packet = 0); + + bit [31:0] data_out; + + RegRead32( + .addr(addr), + .data(data_out), + .priority_packet(priority_packet)); + + if (data !== data_out) begin + this.error($sformatf("Data mismatch at address 0x%h; Read data is %h; expected is %h", addr, data_out, data)); + end + endtask: RegReadVerify32 + + + // Virtual task declarations + protected virtual task automatic single_write_transaction_readback_api ( + input string name ="single_write", + input xil_axi_uint id =0, + input xil_axi_ulong addr =0, + input xil_axi_len_t len =0, + input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), + input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, + input xil_axi_lock_t lock = XIL_AXI_ALOCK_NOLOCK, + input xil_axi_cache_t cache =3, + input xil_axi_prot_t prot =0, + input xil_axi_region_t region =0, + input xil_axi_qos_t qos =0, + input bit [63:0] data =0); + + this.fatal($sformatf("Base class was instantiated instead of the parameterized class!")); + endtask: single_write_transaction_readback_api + + protected virtual task automatic single_read_transaction_readback_api ( + input string name ="single_read", + input xil_axi_uint id =0, + input xil_axi_ulong addr =0, + input xil_axi_len_t len =0, + input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), + input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, + input xil_axi_lock_t lock =XIL_AXI_ALOCK_NOLOCK , + input xil_axi_cache_t cache =3, + input xil_axi_prot_t prot =0, + input xil_axi_region_t region =0, + input xil_axi_qos_t qos =0, + input xil_axi_data_beat aruser =0, + output xil_axi_data_beat Rdatabeat[]); + + this.fatal($sformatf("Base class was instantiated instead of the parameterized class!")); + endtask: single_read_transaction_readback_api + + endclass: m_axi_sequencer_base + + + class m_axi_sequencer #(`AXI_VIP_PARAM_DECL(AXI)) extends m_axi_sequencer_base; + + protected axi_mst_wr_driver #(`AXI_VIP_PARAM_ORDER(AXI)) wr_driver; + protected axi_mst_rd_driver #(`AXI_VIP_PARAM_ORDER(AXI)) rd_driver; + + function new( + input string name, + input axi_mst_wr_driver #(`AXI_VIP_PARAM_ORDER(AXI)) wr_driver, + input axi_mst_rd_driver #(`AXI_VIP_PARAM_ORDER(AXI)) rd_driver, + input adi_agent parent = null); + + super.new(name, parent); + + this.wr_driver = wr_driver; + this.rd_driver = rd_driver; + endfunction: new + + + // --------------------------------------------------------------------------- + // BFM specific tasks + // --------------------------------------------------------------------------- + protected task automatic single_write_transaction_readback_api ( + input string name ="single_write", + input xil_axi_uint id =0, + input xil_axi_ulong addr =0, + input xil_axi_len_t len =0, + input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), + input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, + input xil_axi_lock_t lock = XIL_AXI_ALOCK_NOLOCK, + input xil_axi_cache_t cache =3, + input xil_axi_prot_t prot =0, + input xil_axi_region_t region =0, + input xil_axi_qos_t qos =0, + input bit [63:0] data =0); + + axi_transaction wr_trans; + wr_trans = this.wr_driver.create_transaction(name); + wr_trans.set_write_cmd(addr, burst, id, len, size); + wr_trans.set_prot(prot); + wr_trans.set_lock(lock); + wr_trans.set_cache(cache); + wr_trans.set_region(region); + wr_trans.set_qos(qos); + wr_trans.set_data_block(data); + wr_trans.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN); + this.wr_driver.send(wr_trans); + this.wr_driver.wait_rsp(wr_trans); + endtask: single_write_transaction_readback_api + + protected task automatic single_read_transaction_readback_api ( + input string name ="single_read", + input xil_axi_uint id =0, + input xil_axi_ulong addr =0, + input xil_axi_len_t len =0, + input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), + input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, + input xil_axi_lock_t lock =XIL_AXI_ALOCK_NOLOCK , + input xil_axi_cache_t cache =3, + input xil_axi_prot_t prot =0, + input xil_axi_region_t region =0, + input xil_axi_qos_t qos =0, + input xil_axi_data_beat aruser =0, + output xil_axi_data_beat Rdatabeat[]); + + axi_transaction rd_trans; + rd_trans = this.rd_driver.create_transaction(name); + rd_trans.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN); + rd_trans.set_read_cmd(addr, burst, id, len, size); + rd_trans.set_prot(prot); + rd_trans.set_lock(lock); + rd_trans.set_cache(cache); + rd_trans.set_region(region); + rd_trans.set_qos(qos); + this.rd_driver.send(rd_trans); + this.rd_driver.wait_rsp(rd_trans); + Rdatabeat = new[rd_trans.get_len()+1]; + for( xil_axi_uint beat=0; beat>queue_ev; - endfunction: add_xfer_descriptor + endfunction: add_xfer_descriptor_byte_count // descriptor delay subroutine // - can be overridden in inherited classes for more specific delay generation @@ -214,20 +239,11 @@ package m_axis_sequencer_pkg; wait_clk_count(descriptor_delay); endtask: descriptor_delay_subroutine - // wait until data beat is sent - task beat_sent(); - @beat_done; - endtask: beat_sent - - // wait until packet is sent - task packet_sent(); - @packet_done; - endtask: packet_sent - // wait until queue is empty task wait_empty_descriptor_queue(); - if (this.queue_empty_sig) + if (this.queue_empty_sig) begin return; + end @queue_empty; endtask: wait_empty_descriptor_queue @@ -238,40 +254,34 @@ package m_axis_sequencer_pkg; // generate transfer with transfer descriptors protected task generator(); - this.info($sformatf("generator start"), ADI_VERBOSITY_HIGH); - forever begin - this.info($sformatf("Waiting for enable"), ADI_VERBOSITY_HIGH); - @enable_ev; - this.info($sformatf("Enable found"), ADI_VERBOSITY_HIGH); - fork begin - fork - begin - @disable_ev; - if (this.queue_empty_sig == 0) - case (stop_policy) - STOP_POLICY_DESCRIPTOR_QUEUE: @queue_empty; - STOP_POLICY_PACKET: @packet_done; - STOP_POLICY_DATA_BEAT: @beat_done; - STOP_POLICY_IMMEDIATE: ; - endcase - end - forever begin - if (descriptor_q.size() > 0) begin - if (enabled || (!enabled && stop_policy == STOP_POLICY_DESCRIPTOR_QUEUE)) begin - packetize(); - descriptor_delay_subroutine(); - end else - @enable_ev; - end else begin - this.queue_empty_sig = 1; - ->> queue_empty; - @queue_ev; + this.info($sformatf("Generator started"), ADI_VERBOSITY_HIGH); + this.generator_running = 1; + fork begin + fork + begin + @disable_ev; + case (stop_policy) + STOP_POLICY_DESCRIPTOR_QUEUE: wait_empty_descriptor_queue(); + STOP_POLICY_PACKET: packet_sent(); + STOP_POLICY_DATA_BEAT: beat_sent(); + endcase + end + forever begin + if (descriptor_q.size() > 0) begin + if (enabled || (!enabled && stop_policy == STOP_POLICY_DESCRIPTOR_QUEUE)) begin + packetize(); + descriptor_delay_subroutine(); end + end else begin + this.queue_empty_sig = 1; + ->> queue_empty; + @queue_ev; end - join_any - disable fork; - end join - end + end + join_any + disable fork; + end join + this.generator_running = 0; endtask: generator // function @@ -287,70 +297,91 @@ package m_axis_sequencer_pkg; endtask: data_beat_delay_subroutine task start(); - this.info($sformatf("enable sequencer"), ADI_VERBOSITY_HIGH); - enabled = 1; - ->> enable_ev; + this.info($sformatf("Sequencer started"), ADI_VERBOSITY_HIGH); + if (this.generator_running || this.sender_running) begin + if (this.enabled) begin + this.warning($sformatf("Sequencer is already running!")); + end else begin + this.warning($sformatf("Sequencer is still running!")); + end + return; + end + this.enabled = 1; + fork + generator(); + sender(); + join_none endtask: start task stop(); - this.info($sformatf("disable sequencer"), ADI_VERBOSITY_HIGH); - enabled = 0; - byte_count = 0; - ->> disable_ev; + this.info($sformatf("Sequencer stopped"), ADI_VERBOSITY_HIGH); + this.enabled = 0; + this.byte_count = 0; + ->> this.disable_ev; #1step; endtask: stop - task run(); - fork - generator(); - sender(); - join_none - endtask: run - endclass: m_axis_sequencer_base - class m_axis_sequencer #( type T, `AXIS_VIP_PARAM_DECL) extends m_axis_sequencer_base; + class m_axis_sequencer #(`AXIS_VIP_PARAM_DECL(AXIS)) extends m_axis_sequencer_base; - protected T agent; + protected axi4stream_mst_driver #(`AXIS_VIP_IF_PARAMS(AXIS)) driver; function new( input string name, - input T agent, - input adi_component parent = null); + input axi4stream_mst_driver #(`AXIS_VIP_IF_PARAMS(AXIS)) driver, + input adi_agent parent = null); super.new(name, parent); - this.agent = agent; - this.agent.vif_proxy.set_no_insert_x_when_keep_low(1); + this.driver = driver; + + this.driver.vif_proxy.set_no_insert_x_when_keep_low(1); endfunction: new + // wait until data beat is sent + virtual task beat_sent(); + if (this.driver.is_driver_idle()) begin + return; + end + @beat_done; + endtask: beat_sent + + // wait until packet is sent + virtual task packet_sent(); + if (this.driver.is_driver_idle() && this.trans.get_last()) begin + return; + end + @packet_done; + endtask: packet_sent + // create transfer based on data beats per packet - virtual function void add_xfer_descriptor_packet_size( + virtual function void add_xfer_descriptor_sample_count( input int data_beats_per_packet, input int gen_tlast = 1, input int gen_sync = 1); - add_xfer_descriptor(data_beats_per_packet*AXIS_VIP_DATA_WIDTH/8, gen_tlast, gen_sync); - endfunction: add_xfer_descriptor_packet_size + add_xfer_descriptor_byte_count(data_beats_per_packet*AXIS_VIP_DATA_WIDTH/8, gen_tlast, gen_sync); + endfunction: add_xfer_descriptor_sample_count // set vif proxy to drive outputs with 0 when inactive virtual task set_inactive_drive_output_0(); - agent.vif_proxy.set_dummy_drive_type(XIL_AXI4STREAM_VIF_DRIVE_NONE); + this.driver.vif_proxy.set_dummy_drive_type(XIL_AXI4STREAM_VIF_DRIVE_NONE); this.wait_clk_count(2); endtask: set_inactive_drive_output_0 // check if ready is asserted virtual function bit check_ready_asserted(); - return agent.vif_proxy.is_ready_asserted(); + return this.driver.vif_proxy.is_ready_asserted(); endfunction: check_ready_asserted // wait for set amount of clock cycles virtual task wait_clk_count(input int wait_clocks); - agent.vif_proxy.wait_aclks(wait_clocks); + this.driver.vif_proxy.wait_aclks(wait_clocks); endtask: wait_clk_count // pack the byte stream into transfers(beats) then in packets by setting the tlast @@ -363,44 +394,48 @@ package m_axis_sequencer_pkg; this.info($sformatf("packetize start"), ADI_VERBOSITY_HIGH); byte_per_beat = AXIS_VIP_DATA_WIDTH/8; - descriptor = descriptor_q.pop_front(); + descriptor = this.descriptor_q.pop_front(); // put a copy of the descriptor back into the queue and continue processing - if (this.descriptor_gen_mode == 1 && enabled) - descriptor_q.push_back(descriptor); + if (this.descriptor_gen_mode == 1 && enabled) begin + this.descriptor_q.push_back(descriptor); + end packet_length = descriptor.num_bytes / byte_per_beat; - if (packet_length*byte_per_beat < descriptor.num_bytes) + if (packet_length*byte_per_beat < descriptor.num_bytes) begin packet_length++; + end - if (keep_all) + if (this.keep_all) begin descriptor.num_bytes = packet_length*byte_per_beat; + end for (int tc=0; tc> packet_done; - STOP_POLICY_DATA_BEAT: ->> beat_done; + STOP_POLICY_PACKET: ->> this.packet_done; + STOP_POLICY_DATA_BEAT: ->> this.beat_done; default: ; endcase end @@ -409,8 +444,9 @@ package m_axis_sequencer_pkg; disable fork; end join end + end DATA_GEN_MODE_AUTO_INCR: begin - data[i] = byte_count++; + data[i] = this.byte_count++; keep[i] = 1'b1; end DATA_GEN_MODE_AUTO_RAND: begin @@ -421,59 +457,60 @@ package m_axis_sequencer_pkg; end this.info($sformatf("generating axis transaction"), ADI_VERBOSITY_HIGH); - trans = agent.driver.create_transaction(); - trans.set_data(data); - trans.set_id('h0); - trans.set_dest('h0); - data_beat_delay_subroutine(); + this.trans = this.driver.create_transaction(); + this.trans.set_data(data); + this.trans.set_id('h0); + this.trans.set_dest('h0); - if (AXIS_VIP_HAS_TKEEP) - trans.set_keep(keep); + this.data_beat_delay_subroutine(); + + if (AXIS_VIP_HAS_TKEEP) begin + this.trans.set_keep(keep); + end - if (AXIS_VIP_HAS_TLAST) - trans.set_last((tc == packet_length-1) & descriptor.gen_last); + if (AXIS_VIP_HAS_TLAST) begin + this.trans.set_last((tc == packet_length-1) & descriptor.gen_last); + end - if (AXIS_VIP_USER_WIDTH > 0) - trans.set_user_beat((tc == 0) & descriptor.gen_sync); + if (AXIS_VIP_USER_WIDTH > 0) begin + this.trans.set_user_beat((tc == 0) & descriptor.gen_sync); + end ->> data_av_ev; this.info($sformatf("waiting transfer to complete"), ADI_VERBOSITY_HIGH); - @beat_done; + @this.beat_done; end - ->> packet_done; endtask: packetize // packet sender function virtual protected task sender(); - this.info($sformatf("sender start"), ADI_VERBOSITY_HIGH); - forever begin - this.info($sformatf("Waiting for enable"), ADI_VERBOSITY_HIGH); - @enable_ev; - this.info($sformatf("Enable found"), ADI_VERBOSITY_HIGH); - fork begin - fork - begin - @disable_ev; - if (this.queue_empty_sig == 0) - case (stop_policy) - STOP_POLICY_DESCRIPTOR_QUEUE: @queue_empty; - STOP_POLICY_PACKET: @packet_done; - STOP_POLICY_DATA_BEAT: @beat_done; - STOP_POLICY_IMMEDIATE: ; - endcase + this.info($sformatf("Sender started"), ADI_VERBOSITY_HIGH); + this.sender_running = 1; + fork begin + fork + begin + @this.disable_ev; + case (this.stop_policy) + STOP_POLICY_DESCRIPTOR_QUEUE: wait_empty_descriptor_queue(); + STOP_POLICY_PACKET: packet_sent(); + STOP_POLICY_DATA_BEAT: beat_sent(); + endcase + end + forever begin + @this.data_av_ev; + this.info($sformatf("sending axis transaction"), ADI_VERBOSITY_HIGH); + this.driver.send(this.trans); + ->> this.beat_done; + if (this.trans.get_last()) begin + ->> this.packet_done; end - forever begin - @data_av_ev; - this.info($sformatf("sending axis transaction"), ADI_VERBOSITY_HIGH); - agent.driver.send(trans); - ->> beat_done; - end - join_any - disable fork; - end join - end + end + join_any + disable fork; + end join + this.sender_running = 0; endtask: sender - endclass + endclass: m_axis_sequencer -endpackage +endpackage: m_axis_sequencer_pkg diff --git a/library/vip/amd/s_axis_sequencer.sv b/library/vip/amd/axis/s_axis_sequencer.sv similarity index 72% rename from library/vip/amd/s_axis_sequencer.sv rename to library/vip/amd/axis/s_axis_sequencer.sv index 35418e6c..97286ebe 100644 --- a/library/vip/amd/s_axis_sequencer.sv +++ b/library/vip/amd/axis/s_axis_sequencer.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -34,13 +34,15 @@ // *************************************************************************** `include "utils.svh" +`include "axis_definitions.svh" package s_axis_sequencer_pkg; import axi4stream_vip_pkg::*; + import adi_vip_pkg::*; import logger_pkg::*; - class s_axis_sequencer_base extends adi_component; + class s_axis_sequencer_base extends adi_sequencer; protected xil_axi4stream_data_byte byte_stream [$]; protected xil_axi4stream_ready_gen_policy_t mode; @@ -60,7 +62,7 @@ package s_axis_sequencer_pkg; // new function new( input string name, - input adi_component parent = null); + input adi_agent parent = null); super.new(name, parent); @@ -87,20 +89,20 @@ package s_axis_sequencer_pkg; // ready generation policy functions function void set_mode(input xil_axi4stream_ready_gen_policy_t mode); this.mode = mode; - endfunction + endfunction: set_mode function xil_axi4stream_ready_gen_policy_t get_mode(); return this.mode; - endfunction + endfunction: get_mode // high time functions function void set_high_time(input xil_axi4stream_uint high_time); this.high_time = high_time; - endfunction + endfunction: set_high_time function xil_axi4stream_uint get_high_time(); return this.high_time; - endfunction + endfunction: get_high_time function void set_high_time_range( input xil_axi4stream_uint high_time_min, @@ -108,12 +110,12 @@ package s_axis_sequencer_pkg; this.high_time_min = high_time_min; this.high_time_max = high_time_max; - endfunction + endfunction: set_high_time_range // low time functions function void set_low_time(input xil_axi4stream_uint low_time); this.low_time = low_time; - endfunction + endfunction: set_low_time function xil_axi4stream_uint get_low_time(); return this.low_time; @@ -125,57 +127,46 @@ package s_axis_sequencer_pkg; this.low_time_min = low_time_min; this.low_time_max = low_time_max; - endfunction - - // function for verifying bytes - task verify_byte(input bit [7:0] refdata); - bit [7:0] data; - if (byte_stream.size() == 0) begin - this.error($sformatf("Byte steam empty !!!")); - end else begin - data = byte_stream.pop_front(); - if (data !== refdata) begin - this.error($sformatf("Unexpected data received. Expected: %0h Found: %0h Left : %0d", refdata, data, byte_stream.size())); - end - end - endtask + endfunction: set_low_time_range // call ready generation function - task run(); - user_gen_tready(); - endtask + virtual task start(); + this.fatal($sformatf("Base class was instantiated instead of the parameterized class!")); + endtask: start // virtual tasks to be implemented virtual task user_gen_tready(); - endtask + this.fatal($sformatf("Base class was instantiated instead of the parameterized class!")); + endtask: user_gen_tready - virtual task get_transfer(); - endtask + virtual task stop(); + this.fatal($sformatf("Base class was instantiated instead of the parameterized class!")); + endtask: stop endclass: s_axis_sequencer_base - class s_axis_sequencer #( type T ) extends s_axis_sequencer_base; + class s_axis_sequencer #(`AXIS_VIP_PARAM_DECL(AXIS)) extends s_axis_sequencer_base; - protected T agent; + protected axi4stream_slv_driver #(`AXIS_VIP_IF_PARAMS(AXIS)) driver; function new( input string name, - input T agent, - input adi_component parent = null); + input axi4stream_slv_driver #(`AXIS_VIP_IF_PARAMS(AXIS)) driver, + input adi_agent parent = null); super.new(name, parent); - this.agent = agent; - endfunction + this.driver = driver; + endfunction: new - virtual task user_gen_tready(); + virtual task start(); axi4stream_ready_gen tready_gen; - tready_gen = agent.driver.create_ready("TREADY"); + tready_gen = this.driver.create_ready("TREADY"); tready_gen.set_ready_policy(this.mode); @@ -191,27 +182,13 @@ package s_axis_sequencer_pkg; tready_gen.set_low_time_range(this.low_time_min, this.low_time_max); tready_gen.set_high_time_range(this.high_time_min, this.high_time_max); end - agent.driver.send_tready(tready_gen); - endtask - - // Get transfer from the monitor and serialize data into a byte stream - // Assumption: all bytes from beat are valid (no position or null bytes) - virtual task get_transfer(); - - axi4stream_monitor_transaction mytrans; - xil_axi4stream_data_beat data_beat; + this.driver.send_tready(tready_gen); + endtask: start - agent.monitor.item_collected_port.get(mytrans); - - //$display(mytrans.convert2string); - - data_beat = mytrans.get_data_beat(); - - for (int i=0; i -// -// 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/master/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" - -package m_axi_sequencer_pkg; - - import axi_vip_pkg::*; - import logger_pkg::*; - import reg_accessor_pkg::*; - - class m_axi_sequencer #( type T ) extends reg_accessor; - - T agent; - - semaphore reader_s; - semaphore writer_s; - - function new( - input string name, - input T agent, - input adi_component parent = null); - - super.new(name, parent); - - this.agent = agent; - - reader_s = new(1); - writer_s = new(1); - endfunction - - // --------------------------------------------------------------------------- - // Generic tasks - // --------------------------------------------------------------------------- - virtual task automatic RegWrite32(input xil_axi_ulong addr =0, - input bit [31:0] data); - - static xil_axi_uint id =0; - - writer_s.get(1); - this.info($sformatf("writing to address %h value %h", addr , data), ADI_VERBOSITY_HIGH); - - single_write_transaction_readback_api(.id(id), - .addr(addr), - .len(0), - .size(XIL_AXI_SIZE_4BYTE), - .burst(XIL_AXI_BURST_TYPE_INCR), - .data(data)); - id++; - writer_s.put(1); - - endtask : RegWrite32 - - virtual task automatic RegRead32(input xil_axi_ulong addr =0, - output bit [31:0] data); - - xil_axi_data_beat DataBeat_for_read[]; - static xil_axi_uint id =0; - - reader_s.get(1); - - single_read_transaction_readback_api (.id(id), - .addr(addr), - .len(0), - .size(XIL_AXI_SIZE_4BYTE), - .burst(XIL_AXI_BURST_TYPE_INCR), - .Rdatabeat(DataBeat_for_read)); - id++; - data = DataBeat_for_read[0][0+:32]; - this.info($sformatf(" Reading data : %h @ 0x%h", data, addr), ADI_VERBOSITY_HIGH); - - reader_s.put(1); - - endtask : RegRead32 - - virtual task automatic RegReadVerify32(input xil_axi_ulong addr =0, - input bit [31:0] data); - bit [31:0] data_out; - RegRead32(.addr(addr), - .data(data_out)); - if (data !== data_out) begin - this.error($sformatf(" Address : %h; Data mismatch. Read data is : %h; expected is %h", addr, data_out, data)); - end - - endtask : RegReadVerify32 - - - // --------------------------------------------------------------------------- - // BFM specific tasks - // --------------------------------------------------------------------------- - task automatic single_write_transaction_api ( - input string name ="single_write", - input xil_axi_uint id =0, - input xil_axi_ulong addr =0, - input xil_axi_len_t len =0, - input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), - input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, - input xil_axi_lock_t lock = XIL_AXI_ALOCK_NOLOCK, - input xil_axi_cache_t cache =3, - input xil_axi_prot_t prot =0, - input xil_axi_region_t region =0, - input xil_axi_qos_t qos =0, - input bit [63:0] data =0); - - axi_transaction wr_trans; - wr_trans = agent.wr_driver.create_transaction(name); - wr_trans.set_write_cmd(addr, burst, id, len, size); - wr_trans.set_prot(prot); - wr_trans.set_lock(lock); - wr_trans.set_cache(cache); - wr_trans.set_region(region); - wr_trans.set_qos(qos); - wr_trans.set_data_block(data); - agent.wr_driver.send(wr_trans); - - endtask : single_write_transaction_api - - task automatic single_write_transaction_readback_api ( - input string name ="single_write", - input xil_axi_uint id =0, - input xil_axi_ulong addr =0, - input xil_axi_len_t len =0, - input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), - input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, - input xil_axi_lock_t lock = XIL_AXI_ALOCK_NOLOCK, - input xil_axi_cache_t cache =3, - input xil_axi_prot_t prot =0, - input xil_axi_region_t region =0, - input xil_axi_qos_t qos =0, - input bit [63:0] data =0); - - axi_transaction wr_trans; - wr_trans = agent.wr_driver.create_transaction(name); - wr_trans.set_write_cmd(addr, burst, id, len, size); - wr_trans.set_prot(prot); - wr_trans.set_lock(lock); - wr_trans.set_cache(cache); - wr_trans.set_region(region); - wr_trans.set_qos(qos); - wr_trans.set_data_block(data); - wr_trans.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN); - agent.wr_driver.send(wr_trans); - agent.wr_driver.wait_rsp(wr_trans); - - endtask : single_write_transaction_readback_api - - task automatic single_read_transaction_api ( - input string name ="single_read", - input xil_axi_uint id =0, - input xil_axi_ulong addr =0, - input xil_axi_len_t len =0, - input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), - input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, - input xil_axi_lock_t lock =XIL_AXI_ALOCK_NOLOCK , - input xil_axi_cache_t cache =3, - input xil_axi_prot_t prot =0, - input xil_axi_region_t region =0, - input xil_axi_qos_t qos =0, - input xil_axi_data_beat aruser =0); - - axi_transaction rd_trans; - rd_trans = agent.rd_driver.create_transaction(name); - rd_trans.set_read_cmd(addr, burst, id, len, size); - rd_trans.set_prot(prot); - rd_trans.set_lock(lock); - rd_trans.set_cache(cache); - rd_trans.set_region(region); - rd_trans.set_qos(qos); - agent.rd_driver.send(rd_trans); - endtask : single_read_transaction_api - - task automatic single_read_transaction_readback_api ( - input string name ="single_read", - input xil_axi_uint id =0, - input xil_axi_ulong addr =0, - input xil_axi_len_t len =0, - input xil_axi_size_t size =xil_axi_size_t'(xil_clog2((32)/8)), - input xil_axi_burst_t burst =XIL_AXI_BURST_TYPE_INCR, - input xil_axi_lock_t lock =XIL_AXI_ALOCK_NOLOCK , - input xil_axi_cache_t cache =3, - input xil_axi_prot_t prot =0, - input xil_axi_region_t region =0, - input xil_axi_qos_t qos =0, - input xil_axi_data_beat aruser =0, - output xil_axi_data_beat Rdatabeat[]); - - axi_transaction rd_trans; - rd_trans = agent.rd_driver.create_transaction(name); - rd_trans.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN); - rd_trans.set_read_cmd(addr, burst, id, len, size); - rd_trans.set_prot(prot); - rd_trans.set_lock(lock); - rd_trans.set_cache(cache); - rd_trans.set_region(region); - rd_trans.set_qos(qos); - agent.rd_driver.send(rd_trans); - agent.rd_driver.wait_rsp(rd_trans); - Rdatabeat = new[rd_trans.get_len()+1]; - for( xil_axi_uint beat=0; beat> 1); @@ -561,32 +570,25 @@ program test_program; end // Disable the module - env.mng.RegWrite32(`TDD_BA+GetAddrs(TDDN_CNTRL_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`TDD_BA+GetAddrs(TDDN_CNTRL_CONTROL), `SET_TDDN_CNTRL_CONTROL_ENABLE(0)); + base_env.stop(); stop_clocks(); `INFO(("Testbench finished!"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end task start_clocks(); - `TH.`DEVICE_CLK.inst.IF.start_clock; + `TH.`DEVICE_CLK.inst.IF.start_clock(); endtask task stop_clocks(); - `TH.`DEVICE_CLK.inst.IF.stop_clock; - endtask - - - task sys_reset(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; + `TH.`DEVICE_CLK.inst.IF.stop_clock(); endtask @@ -607,11 +609,15 @@ program test_program; time t1=0, t2=0, expected_pulse_lengh; fork - channel_probe(i, t1, t2); - join_none - @(posedge `TH.dut_tdd.inst.tdd_endof_frame); - repeat (3) @(posedge `TH.dut_tdd.inst.clk); - disable fork; + begin + fork + channel_probe(i, t1, t2); + join_none + @(posedge `TH.dut_tdd.inst.tdd_endof_frame); + repeat (3) @(posedge `TH.dut_tdd.inst.clk); + disable fork; + end + join if (ch_on[i] == ch_off[i]) begin expected_pulse_lengh = 0; diff --git a/testbenches/ip/axi_tdd/waves/cfg1.wcfg b/testbenches/ip/axi_tdd/waves/cfg1.wcfg index 54504f63..ae7e3945 100644 --- a/testbenches/ip/axi_tdd/waves/cfg1.wcfg +++ b/testbenches/ip/axi_tdd/waves/cfg1.wcfg @@ -14,7 +14,6 @@ - diff --git a/testbenches/ip/axis_sequencers/Makefile b/testbenches/ip/axis_sequencers/Makefile index 0319e0db..095446af 100644 --- a/testbenches/ip/axis_sequencers/Makefile +++ b/testbenches/ip/axis_sequencers/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2022(c) Analog Devices, Inc. +## Copyright (C) 2022 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/axis_sequencers/environment.sv b/testbenches/ip/axis_sequencers/environment.sv index ba3fe31c..20198af9 100644 --- a/testbenches/ip/axis_sequencers/environment.sv +++ b/testbenches/ip/axis_sequencers/environment.sv @@ -1,32 +1,56 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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 "axis_definitions.svh" package environment_pkg; - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import m_axis_sequencer_pkg::*; - import s_axis_sequencer_pkg::*; import logger_pkg::*; - import axi_vip_pkg::*; - import axi4stream_vip_pkg::*; - import test_harness_env_pkg::*; - - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; + import adi_environment_pkg::*; - import `PKGIFY(test_harness, src_axis)::*; - import `PKGIFY(test_harness, dst_axis)::*; - - class environment extends test_harness_env; + import axi4stream_vip_pkg::*; + import m_axis_sequencer_pkg::*; + import s_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; - // agents and sequencers - `AGENT(test_harness, src_axis, mst_t) src_axis_agent; - `AGENT(test_harness, dst_axis, slv_t) dst_axis_agent; + class axis_sequencer_environment #(`AXIS_VIP_PARAM_DECL(src_axis), `AXIS_VIP_PARAM_DECL(dst_axis)) extends adi_environment; - m_axis_sequencer #(`AGENT(test_harness, src_axis, mst_t), - `AXIS_VIP_PARAMS(test_harness, src_axis) - ) src_axis_seq; - s_axis_sequencer #(`AGENT(test_harness, dst_axis, slv_t)) dst_axis_seq; + // Agents + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(src_axis)) src_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(dst_axis)) dst_axis_agent; //============================================================================ // Constructor @@ -34,34 +58,14 @@ package environment_pkg; function new ( input string name, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, src_axis)) src_axis_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, dst_axis)) dst_axis_vip_if - ); + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(src_axis)) src_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(dst_axis)) dst_axis_vip_if); // creating the agents - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); - - src_axis_agent = new("Source AXI Stream Agent", src_axis_vip_if); - dst_axis_agent = new("Destination AXI Stream Agent", dst_axis_vip_if); - - src_axis_seq = new("Source AXI Stream Agent", src_axis_agent, this); - dst_axis_seq = new("Destination AXI Stream Agent", dst_axis_agent, this); + super.new(name); + this.src_axis_agent = new("Source AXI Stream Agent", src_axis_vip_if, this); + this.dst_axis_agent = new("Destination AXI Stream Agent", dst_axis_vip_if, this); endfunction //============================================================================ @@ -69,68 +73,41 @@ package environment_pkg; // - Configure the sequencer VIPs with an initial configuration before starting them //============================================================================ task configure(); - xil_axi4stream_ready_gen_policy_t dac_mode; // source stub - src_axis_seq.set_stop_policy(STOP_POLICY_PACKET); + this.src_axis_agent.sequencer.set_stop_policy(STOP_POLICY_PACKET); // destination stub dac_mode = XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE; - dst_axis_seq.set_mode(dac_mode); - + this.dst_axis_agent.sequencer.set_mode(dac_mode); endtask //============================================================================ // Start environment //============================================================================ task start(); - - super.start(); - - src_axis_agent.start_master(); - dst_axis_agent.start_slave(); - - endtask - - //============================================================================ - // Start the test - //============================================================================ - task test(); - fork - src_axis_seq.run(); - dst_axis_seq.run(); - join_none - endtask - - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); + this.src_axis_agent.agent.start_master(); + this.dst_axis_agent.agent.start_slave(); endtask //============================================================================ // Run subroutine //============================================================================ task run; - - //pre_test(); - test(); - + fork + this.src_axis_agent.sequencer.run(); + this.dst_axis_agent.sequencer.run(); + join_none endtask //============================================================================ // Stop subroutine //============================================================================ task stop; - - super.stop(); - src_axis_seq.stop(); - src_axis_agent.stop_master(); - dst_axis_agent.stop_slave(); - post_test(); - + this.src_axis_agent.sequencer.stop(); + this.src_axis_agent.agent.stop_master(); + this.dst_axis_agent.agent.stop_slave(); endtask endclass diff --git a/testbenches/ip/axis_sequencers/system_bd.tcl b/testbenches/ip/axis_sequencers/system_bd.tcl index b05934de..783cc71c 100644 --- a/testbenches/ip/axis_sequencers/system_bd.tcl +++ b/testbenches/ip/axis_sequencers/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2022 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/axis_sequencers/system_tb.sv b/testbenches/ip/axis_sequencers/system_tb.sv index 36eff4db..2723b531 100644 --- a/testbenches/ip/axis_sequencers/system_tb.sv +++ b/testbenches/ip/axis_sequencers/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/axis_sequencers/tests/test_program.sv b/testbenches/ip/axis_sequencers/tests/test_program.sv index ac02bb73..034918d1 100644 --- a/testbenches/ip/axis_sequencers/tests/test_program.sv +++ b/testbenches/ip/axis_sequencers/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -26,91 +26,104 @@ // // 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/master/LICENSE_ADIBSD +// 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" -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; -import m_axis_sequencer_pkg::*; -import s_axis_sequencer_pkg::*; import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import environment_pkg::*; import watchdog_pkg::*; +import axi4stream_vip_pkg::*; +import m_axis_sequencer_pkg::*; +import s_axis_sequencer_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; -//============================================================================= -// Register Maps -//============================================================================= +import `PKGIFY(test_harness, src_axis)::*; +import `PKGIFY(test_harness, dst_axis)::*; program test_program; // declare the class instances - environment env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + axis_sequencer_environment #(`AXIS_VIP_PARAMS(test_harness, src_axis), `AXIS_VIP_PARAMS(test_harness, dst_axis)) axis_seq_env; watchdog send_data_wd; initial begin // create environment - env = new("Axis Sequencers Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SRC_AXIS.inst.IF, - `TH.`DST_AXIS.inst.IF - ); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + axis_seq_env = new("Axis Sequencers Environment", + `TH.`SRC_AXIS.inst.IF, + `TH.`DST_AXIS.inst.IF); setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + axis_seq_env.start(); + + base_env.sys_reset(); - env.configure(); + axis_seq_env.configure(); - env.run(); + axis_seq_env.run(); - env.src_axis_seq.set_data_beat_delay(`SRC_BEAT_DELAY); - env.src_axis_seq.set_descriptor_delay(`SRC_DESCRIPTOR_DELAY); + axis_seq_env.src_axis_agent.sequencer.set_data_beat_delay(`SRC_BEAT_DELAY); + axis_seq_env.src_axis_agent.sequencer.set_descriptor_delay(`SRC_DESCRIPTOR_DELAY); - env.dst_axis_seq.set_high_time(`DEST_BEAT_DELAY_HIGH); - env.dst_axis_seq.set_low_time(`DEST_BEAT_DELAY_LOW); + axis_seq_env.dst_axis_agent.sequencer.set_high_time(`DEST_BEAT_DELAY_HIGH); + axis_seq_env.dst_axis_agent.sequencer.set_low_time(`DEST_BEAT_DELAY_LOW); case (`DEST_BACKPRESSURE) - 1: env.dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_SINGLE); - 2: env.dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + 1: axis_seq_env.dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_SINGLE); + 2: axis_seq_env.dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); default: `FATAL(("Destination backpressure mode parameter incorrect!")); endcase case (`SRC_DESCRIPTORS) 1: begin - env.src_axis_seq.set_descriptor_gen_mode(0); - env.src_axis_seq.set_stop_policy(STOP_POLICY_DATA_BEAT); - // env.src_axis_seq.add_xfer_descriptor(32'h600, 1, 0); - env.src_axis_seq.add_xfer_descriptor_packet_size(32'd10, 1, 0); + axis_seq_env.src_axis_agent.sequencer.set_descriptor_gen_mode(0); + axis_seq_env.src_axis_agent.sequencer.set_stop_policy(STOP_POLICY_DATA_BEAT); + // axis_seq_env.src_axis_agent.sequencer.add_xfer_descriptor_byte_count(32'h600, 1, 0); + axis_seq_env.src_axis_agent.sequencer.add_xfer_descriptor_sample_count(32'd10, 1, 0); send_data_wd = new("Axis Sequencer Watchdog", 1000, "Send data"); end 2: begin - env.src_axis_seq.set_descriptor_gen_mode(0); - env.src_axis_seq.set_stop_policy(STOP_POLICY_DESCRIPTOR_QUEUE); - repeat (10) env.src_axis_seq.add_xfer_descriptor(32'h600, 1, 0); + axis_seq_env.src_axis_agent.sequencer.set_descriptor_gen_mode(0); + axis_seq_env.src_axis_agent.sequencer.set_stop_policy(STOP_POLICY_DESCRIPTOR_QUEUE); + repeat (10) axis_seq_env.src_axis_agent.sequencer.add_xfer_descriptor_byte_count(32'h600, 1, 0); send_data_wd = new("Axis Sequencer Watchdog", 30000, "Send data"); end 3: begin - env.src_axis_seq.set_descriptor_gen_mode(1); - env.src_axis_seq.set_stop_policy(STOP_POLICY_PACKET); - env.src_axis_seq.add_xfer_descriptor(32'h600, 1, 0); + axis_seq_env.src_axis_agent.sequencer.set_descriptor_gen_mode(1); + axis_seq_env.src_axis_agent.sequencer.set_stop_policy(STOP_POLICY_PACKET); + axis_seq_env.src_axis_agent.sequencer.add_xfer_descriptor_byte_count(32'h600, 1, 0); send_data_wd = new("Axis Sequencer Watchdog", 20000, "Send data"); end @@ -119,27 +132,27 @@ program test_program; send_data_wd.start(); - env.src_axis_seq.start(); + axis_seq_env.src_axis_agent.sequencer.start(); #1step; case (`SRC_DESCRIPTORS) - 1: //env.src_axis_seq.beat_sent(); - env.src_axis_seq.packet_sent(); - 2: env.src_axis_seq.wait_empty_descriptor_queue(); + 1: //axis_seq_env.src_axis_agent.sequencer.beat_sent(); + axis_seq_env.src_axis_agent.sequencer.packet_sent(); + 2: axis_seq_env.src_axis_agent.sequencer.wait_empty_descriptor_queue(); 3: begin #10us; - env.src_axis_seq.stop(); + axis_seq_env.src_axis_agent.sequencer.stop(); - env.src_axis_seq.packet_sent(); + axis_seq_env.src_axis_agent.sequencer.packet_sent(); end default: ; endcase send_data_wd.stop(); - env.stop(); + base_env.stop(); `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); $finish(); diff --git a/testbenches/ip/axis_sequencers/waves/cfg1.wcfg b/testbenches/ip/axis_sequencers/waves/cfg1.wcfg index 4a417396..a320c7a1 100644 --- a/testbenches/ip/axis_sequencers/waves/cfg1.wcfg +++ b/testbenches/ip/axis_sequencers/waves/cfg1.wcfg @@ -14,7 +14,6 @@ - diff --git a/testbenches/ip/base/Makefile b/testbenches/ip/base/Makefile index 6c2e0bea..74545915 100644 --- a/testbenches/ip/base/Makefile +++ b/testbenches/ip/base/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2024(c) Analog Devices, Inc. +## Copyright (C) 2024 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -9,7 +9,6 @@ include ../../../scripts/make_tb_path.mk include $(TB_LIBRARY_PATH)/includes/Makeinclude_common.mk # Remaining test-bench dependencies except test programs -SV_DEPS += environment.sv # default test program TP := test_program diff --git a/testbenches/ip/base/environment.sv b/testbenches/ip/base/environment.sv deleted file mode 100644 index 90b91888..00000000 --- a/testbenches/ip/base/environment.sv +++ /dev/null @@ -1,91 +0,0 @@ -`include "utils.svh" - -package environment_pkg; - - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import logger_pkg::*; - - import axi_vip_pkg::*; - import test_harness_env_pkg::*; - - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; - - class environment extends test_harness_env; - - /* Add agents and sequencers */ - - //============================================================================ - // Constructor - //============================================================================ - function new ( - input string name, - - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if - ); - - // Creating the agents - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); - - endfunction - - //============================================================================ - // Start environment - //============================================================================ - task start(); - - super.start(); - - endtask - - //============================================================================ - // Start the test - //============================================================================ - task test(); - endtask - - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run; - - //pre_test(); - test(); - - endtask - - //============================================================================ - // Stop subroutine - //============================================================================ - task stop; - - super.stop(); - - post_test(); - - endtask - - endclass - -endpackage diff --git a/testbenches/ip/base/system_bd.tcl b/testbenches/ip/base/system_bd.tcl index 7e456b0a..c0eabdcb 100644 --- a/testbenches/ip/base/system_bd.tcl +++ b/testbenches/ip/base/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2024 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/base/system_project.tcl b/testbenches/ip/base/system_project.tcl index d86009f2..cc9ad709 100644 --- a/testbenches/ip/base/system_project.tcl +++ b/testbenches/ip/base/system_project.tcl @@ -18,7 +18,6 @@ adi_sim_project_xilinx $project_name "xcvu9p-flga2104-2L-e" # Add test files to the project adi_sim_project_files [list \ - "environment.sv" \ "tests/test_program.sv" \ ] diff --git a/testbenches/ip/base/system_tb.sv b/testbenches/ip/base/system_tb.sv index b2e0c285..0ad34c87 100644 --- a/testbenches/ip/base/system_tb.sv +++ b/testbenches/ip/base/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2024 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/base/tests/test_program.sv b/testbenches/ip/base/tests/test_program.sv index 2ab88bd3..5ad24bf9 100644 --- a/testbenches/ip/base/tests/test_program.sv +++ b/testbenches/ip/base/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -34,15 +34,22 @@ // *************************************************************************** `include "utils.svh" +`include "axi_definitions.svh" -import axi_vip_pkg::*; import logger_pkg::*; -import environment_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; program test_program; // Declare the class instances - environment env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // Process variables process current_process; @@ -58,25 +65,27 @@ program test_program; `INFO(("Randomization state: %s", current_process_random_state), ADI_VERBOSITY_NONE); // Create environment - env = new("Base Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF - ); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); - env.start(); - env.sys_reset(); + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) - /* Add other configurations if necessary before calling run */ + base_env.irq_handler = new("IRQ handler", base_env.mng.master_sequencer, `IRQ_C_BA, `TH.`IRQ.inst.inst.IF.vif, base_env); - env.run(); + base_env.start(); + base_env.sys_reset(); + base_env.irq_handler.start(); /* Add stimulus tasks */ - env.stop(); + base_env.stop(); `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); $finish(); diff --git a/testbenches/ip/base/waves/cfg1.wcfg b/testbenches/ip/base/waves/cfg1.wcfg index 2fe219f8..4469603f 100644 --- a/testbenches/ip/base/waves/cfg1.wcfg +++ b/testbenches/ip/base/waves/cfg1.wcfg @@ -13,7 +13,6 @@ - diff --git a/testbenches/ip/data_offload/Makefile b/testbenches/ip/data_offload/Makefile index 7770fc41..136eaf46 100644 --- a/testbenches/ip/data_offload/Makefile +++ b/testbenches/ip/data_offload/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/data_offload/environment.sv b/testbenches/ip/data_offload/environment.sv index 66c3fafe..ff4def5b 100644 --- a/testbenches/ip/data_offload/environment.sv +++ b/testbenches/ip/data_offload/environment.sv @@ -117,7 +117,7 @@ package environment_pkg; task adc_stream_gen(); - while(1) begin + forever begin if (adc_src_axis_agent.driver.is_driver_idle) begin rx_transaction = adc_src_axis_agent.driver.create_transaction(""); ADC_TRANSACTION_FAIL: assert(rx_transaction.randomize()); diff --git a/testbenches/ip/data_offload/tests/test_program.sv b/testbenches/ip/data_offload/tests/test_program.sv index 3268193e..47a84d4f 100644 --- a/testbenches/ip/data_offload/tests/test_program.sv +++ b/testbenches/ip/data_offload/tests/test_program.sv @@ -1,3 +1,38 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2021 - 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 responsabilities 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" import axi_vip_pkg::*; @@ -82,7 +117,7 @@ module test_program(); // ADC stub env.adc_src_axis_seq.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - env.adc_src_axis_seq.add_xfer_descriptor(`ADC_TRANSFER_LENGTH, 0, 0); + env.adc_src_axis_seq.add_xfer_descriptor_byte_count(`ADC_TRANSFER_LENGTH, 0, 0); // DAC stub dac_mode = XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE; @@ -92,7 +127,7 @@ module test_program(); setLoggerVerbosity(ADI_VERBOSITY_NONE); - `TH.`PLDDR_RST.inst.IF.assert_reset; + `TH.`PLDDR_RST.inst.IF.assert_reset(); #1; start_clocks(); @@ -139,33 +174,33 @@ module test_program(); task start_clocks(); #1 - `TH.`SRC_CLK.inst.IF.start_clock; + `TH.`SRC_CLK.inst.IF.start_clock(); #1 - `TH.`DST_CLK.inst.IF.start_clock; + `TH.`DST_CLK.inst.IF.start_clock(); #1 - `TH.`SYS_CLK.inst.IF.start_clock; + `TH.`SYS_CLK.inst.IF.start_clock(); #1 - `TH.`PLDDR_CLK.inst.IF.start_clock; + `TH.`PLDDR_CLK.inst.IF.start_clock(); endtask task stop_clocks(); - `TH.`SRC_CLK.inst.IF.stop_clock; - `TH.`DST_CLK.inst.IF.stop_clock; - `TH.`SYS_CLK.inst.IF.stop_clock; - `TH.`PLDDR_CLK.inst.IF.stop_clock; + `TH.`SRC_CLK.inst.IF.stop_clock(); + `TH.`DST_CLK.inst.IF.stop_clock(); + `TH.`SYS_CLK.inst.IF.stop_clock(); + `TH.`PLDDR_CLK.inst.IF.stop_clock(); endtask task sys_reset(); - `TH.`SRC_RST.inst.IF.assert_reset; - `TH.`DST_RST.inst.IF.assert_reset; - `TH.`SYS_RST.inst.IF.assert_reset; - `TH.`PLDDR_RST.inst.IF.assert_reset; + `TH.`SRC_RST.inst.IF.assert_reset(); + `TH.`DST_RST.inst.IF.assert_reset(); + `TH.`SYS_RST.inst.IF.assert_reset(); + `TH.`PLDDR_RST.inst.IF.assert_reset(); #500 - `TH.`SRC_RST.inst.IF.deassert_reset; - `TH.`DST_RST.inst.IF.deassert_reset; - `TH.`SYS_RST.inst.IF.deassert_reset; - `TH.`PLDDR_RST.inst.IF.deassert_reset; + `TH.`SRC_RST.inst.IF.deassert_reset(); + `TH.`DST_RST.inst.IF.deassert_reset(); + `TH.`SYS_RST.inst.IF.deassert_reset(); + `TH.`PLDDR_RST.inst.IF.deassert_reset(); endtask task systemBringUp(); @@ -210,7 +245,7 @@ module test_program(); // Memory initialization function for a 8byte DATA_WIDTH AXI4 bus task init_mem_64(longint unsigned addr, int byte_length); for (int i=0; i - diff --git a/testbenches/ip/data_offload_2/waves/cfg2.wcfg b/testbenches/ip/data_offload_2/waves/cfg2.wcfg index 9fa04440..10d70433 100644 --- a/testbenches/ip/data_offload_2/waves/cfg2.wcfg +++ b/testbenches/ip/data_offload_2/waves/cfg2.wcfg @@ -14,7 +14,6 @@ - diff --git a/testbenches/ip/data_offload_2/waves/cfg3.wcfg b/testbenches/ip/data_offload_2/waves/cfg3.wcfg index fd2b5b57..c4434594 100644 --- a/testbenches/ip/data_offload_2/waves/cfg3.wcfg +++ b/testbenches/ip/data_offload_2/waves/cfg3.wcfg @@ -14,7 +14,7 @@ - + diff --git a/testbenches/ip/data_offload_2/waves/cfg4.wcfg b/testbenches/ip/data_offload_2/waves/cfg4.wcfg index 96af8b88..6ce229cf 100644 --- a/testbenches/ip/data_offload_2/waves/cfg4.wcfg +++ b/testbenches/ip/data_offload_2/waves/cfg4.wcfg @@ -14,7 +14,7 @@ - + diff --git a/testbenches/ip/dma_flock/environment.sv b/testbenches/ip/dma_flock/environment.sv index cdf0ff9d..864938b5 100644 --- a/testbenches/ip/dma_flock/environment.sv +++ b/testbenches/ip/dma_flock/environment.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -34,37 +34,24 @@ // *************************************************************************** `include "utils.svh" +`include "axis_definitions.svh" package environment_pkg; - import axi_vip_pkg::*; + import logger_pkg::*; + import adi_environment_pkg::*; + import scoreboard_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 test_harness_env_pkg::*; - import dma_trans_pkg::*; - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; - import `PKGIFY(test_harness, src_axis_vip)::*; - import `PKGIFY(test_harness, dst_axis_vip)::*; + import adi_axis_agent_pkg::*; - class environment extends test_harness_env; + class dma_flock_environment #(`AXIS_VIP_PARAM_DECL(src_axis), `AXIS_VIP_PARAM_DECL(dst_axis)) extends adi_environment; // Agents - `AGENT(test_harness, src_axis_vip, mst_t) src_axis_agent; - `AGENT(test_harness, dst_axis_vip, slv_t) dst_axis_agent; - - // Sequencers - m_axis_sequencer #(`AGENT(test_harness, src_axis_vip, mst_t), - `AXIS_VIP_PARAMS(test_harness, src_axis_vip) - ) src_axis_seq; - s_axis_sequencer #(`AGENT(test_harness, dst_axis_vip, slv_t)) dst_axis_seq; - // Register accessors - - dma_transfer_group trans_q[$]; + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(src_axis)) src_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(dst_axis)) dst_axis_agent; scoreboard scrb; @@ -74,34 +61,16 @@ package environment_pkg; function new( input string name, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, src_axis_vip)) src_axis_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, dst_axis_vip)) dst_axis_vip_if - ); - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(src_axis)) src_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(dst_axis)) dst_axis_vip_if); - // Creating the agents - src_axis_agent = new("Src AXI stream agent", src_axis_vip_if); - dst_axis_agent = new("Dest AXI stream agent", dst_axis_vip_if); + super.new(name); - // Creating the sequencers - src_axis_seq = new("Src AXI stream sequencer", src_axis_agent, this); - dst_axis_seq = new("Dest AXI stream sequencer", dst_axis_agent, this); + // Creating the agents + this.src_axis_agent = new("Src AXI stream agent", src_axis_vip_if, this); + this.dst_axis_agent = new("Dest AXI stream agent", dst_axis_vip_if, this); - scrb = new("Scoreboard", this); + this.scrb = new("Scoreboard", this); endfunction @@ -111,15 +80,12 @@ package environment_pkg; // - Start the agents //============================================================================ task start(); - super.start(); - scrb.connect( - src_axis_agent.monitor.item_collected_port, - dst_axis_agent.monitor.item_collected_port - ); - - src_axis_agent.start_master(); - dst_axis_agent.start_slave(); + this.scrb.connect( + this.src_axis_agent.agent.monitor.item_collected_port, + this.dst_axis_agent.agent.monitor.item_collected_port); + this.src_axis_agent.agent.start_master(); + this.dst_axis_agent.agent.start_slave(); endtask //============================================================================ @@ -128,27 +94,24 @@ package environment_pkg; // - start the sequencers //============================================================================ task test(); - super.test(); - src_axis_seq.run(); + this.src_axis_agent.sequencer.run(); // DEST AXIS does not have to run, scoreboard connects and // gathers packets from the agent - scrb.run(); - test_c_run(); + this.scrb.run(); endtask //============================================================================ // Post test subroutine //============================================================================ task post_test(); - super.post_test(); // wait until done - scrb.shutdown(); + this.scrb.shutdown(); endtask //============================================================================ // Run subroutine //============================================================================ - task run; + task run(); test(); post_test(); endtask @@ -156,10 +119,9 @@ package environment_pkg; //============================================================================ // Stop subroutine //============================================================================ - task stop; - super.stop(); - src_axis_agent.stop_master(); - dst_axis_agent.stop_slave(); + task stop(); + this.src_axis_agent.agent.stop_master(); + this.dst_axis_agent.agent.stop_slave(); endtask endclass diff --git a/testbenches/ip/dma_flock/scoreboard.sv b/testbenches/ip/dma_flock/scoreboard.sv index e728d0d0..2e5f1828 100644 --- a/testbenches/ip/dma_flock/scoreboard.sv +++ b/testbenches/ip/dma_flock/scoreboard.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 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 @@ -37,6 +37,7 @@ package scoreboard_pkg; + import adi_common_pkg::*; import xil_common_vip_pkg::*; import axi4stream_vip_pkg::*; import axi_vip_pkg::*; @@ -120,7 +121,8 @@ package scoreboard_pkg; end end endtask : run_dst - task shutdown; + + task shutdown(); -> shutdown_event; endtask: shutdown diff --git a/testbenches/ip/dma_flock/system_tb.sv b/testbenches/ip/dma_flock/system_tb.sv index 8fb9ed2f..f76d6dd6 100644 --- a/testbenches/ip/dma_flock/system_tb.sv +++ b/testbenches/ip/dma_flock/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 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 diff --git a/testbenches/ip/dma_flock/tests/test_program.sv b/testbenches/ip/dma_flock/tests/test_program.sv index 18347e63..8fcd5c4b 100644 --- a/testbenches/ip/dma_flock/tests/test_program.sv +++ b/testbenches/ip/dma_flock/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -35,18 +35,33 @@ `include "utils.svh" +import logger_pkg::*; import environment_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; -import logger_pkg::*; import adi_regmap_pkg::*; import adi_regmap_dmac_pkg::*; import dmac_api_pkg::*; import dma_trans_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +import `PKGIFY(test_harness, src_axis_vip)::*; +import `PKGIFY(test_harness, dst_axis_vip)::*; + program test_program; - environment env; + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + dma_flock_environment #(`AXIS_VIP_PARAMS(test_harness, src_axis_vip), `AXIS_VIP_PARAMS(test_harness, dst_axis_vip)) dma_flock_env; + // Register accessors dmac_api m_dmac_api; dmac_api s_dmac_api; @@ -58,32 +73,40 @@ program test_program; initial begin //creating environment - env = new("DMA Flock environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SRC_AXIS.inst.IF, - `TH.`DST_AXIS.inst.IF - ); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - #2ps; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + dma_flock_env = new("DMA Flock Environment", + `TH.`SRC_AXIS.inst.IF, + `TH.`DST_AXIS.inst.IF); has_sfsync = `M_DMA_CFG_USE_EXT_SYNC; has_dfsync = `S_DMA_CFG_USE_EXT_SYNC; setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + + base_env.start(); + dma_flock_env.start(); + start_clocks(); - env.sys_reset(); - env.run(); - m_dmac_api = new("TX_DMA_BA", env.mng, `TX_DMA_BA); + base_env.sys_reset(); + + dma_flock_env.run(); + + m_dmac_api = new("TX_DMA_BA", base_env.mng.master_sequencer, `TX_DMA_BA); m_dmac_api.probe(); - s_dmac_api = new("RX_DMA_BA", env.mng, `RX_DMA_BA); + s_dmac_api = new("RX_DMA_BA", base_env.mng.master_sequencer, `RX_DMA_BA); s_dmac_api.probe(); sanity_test; @@ -115,8 +138,8 @@ program test_program; .dst_clk( 50000000) ); + base_env.stop(); stop_clocks(); - env.stop(); `INFO(("Testbench done!"), ADI_VERBOSITY_NONE); $finish(); @@ -138,13 +161,13 @@ program test_program; axi_ready_gen wready_gen; // Set no backpressure from AXIS destination - env.dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); - env.dst_axis_seq.user_gen_tready(); + dma_flock_env.dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + dma_flock_env.dst_axis_agent.sequencer.user_gen_tready(); // Set no backpressure from DDR - wready_gen = env.ddr_axi_agent.wr_driver.create_ready("wready"); + wready_gen = base_env.ddr.agent.wr_driver.create_ready("wready"); wready_gen.set_ready_policy(XIL_AXI_READY_GEN_NO_BACKPRESSURE); - env.ddr_axi_agent.wr_driver.send_wready(wready_gen); + base_env.ddr.agent.wr_driver.send_wready(wready_gen); m_seg = new(m_dmac_api.p); rand_succ = m_seg.randomize() with { dst_addr == 0; @@ -160,9 +183,9 @@ program test_program; s_seg = m_seg.toSlaveSeg(); - env.src_axis_seq.set_stop_policy(m_axis_sequencer_pkg::STOP_POLICY_DESCRIPTOR_QUEUE); - env.src_axis_seq.set_data_gen_mode(m_axis_sequencer_pkg::DATA_GEN_MODE_TEST_DATA); - env.src_axis_seq.start(); + dma_flock_env.src_axis_agent.sequencer.set_stop_policy(m_axis_sequencer_pkg::STOP_POLICY_DESCRIPTOR_QUEUE); + dma_flock_env.src_axis_agent.sequencer.set_data_gen_mode(m_axis_sequencer_pkg::DATA_GEN_MODE_TEST_DATA); + dma_flock_env.src_axis_agent.sequencer.start(); m_dmac_api.set_control('b1001); m_dmac_api.set_flags('b111); @@ -191,7 +214,7 @@ program test_program; begin for (int l = 0; l < m_seg.ylength; l++) begin // update the AXIS generator command - env.src_axis_seq.add_xfer_descriptor(.bytes_to_generate(m_seg.length), + dma_flock_env.src_axis_agent.sequencer.add_xfer_descriptor_byte_count(.bytes_to_generate(m_seg.length), .gen_last(1), .gen_sync(l==0)); end @@ -199,7 +222,7 @@ program test_program; // update the AXIS generator data for (int j = 0; j < m_seg.get_bytes_in_transfer; j++) begin // ADI DMA frames start from offset 0x00 - env.src_axis_seq.push_byte_for_stream(frame_count); + dma_flock_env.src_axis_agent.sequencer.push_byte_for_stream(frame_count); end end join @@ -220,7 +243,7 @@ program test_program; sync_gen_en = 0; // Stop triggers wait stop policy - env.src_axis_seq.stop(); + dma_flock_env.src_axis_agent.sequencer.stop(); // Shutdown DMACs m_dmac_api.disable_dma(); @@ -235,16 +258,16 @@ program test_program; bit [63:0] mtestWData; // Write Data bit [31:0] rdData; - env.mng.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); + base_env.mng.master_sequencer.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); mtestWData = 0; repeat (10) begin - env.mng.RegWrite32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); - env.mng.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); + base_env.mng.master_sequencer.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); mtestWData += 4; end - env.mng.RegReadVerify32(`RX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); + base_env.mng.master_sequencer.RegReadVerify32(`RX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); endtask @@ -269,15 +292,15 @@ program test_program; set_dst_clock(100000000); set_ddr_clock(600000000); - `TH.`SRC_CLK.inst.IF.start_clock; - `TH.`DST_CLK.inst.IF.start_clock; + `TH.`SRC_CLK.inst.IF.start_clock(); + `TH.`DST_CLK.inst.IF.start_clock(); #100ns; endtask // Stop all clocks task stop_clocks(); - `TH.`SRC_CLK.inst.IF.stop_clock; - `TH.`DST_CLK.inst.IF.stop_clock; + `TH.`SRC_CLK.inst.IF.stop_clock(); + `TH.`DST_CLK.inst.IF.stop_clock(); endtask // Assert external sync for one clock cycle diff --git a/testbenches/ip/dma_flock/tests/test_program_frame_delay.sv b/testbenches/ip/dma_flock/tests/test_program_frame_delay.sv index f91b0498..ae7a895f 100644 --- a/testbenches/ip/dma_flock/tests/test_program_frame_delay.sv +++ b/testbenches/ip/dma_flock/tests/test_program_frame_delay.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -35,18 +35,33 @@ `include "utils.svh" -import environment_pkg::*; -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; import logger_pkg::*; +import environment_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import adi_regmap_dmac_pkg::*; import dmac_api_pkg::*; import dma_trans_pkg::*; +import axi_vip_pkg::*; +import axi4stream_vip_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +import `PKGIFY(test_harness, src_axis_vip)::*; +import `PKGIFY(test_harness, dst_axis_vip)::*; program test_program_frame_delay; - environment env; + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + dma_flock_environment #(`AXIS_VIP_PARAMS(test_harness, src_axis_vip), `AXIS_VIP_PARAMS(test_harness, dst_axis_vip)) dma_flock_env; + // Register accessors dmac_api m_dmac_api; dmac_api s_dmac_api; @@ -59,19 +74,23 @@ program test_program_frame_delay; int sync_gen_en; initial begin + //creating environment - env = new("DMA Flock environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SRC_AXIS.inst.IF, - `TH.`DST_AXIS.inst.IF - ); - - #2ps; + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + dma_flock_env = new("DMA Flock Environment", + `TH.`SRC_AXIS.inst.IF, + `TH.`DST_AXIS.inst.IF); has_sfsync = `M_DMA_CFG_USE_EXT_SYNC; has_dfsync = `S_DMA_CFG_USE_EXT_SYNC; @@ -79,15 +98,20 @@ program test_program_frame_delay; has_s_autorun = `S_DMA_CFG_AUTORUN; setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + + base_env.start(); + dma_flock_env.start(); + start_clocks(); - env.sys_reset(); - env.run(); - m_dmac_api = new("TX_DMA_BA", env.mng, `TX_DMA_BA); + base_env.sys_reset(); + + dma_flock_env.run(); + + m_dmac_api = new("TX_DMA_BA", base_env.mng.master_sequencer, `TX_DMA_BA); m_dmac_api.probe(); - s_dmac_api = new("RX_DMA_BA", env.mng, `RX_DMA_BA); + s_dmac_api = new("RX_DMA_BA", base_env.mng.master_sequencer, `RX_DMA_BA); s_dmac_api.probe(); @@ -144,8 +168,8 @@ program test_program_frame_delay; `ERROR(("Both DMACs must be set in autorun mode.")); end + base_env.stop(); stop_clocks(); - env.stop(); `INFO(("Testbench done!"), ADI_VERBOSITY_NONE); $finish(); @@ -169,13 +193,13 @@ program test_program_frame_delay; axi_ready_gen wready_gen; // Set no backpressure from AXIS destination - env.dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); - env.dst_axis_seq.user_gen_tready(); + dma_flock_env.dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + dma_flock_env.dst_axis_agent.sequencer.user_gen_tready(); // Set no backpressure from DDR - wready_gen = env.ddr_axi_agent.wr_driver.create_ready("wready"); + wready_gen = base_env.ddr.agent.wr_driver.create_ready("wready"); wready_gen.set_ready_policy(XIL_AXI_READY_GEN_NO_BACKPRESSURE); - env.ddr_axi_agent.wr_driver.send_wready(wready_gen); + base_env.ddr.agent.wr_driver.send_wready(wready_gen); m_seg = new(m_dmac_api.p); @@ -202,9 +226,9 @@ program test_program_frame_delay; s_seg = m_seg.toSlaveSeg(); - env.src_axis_seq.set_stop_policy(m_axis_sequencer_pkg::STOP_POLICY_DESCRIPTOR_QUEUE); - env.src_axis_seq.set_data_gen_mode(m_axis_sequencer_pkg::DATA_GEN_MODE_TEST_DATA); - env.src_axis_seq.start(); + dma_flock_env.src_axis_agent.sequencer.set_stop_policy(m_axis_sequencer_pkg::STOP_POLICY_DESCRIPTOR_QUEUE); + dma_flock_env.src_axis_agent.sequencer.set_data_gen_mode(m_axis_sequencer_pkg::DATA_GEN_MODE_TEST_DATA); + dma_flock_env.src_axis_agent.sequencer.start(); if (has_autorun == 0) begin m_dmac_api.set_control('b1001); @@ -238,7 +262,7 @@ program test_program_frame_delay; begin for (int l = 0; l < m_seg.ylength; l++) begin // update the AXIS generator command - env.src_axis_seq.add_xfer_descriptor(.bytes_to_generate(m_seg.length), + dma_flock_env.src_axis_agent.sequencer.add_xfer_descriptor_byte_count(.bytes_to_generate(m_seg.length), .gen_last(1), .gen_sync(l==0)); end @@ -246,7 +270,7 @@ program test_program_frame_delay; // update the AXIS generator data for (int j = 0; j < m_seg.get_bytes_in_transfer; j++) begin // ADI DMA frames start from offset 0x00 - env.src_axis_seq.push_byte_for_stream(frame_count); + dma_flock_env.src_axis_agent.sequencer.push_byte_for_stream(frame_count); end end join @@ -269,7 +293,7 @@ program test_program_frame_delay; sync_gen_en = 0; // Stop triggers wait stop policy - env.src_axis_seq.stop(); + dma_flock_env.src_axis_agent.sequencer.stop(); // Shutdown DMACs if (!has_m_autorun) begin @@ -288,16 +312,16 @@ program test_program_frame_delay; bit [63:0] mtestWData; // Write Data bit [31:0] rdData; - env.mng.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); + base_env.mng.master_sequencer.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); mtestWData = 0; repeat (10) begin - env.mng.RegWrite32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); - env.mng.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); + base_env.mng.master_sequencer.RegReadVerify32(`TX_DMA_BA + GetAddrs(DMAC_SCRATCH), mtestWData); mtestWData += 4; end - env.mng.RegReadVerify32(`RX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); + base_env.mng.master_sequencer.RegReadVerify32(`RX_DMA_BA + GetAddrs(DMAC_IDENTIFICATION), 'h44_4D_41_43); endtask @@ -322,15 +346,15 @@ program test_program_frame_delay; set_dst_clock(100000000); set_ddr_clock(500000000); - `TH.`SRC_CLK.inst.IF.start_clock; - `TH.`DST_CLK.inst.IF.start_clock; + `TH.`SRC_CLK.inst.IF.start_clock(); + `TH.`DST_CLK.inst.IF.start_clock(); #100ns; endtask // Stop all clocks task stop_clocks(); - `TH.`SRC_CLK.inst.IF.stop_clock; - `TH.`DST_CLK.inst.IF.stop_clock; + `TH.`SRC_CLK.inst.IF.stop_clock(); + `TH.`DST_CLK.inst.IF.stop_clock(); endtask // Assert external sync for one clock cycle diff --git a/testbenches/ip/dma_flock/waves/cfg1.wcfg b/testbenches/ip/dma_flock/waves/cfg1.wcfg index f099716c..2e3129b7 100644 --- a/testbenches/ip/dma_flock/waves/cfg1.wcfg +++ b/testbenches/ip/dma_flock/waves/cfg1.wcfg @@ -6,7 +6,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/testbenches/ip/dma_flock/waves/cfg2_fsync.wcfg b/testbenches/ip/dma_flock/waves/cfg2_fsync.wcfg index f099716c..2e3129b7 100644 --- a/testbenches/ip/dma_flock/waves/cfg2_fsync.wcfg +++ b/testbenches/ip/dma_flock/waves/cfg2_fsync.wcfg @@ -6,7 +6,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/testbenches/ip/dma_flock/waves/cfg3_fsync_autorun.wcfg b/testbenches/ip/dma_flock/waves/cfg3_fsync_autorun.wcfg index f099716c..2e3129b7 100644 --- a/testbenches/ip/dma_flock/waves/cfg3_fsync_autorun.wcfg +++ b/testbenches/ip/dma_flock/waves/cfg3_fsync_autorun.wcfg @@ -6,7 +6,7 @@ - + @@ -19,7 +19,7 @@ - + diff --git a/testbenches/ip/dma_loopback/Makefile b/testbenches/ip/dma_loopback/Makefile index 3b461f72..aabd7597 100644 --- a/testbenches/ip/dma_loopback/Makefile +++ b/testbenches/ip/dma_loopback/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/dma_loopback/system_bd.tcl b/testbenches/ip/dma_loopback/system_bd.tcl index a2fa7b7c..f190aee1 100644 --- a/testbenches/ip/dma_loopback/system_bd.tcl +++ b/testbenches/ip/dma_loopback/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/dma_loopback/system_tb.sv b/testbenches/ip/dma_loopback/system_tb.sv index 3aa095c4..5c718309 100644 --- a/testbenches/ip/dma_loopback/system_tb.sv +++ b/testbenches/ip/dma_loopback/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/dma_loopback/tests/test_program.sv b/testbenches/ip/dma_loopback/tests/test_program.sv index 0e609f33..feb0902b 100644 --- a/testbenches/ip/dma_loopback/tests/test_program.sv +++ b/testbenches/ip/dma_loopback/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,29 +26,35 @@ // // 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/master/LICENSE_ADIBSD +// 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" import test_harness_env_pkg::*; -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; +import adi_axi_agent_pkg::*; import logger_pkg::*; import adi_regmap_pkg::*; import adi_regmap_dmac_pkg::*; import dmac_api_pkg::*; import dma_trans_pkg::*; +import axi_vip_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; program test_program; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + // Register accessors dmac_api m_dmac_api; dmac_api s_dmac_api; @@ -56,37 +62,37 @@ program test_program; initial begin //creating environment - env = new("DMA Loopback Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - #2ps; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + + base_env.start(); + start_clocks(); + base_env.sys_reset(); - m_dmac_api = new("TX_DMA", env.mng, `TX_DMA_BA); + m_dmac_api = new("TX_DMA", base_env.mng.master_sequencer, `TX_DMA_BA); m_dmac_api.probe(); - s_dmac_api = new("RX_DMA", env.mng, `RX_DMA_BA); + s_dmac_api = new("RX_DMA", base_env.mng.master_sequencer, `RX_DMA_BA); s_dmac_api.probe(); - start_clocks(); - sys_reset(); - - #1us; - // ------------------------------------------------------- // Test TX DMA and RX DMA in loopback // ------------------------------------------------------- // Init test data for (int i=0;i<2048*2 ;i=i+2) begin - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BA+i*2,(((i+1)) << 16) | i ,'hF); + base_env.ddr.slave_sequencer.set_reg_data_in_mem(xil_axi_uint'(`DDR_BA+i*2),(((i+1)) << 16) | i ,'hF); end do_transfer( @@ -103,6 +109,11 @@ program test_program; .length('h1000) ); + base_env.stop(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); + end task do_transfer(bit [31:0] src_addr, @@ -147,8 +158,8 @@ program test_program; for (int i=0;i - + @@ -17,7 +17,7 @@ - + diff --git a/testbenches/ip/dma_sg/waves/cfg2.wcfg b/testbenches/ip/dma_sg/waves/cfg2.wcfg index a4a4c9df..a187b39f 100644 --- a/testbenches/ip/dma_sg/waves/cfg2.wcfg +++ b/testbenches/ip/dma_sg/waves/cfg2.wcfg @@ -5,7 +5,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/testbenches/ip/hbm/Makefile b/testbenches/ip/hbm/Makefile index 956fb144..f6e420b5 100644 --- a/testbenches/ip/hbm/Makefile +++ b/testbenches/ip/hbm/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/hbm/system_bd.tcl b/testbenches/ip/hbm/system_bd.tcl index 71be57d5..33153841 100644 --- a/testbenches/ip/hbm/system_bd.tcl +++ b/testbenches/ip/hbm/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/hbm/system_tb.sv b/testbenches/ip/hbm/system_tb.sv index 3aa095c4..5c718309 100644 --- a/testbenches/ip/hbm/system_tb.sv +++ b/testbenches/ip/hbm/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/hbm/tests/test_program.sv b/testbenches/ip/hbm/tests/test_program.sv index a8480581..e8134b51 100644 --- a/testbenches/ip/hbm/tests/test_program.sv +++ b/testbenches/ip/hbm/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,55 +26,60 @@ // // 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/master/LICENSE_ADIBSD +// 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" import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import logger_pkg::*; import adi_regmap_dmac_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + `define RX_DMA 32'h7c42_0000 `define TX_DMA 32'h7c43_0000 `define DDR_BASE 32'h8000_0000 program test_program; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + bit [31:0] val; bit [31:0] src_addr; initial begin //creating environment - env = new("HBM Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); - - #2ps; + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); - `TH.`HBM_CLK.inst.IF.start_clock; + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) - env.sys_reset(); + setLoggerVerbosity(ADI_VERBOSITY_NONE); - #1us; + base_env.start(); + `TH.`HBM_CLK.inst.IF.start_clock(); + base_env.sys_reset(); // // ------------------------------------------------------- // // Test TX DMA and RX DMA in loopback @@ -82,7 +87,7 @@ program test_program; // // // Init test data // for (int i=0;i<2048*2 ;i=i+2) begin -// env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BASE+src_addr+i*2,(((i+1)) << 16) | i ,'hF); +// base_env.ddr.slave_sequencer.set_reg_data_in_mem(`DDR_BASE+src_addr+i*2,(((i+1)) << 16) | i ,'hF); // end // // do_transfer( @@ -98,12 +103,13 @@ program test_program; // .dest_addr(`DDR_BASE+'h2000), // .length('h1000) // ); -// -// env.stop(); -// -// `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); -// $finish(); -// + + base_env.stop(); + `TH.`HBM_CLK.inst.IF.stop_clock(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); + end // task do_transfer(bit [31:0] src_addr, @@ -111,27 +117,27 @@ program test_program; // bit [31:0] length); // // // Configure TX DMA -// env.mng.RegWrite32(`TX_DMA+GetAddrs(dmac_CONTROL), +// base_env.mng.master_sequencer.RegWrite32(`TX_DMA+GetAddrs(dmac_CONTROL), // `SET_dmac_CONTROL_ENABLE(1)); -// env.mng.RegWrite32(`TX_DMA+GetAddrs(dmac_FLAGS), +// base_env.mng.master_sequencer.RegWrite32(`TX_DMA+GetAddrs(dmac_FLAGS), // `SET_dmac_FLAGS_TLAST(32'h00000006)); -// env.mng.RegWrite32(`TX_DMA+GetAddrs(dmac_X_LENGTH), +// base_env.mng.master_sequencer.RegWrite32(`TX_DMA+GetAddrs(dmac_X_LENGTH), // `SET_dmac_X_LENGTH_X_LENGTH(length-1)); -// env.mng.RegWrite32(`TX_DMA+GetAddrs(dmac_SRC_ADDRESS), +// base_env.mng.master_sequencer.RegWrite32(`TX_DMA+GetAddrs(dmac_SRC_ADDRESS), // `SET_dmac_SRC_ADDRESS_SRC_ADDRESS(src_addr)); -// env.mng.RegWrite32(`TX_DMA+GetAddrs(dmac_TRANSFER_SUBMIT), +// base_env.mng.master_sequencer.RegWrite32(`TX_DMA+GetAddrs(dmac_TRANSFER_SUBMIT), // `SET_dmac_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // // // Configure RX DMA -// env.mng.RegWrite32(`RX_DMA+GetAddrs(dmac_CONTROL), +// base_env.mng.master_sequencer.RegWrite32(`RX_DMA+GetAddrs(dmac_CONTROL), // `SET_dmac_CONTROL_ENABLE(1)); -// env.mng.RegWrite32(`RX_DMA+GetAddrs(dmac_FLAGS), +// base_env.mng.master_sequencer.RegWrite32(`RX_DMA+GetAddrs(dmac_FLAGS), // `SET_dmac_FLAGS_TLAST(32'h00000006)); -// env.mng.RegWrite32(`RX_DMA+GetAddrs(dmac_X_LENGTH), +// base_env.mng.master_sequencer.RegWrite32(`RX_DMA+GetAddrs(dmac_X_LENGTH), // `SET_dmac_X_LENGTH_X_LENGTH(length-1)); -// env.mng.RegWrite32(`RX_DMA+GetAddrs(dmac_DEST_ADDRESS), +// base_env.mng.master_sequencer.RegWrite32(`RX_DMA+GetAddrs(dmac_DEST_ADDRESS), // `SET_dmac_DEST_ADDRESS_DEST_ADDRESS(dest_addr)); -// env.mng.RegWrite32(`RX_DMA+GetAddrs(dmac_TRANSFER_SUBMIT), +// base_env.mng.master_sequencer.RegWrite32(`RX_DMA+GetAddrs(dmac_TRANSFER_SUBMIT), // `SET_dmac_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // endtask // @@ -149,8 +155,8 @@ program test_program; // for (int i=0;i - + diff --git a/testbenches/ip/irq_handler/Makefile b/testbenches/ip/irq_handler/Makefile new file mode 100644 index 00000000..74545915 --- /dev/null +++ b/testbenches/ip/irq_handler/Makefile @@ -0,0 +1,37 @@ +#################################################################################### +#################################################################################### +## Copyright (C) 2024 Analog Devices, Inc. +#################################################################################### +#################################################################################### + +# Makeincludes +include ../../../scripts/make_tb_path.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_common.mk + +# Remaining test-bench dependencies except test programs + +# default test program +TP := test_program + +# config files should have the following format +# cfg__.tcl +CFG_FILES := $(notdir $(wildcard cfgs/cfg*.tcl)) +#$(warning $(CFG_FILES)) + +# List of tests and configuration combinations that has to be run +# Format is: : +TESTS := $(foreach cfg, $(basename $(CFG_FILES)), $(addprefix $(cfg):, $(TP))) +#TESTS += cfg1:test_program + +include $(ADI_TB_DIR)/scripts/project-sim.mk + +# usage : +# +# run specific test on a specific configuration in gui mode +# make CFG=cfg2_fsync TST=test_frame_delay MODE=gui +# +# run all test from a configuration +# make cfg1_mm2mm_default + +#################################################################################### +#################################################################################### diff --git a/testbenches/ip/irq_handler/README.md b/testbenches/ip/irq_handler/README.md new file mode 100644 index 00000000..7c6d0faa --- /dev/null +++ b/testbenches/ip/irq_handler/README.md @@ -0,0 +1,35 @@ +Base design to be copied when starting to work on a new testbench. + +By default includes: + + * all the files that are needed for any testbench + * scoreboard and auxiliary module imports, ready to be integrated + * new environment file ready to expand the base test harness environment + * test program that powers up and shuts down the system + * option to add manual seeding + +Run all tests in batch mode: + + make + + +Run all tests in GUI mode: + + make MODE=gui + + +Run specific test on a specific configuration in gui mode: + + make CFG= TST= MODE=gui + + +Run all test from a configuration: + + make + + +Where: + + * is a file from the cfgs directory without the tcl extension of format cfg\* + * is a file from the tests directory without the tcl extension + diff --git a/testbenches/ip/irq_handler/cfgs/cfg1.tcl b/testbenches/ip/irq_handler/cfgs/cfg1.tcl new file mode 100644 index 00000000..d040d253 --- /dev/null +++ b/testbenches/ip/irq_handler/cfgs/cfg1.tcl @@ -0,0 +1 @@ +global ad_project_params diff --git a/testbenches/ip/irq_handler/system_bd.tcl b/testbenches/ip/irq_handler/system_bd.tcl new file mode 100644 index 00000000..28fdb912 --- /dev/null +++ b/testbenches/ip/irq_handler/system_bd.tcl @@ -0,0 +1,45 @@ +# *************************************************************************** +# *************************************************************************** +# Copyright (C) 2024 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. +# +# *************************************************************************** +# *************************************************************************** + +global ad_project_params + +# create IRQ VIP +ad_ip_instance io_vip irq_test_vip [ list \ + MODE {1} \ +] +adi_sim_add_define "IRQ_TEST=irq_test_vip" + +ad_connect irq_test_vip/clk sys_cpu_clk +ad_cpu_interrupt ps-0 mb-0 irq_test_vip/o diff --git a/testbenches/ip/irq_handler/system_project.tcl b/testbenches/ip/irq_handler/system_project.tcl new file mode 100644 index 00000000..cc9ad709 --- /dev/null +++ b/testbenches/ip/irq_handler/system_project.tcl @@ -0,0 +1,30 @@ +source ../../../scripts/adi_sim.tcl + +if {$argc < 1} { + puts "Expecting at least one argument that specifies the test configuration" + exit 1 +} else { + set cfg_file [lindex $argv 0] +} + +# Read config file +source "cfgs/${cfg_file}" + +# Set the project name +set project_name [file rootname $cfg_file] + +# Create the project +adi_sim_project_xilinx $project_name "xcvu9p-flga2104-2L-e" + +# Add test files to the project +adi_sim_project_files [list \ + "tests/test_program.sv" \ +] + +#set a default test program +adi_sim_add_define "TEST_PROGRAM=test_program" + +adi_sim_generate $project_name + +# Use this only for debugging specific seeds that failed previously +#set_property -name {xsim.simulate.xsim.more_options} -value {-sv_seed 1695199824} -objects [get_filesets sim_1] diff --git a/library/drivers/common/interfaces.svh b/testbenches/ip/irq_handler/system_tb.sv similarity index 79% rename from library/drivers/common/interfaces.svh rename to testbenches/ip/irq_handler/system_tb.sv index a7a2d397..0ad34c87 100644 --- a/library/drivers/common/interfaces.svh +++ b/testbenches/ip/irq_handler/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2024 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 @@ -26,28 +26,20 @@ // // 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/master/LICENSE_ADIBSD +// 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. // // *************************************************************************** // *************************************************************************** -`ifndef _INTERFACES_SVH_ -`define _INTERFACES_SVH_ +`timescale 1ns/1ps -interface clk_if (); - logic clk; +`include "utils.svh" - task start_clock(int clk_period); - clk = 1'b1; - fork - forever begin - #((clk_period / 2)*1ps); - clk = ~clk; - end - join_none - endtask: start_clock -endinterface: clk_if +module system_tb(); -`endif + `TEST_PROGRAM test(); + test_harness `TH (); + +endmodule diff --git a/testbenches/ip/irq_handler/tests/test_program.sv b/testbenches/ip/irq_handler/tests/test_program.sv new file mode 100644 index 00000000..f4121817 --- /dev/null +++ b/testbenches/ip/irq_handler/tests/test_program.sv @@ -0,0 +1,139 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2024 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 responsabilities 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" + +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +program test_program; + + // Declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + // Process variables + process current_process; + string current_process_random_state; + + event dummy_api_event; + + reg [31:0] data; + + + initial begin + + setLoggerVerbosity(ADI_VERBOSITY_HIGH); + + current_process = process::self(); + current_process_random_state = current_process.get_randstate(); + `INFO(("Randomization state: %s", current_process_random_state), ADI_VERBOSITY_NONE); + + // Create environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + base_env.irq_handler = new("IRQ handler", base_env.mng.master_sequencer, `IRQ_C_BA, `TH.`IRQ.inst.inst.IF.vif, base_env); + + base_env.start(); + base_env.sys_reset(); + + // register IRQ devices + dummy_api_event = base_env.irq_handler.register_device(0); + + // start IRQ handler + base_env.irq_handler.start(); + + // wait for the IRQ to trigger before it is triggered + fork + begin + @dummy_api_event; + `INFO(("IRQ triggered"), ADI_VERBOSITY_LOW); + end + join_none + + #1us; + + // trigger the IRQ + `TH.`IRQ_TEST.inst.inst.IF.vif.set_io(1'b1); + #10ns; + `TH.`IRQ_TEST.inst.inst.IF.vif.set_io(1'b0); + + #1us; + + // priority packet test + fork + begin + repeat(5) begin + fork + base_env.mng.master_sequencer.RegWrite32(`IRQ_C_BA + 'h10, 'd0); + base_env.mng.master_sequencer.RegRead32(`IRQ_C_BA + 'h10, data); + join_none + end + repeat(5) begin + fork + base_env.mng.master_sequencer.RegWrite32(`IRQ_C_BA + 'h10, 'd0, 1); + base_env.mng.master_sequencer.RegRead32(`IRQ_C_BA + 'h10, data, 1); + join_none + end + end + join + + #10us; + + base_env.stop(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); + + end + +endprogram diff --git a/testbenches/ip/irq_handler/waves/cfg1.wcfg b/testbenches/ip/irq_handler/waves/cfg1.wcfg new file mode 100644 index 00000000..5552f058 --- /dev/null +++ b/testbenches/ip/irq_handler/waves/cfg1.wcfg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clk + clk + + + i[0:0] + i[0:0] + + + o[0:0] + o[0:0] + + + io[0:0] + io[0:0] + + + IO[0:0] + IO[0:0] + + + intf_is_master + intf_is_master + + + intf_is_slave + intf_is_slave + + diff --git a/testbenches/ip/jesd_loopback/Makefile b/testbenches/ip/jesd_loopback/Makefile index 197b3f07..9b805f0a 100644 --- a/testbenches/ip/jesd_loopback/Makefile +++ b/testbenches/ip/jesd_loopback/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/jesd_loopback/system_bd.tcl b/testbenches/ip/jesd_loopback/system_bd.tcl index 7b71ed7a..31d59778 100644 --- a/testbenches/ip/jesd_loopback/system_bd.tcl +++ b/testbenches/ip/jesd_loopback/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/jesd_loopback/system_tb.sv b/testbenches/ip/jesd_loopback/system_tb.sv index 2abe0526..6394fb3f 100644 --- a/testbenches/ip/jesd_loopback/system_tb.sv +++ b/testbenches/ip/jesd_loopback/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/jesd_loopback/tests/test_program.sv b/testbenches/ip/jesd_loopback/tests/test_program.sv index b455b544..42dd5022 100644 --- a/testbenches/ip/jesd_loopback/tests/test_program.sv +++ b/testbenches/ip/jesd_loopback/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2021 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 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 @@ -26,21 +26,18 @@ // // 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/master/LICENSE_ADIBSD +// 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" -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import adi_regmap_jesd_tx_pkg::*; import adi_regmap_jesd_rx_pkg::*; @@ -51,6 +48,9 @@ import adi_regmap_xcvr_pkg::*; import adi_jesd204_pkg::*; import adi_xcvr_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + `define MODE_8B10B 1 `define MODE_64B66B 2 @@ -63,7 +63,11 @@ import adi_xcvr_pkg::*; program test_program; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + bit [31:0] val; jesd_link link; @@ -77,19 +81,24 @@ program test_program; longint unsigned lane_rate = lane_rate_khz*1000; initial begin + //creating environment - env = new("JESD Loopback Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - #2ps; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + + base_env.start(); + base_env.sys_reset(); link = new; link.set_L(`JESD_L); @@ -102,25 +111,25 @@ program test_program; link.set_encoding(`LINK_MODE == `MODE_8B10B ? enc8b10b : enc64b66b); link.set_lane_rate(lane_rate); - rx_ll = new("RX_LINK_LAYER", env.mng, `AXI_JESD_RX_BA, link); + rx_ll = new("RX_LINK_LAYER", base_env.mng.master_sequencer, `AXI_JESD_RX_BA, link); rx_ll.probe(); - tx_ll = new("TX_LINK_LAYER", env.mng, `AXI_JESD_TX_BA, link); + tx_ll = new("TX_LINK_LAYER", base_env.mng.master_sequencer, `AXI_JESD_TX_BA, link); tx_ll.probe(); - rx_xcvr = new("RX_XCVR", env.mng, `ADC_XCVR_BA); + rx_xcvr = new("RX_XCVR", base_env.mng.master_sequencer, `ADC_XCVR_BA); rx_xcvr.probe(); - tx_xcvr = new("TX_XCVR", env.mng, `DAC_XCVR_BA); + tx_xcvr = new("TX_XCVR", base_env.mng.master_sequencer, `DAC_XCVR_BA); tx_xcvr.probe(); `TH.`REF_CLK.inst.IF.set_clk_frq(.user_frequency(`REF_CLK_RATE*1000000)); `TH.`DEVICE_CLK.inst.IF.set_clk_frq(.user_frequency(rx_ll.calc_device_clk())); `TH.`SYSREF_CLK.inst.IF.set_clk_frq(.user_frequency(rx_ll.calc_sysref_clk())); - `TH.`REF_CLK.inst.IF.start_clock; - `TH.`DEVICE_CLK.inst.IF.start_clock; - `TH.`SYSREF_CLK.inst.IF.start_clock; + `TH.`REF_CLK.inst.IF.start_clock(); + `TH.`DEVICE_CLK.inst.IF.start_clock(); + `TH.`SYSREF_CLK.inst.IF.start_clock(); rx_xcvr.setup_clocks(lane_rate, `REF_CLK_RATE*1000000); @@ -139,20 +148,20 @@ program test_program; jesd_link_test(); // Check link restart counter - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + 'h2c4, 1); + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + 'h2c4, 1); // ======================= // TPL SYNC control test // ======================= arm_disarm_test(); + + base_env.stop(); + `TH.`REF_CLK.inst.IF.stop_clock(); + `TH.`DEVICE_CLK.inst.IF.stop_clock(); + `TH.`SYSREF_CLK.inst.IF.stop_clock(); - - `INFO(("======================="), ADI_VERBOSITY_LOW); - `INFO((" TB DONE "), ADI_VERBOSITY_LOW); - `INFO(("======================="), ADI_VERBOSITY_LOW); - - env.stop(); - $finish; + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); end @@ -175,26 +184,26 @@ program test_program; for (int i = 0; i < `JESD_M; i++) begin if (use_dds) begin // Select DDS as source - env.mng.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(0)); // Configure tone amplitude and frequency - env.mng.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_1_DDS_SCALE_1(16'h0fff)); - env.mng.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_2_DDS_INCR_1(16'h0100)); end else begin // Set DMA as source for DAC TPL - env.mng.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + 'h40 * i + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(2)); end end - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), `SET_DAC_COMMON_REG_RSTN_RSTN(1)); if (use_dds) begin // Sync DDS cores - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1), `SET_DAC_COMMON_REG_CNTRL_1_SYNC(1)); end @@ -209,11 +218,11 @@ program test_program; // Configure ADC TPL // ----------------------- for (int i = 0; i < `JESD_M; i++) begin - env.mng.RegWrite32(`ADC_TPL_BA + 'h40 * i + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + 'h40 * i + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), `SET_ADC_CHANNEL_REG_CHAN_CNTRL_ENABLE(1)); end - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), `SET_ADC_COMMON_REG_RSTN_RSTN(1)); rx_ll.link_up(); @@ -225,13 +234,13 @@ program test_program; #5us; // Arm external sync - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),2); - env.mng.RegWrite32(`ADC_TPL_BA + 'h48,2); + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),2); + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + 'h48,2); #1us; // Check if armed - env.mng.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), `SET_DAC_COMMON_REG_SYNC_STATUS_DAC_SYNC_STATUS(1)); - env.mng.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), `SET_ADC_COMMON_REG_SYNC_STATUS_ADC_SYNC(1)); #1us; // Trigger external sync @@ -242,7 +251,7 @@ program test_program; #1us; // Check if trigger captured - env.mng.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), `SET_DAC_COMMON_REG_SYNC_STATUS_DAC_SYNC_STATUS(0)); #5us; @@ -259,17 +268,17 @@ program test_program; @(posedge system_tb.sysref); @(negedge system_tb.sysref); // Check SYSREF alignment ERROR - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); @@ -280,17 +289,17 @@ program test_program; @(posedge system_tb.sysref); @(negedge system_tb.sysref); // Check SYSREF alignment ERROR - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_ALIGNMENT_ERROR(1) | `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); @@ -310,25 +319,25 @@ program test_program; // ----------------- task arm_disarm_test(); // Arm external sync - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),2); - env.mng.RegWrite32(`ADC_TPL_BA + 'h48,2); + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),2); + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + 'h48,2); #1us; // Check if armed - env.mng.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), `SET_DAC_COMMON_REG_SYNC_STATUS_DAC_SYNC_STATUS(1)); - env.mng.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), `SET_ADC_COMMON_REG_SYNC_STATUS_ADC_SYNC(1)); // DisArm external sync - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),4); - env.mng.RegWrite32(`ADC_TPL_BA + 'h48,4); + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1),4); + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + 'h48,4); #1us; // Check if disarmed - env.mng.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_SYNC_STATUS), `SET_DAC_COMMON_REG_SYNC_STATUS_DAC_SYNC_STATUS(0)); - env.mng.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_SYNC_STATUS), `SET_ADC_COMMON_REG_SYNC_STATUS_ADC_SYNC(0)); `INFO(("======================="), ADI_VERBOSITY_LOW); `INFO((" ARM-DISARM TEST DONE "), ADI_VERBOSITY_LOW); @@ -371,18 +380,18 @@ program test_program; ); end // set TXOUTCLKSEL to 3'b010 (TXOUTCLKPMA) - env.mng.RegRead32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); + base_env.mng.master_sequencer.RegRead32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); tx_out_clk_sel = `GET_XCVR_CONTROL_OUTCLK_SEL(val); - env.mng.RegWrite32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val & (~{32'b111} << 0) | `SET_XCVR_CONTROL_OUTCLK_SEL(2)); // set RXOUTCLKSEL to 3'b010 (RXOUTCLKPMA) - env.mng.RegRead32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); + base_env.mng.master_sequencer.RegRead32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); rx_out_clk_sel = `GET_XCVR_CONTROL_OUTCLK_SEL(val); - env.mng.RegWrite32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val & (~{32'b111} << 0) | `SET_XCVR_CONTROL_OUTCLK_SEL(2)); @@ -396,36 +405,36 @@ program test_program; // ----------------------- // Put XCVR in PRBS mode // ----------------------- - env.mng.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_9); - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7); + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_9); + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7); #1us; // Error should be detected - env.mng.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 1<<8 | 0); + base_env.mng.master_sequencer.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 1<<8 | 0); // Check if error can be cleared - env.mng.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_7); - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7 | 1 << 8); // Set prbs err cntr reset - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7 | 0 << 8); // Clear prbs err cntr reset + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_7); + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7 | 1 << 8); // Set prbs err cntr reset + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7 | 0 << 8); // Clear prbs err cntr reset #1us; // No error should be detected, Lock should be set - env.mng.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 0<<8 | 1); + base_env.mng.master_sequencer.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 0<<8 | 1); // ----------------------- // Check Error injection // ----------------------- - env.mng.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_7 | 1<<16 ); // Enable Error inject - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, 1 << 8); // Clear prbs err - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7); + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_7 | 1<<16 ); // Enable Error inject + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, 1 << 8); // Clear prbs err + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_7); #1us; // Error should be detected - env.mng.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 1<<8 | 0); + base_env.mng.master_sequencer.RegReadVerify32(`ADC_XCVR_BA + 32'h0184, 1<<8 | 0); - env.mng.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_OFF); - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, 1 << 8); // Clear prbs err - env.mng.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_OFF); + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + 32'h0180, `PRBS_OFF); + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, 1 << 8); // Clear prbs err + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + 32'h0180, `PRBS_OFF); rx_xcvr.down(); tx_xcvr.down(); @@ -451,14 +460,14 @@ program test_program; ); end // set TXOUTCLKSEL old value - env.mng.RegRead32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); - env.mng.RegWrite32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegRead32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); + base_env.mng.master_sequencer.RegWrite32(`DAC_XCVR_BA + GetAddrs(XCVR_CONTROL), val & (~{32'b111} << 0) | `SET_XCVR_CONTROL_OUTCLK_SEL(tx_out_clk_sel)); // set RXOUTCLKSEL to 3'b010 (RXOUTCLKPMA) - env.mng.RegRead32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); - env.mng.RegWrite32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegRead32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val); + base_env.mng.master_sequencer.RegWrite32(`ADC_XCVR_BA + GetAddrs(XCVR_CONTROL), val & (~{32'b111} << 0) | `SET_XCVR_CONTROL_OUTCLK_SEL(rx_out_clk_sel)); diff --git a/testbenches/ip/jesd_loopback/waves/cfg1.wcfg b/testbenches/ip/jesd_loopback/waves/cfg1.wcfg index 571dd15b..56454f25 100644 --- a/testbenches/ip/jesd_loopback/waves/cfg1.wcfg +++ b/testbenches/ip/jesd_loopback/waves/cfg1.wcfg @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/testbenches/ip/jesd_loopback_64b/Makefile b/testbenches/ip/jesd_loopback_64b/Makefile index 197b3f07..9b805f0a 100644 --- a/testbenches/ip/jesd_loopback_64b/Makefile +++ b/testbenches/ip/jesd_loopback_64b/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/jesd_loopback_64b/system_bd.tcl b/testbenches/ip/jesd_loopback_64b/system_bd.tcl index 33387a9a..e032ad70 100644 --- a/testbenches/ip/jesd_loopback_64b/system_bd.tcl +++ b/testbenches/ip/jesd_loopback_64b/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/jesd_loopback_64b/system_tb.sv b/testbenches/ip/jesd_loopback_64b/system_tb.sv index 656b5063..8e1f73d4 100644 --- a/testbenches/ip/jesd_loopback_64b/system_tb.sv +++ b/testbenches/ip/jesd_loopback_64b/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/jesd_loopback_64b/tests/test_program.sv b/testbenches/ip/jesd_loopback_64b/tests/test_program.sv index 463a3bbe..5496b9d4 100644 --- a/testbenches/ip/jesd_loopback_64b/tests/test_program.sv +++ b/testbenches/ip/jesd_loopback_64b/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,22 +26,19 @@ // // 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/master/LICENSE_ADIBSD +// 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" +import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; -import logger_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_jesd_tx_pkg::*; import adi_regmap_jesd_rx_pkg::*; @@ -49,11 +46,18 @@ import adi_regmap_common_pkg::*; import adi_regmap_dac_pkg::*; import adi_regmap_adc_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + parameter OUT_BYTES = (`JESD_F % 3 != 0) ? 8 : 12; program test_program; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + bit [31:0] val; int link_clk_freq_khz; int device_clk_freq_khz; @@ -67,23 +71,28 @@ program test_program; int use_dds = 0; initial begin + //creating environment - env = new("JESD Loopback 64b", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); - #2ps; + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - `TH.`SYS_CLK.inst.IF.start_clock; - `TH.`DMA_CLK.inst.IF.start_clock; - `TH.`DDR_CLK.inst.IF.start_clock; + base_env.start(); + base_env.sys_reset(); + + `TH.`SYS_CLK.inst.IF.start_clock(); + `TH.`DMA_CLK.inst.IF.start_clock(); + `TH.`DDR_CLK.inst.IF.start_clock(); link_clk_freq_khz = lane_rate_khz/66; data_path_width = 8; @@ -95,85 +104,85 @@ program test_program; `TH.`DEVICE_CLK.inst.IF.set_clk_frq(.user_frequency(device_clk_freq_khz*1000)); `TH.`SYSREF_CLK.inst.IF.set_clk_frq(.user_frequency(sysref_freq_khz*1000)); - `TH.`REF_CLK.inst.IF.start_clock; - `TH.`DRP_CLK.inst.IF.start_clock; - `TH.`DEVICE_CLK.inst.IF.start_clock; - `TH.`SYSREF_CLK.inst.IF.start_clock; + `TH.`REF_CLK.inst.IF.start_clock(); + `TH.`DRP_CLK.inst.IF.start_clock(); + `TH.`DEVICE_CLK.inst.IF.start_clock(); + `TH.`SYSREF_CLK.inst.IF.start_clock(); for (int i = 0; i < `JESD_M; i++) begin if (use_dds) begin // Select DDS as source - env.mng.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(0)); // Configure tone amplitude and frequency - env.mng.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_1_DDS_SCALE_1(16'h0fff)); - env.mng.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_2_DDS_INCR_1(16'h0100)); end else begin // Set DMA as source for DAC TPL - env.mng.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+'h40*i+GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(2)); end end for (int i = 0; i < `JESD_M; i++) begin - env.mng.RegWrite32(`ADC_TPL_BA+'h40*i+GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA+'h40*i+GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), `SET_ADC_CHANNEL_REG_CHAN_CNTRL_ENABLE(1)); end - env.mng.RegWrite32(`DAC_TPL_BA+GetAddrs(DAC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+GetAddrs(DAC_COMMON_REG_RSTN), `SET_DAC_COMMON_REG_RSTN_RSTN(1)); - env.mng.RegWrite32(`ADC_TPL_BA+GetAddrs(ADC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA+GetAddrs(ADC_COMMON_REG_RSTN), `SET_ADC_COMMON_REG_RSTN_RSTN(1)); // Sync DDS cores - env.mng.RegWrite32(`DAC_TPL_BA+GetAddrs(DAC_COMMON_REG_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA+GetAddrs(DAC_COMMON_REG_CNTRL_1), `SET_DAC_COMMON_REG_CNTRL_1_SYNC(1)); //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(1)); //SYSREFCONF - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_SYSREF_CONF), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_SYSREF_CONF), `SET_JESD_RX_SYSREF_CONF_SYSREF_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_SYSREF_CONF), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_SYSREF_CONF), `SET_JESD_TX_SYSREF_CONF_SYSREF_DISABLE(0)); //CONF0 - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF0), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF0), `SET_JESD_RX_LINK_CONF0_OCTETS_PER_FRAME(`JESD_F-1) | `SET_JESD_RX_LINK_CONF0_OCTETS_PER_MULTIFRAME(`JESD_F*`JESD_K-1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF0), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF0), `SET_JESD_TX_LINK_CONF0_OCTETS_PER_FRAME(`JESD_F-1) | `SET_JESD_TX_LINK_CONF0_OCTETS_PER_MULTIFRAME(`JESD_F*`JESD_K-1)); - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF4), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF4), `SET_JESD_RX_LINK_CONF4_TPL_BEATS_PER_MULTIFRAME((`JESD_F*`JESD_K)/`LL_OUT_BYTES-1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF4), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF4), `SET_JESD_TX_LINK_CONF4_TPL_BEATS_PER_MULTIFRAME((`JESD_F*`JESD_K)/`LL_OUT_BYTES-1)); //CONF1 - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF1), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_CONF1), `SET_JESD_RX_LINK_CONF1_DESCRAMBLER_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF1), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF1), `SET_JESD_TX_LINK_CONF1_SCRAMBLER_DISABLE(0)); //CONF2 - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF2), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_CONF2), `SET_JESD_TX_LINK_CONF2_CONTINUOUS_CGS(0)); //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(0)); #25us; // Read status back - env.mng.RegReadVerify32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_STATUS), `SET_JESD_RX_LINK_STATUS_STATUS_STATE(3)); #1us; @@ -182,28 +191,37 @@ program test_program; // -------------------------------------- //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(1)); #1us; //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA+GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(0)); #25us; // Read status back - env.mng.RegReadVerify32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA+GetAddrs(JESD_RX_LINK_STATUS), `SET_JESD_RX_LINK_STATUS_STATUS_STATE(3)); - - `INFO(("Test Done"), ADI_VERBOSITY_NONE); - env.stop(); - $finish; + base_env.stop(); + + `TH.`SYS_CLK.inst.IF.stop_clock(); + `TH.`DMA_CLK.inst.IF.stop_clock(); + `TH.`DDR_CLK.inst.IF.stop_clock(); + + `TH.`REF_CLK.inst.IF.stop_clock(); + `TH.`DRP_CLK.inst.IF.stop_clock(); + `TH.`DEVICE_CLK.inst.IF.stop_clock(); + `TH.`SYSREF_CLK.inst.IF.stop_clock(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); end diff --git a/testbenches/ip/scoreboard/Makefile b/testbenches/ip/scoreboard/Makefile index b8505a2d..b39c6e04 100644 --- a/testbenches/ip/scoreboard/Makefile +++ b/testbenches/ip/scoreboard/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2022(c) Analog Devices, Inc. +## Copyright (C) 2022 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/scoreboard/environment.sv b/testbenches/ip/scoreboard/environment.sv index 731e2ae9..63e435c4 100644 --- a/testbenches/ip/scoreboard/environment.sv +++ b/testbenches/ip/scoreboard/environment.sv @@ -1,145 +1,84 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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 m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import m_axis_sequencer_pkg::*; - import s_axis_sequencer_pkg::*; import logger_pkg::*; + import adi_environment_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; - import test_harness_env_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 x_monitor_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_dst_axi_pt_0)::*; - import `PKGIFY(test_harness, dac_src_axi_pt_0)::*; - - // import `PKGIFY(test_harness, adc_src_axis_1)::*; - // import `PKGIFY(test_harness, dac_dst_axis_1)::*; - // import `PKGIFY(test_harness, adc_dst_axi_pt_1)::*; - // import `PKGIFY(test_harness, dac_src_axi_pt_1)::*; - - class environment extends test_harness_env; - - // agents and sequencers - `AGENT(test_harness, adc_src_axis_0, mst_t) adc_src_axis_agent_0; - `AGENT(test_harness, dac_dst_axis_0, slv_t) dac_dst_axis_agent_0; - `AGENT(test_harness, adc_dst_axi_pt_0, passthrough_mem_t) adc_dst_axi_pt_agent_0; - `AGENT(test_harness, dac_src_axi_pt_0, passthrough_mem_t) dac_src_axi_pt_agent_0; - - // `AGENT(test_harness, adc_src_axis_1, mst_t) adc_src_axis_agent_1; - // `AGENT(test_harness, dac_dst_axis_1, slv_t) dac_dst_axis_agent_1; - // `AGENT(test_harness, adc_dst_axi_pt_1, passthrough_mem_t) adc_dst_axi_pt_agent_1; - // `AGENT(test_harness, dac_src_axi_pt_1, passthrough_mem_t) dac_src_axi_pt_agent_1; - - m_axis_sequencer #(`AGENT(test_harness, adc_src_axis_0, mst_t), - `AXIS_VIP_PARAMS(test_harness, adc_src_axis_0) - ) adc_src_axis_seq_0; - s_axis_sequencer #(`AGENT(test_harness, dac_dst_axis_0, slv_t)) dac_dst_axis_seq_0; - s_axi_sequencer #(`AGENT(test_harness, adc_dst_axi_pt_0, passthrough_mem_t)) adc_dst_axi_pt_seq_0; - s_axi_sequencer #(`AGENT(test_harness, dac_src_axi_pt_0, passthrough_mem_t)) dac_src_axi_pt_seq_0; - // m_axis_sequencer #(`AGENT(test_harness, adc_src_axis_1, mst_t), - // `AXIS_VIP_PARAMS(test_harness, adc_src_axis_1) - // ) adc_src_axis_seq_1; - // s_axis_sequencer #(`AGENT(test_harness, dac_dst_axis_1, slv_t)) dac_dst_axis_seq_1; - // s_axi_sequencer #(`AGENT(test_harness, adc_dst_axi_pt_1, passthrough_mem_t)) adc_dst_axi_pt_seq_1; - // s_axi_sequencer #(`AGENT(test_harness, dac_src_axi_pt_1, passthrough_mem_t)) dac_src_axi_pt_seq_1; - x_axis_monitor #(`AGENT(test_harness, adc_src_axis_0, mst_t)) adc_src_axis_0_mon; - x_axis_monitor #(`AGENT(test_harness, dac_dst_axis_0, slv_t)) dac_dst_axis_0_mon; - x_axi_monitor #(`AGENT(test_harness, adc_dst_axi_pt_0, passthrough_mem_t), WRITE_OP) adc_dst_axi_pt_0_mon; - x_axi_monitor #(`AGENT(test_harness, dac_src_axi_pt_0, passthrough_mem_t), READ_OP) dac_src_axi_pt_0_mon; + class scoreboard_environment extends adi_environment; - // x_axis_monitor #(`AGENT(test_harness, adc_src_axis_1, mst_t)) adc_src_axis_1_mon; - // x_axis_monitor #(`AGENT(test_harness, dac_dst_axis_1, slv_t)) dac_dst_axis_1_mon; - // x_axi_monitor #(`AGENT(test_harness, adc_dst_axi_pt_1, passthrough_mem_t), WRITE_OP) adc_dst_axi_pt_1_mon; - // x_axi_monitor #(`AGENT(test_harness, dac_src_axi_pt_1, passthrough_mem_t), READ_OP) dac_src_axi_pt_1_mon; + // 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 scoreboard_tx0; - scoreboard scoreboard_rx0; - // scoreboard scoreboard_tx1; - // scoreboard scoreboard_rx1; + scoreboard #(logic [7:0]) scoreboard_tx; + scoreboard #(logic [7:0]) scoreboard_rx; //============================================================================ // Constructor //============================================================================ - function new ( - input string name, - - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, adc_src_axis_0)) adc_src_axis_vip_if_0, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, dac_dst_axis_0)) dac_dst_axis_vip_if_0, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, adc_dst_axi_pt_0)) adc_dst_axi_pt_vip_if_0, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, dac_src_axi_pt_0)) dac_src_axi_pt_vip_if_0 - - // virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, adc_src_axis_1)) adc_src_axis_vip_if_1, - // virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, dac_dst_axis_1)) dac_dst_axis_vip_if_1, - // virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, adc_dst_axi_pt_1)) adc_dst_axi_pt_vip_if_1, - // virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, dac_src_axi_pt_1)) dac_src_axi_pt_vip_if_1 - - ); + function new (input string name); // creating the agents - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); - - adc_src_axis_agent_0 = new("ADC Source AXI Stream Agent 0", adc_src_axis_vip_if_0); - dac_dst_axis_agent_0 = new("DAC Destination AXI Stream Agent 0", dac_dst_axis_vip_if_0); - adc_dst_axi_pt_agent_0 = new("ADC Destination AXI Agent 0", adc_dst_axi_pt_vip_if_0); - dac_src_axi_pt_agent_0 = new("DAC Source AXI Agent 0", dac_src_axi_pt_vip_if_0); - - // adc_src_axis_agent_1 = new("ADC Source AXI Stream Agent 1", adc_src_axis_vip_if_1); - // dac_dst_axis_agent_1 = new("DAC Destination AXI Stream Agent 1", dac_dst_axis_vip_if_1); - // adc_dst_axi_pt_agent_1 = new("ADC Destination AXI Agent 1", adc_dst_axi_pt_vip_if_1); - // dac_src_axi_pt_agent_1 = new("DAC Source AXI Agent 1", dac_src_axi_pt_vip_if_1); + super.new(name); - adc_src_axis_seq_0 = new("ADC Source AXI Stream Sequencer 0", adc_src_axis_agent_0, this); - dac_dst_axis_seq_0 = new("DAC Destination AXI Stream Sequencer 0", dac_dst_axis_agent_0, this); - adc_dst_axi_pt_seq_0 = new("ADC Destination AXI Sequencer 0", adc_dst_axi_pt_agent_0, this); - dac_src_axi_pt_seq_0 = new("DAC Source AXI Sequencer 0", dac_src_axi_pt_agent_0, this); - - // adc_src_axis_seq_1 = new("ADC Source AXI Stream Sequencer 1", adc_src_axis_agent_1, this); - // dac_dst_axis_seq_1 = new("DAC Destination AXI Stream Sequencer 1", dac_dst_axis_agent_1, this); - // adc_dst_axi_pt_seq_1 = new("ADC Destination AXI Sequencer 1", adc_dst_axi_pt_agent_1, this); - // dac_src_axi_pt_seq_1 = new("DAC Source AXI Sequencer 1", dac_src_axi_pt_agent_1, this); - - adc_src_axis_0_mon = new("ADC Source AXIS 0 Transaction Monitor", adc_src_axis_agent_0, this); - dac_dst_axis_0_mon = new("DAC Destination AXIS 0 Transaction Monitor", dac_dst_axis_agent_0, this); - adc_dst_axi_pt_0_mon = new("ADC Destination AXI 0 Transaction Monitor", adc_dst_axi_pt_agent_0, this); - dac_src_axi_pt_0_mon = new("DAC Source AXI 0 Transaction Monitor", dac_src_axi_pt_agent_0, this); - - // adc_src_axis_1_mon = new("ADC Source AXIS 1 Transaction Monitor", adc_src_axis_agent_1, this); - // dac_dst_axis_1_mon = new("DAC Destination AXIS 1 Transaction Monitor", dac_dst_axis_agent_1, this); - // adc_dst_axi_pt_1_mon = new("ADC Destination AXI 1 Transaction Monitor", adc_dst_axi_pt_agent_1, this); - // dac_src_axi_pt_1_mon = new("DAC Source AXI 1 Transaction Monitor", dac_src_axi_pt_agent_1, this); - - scoreboard_tx0 = new("Data Offload TX 0 Scoreboard", this); - scoreboard_rx0 = new("Data Offload RX 0 Scoreboard", this); - // scoreboard_tx1 = new("Data Offload TX 1 Scoreboard", this); - // scoreboard_rx1 = new("Data Offload RX 1 Scoreboard", this); + this.adc_src_axis_agent = new("ADC Source AXI Stream Agent", adi_axis_agent_pkg::MASTER, this); + this.dac_dst_axis_agent = new("DAC Destination AXI Stream Agent", adi_axis_agent_pkg::SLAVE, this); + this.adc_dst_axi_pt_agent = new("ADC Destination AXI Agent", adi_axi_agent_pkg::PASSTHROUGH, this); + this.dac_src_axi_pt_agent = new("DAC Source AXI Agent", adi_axi_agent_pkg::PASSTHROUGH, this); + this.scoreboard_tx = new("Data Offload TX Scoreboard", this); + this.scoreboard_rx = new("Data Offload RX Scoreboard", this); endfunction //============================================================================ @@ -147,21 +86,12 @@ package environment_pkg; // - Configure the sequencer VIPs with an initial configuration before starting them //============================================================================ task configure(int bytes_to_generate); - // ADC stub - adc_src_axis_seq_0.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - adc_src_axis_seq_0.add_xfer_descriptor(bytes_to_generate, 0, 0); + 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 - dac_dst_axis_seq_0.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); - - // // ADC stub - // adc_src_axis_seq_1.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - // adc_src_axis_seq_1.add_xfer_descriptor(bytes_to_generate, 0, 0); - - // // DAC stub - // dac_dst_axis_seq_1.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); - + this.dac_dst_axis_agent.slave_sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); endtask //============================================================================ @@ -170,103 +100,37 @@ package environment_pkg; // - Start the agents //============================================================================ task start(); + this.adc_src_axis_agent.start_master(); + this.dac_dst_axis_agent.start_slave(); + this.adc_dst_axi_pt_agent.start_monitor(); + this.dac_src_axi_pt_agent.start_monitor(); - super.start(); - - adc_src_axis_agent_0.start_master(); - dac_dst_axis_agent_0.start_slave(); - adc_dst_axi_pt_agent_0.start_monitor(); - dac_src_axi_pt_agent_0.start_monitor(); - - // adc_src_axis_agent_1.start_master(); - // dac_dst_axis_agent_1.start_slave(); - // adc_dst_axi_pt_agent_1.start_monitor(); - // dac_src_axi_pt_agent_1.start_monitor(); - - scoreboard_tx0.set_source_stream(dac_src_axi_pt_0_mon); - scoreboard_tx0.set_sink_stream(dac_dst_axis_0_mon); - - scoreboard_rx0.set_source_stream(adc_src_axis_0_mon); - scoreboard_rx0.set_sink_stream(adc_dst_axi_pt_0_mon); - - // scoreboard_tx1.set_source_stream(dac_src_axi_pt_1_mon); - // scoreboard_tx1.set_sink_stream(dac_dst_axis_1_mon); - - // scoreboard_rx1.set_source_stream(adc_src_axis_1_mon); - // scoreboard_rx1.set_sink_stream(adc_dst_axi_pt_1_mon); + this.dac_src_axi_pt_agent.monitor.publisher_rx.subscribe(this.scoreboard_tx.subscriber_source); + 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); + this.adc_dst_axi_pt_agent.monitor.publisher_tx.subscribe(this.scoreboard_rx.subscriber_sink); endtask //============================================================================ - // Start the test - // - start the RX scoreboard and sequencer - // - start the TX scoreboard and sequencer - // - setup the RX DMA - // - setup the TX DMA + // Run subroutine //============================================================================ - task test(); - + task run(); fork - adc_src_axis_seq_0.run(); - dac_dst_axis_seq_0.run(); + this.adc_src_axis_agent.master_sequencer.start(); + this.dac_dst_axis_agent.slave_sequencer.start(); - // adc_src_axis_seq_1.run(); - // dac_dst_axis_seq_1.run(); - - adc_src_axis_0_mon.run(); - dac_dst_axis_0_mon.run(); - adc_dst_axi_pt_0_mon.run(); - dac_src_axi_pt_0_mon.run(); - - // adc_src_axis_1_mon.run(); - // dac_dst_axis_1_mon.run(); - // adc_dst_axi_pt_1_mon.run(); - // dac_src_axi_pt_1_mon.run(); - - scoreboard_tx0.run(); - scoreboard_rx0.run(); - - // scoreboard_tx1.run(); - // scoreboard_rx1.run(); + this.scoreboard_tx.run(); + this.scoreboard_rx.run(); join_none - - endtask - - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - // Evaluate the scoreboard's results - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run; - - //pre_test(); - test(); - endtask //============================================================================ // Stop subroutine //============================================================================ - task stop; - - super.stop(); - - adc_src_axis_seq_0.stop(); - adc_src_axis_agent_0.stop_master(); - dac_dst_axis_agent_0.stop_slave(); - - // adc_src_axis_seq_1.stop(); - // adc_src_axis_agent_1.stop_master(); - // dac_dst_axis_agent_1.stop_slave(); - - post_test(); - + task stop(); + this.adc_src_axis_agent.stop_master(); + this.dac_dst_axis_agent.stop_slave(); endtask endclass diff --git a/testbenches/ip/scoreboard/system_bd.tcl b/testbenches/ip/scoreboard/system_bd.tcl index 3385de14..a0d7856a 100644 --- a/testbenches/ip/scoreboard/system_bd.tcl +++ b/testbenches/ip/scoreboard/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2022 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # @@ -65,7 +65,7 @@ ad_ip_instance xlconstant GND [list \ ] ad_connect gnd GND/dout -for {set i 0} {$i < 1} {incr i} { +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 \ diff --git a/testbenches/ip/scoreboard/system_tb.sv b/testbenches/ip/scoreboard/system_tb.sv index 36eff4db..2723b531 100644 --- a/testbenches/ip/scoreboard/system_tb.sv +++ b/testbenches/ip/scoreboard/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/scoreboard/tests/test_program.sv b/testbenches/ip/scoreboard/tests/test_program.sv index d3069c37..dd65c811 100644 --- a/testbenches/ip/scoreboard/tests/test_program.sv +++ b/testbenches/ip/scoreboard/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -26,30 +26,61 @@ // // 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/master/LICENSE_ADIBSD +// 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" -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; 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 `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_dst_axi_pt_0)::*; +import `PKGIFY(test_harness, dac_src_axi_pt_0)::*; + +import `PKGIFY(test_harness, adc_src_axis_1)::*; +import `PKGIFY(test_harness, dac_dst_axis_1)::*; +import `PKGIFY(test_harness, adc_dst_axi_pt_1)::*; +import `PKGIFY(test_harness, dac_src_axi_pt_1)::*; + `define ADC_TRANSFER_LENGTH 32'h600 -program test_program; +program test_program(); // declare the class instances - environment env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + scoreboard_environment scb_env_0; + + 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; + adi_axi_passthrough_mem_agent #(`AXI_VIP_PARAMS(test_harness, adc_dst_axi_pt_0)) adc_dst_axi_pt_agent_0; + adi_axi_passthrough_mem_agent #(`AXI_VIP_PARAMS(test_harness, dac_src_axi_pt_0)) dac_src_axi_pt_agent_0; + + scoreboard_environment scb_env_1; + + 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; + adi_axi_passthrough_mem_agent #(`AXI_VIP_PARAMS(test_harness, adc_dst_axi_pt_1)) adc_dst_axi_pt_agent_1; + adi_axi_passthrough_mem_agent #(`AXI_VIP_PARAMS(test_harness, dac_src_axi_pt_1)) dac_src_axi_pt_agent_1; dmac_api dmac_tx_0; dmac_api dmac_rx_0; @@ -64,34 +95,51 @@ program test_program; initial begin // create environment - env = new("Scoreboard Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - - `TH.`ADC_SRC_AXIS_0.inst.IF, - `TH.`DAC_DST_AXIS_0.inst.IF, - `TH.`ADC_DST_AXI_PT_0.inst.IF, - `TH.`DAC_SRC_AXI_PT_0.inst.IF - - // `TH.`ADC_SRC_AXIS_1.inst.IF, - // `TH.`DAC_DST_AXIS_1.inst.IF, - // `TH.`ADC_DST_AXI_PT_1.inst.IF, - // `TH.`DAC_SRC_AXI_PT_1.inst.IF - ); - - dmac_tx_0 = new("DMAC TX 0", env.mng, `TX_DMA_BA_0); - dmac_rx_0 = new("DMAC RX 0", env.mng, `RX_DMA_BA_0); - // dmac_tx_1 = new("DMAC TX 1", env.mng, `TX_DMA_BA_1); - // dmac_rx_1 = new("DMAC RX 1", env.mng, `RX_DMA_BA_1); - - do_tx_0 = new("Data Offload TX 0", env.mng, `TX_DOFF_BA_0); - do_rx_0 = new("Data Offload RX 0", env.mng, `RX_DOFF_BA_0); - // do_tx_1 = new("Data Offload TX 1", env.mng, `TX_DOFF_BA_1); - // do_rx_1 = new("Data Offload RX 1", env.mng, `RX_DOFF_BA_1); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + scb_env_0 = new("Scoreboard Environment 0"); + + 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); + adc_dst_axi_pt_agent_0 = new("", `TH.`ADC_DST_AXI_PT_0.inst.IF); + dac_src_axi_pt_agent_0 = new("", `TH.`DAC_SRC_AXI_PT_0.inst.IF); + + `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(adc_dst_axi_pt_agent_0, scb_env_0, adc_dst_axi_pt_agent) + `LINK(dac_src_axi_pt_agent_0, 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); + adc_dst_axi_pt_agent_1 = new("", `TH.`ADC_DST_AXI_PT_1.inst.IF); + dac_src_axi_pt_agent_1 = new("", `TH.`DAC_SRC_AXI_PT_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(adc_dst_axi_pt_agent_1, scb_env_1, adc_dst_axi_pt_agent) + `LINK(dac_src_axi_pt_agent_1, 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 @@ -101,11 +149,15 @@ program test_program; setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + scb_env_0.start(); + scb_env_1.start(); + + base_env.sys_reset(); // configure environment sequencers - env.configure(`ADC_TRANSFER_LENGTH); + scb_env_0.configure(`ADC_TRANSFER_LENGTH); + scb_env_1.configure(`ADC_TRANSFER_LENGTH); `INFO(("Bring up IP from reset."), ADI_VERBOSITY_LOW); systemBringUp(); @@ -114,30 +166,36 @@ program test_program; do_set_transfer_length(`ADC_TRANSFER_LENGTH/64); // Start the ADC/DAC stubs - `INFO(("Call the run() ..."), ADI_VERBOSITY_LOW); - env.run(); - - env.adc_src_axis_seq_0.start(); - // env.adc_src_axis_seq_1.start(); + `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(); // Generate DMA transfers - `INFO(("Start RX DMA ..."), ADI_VERBOSITY_LOW); + `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); + rx_dma_transfer(dmac_rx_1, 32'h80000000, `ADC_TRANSFER_LENGTH); - env.scoreboard_rx0.wait_until_complete(); + 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); + `INFO(("Initialize the memory"), ADI_VERBOSITY_LOW); init_mem_64(32'h80000000, 1024); - `INFO(("Start TX DMA ..."), ADI_VERBOSITY_LOW); + `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); + tx_dma_transfer(dmac_tx_1, 32'h80000000, 1024); #1us; - env.scoreboard_tx0.wait_until_complete(); - - env.stop(); + 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(); + base_env.stop(); `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); $finish(); @@ -145,46 +203,39 @@ 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(); + `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(); + 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(); - + `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); + do_rx_1.set_transfer_length(length); endtask // RX DMA transfer generator - task rx_dma_transfer( input dmac_api dmac, input int xfer_addr, @@ -195,6 +246,7 @@ program test_program; dmac.transfer_start(); endtask + // TX DMA transfer generator task tx_dma_transfer( input dmac_api dmac, input int xfer_addr, @@ -211,7 +263,8 @@ program test_program; input int byte_length); `INFO(("Initial address: %x", addr), ADI_VERBOSITY_LOW); for (int i=0; i - + @@ -22,7 +22,7 @@ - + diff --git a/testbenches/ip/spi_engine/Makefile b/testbenches/ip/spi_engine/Makefile index 629aab2d..c256e5a8 100644 --- a/testbenches/ip/spi_engine/Makefile +++ b/testbenches/ip/spi_engine/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2024(c) Analog Devices, Inc. +## Copyright (C) 2024 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -22,12 +22,10 @@ ENV_DEPS += $(HDL_LIBRARY_PATH)/common/ad_edge_detect.v LIB_DEPS += axi_clkgen LIB_DEPS += axi_pwm_gen LIB_DEPS += axi_dmac -LIB_DEPS += axi_sysid LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_engine_execution LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload -LIB_DEPS += sysid_rom # default test programs # Format is: diff --git a/testbenches/ip/spi_engine/spi_environment.sv b/testbenches/ip/spi_engine/spi_environment.sv index 5353c88a..eca60f3e 100644 --- a/testbenches/ip/spi_engine/spi_environment.sv +++ b/testbenches/ip/spi_engine/spi_environment.sv @@ -34,39 +34,28 @@ // *************************************************************************** `include "utils.svh" +`include "axis_definitions.svh" package spi_environment_pkg; - import axi_vip_pkg::*; - import axi4stream_vip_pkg::*; - import m_axi_sequencer_pkg::*; + import logger_pkg::*; + import adi_environment_pkg::*; + import m_axis_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import s_spi_sequencer_pkg::*; + import adi_axis_agent_pkg::*; import adi_spi_vip_pkg::*; - import test_harness_env_pkg::*; - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; - import `PKGIFY(test_harness, spi_s_vip)::*; + import adi_spi_vip_if_base_pkg::*; + `ifdef DEF_SDO_STREAMING import `PKGIFY(test_harness, sdo_src)::*; `endif - class spi_environment extends test_harness_env; + class spi_environment extends adi_environment; // Agents - adi_spi_agent #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_agent; - `ifdef DEF_SDO_STREAMING - `AGENT(test_harness, sdo_src, mst_t) sdo_src_agent; - `endif - - - // Sequencers - s_spi_sequencer #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_seq; + adi_spi_agent spi_agent; `ifdef DEF_SDO_STREAMING - m_axis_sequencer #(`AGENT(test_harness, sdo_src, mst_t), - `AXIS_VIP_PARAMS(test_harness, sdo_src) - ) sdo_src_seq; + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(test_harness_sdo_src_0)) sdo_src_agent; `endif //============================================================================ @@ -75,45 +64,24 @@ package spi_environment_pkg; function new( input string name, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - `ifdef DEF_SDO_STREAMING - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, sdo_src)) sdo_src_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness_sdo_src_0)) sdo_src_axis_vip_if, `endif - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - virtual interface spi_vip_if #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_s_vip_if - ); - - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); + adi_spi_vip_if_base spi_s_vip_if); - // Creating the agents - spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); - `ifdef DEF_SDO_STREAMING - sdo_src_agent = new("SDO Source AXI Stream Agent", sdo_src_axis_vip_if); - `endif + super.new(name); - // Creating the sequencers - spi_seq = new("SPI VIP Agent", spi_agent, this); + // Creating the agents + this.spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); `ifdef DEF_SDO_STREAMING - sdo_src_seq = new("SPI VIP Agent", sdo_src_agent, this); + this.sdo_src_agent = new("SDO Source AXI Stream Agent", sdo_src_axis_vip_if); `endif // downgrade reset check: we are currently using a clock generator for the SPI clock, // so it will come a bit after the reset and trigger the default error. // This is harmless for this test (we don't want to test any reset scheme) `ifdef DEF_SDO_STREAMING - sdo_src_axis_vip_if.set_xilinx_reset_check_to_warn(); + sdo_src_axis_vip_if.set_xilinx_reset_check_to_warn(); `endif endfunction @@ -123,8 +91,8 @@ package spi_environment_pkg; //============================================================================ task configure(); `ifdef DEF_SDO_STREAMING - sdo_src_seq.set_stop_policy(STOP_POLICY_PACKET); - sdo_src_seq.set_data_gen_mode(DATA_GEN_MODE_TEST_DATA); + this.sdo_src_agent.sequencer.set_stop_policy(STOP_POLICY_PACKET); + this.sdo_src_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_TEST_DATA); `endif endtask @@ -134,50 +102,30 @@ package spi_environment_pkg; // - Start the agents //============================================================================ task start(); - super.start(); - spi_agent.start(); + this.spi_agent.start(); `ifdef DEF_SDO_STREAMING - sdo_src_agent.start_master(); + this.sdo_src_agent.start(); `endif endtask //============================================================================ - // Start the test - // - start the scoreboard - // - start the sequencers + // Run subroutine //============================================================================ - task test(); - super.test(); + task run(); fork `ifdef DEF_SDO_STREAMING - sdo_src_seq.run(); + this.sdo_src_agent.run(); `endif join_none endtask - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - super.post_test(); - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run; - test(); - endtask - //============================================================================ // Stop subroutine //============================================================================ - task stop; - spi_agent.stop(); - super.stop(); + task stop(); + this.spi_agent.stop(); `ifdef DEF_SDO_STREAMING - sdo_src_seq.stop(); - sdo_src_agent.stop_master(); + this.sdo_src_agent.stop(); `endif endtask diff --git a/testbenches/ip/spi_engine/system_tb.sv b/testbenches/ip/spi_engine/system_tb.sv index 71a5a321..d002884d 100644 --- a/testbenches/ip/spi_engine/system_tb.sv +++ b/testbenches/ip/spi_engine/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2021 - 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2021 - 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/spi_engine/tests/test_program.sv b/testbenches/ip/spi_engine/tests/test_program.sv index bb203868..f94ce750 100644 --- a/testbenches/ip/spi_engine/tests/test_program.sv +++ b/testbenches/ip/spi_engine/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2023-2025 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 - 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 @@ -36,18 +36,25 @@ // `include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" -import axi_vip_pkg::*; +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import spi_environment_pkg::*; import axi4stream_vip_pkg::*; import adi_regmap_pkg::*; import adi_regmap_clkgen_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; -import logger_pkg::*; -import spi_environment_pkg::*; import spi_engine_instr_pkg::*; import adi_spi_vip_pkg::*; +import axi_vip_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -59,374 +66,387 @@ program test_program ( inout [(`NUM_OF_CS - 1):0] spi_engine_spi_cs, inout spi_engine_spi_clk, `ifdef DEF_ECHO_SCLK - inout spi_engine_echo_sclk, + inout spi_engine_echo_sclk, `endif inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); -timeunit 1ns; -timeprecision 100ps; - -spi_environment env; - -// -------------------------- -// Wrapper function for AXI read verify -// -------------------------- -task axi_read_v( - input [31:0] raddr, - input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); -endtask - -task axi_read( - input [31:0] raddr, - output [31:0] data); - env.mng.RegRead32(raddr,data); -endtask - -// -------------------------- -// Wrapper function for AXI write -// -------------------------- -task axi_write( - input [31:0] waddr, - input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); -endtask - -// -------------------------- -// Wrapper function for SPI receive (from DUT) -// -------------------------- -task spi_receive( - output [`DATA_DLENGTH:0] data); - env.spi_seq.receive_data(data); -endtask - -// -------------------------- -// Wrapper function for SPI send (to DUT) -// -------------------------- -task spi_send( - input [`DATA_DLENGTH:0] data); - env.spi_seq.send_data(data); -endtask - -// -------------------------- -// Wrapper function for waiting for all SPI -// -------------------------- -task spi_wait_send(); - env.spi_seq.flush_send(); -endtask - - - -// -------------------------- -// Main procedure -// -------------------------- -initial begin - - //creating environment - env = new("SPI Engine Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `ifdef DEF_SDO_STREAMING - `TH.`SDO_SRC.inst.IF, - `endif - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SPI_S.inst.IF - ); - - setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.configure(); - - env.sys_reset(); - - env.run(); - - env.spi_seq.set_default_miso_data('h2AA55); - - // start sdo source (will wait for data enqueued) - `ifdef DEF_SDO_STREAMING - env.sdo_src_seq.start(); - `endif + timeunit 1ns; + timeprecision 100ps; + + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; - sanity_test(); + spi_environment spi_env; - #100ns + // -------------------------- + // Wrapper function for AXI read verify + // -------------------------- + task axi_read_v( + input [31:0] raddr, + input [31:0] vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); + endtask - fifo_spi_test(); + task axi_read( + input [31:0] raddr, + output [31:0] data); + base_env.mng.master_sequencer.RegRead32(raddr,data); + endtask - #100ns + // -------------------------- + // Wrapper function for AXI write + // -------------------------- + task axi_write( + input [31:0] waddr, + input [31:0] wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); + endtask - offload_spi_test(); + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task spi_receive( + output [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.receive_data(data); + endtask - env.stop(); + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.send_data(data); + endtask - `INFO(("Test Done"), ADI_VERBOSITY_NONE); + // -------------------------- + // Wrapper function for waiting for all SPI + // -------------------------- + task spi_wait_send(); + spi_env.spi_agent.sequencer.flush_send(); + endtask - $finish; -end + // -------------------------- + // Main procedure + // -------------------------- + initial begin -//--------------------------------------------------------------------------- -// Sanity test reg interface -//--------------------------------------------------------------------------- + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); -task sanity_test(); - bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; - axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); -endtask + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); -//--------------------------------------------------------------------------- -// SPI Engine generate transfer -//--------------------------------------------------------------------------- + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); -task generate_transfer_cmd( - input [7:0] sync_id); - // assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_WRD); - // de-assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); - // SYNC command to generate interrupt - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); - `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); -endtask + setLoggerVerbosity(ADI_VERBOSITY_NONE); -//--------------------------------------------------------------------------- -// SPI Engine SDO data -//--------------------------------------------------------------------------- + base_env.start(); + spi_env.start(); -task sdo_stream_gen( - input [`DATA_DLENGTH:0] tx_data); - xil_axi4stream_data_byte data[(`DATA_WIDTH/8)-1:0]; - `ifdef DEF_SDO_STREAMING - for (int i = 0; i<(`DATA_WIDTH/8);i++) begin - data[i] = (tx_data & (8'hFF << 8*i)) >> 8*i; - env.sdo_src_seq.push_byte_for_stream(data[i]); - end - env.sdo_src_seq.add_xfer_descriptor((`DATA_WIDTH/8),0,0); - `endif -endtask + base_env.sys_reset(); -//--------------------------------------------------------------------------- -// IRQ callback -//--------------------------------------------------------------------------- + spi_env.configure(); -reg [4:0] irq_pending = 0; -reg [7:0] sync_id = 0; + spi_env.run(); -initial begin - forever begin - @(posedge spi_engine_irq); - // read pending IRQs + spi_env.spi_agent.sequencer.set_default_miso_data('h2AA55); - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - // IRQ launched by Offload SYNC command - if (irq_pending & 5'b10000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); - `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SYNC command - if (irq_pending & 5'b01000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); - `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDI FIFO - if (irq_pending & 5'b00100) begin - `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00010) begin - `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00001) begin - `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // Clear all pending IRQs - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - end -end + // start sdo source (will wait for data enqueued) + `ifdef DEF_SDO_STREAMING + spi_env.sdo_src_agent.sequencer.start(); + `endif -//--------------------------------------------------------------------------- -// Echo SCLK generation - we need this only if ECHO_SCLK is enabled -//--------------------------------------------------------------------------- -`ifdef DEF_ECHO_SCLK - assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; -`endif + sanity_test(); + #100ns -//--------------------------------------------------------------------------- -// Offload SPI Test -//--------------------------------------------------------------------------- + fifo_spi_test(); + + #100ns + + offload_spi_test(); + + spi_env.stop(); + base_env.stop(); + + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); -bit [`DATA_DLENGTH-1:0] sdi_read_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdo_write_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_read_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; -bit [`DATA_DLENGTH-1:0] sdo_write_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; -bit [`DATA_DLENGTH-1:0] rx_data; -bit [`DATA_DLENGTH-1:0] tx_data; - -task offload_spi_test(); - //Configure DMA - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), - `SET_DMAC_FLAGS_TLAST(1) | - `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) - ); // Use TLAST - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); - - // Configure the Offload module - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); end - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_WRD); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); - - // Enqueue transfers transfers to DUT - for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin - rx_data = $urandom; - spi_send(rx_data); - sdi_read_data_store[i] = rx_data; - tx_data = $urandom; - `ifdef DEF_SDO_STREAMING - sdo_stream_gen(tx_data); - sdo_write_data_store[i] = tx_data; - `else - if (i<(`NUM_OF_WORDS)) begin - sdo_write_data_store[i] = tx_data; - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), sdo_write_data_store[i]); - end else begin - sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; + + //--------------------------------------------------------------------------- + // Sanity test reg interface + //--------------------------------------------------------------------------- + + task sanity_test(); + bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; + axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // SPI Engine generate transfer + //--------------------------------------------------------------------------- + + task generate_transfer_cmd( + input [7:0] sync_id); + // assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_WRD); + // de-assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); + // SYNC command to generate interrupt + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // SPI Engine SDO data + //--------------------------------------------------------------------------- + + task sdo_stream_gen( + input [`DATA_DLENGTH:0] tx_data); + xil_axi4stream_data_byte data[(`DATA_WIDTH/8)-1:0]; + `ifdef DEF_SDO_STREAMING + for (int i = 0; i<(`DATA_WIDTH/8);i++) begin + data[i] = (tx_data & (8'hFF << 8*i)) >> 8*i; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i]); end - `endif + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8),0,0); + `endif + endtask + + //--------------------------------------------------------------------------- + // IRQ callback + //--------------------------------------------------------------------------- + + reg [4:0] irq_pending = 0; + reg [7:0] sync_id = 0; + + initial begin + forever begin + @(posedge spi_engine_irq); + // read pending IRQs + + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + // IRQ launched by Offload SYNC command + if (irq_pending & 5'b10000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); + `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); + end + // IRQ launched by SYNC command + if (irq_pending & 5'b01000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDI FIFO + if (irq_pending & 5'b00100) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00010) begin + `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00001) begin + `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // Clear all pending IRQs + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + end end - // Start the offload - #100ns - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); - `INFO(("Offload started."), ADI_VERBOSITY_LOW); + //--------------------------------------------------------------------------- + // Echo SCLK generation - we need this only if ECHO_SCLK is enabled + //--------------------------------------------------------------------------- + `ifdef DEF_ECHO_SCLK + assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; + `endif - spi_wait_send(); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); + //--------------------------------------------------------------------------- + // Offload SPI Test + //--------------------------------------------------------------------------- + + bit [`DATA_DLENGTH-1:0] sdi_read_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdo_write_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; + bit [`DATA_DLENGTH-1:0] rx_data; + bit [`DATA_DLENGTH-1:0] tx_data; + + task offload_spi_test(); + //Configure DMA + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), + `SET_DMAC_FLAGS_TLAST(1) | + `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) + ); // Use TLAST + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); + + // Configure the Offload module + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_WRD); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); + + // Enqueue transfers transfers to DUT + for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin + rx_data = $urandom; + spi_send(rx_data); + sdi_read_data_store[i] = rx_data; + tx_data = $urandom; + `ifdef DEF_SDO_STREAMING + sdo_stream_gen(tx_data); + sdo_write_data_store[i] = tx_data; + `else + if (i<(`NUM_OF_WORDS)) begin + sdo_write_data_store[i] = tx_data; + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), sdo_write_data_store[i]); + end else begin + sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; + end + `endif + end - `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); + // Start the offload + #100ns + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); + `INFO(("Offload started."), ADI_VERBOSITY_LOW); - #2000ns + spi_wait_send(); - if (irq_pending == 'h0) begin - `FATAL(("IRQ Test FAILED")); - end else begin - `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); - end + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - sdi_read_data[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); - if (sdi_read_data[i] != sdi_read_data_store[i]) begin - `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", i, sdi_read_data[i], i, sdi_read_data_store[i]), ADI_VERBOSITY_LOW); - `ERROR(("Offload Read Test FAILED")); - end - end - `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - spi_receive(sdo_write_data[i]); - if (sdo_write_data[i] != sdo_write_data_store[i]) begin - `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", i, sdo_write_data[i], i, sdo_write_data_store[i]), ADI_VERBOSITY_LOW); - `ERROR(("Offload Write Test FAILED")); + #2000ns + + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); end - end - `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); -endtask -//--------------------------------------------------------------------------- -// FIFO SPI Test -//--------------------------------------------------------------------------- + for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + sdi_read_data[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); + if (sdi_read_data[i] != sdi_read_data_store[i]) begin + `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", i, sdi_read_data[i], i, sdi_read_data_store[i]), ADI_VERBOSITY_LOW); + `ERROR(("Offload Read Test FAILED")); + end + end + `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); -bit [`DATA_DLENGTH-1:0] sdi_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdo_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store [`NUM_OF_WORDS-1:0]; -bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store [`NUM_OF_WORDS-1:0]; - -task fifo_spi_test(); - // Start spi clk generator - axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); - - // Config pwm - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d121)); // set PWM period - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration - `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - - // Enable SPI Engine - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); - - // Configure the execution module - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); - end + for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + spi_receive(sdo_write_data[i]); + if (sdo_write_data[i] != sdo_write_data_store[i]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", i, sdo_write_data[i], i, sdo_write_data_store[i]), ADI_VERBOSITY_LOW); + `ERROR(("Offload Write Test FAILED")); + end + end + `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // FIFO SPI Test + //--------------------------------------------------------------------------- + + bit [`DATA_DLENGTH-1:0] sdi_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store [`NUM_OF_WORDS-1:0]; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store [`NUM_OF_WORDS-1:0]; + + task fifo_spi_test(); + // Start spi clk generator + axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), + `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | + `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) + ); + + // Config pwm + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d121)); // set PWM period + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + // Enable SPI Engine + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + + // Configure the execution module + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end - // Set up the interrupts - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), - `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | - `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) - ); - - #100ns - // Generate a FIFO transaction, write SDO first - for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin - rx_data = $urandom; - tx_data = $urandom; - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); - spi_send(rx_data); - sdi_fifo_data_store[i] = rx_data; - sdo_fifo_data_store[i] = tx_data; - end + // Set up the interrupts + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), + `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | + `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) + ); + + #100ns + // Generate a FIFO transaction, write SDO first + for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin + rx_data = $urandom; + tx_data = $urandom; + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); + spi_send(rx_data); + sdi_fifo_data_store[i] = rx_data; + sdo_fifo_data_store[i] = tx_data; + end - generate_transfer_cmd(1); + generate_transfer_cmd(1); - `INFO(("Waiting for SPI VIP send..."), ADI_VERBOSITY_LOW); - spi_wait_send(); - `INFO(("SPI sent"), ADI_VERBOSITY_LOW); + `INFO(("Waiting for SPI VIP send..."), ADI_VERBOSITY_LOW); + spi_wait_send(); + `INFO(("SPI sent"), ADI_VERBOSITY_LOW); - for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_fifo_data[i]); - spi_receive(sdo_fifo_data[i]); - end + for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_fifo_data[i]); + spi_receive(sdo_fifo_data[i]); + end - if (sdi_fifo_data !== sdi_fifo_data_store) begin - `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data, sdi_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Fifo Read Test FAILED")); - end - `INFO(("Fifo Read Test PASSED"), ADI_VERBOSITY_LOW); + if (sdi_fifo_data !== sdi_fifo_data_store) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data, sdi_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Read Test FAILED")); + end + `INFO(("Fifo Read Test PASSED"), ADI_VERBOSITY_LOW); - if (sdo_fifo_data !== sdo_fifo_data_store) begin - `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data, sdo_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Fifo Write Test FAILED")); - end - `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); -endtask + if (sdo_fifo_data !== sdo_fifo_data_store) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data, sdo_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end + `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask endprogram diff --git a/testbenches/ip/spi_engine/tests/test_sleep_delay.sv b/testbenches/ip/spi_engine/tests/test_sleep_delay.sv index 1206ffc2..ce699333 100644 --- a/testbenches/ip/spi_engine/tests/test_sleep_delay.sv +++ b/testbenches/ip/spi_engine/tests/test_sleep_delay.sv @@ -34,18 +34,25 @@ // *************************************************************************** `include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" -import axi_vip_pkg::*; +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import spi_environment_pkg::*; import axi4stream_vip_pkg::*; import adi_regmap_pkg::*; import adi_regmap_clkgen_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; -import logger_pkg::*; -import spi_environment_pkg::*; import spi_engine_instr_pkg::*; import adi_spi_vip_pkg::*; +import axi_vip_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -57,461 +64,476 @@ program test_sleep_delay ( inout [(`NUM_OF_CS - 1):0] spi_engine_spi_cs, inout spi_engine_spi_clk, `ifdef DEF_ECHO_SCLK - inout spi_engine_echo_sclk, + inout spi_engine_echo_sclk, `endif inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); -timeunit 1ns; -timeprecision 100ps; - -spi_environment env; - -// -------------------------- -// Wrapper function for AXI read verify -// -------------------------- -task axi_read_v( - input [31:0] raddr, - input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); -endtask - -task axi_read( - input [31:0] raddr, - output [31:0] data); - env.mng.RegRead32(raddr,data); -endtask - -// -------------------------- -// Wrapper function for AXI write -// -------------------------- -task axi_write( - input [31:0] waddr, - input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); -endtask - -// -------------------------- -// Wrapper function for SPI receive (from DUT) -// -------------------------- -task spi_receive( - output [`DATA_DLENGTH:0] data); - env.spi_seq.receive_data(data); -endtask - -// -------------------------- -// Wrapper function for SPI send (to DUT) -// -------------------------- -task spi_send( - input [`DATA_DLENGTH:0] data); - env.spi_seq.send_data(data); -endtask - -// -------------------------- -// Wrapper function for waiting for all SPI -// -------------------------- -task spi_wait_send(); - env.spi_seq.flush_send(); -endtask - -// -------------------------- -// Main procedure -// -------------------------- -initial begin - - //creating environment - env = new("SPI Engine Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `ifdef DEF_SDO_STREAMING - `TH.`SDO_SRC.inst.IF, - `endif - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SPI_S.inst.IF - ); - - setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.configure(); - - env.sys_reset(); - - env.run(); - - env.spi_seq.set_default_miso_data('h2AA55); - - // start sdo source (will wait for data enqueued) - `ifdef DEF_SDO_STREAMING - env.sdo_src_seq.start(); - `endif - - sanity_test(); - - #100ns - - sleep_delay_test(7); - - cs_delay_test(3,3); - - env.stop(); - - `INFO(("Test Done"), ADI_VERBOSITY_NONE); - - $finish; - -end - -//--------------------------------------------------------------------------- -// Sanity test reg interface -//--------------------------------------------------------------------------- - -task sanity_test(); - bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; - axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); -endtask - -//--------------------------------------------------------------------------- -// IRQ callback -//--------------------------------------------------------------------------- + timeunit 1ns; + timeprecision 100ps; + + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + spi_environment spi_env; + + // -------------------------- + // Wrapper function for AXI read verify + // -------------------------- + task axi_read_v( + input [31:0] raddr, + input [31:0] vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); + endtask + + task axi_read( + input [31:0] raddr, + output [31:0] data); + base_env.mng.master_sequencer.RegRead32(raddr,data); + endtask + + // -------------------------- + // Wrapper function for AXI write + // -------------------------- + task axi_write( + input [31:0] waddr, + input [31:0] wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); + endtask + + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task spi_receive( + output [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.receive_data(data); + endtask + + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.send_data(data); + endtask + + // -------------------------- + // Wrapper function for waiting for all SPI + // -------------------------- + task spi_wait_send(); + spi_env.spi_agent.sequencer.flush_send(); + endtask + + + // -------------------------- + // Main procedure + // -------------------------- + initial begin + + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); + + setLoggerVerbosity(ADI_VERBOSITY_NONE); + + base_env.start(); + spi_env.start(); + + base_env.sys_reset(); + + spi_env.configure(); + + spi_env.run(); + + spi_env.spi_agent.sequencer.set_default_miso_data('h2AA55); + + // start sdo source (will wait for data enqueued) + `ifdef DEF_SDO_STREAMING + spi_env.sdo_src_agent.sequencer.start(); + `endif + + sanity_test(); + + #100ns + + sleep_delay_test(7); + + cs_delay_test(3,3); + + spi_env.stop(); + base_env.stop(); + + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); -reg [4:0] irq_pending = 0; -reg [7:0] sync_id = 0; - -initial begin - forever begin - @(posedge spi_engine_irq); - // read pending IRQs - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - // IRQ launched by Offload SYNC command - if (irq_pending & 5'b10000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD_SYNC_ID), sync_id); - `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SYNC command - if (irq_pending & 5'b01000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); - `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDI FIFO - if (irq_pending & 5'b00100) begin - `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00010) begin - `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00001) begin - `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // Clear all pending IRQs - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); end -end - -//--------------------------------------------------------------------------- -// Echo SCLK generation - we need this only if ECHO_SCLK is enabled -//--------------------------------------------------------------------------- -`ifdef DEF_ECHO_SCLK - assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; -`endif - -//--------------------------------------------------------------------------- -// Sleep and Chip Select Instruction time counter -//--------------------------------------------------------------------------- -int sleep_instr_time[$]; -int sleep_duration; -int sleep_current_duration; -bit sleeping; -int cs_instr_time[$]; -int cs_current_duration; -int cs_duration; -bit cs_sleeping; -wire [15:0] cmd, cmd_d1; -wire cmd_valid, cmd_ready; -wire idle; - -assign cmd = `TH.spi_engine.spi_engine_execution.inst.cmd; -assign cmd_d1 = `TH.spi_engine.spi_engine_execution.inst.cmd_d1; -assign cmd_valid = `TH.spi_engine.spi_engine_execution.inst.cmd_valid; -assign cmd_ready = `TH.spi_engine.spi_engine_execution.inst.cmd_ready; -assign idle = `TH.spi_engine.spi_engine_execution.inst.idle; - -initial begin - sleep_current_duration = 0; - sleep_duration = 0; - sleeping = 1'b0; - cs_current_duration = 0; - cs_duration = 0; - cs_sleeping = 1'b0; - forever begin - @(posedge spi_engine_spi_clk); - if (idle && (cmd_d1[15:8] == 8'h31) && sleeping) begin - sleeping <= 1'b0; - sleep_duration = sleep_current_duration+1; - sleep_instr_time.push_front(sleep_current_duration+1); // add one to account for this cycle + //--------------------------------------------------------------------------- + // Sanity test reg interface + //--------------------------------------------------------------------------- + + task sanity_test(); + bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; + axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // IRQ callback + //--------------------------------------------------------------------------- + + reg [4:0] irq_pending = 0; + reg [7:0] sync_id = 0; + + initial begin + forever begin + @(posedge spi_engine_irq); + // read pending IRQs + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + // IRQ launched by Offload SYNC command + if (irq_pending & 5'b10000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD_SYNC_ID), sync_id); + `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (cmd_valid && cmd_ready && (cmd[15:8] == 8'h31)) begin - sleep_current_duration <= 0; - sleeping <= 1'b1; - end else begin - sleep_current_duration <= sleep_current_duration+1; + // IRQ launched by SYNC command + if (irq_pending & 5'b01000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (idle && (cmd_d1[15:10] == 6'h4) && cs_sleeping) begin - cs_sleeping = 1'b0; - cs_duration = cs_current_duration+1; - cs_instr_time.push_front(cs_current_duration+1); // add one to account for this cycle + // IRQ launched by SDI FIFO + if (irq_pending & 5'b00100) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); end - if (cmd_valid && cmd_ready && (cmd[15:10] == 6'h4)) begin - cs_current_duration <= 0; - cs_sleeping <= 1'b1; - end else begin - cs_current_duration <= cs_current_duration+1; + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00010) begin + `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); end + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00001) begin + `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // Clear all pending IRQs + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + end end -end - -//--------------------------------------------------------------------------- -// Sleep delay Test -//--------------------------------------------------------------------------- - -int sleep_time; -int expected_sleep_time; -task sleep_delay_test( - input [7:0] sleep_param); - // Start spi clk generator - axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); - - // Config pwm - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d1000)); // set PWM period - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration - `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - - // Enable SPI Engine - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); - - // Set up the interrupts - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), - `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | - `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) - ); + //--------------------------------------------------------------------------- + // Echo SCLK generation - we need this only if ECHO_SCLK is enabled + //--------------------------------------------------------------------------- + `ifdef DEF_ECHO_SCLK + assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; + `endif - // Write commands - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_DLENGTH(`DATA_WIDTH - `DATA_DLENGTH)); - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + //--------------------------------------------------------------------------- + // Sleep and Chip Select Instruction time counter + //--------------------------------------------------------------------------- + + int sleep_instr_time[$]; + int sleep_duration; + int sleep_current_duration; + bit sleeping; + int cs_instr_time[$]; + int cs_current_duration; + int cs_duration; + bit cs_sleeping; + wire [15:0] cmd, cmd_d1; + wire cmd_valid, cmd_ready; + wire idle; + + assign cmd = `TH.spi_engine.spi_engine_execution.inst.cmd; + assign cmd_d1 = `TH.spi_engine.spi_engine_execution.inst.cmd_d1; + assign cmd_valid = `TH.spi_engine.spi_engine_execution.inst.cmd_valid; + assign cmd_ready = `TH.spi_engine.spi_engine_execution.inst.cmd_ready; + assign idle = `TH.spi_engine.spi_engine_execution.inst.idle; + + initial begin + sleep_current_duration = 0; + sleep_duration = 0; + sleeping = 1'b0; + cs_current_duration = 0; + cs_duration = 0; + cs_sleeping = 1'b0; + forever begin + @(posedge spi_engine_spi_clk); + if (idle && (cmd_d1[15:8] == 8'h31) && sleeping) begin + sleeping <= 1'b0; + sleep_duration = sleep_current_duration+1; + sleep_instr_time.push_front(sleep_current_duration+1); // add one to account for this cycle + end + if (cmd_valid && cmd_ready && (cmd[15:8] == 8'h31)) begin + sleep_current_duration <= 0; + sleeping <= 1'b1; + end else begin + sleep_current_duration <= sleep_current_duration+1; + end + if (idle && (cmd_d1[15:10] == 6'h4) && cs_sleeping) begin + cs_sleeping = 1'b0; + cs_duration = cs_current_duration+1; + cs_instr_time.push_front(cs_current_duration+1); // add one to account for this cycle + end + if (cmd_valid && cmd_ready && (cmd[15:10] == 6'h4)) begin + cs_current_duration <= 0; + cs_sleeping <= 1'b1; + end else begin + cs_current_duration <= cs_current_duration+1; + end + end end - expected_sleep_time = 2+(sleep_param+1)*((`CLOCK_DIVIDER+1)*2); - // Start the test - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`SLEEP(sleep_param))); - - #2000ns - sleep_time = sleep_instr_time.pop_back(); - if ((sleep_time != expected_sleep_time)) begin - `FATAL(("Sleep Test FAILED: unexpected sleep instruction duration. Expected=%d, Got=%d",expected_sleep_time,sleep_time)); - end else begin - `INFO(("Sleep Test PASSED"), ADI_VERBOSITY_LOW); - end + //--------------------------------------------------------------------------- + // Sleep delay Test + //--------------------------------------------------------------------------- + + int sleep_time; + int expected_sleep_time; + + task sleep_delay_test( + input [7:0] sleep_param); + // Start spi clk generator + axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), + `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | + `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) + ); + + // Config pwm + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d1000)); // set PWM period + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + // Enable SPI Engine + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + + // Set up the interrupts + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), + `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | + `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) + ); + + // Write commands + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_DLENGTH(`DATA_WIDTH - `DATA_DLENGTH)); + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end - // change the SPI word size (this should not affect sleep delay) - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`SLEEP(sleep_param))); - #2000ns - sleep_time = sleep_instr_time.pop_back(); - #100ns - if ((sleep_time != expected_sleep_time)) begin - `FATAL(("Sleep Test FAILED: unexpected sleep instruction duration. Expected=%d, Got=%d",expected_sleep_time,sleep_time)); - end else begin - `INFO(("Sleep Test PASSED"), ADI_VERBOSITY_LOW); - end + expected_sleep_time = 2+(sleep_param+1)*((`CLOCK_DIVIDER+1)*2); + // Start the test + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`SLEEP(sleep_param))); - // Disable SPI Engine - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), 1); -endtask + #2000ns + sleep_time = sleep_instr_time.pop_back(); + if ((sleep_time != expected_sleep_time)) begin + `FATAL(("Sleep Test FAILED: unexpected sleep instruction duration. Expected=%d, Got=%d",expected_sleep_time,sleep_time)); + end else begin + `INFO(("Sleep Test PASSED"), ADI_VERBOSITY_LOW); + end -//--------------------------------------------------------------------------- -// CS delay Test -//--------------------------------------------------------------------------- + // change the SPI word size (this should not affect sleep delay) + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`SLEEP(sleep_param))); + #2000ns + sleep_time = sleep_instr_time.pop_back(); + #100ns + if ((sleep_time != expected_sleep_time)) begin + `FATAL(("Sleep Test FAILED: unexpected sleep instruction duration. Expected=%d, Got=%d",expected_sleep_time,sleep_time)); + end else begin + `INFO(("Sleep Test PASSED"), ADI_VERBOSITY_LOW); + end -bit [`DATA_DLENGTH:0] offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)-1:0]; -bit [`DATA_DLENGTH:0] offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)-1:0]; -int cs_activate_time; -int expected_cs_activate_time; -int cs_deactivate_time; -int expected_cs_deactivate_time; -bit [`DATA_DLENGTH-1:0] temp_data; - -task cs_delay_test( - input [1:0] cs_activate_delay, - input [1:0] cs_deactivate_delay); - // Start spi clk generator - axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) + // Disable SPI Engine + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), 1); + endtask + + //--------------------------------------------------------------------------- + // CS delay Test + //--------------------------------------------------------------------------- + + bit [`DATA_DLENGTH:0] offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)-1:0]; + bit [`DATA_DLENGTH:0] offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)-1:0]; + int cs_activate_time; + int expected_cs_activate_time; + int cs_deactivate_time; + int expected_cs_deactivate_time; + bit [`DATA_DLENGTH-1:0] temp_data; + + task cs_delay_test( + input [1:0] cs_activate_delay, + input [1:0] cs_deactivate_delay); + // Start spi clk generator + axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), + `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | + `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) + ); + + // Config cnv + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d1000)); // set PWM period + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + //Configure DMA + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), + `SET_DMAC_FLAGS_TLAST(1) | + `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) + ); // Use TLAST + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); + + // Enable SPI Engine + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + + // Set up the interrupts + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), + `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | + `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) ); - // Config cnv - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d1000)); // set PWM period - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); - `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - - //Configure DMA - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), - `SET_DMAC_FLAGS_TLAST(1) | - `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) - ); // Use TLAST - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); - - // Enable SPI Engine - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); - - // Set up the interrupts - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), - `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | - `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) - ); - - // Configure the Offload module - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(1)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(0)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_RD); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 1); - - expected_cs_activate_time = 2; - expected_cs_deactivate_time = 2; - - // Enqueue transfers to DUT - for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin - temp_data = $urandom; - spi_send(temp_data); - offload_sdi_data_store_arr[i] = temp_data; - end + // Configure the Offload module + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(1)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(0)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_RD); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 1); + + expected_cs_activate_time = 2; + expected_cs_deactivate_time = 2; + + // Enqueue transfers to DUT + for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin + temp_data = $urandom; + spi_send(temp_data); + offload_sdi_data_store_arr[i] = temp_data; + end - // Start the offload - #100ns - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); - `INFO(("Offload started (no delay on CS change)."), ADI_VERBOSITY_LOW); + // Start the offload + #100ns + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); + `INFO(("Offload started (no delay on CS change)."), ADI_VERBOSITY_LOW); - spi_wait_send(); + spi_wait_send(); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); - `INFO(("Offload stopped (no delay on CS change)."), ADI_VERBOSITY_LOW); + `INFO(("Offload stopped (no delay on CS change)."), ADI_VERBOSITY_LOW); - #2000ns + #2000ns - for (int i=0; i<=(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS); i=i+1) begin - offload_captured_word_arr[i][`DATA_DLENGTH-1:0] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); - end + for (int i=0; i<=(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS); i=i+1) begin + offload_captured_word_arr[i][`DATA_DLENGTH-1:0] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); + end - if (irq_pending == 'h0) begin - `FATAL(("IRQ Test FAILED")); - end else begin - `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); - end + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); + end - if (offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0] !== offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0]) begin - `ERROR(("CS Delay Test FAILED: bad data")); - end + if (offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0] !== offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0]) begin + `FATAL(("CS Delay Test FAILED: bad data")); + end - repeat (`NUM_OF_TRANSFERS) begin - cs_activate_time = cs_instr_time.pop_back(); - cs_deactivate_time = cs_instr_time.pop_back(); - end - if ((cs_activate_time != expected_cs_activate_time)) begin - `FATAL(("CS Delay Test FAILED: unexpected chip select activate instruction duration. Expected=%d, Got=%d",expected_cs_activate_time,cs_activate_time)); - end - if (cs_deactivate_time != expected_cs_deactivate_time) begin - `FATAL(("CS Delay Test FAILED: unexpected chip select deactivate instruction duration. Expected=%d, Got=%d",expected_cs_deactivate_time,cs_deactivate_time)); - end - `INFO(("CS Delay Test PASSED"), ADI_VERBOSITY_LOW); - - #2000ns - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); - - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(1)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(0)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_DELAY(8'hFE,cs_activate_delay)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_RD); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_DELAY(8'hFF,cs_deactivate_delay)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); - - // breakdown: cs_activate_delay*(1+`CLOCK_DIVIDER)*2, times 2 since it's before and after cs transition, and added 3 cycles (1 for each timer comparison, plus one for fetching next instruction) - expected_cs_activate_time = 2+2*cs_activate_delay*(1+`CLOCK_DIVIDER)*2; - expected_cs_deactivate_time = 2+2*cs_deactivate_delay*(1+`CLOCK_DIVIDER)*2; - - // Enqueue transfers to DUT - for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin - temp_data = $urandom; - spi_send(temp_data); - offload_sdi_data_store_arr[i] = temp_data; - end + repeat (`NUM_OF_TRANSFERS) begin + cs_activate_time = cs_instr_time.pop_back(); + cs_deactivate_time = cs_instr_time.pop_back(); + end + if ((cs_activate_time != expected_cs_activate_time)) begin + `FATAL(("CS Delay Test FAILED: unexpected chip select activate instruction duration. Expected=%d, Got=%d",expected_cs_activate_time,cs_activate_time)); + end + if (cs_deactivate_time != expected_cs_deactivate_time) begin + `FATAL(("CS Delay Test FAILED: unexpected chip select deactivate instruction duration. Expected=%d, Got=%d",expected_cs_deactivate_time,cs_deactivate_time)); + end + `INFO(("CS Delay Test PASSED"), ADI_VERBOSITY_LOW); + + #2000ns + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); + + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(1)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET), `SET_AXI_SPI_ENGINE_OFFLOAD0_MEM_RESET_OFFLOAD0_MEM_RESET(0)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_DELAY(8'hFE,cs_activate_delay)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_RD); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_DELAY(8'hFF,cs_deactivate_delay)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); + + // breakdown: cs_activate_delay*(1+`CLOCK_DIVIDER)*2, times 2 since it's before and after cs transition, and added 3 cycles (1 for each timer comparison, plus one for fetching next instruction) + expected_cs_activate_time = 2+2*cs_activate_delay*(1+`CLOCK_DIVIDER)*2; + expected_cs_deactivate_time = 2+2*cs_deactivate_delay*(1+`CLOCK_DIVIDER)*2; + + // Enqueue transfers to DUT + for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin + temp_data = $urandom; + spi_send(temp_data); + offload_sdi_data_store_arr[i] = temp_data; + end - // Start the offload - #100ns - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); - `INFO(("Offload started (with delay on CS change)."), ADI_VERBOSITY_LOW); + // Start the offload + #100ns + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); + `INFO(("Offload started (with delay on CS change)."), ADI_VERBOSITY_LOW); - spi_wait_send(); + spi_wait_send(); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); - `INFO(("Offload stopped (with delay on CS change)."), ADI_VERBOSITY_LOW); + `INFO(("Offload stopped (with delay on CS change)."), ADI_VERBOSITY_LOW); - #2000ns + #2000ns - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - offload_captured_word_arr[i][`DATA_DLENGTH-1:0] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); - end + for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + offload_captured_word_arr[i][`DATA_DLENGTH-1:0] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); + end - if (irq_pending == 'h0) begin - `FATAL(("IRQ Test FAILED")); - end else begin - `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); - end + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); + end - if (offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0] !== offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0]) begin - `ERROR(("CS Delay Test FAILED: bad data")); - end - repeat (`NUM_OF_TRANSFERS) begin - cs_activate_time = cs_instr_time.pop_back(); - cs_deactivate_time = cs_instr_time.pop_back(); - end - if ((cs_activate_time != expected_cs_activate_time)) begin - `FATAL(("CS Delay Test FAILED: unexpected chip select activate instruction duration. Expected=%d, Got=%d",expected_cs_activate_time,cs_activate_time)); - end - if (cs_deactivate_time != expected_cs_deactivate_time) begin - `FATAL(("CS Delay Test FAILED: unexpected chip select deactivate instruction duration. Expected=%d, Got=%d",expected_cs_deactivate_time,cs_deactivate_time)); - end - `INFO(("CS Delay Test PASSED"), ADI_VERBOSITY_LOW); -endtask + if (offload_captured_word_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0] !== offload_sdi_data_store_arr [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) - 1:0]) begin + `FATAL(("CS Delay Test FAILED: bad data")); + end + repeat (`NUM_OF_TRANSFERS) begin + cs_activate_time = cs_instr_time.pop_back(); + cs_deactivate_time = cs_instr_time.pop_back(); + end + if ((cs_activate_time != expected_cs_activate_time)) begin + `FATAL(("CS Delay Test FAILED: unexpected chip select activate instruction duration. Expected=%d, Got=%d",expected_cs_activate_time,cs_activate_time)); + end + if (cs_deactivate_time != expected_cs_deactivate_time) begin + `FATAL(("CS Delay Test FAILED: unexpected chip select deactivate instruction duration. Expected=%d, Got=%d",expected_cs_deactivate_time,cs_deactivate_time)); + end + `INFO(("CS Delay Test PASSED"), ADI_VERBOSITY_LOW); + endtask endprogram diff --git a/testbenches/ip/spi_engine/tests/test_slowdata.sv b/testbenches/ip/spi_engine/tests/test_slowdata.sv index bd946ef5..2d905b70 100644 --- a/testbenches/ip/spi_engine/tests/test_slowdata.sv +++ b/testbenches/ip/spi_engine/tests/test_slowdata.sv @@ -36,18 +36,25 @@ // `include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" -import axi_vip_pkg::*; +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import spi_environment_pkg::*; import axi4stream_vip_pkg::*; import adi_regmap_pkg::*; import adi_regmap_clkgen_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; -import logger_pkg::*; -import spi_environment_pkg::*; import spi_engine_instr_pkg::*; import adi_spi_vip_pkg::*; +import axi_vip_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -59,535 +66,550 @@ program test_slowdata ( inout [(`NUM_OF_CS - 1):0] spi_engine_spi_cs, inout spi_engine_spi_clk, `ifdef DEF_ECHO_SCLK - inout spi_engine_echo_sclk, + inout spi_engine_echo_sclk, `endif inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); -timeunit 1ns; -timeprecision 100ps; - -spi_environment env; - -// -------------------------- -// Wrapper function for AXI read verify -// -------------------------- -task axi_read_v( - input [31:0] raddr, - input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); -endtask - -task axi_read( - input [31:0] raddr, - output [31:0] data); - env.mng.RegRead32(raddr,data); -endtask - -// -------------------------- -// Wrapper function for AXI write -// -------------------------- -task axi_write( - input [31:0] waddr, - input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); -endtask - -// -------------------------- -// Wrapper function for SPI receive (from DUT) -// -------------------------- -task spi_receive( - output [`DATA_DLENGTH:0] data); - env.spi_seq.receive_data(data); -endtask - -// -------------------------- -// Wrapper function for SPI send (to DUT) -// -------------------------- -task spi_send( - input [`DATA_DLENGTH:0] data); - env.spi_seq.send_data(data); -endtask - -// -------------------------- -// Wrapper function for waiting for all SPI -// -------------------------- -task spi_wait_send(); - env.spi_seq.flush_send(); -endtask - - - -// -------------------------- -// Main procedure -// -------------------------- -initial begin - - //creating environment - env = new("SPI Engine Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `ifdef DEF_SDO_STREAMING - `TH.`SDO_SRC.inst.IF, - `endif - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SPI_S.inst.IF - ); - - setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.configure(); - - env.sys_reset(); - - env.run(); - - env.spi_seq.set_default_miso_data('h2AA55); - - // start sdo source (will wait for data enqueued) - `ifdef DEF_SDO_STREAMING - env.sdo_src_seq.start(); - `endif + timeunit 1ns; + timeprecision 100ps; + + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + spi_environment spi_env; - sanity_test(); + // -------------------------- + // Wrapper function for AXI read verify + // -------------------------- + task axi_read_v( + input [31:0] raddr, + input [31:0] vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); + endtask - #100ns + task axi_read( + input [31:0] raddr, + output [31:0] data); + base_env.mng.master_sequencer.RegRead32(raddr,data); + endtask - fifo_init_test(); + // -------------------------- + // Wrapper function for AXI write + // -------------------------- + task axi_write( + input [31:0] waddr, + input [31:0] wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); + endtask - fifo_single_read_test(); + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task spi_receive( + output [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.receive_data(data); + endtask - fifo_double_write_test(); + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH:0] data); + spi_env.spi_agent.sequencer.send_data(data); + endtask - fifo_double_read_test(); + // -------------------------- + // Wrapper function for waiting for all SPI + // -------------------------- + task spi_wait_send(); + spi_env.spi_agent.sequencer.flush_send(); + endtask - fifo_double_write_test(); - offload_spi_test(); + // -------------------------- + // Main procedure + // -------------------------- + initial begin - #100ns - `INFO(("Test Done"), ADI_VERBOSITY_NONE); + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - $finish; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); -end + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); -//--------------------------------------------------------------------------- -// Sanity test reg interface -//--------------------------------------------------------------------------- + setLoggerVerbosity(ADI_VERBOSITY_NONE); -task sanity_test(); - bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 - | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; - //axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); -endtask + base_env.start(); + spi_env.start(); -//--------------------------------------------------------------------------- -// SPI Engine generate transfer -//--------------------------------------------------------------------------- + base_env.sys_reset(); -task generate_init_transfer_cmd( - input [7:0] sync_id); - // configure cs - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - // write cfg - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - // assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); - // write prescaler - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - // write dlen - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_WR); - // de-assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); - // SYNC command to generate interrupt - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); - `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); -endtask - -task generate_single_rtransfer_cmd( - input [7:0] sync_id); - // configure cs - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - // write cfg - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - // assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); - // write prescaler - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - // write dlen - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); - // de-assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); - // SYNC command to generate interrupt - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); - `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); -endtask - - -task generate_double_rtransfer_cmd( - input [7:0] sync_id); - // configure cs - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - // write cfg - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - // assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); - // write prescaler - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - // write dlen - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); - // de-assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); - // SYNC command to generate interrupt - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); - `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); -endtask - -task generate_double_wtransfer_cmd( - input [7:0] sync_id); - // configure cs - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - // write cfg - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); - // assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); - // write prescaler - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); - // write dlen - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_WR & 16'hFF00)); - // transfer data - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_WR & 16'hFF00)); - // de-assert CSN - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); - // SYNC command to generate interrupt - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); - `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); -endtask + spi_env.configure(); -//--------------------------------------------------------------------------- -// IRQ callback -//--------------------------------------------------------------------------- + spi_env.run(); -reg [4:0] irq_pending = 0; -reg [7:0] sync_id = 0; + spi_env.spi_agent.sequencer.set_default_miso_data('h2AA55); -initial begin - forever begin - @(posedge spi_engine_irq); - // read pending IRQs + // start sdo source (will wait for data enqueued) + `ifdef DEF_SDO_STREAMING + spi_env.sdo_src_agent.sequencer.start(); + `endif - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - // IRQ launched by Offload SYNC command - if (irq_pending & 5'b10000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); - `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SYNC command - if (irq_pending & 5'b01000) begin - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); - `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDI FIFO - if (irq_pending & 5'b00100) begin - `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00010) begin - `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // IRQ launched by SDO FIFO - if (irq_pending & 5'b00001) begin - `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); - end - // Clear all pending IRQs - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - end -end + sanity_test(); -//--------------------------------------------------------------------------- -// SPI Engine SDO data -//--------------------------------------------------------------------------- + #100ns -task sdo_stream_gen( - input [`DATA_DLENGTH:0] tx_data); - xil_axi4stream_data_byte data[(`DATA_WIDTH/8)-1:0]; - `ifdef DEF_SDO_STREAMING - for (int i = 0; i<(`DATA_WIDTH/8);i++) begin - data[i] = (tx_data & (8'hFF << 8*i)) >> 8*i; - env.sdo_src_seq.push_byte_for_stream(data[i]); - end - env.sdo_src_seq.add_xfer_descriptor((`DATA_WIDTH/8),0,0); - `endif -endtask + fifo_init_test(); -//--------------------------------------------------------------------------- -// Echo SCLK generation - we need this only if ECHO_SCLK is enabled -//--------------------------------------------------------------------------- -`ifdef DEF_ECHO_SCLK - assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; -`endif + fifo_single_read_test(); -//--------------------------------------------------------------------------- -// FIFO SPI Test -//--------------------------------------------------------------------------- + fifo_double_write_test(); -bit [`DATA_DLENGTH-1:0] sdi_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdo_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store [`NUM_OF_WORDS-1:0]; -bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store [`NUM_OF_WORDS-1:0]; -bit [`DATA_DLENGTH-1:0] rx_data; -bit [`DATA_DLENGTH-1:0] tx_data; - -task fifo_init_test(); - // Start spi clk generator - axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); - - // Enable SPI Engine - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); - - // Set up the interrupts - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), - `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | - `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) - ); - - #100ns - - // send cmd before data - generate_init_transfer_cmd(1); - - // write sdo fifo - for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin - tx_data = ((i%6) == 5) ? 8'hFE : 8'hFF; - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); - sdo_fifo_data_store[i] = tx_data; - end + fifo_double_read_test(); - `INFO(("Wait for SPI VIP receiving data"), ADI_VERBOSITY_LOW); - for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin - spi_receive(sdo_fifo_data[i]); - end + fifo_double_write_test(); - if (sdo_fifo_data !== sdo_fifo_data_store) begin - `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data, sdo_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Fifo Write Test FAILED")); - end - `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); -endtask + offload_spi_test(); -bit [`DATA_DLENGTH-1:0] sdo_2_fifo_data [2-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdo_2_fifo_data_store [2-1:0]; -task fifo_double_write_test(); + #100ns - #100ns + spi_env.stop(); + base_env.stop(); - // send cmd before data - generate_double_wtransfer_cmd(1); + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); - // write sdo fifo - for (int i = 0; i<(2) ; i=i+1) begin - tx_data = $urandom; - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); - sdo_2_fifo_data_store[i] = tx_data; end - `INFO(("Wait for SPI VIP receiving data"), ADI_VERBOSITY_LOW); - for (int i = 0; i<(2) ; i=i+1) begin - spi_receive(sdo_2_fifo_data[i]); + //--------------------------------------------------------------------------- + // Sanity test reg interface + //--------------------------------------------------------------------------- + + task sanity_test(); + bit [31:0] pcore_version = (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_PATCH) + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MINOR)<<8 + | (`DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR)<<16; + //axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + axi_read_v (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); + `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // SPI Engine generate transfer + //--------------------------------------------------------------------------- + + task generate_init_transfer_cmd( + input [7:0] sync_id); + // configure cs + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + // write cfg + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + // assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); + // write prescaler + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + // write dlen + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_WR); + // de-assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); + // SYNC command to generate interrupt + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + task generate_single_rtransfer_cmd( + input [7:0] sync_id); + // configure cs + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + // write cfg + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + // assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); + // write prescaler + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + // write dlen + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); + // de-assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); + // SYNC command to generate interrupt + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + + task generate_double_rtransfer_cmd( + input [7:0] sync_id); + // configure cs + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + // write cfg + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + // assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); + // write prescaler + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + // write dlen + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_RD & 16'hFF00)); + // de-assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); + // SYNC command to generate interrupt + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + task generate_double_wtransfer_cmd( + input [7:0] sync_id); + // configure cs + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + // write cfg + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_CFG); + // assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFE)); + // write prescaler + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_PRESCALE); + // write dlen + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `INST_DLENGTH); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_WR & 16'hFF00)); + // transfer data + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_WR & 16'hFF00)); + // de-assert CSN + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), `SET_CS(8'hFF)); + // SYNC command to generate interrupt + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), (`INST_SYNC | sync_id)); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // IRQ callback + //--------------------------------------------------------------------------- + + reg [4:0] irq_pending = 0; + reg [7:0] sync_id = 0; + + initial begin + forever begin + @(posedge spi_engine_irq); + // read pending IRQs + + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + // IRQ launched by Offload SYNC command + if (irq_pending & 5'b10000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); + `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); + end + // IRQ launched by SYNC command + if (irq_pending & 5'b01000) begin + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SYNC_ID), sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDI FIFO + if (irq_pending & 5'b00100) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00010) begin + `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (irq_pending & 5'b00001) begin + `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // Clear all pending IRQs + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); + end end - if (sdo_2_fifo_data !== sdo_2_fifo_data_store) begin - `INFO(("sdo_2_fifo_data: %x; sdo_2_fifo_data_store %x", sdo_2_fifo_data, sdo_2_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Double Write Test FAILED")); - end - `INFO(("Double Write Test PASSED"), ADI_VERBOSITY_LOW); -endtask + //--------------------------------------------------------------------------- + // SPI Engine SDO data + //--------------------------------------------------------------------------- + + task sdo_stream_gen( + input [`DATA_DLENGTH:0] tx_data); + xil_axi4stream_data_byte data[(`DATA_WIDTH/8)-1:0]; + `ifdef DEF_SDO_STREAMING + for (int i = 0; i<(`DATA_WIDTH/8);i++) begin + data[i] = (tx_data & (8'hFF << 8*i)) >> 8*i; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i]); + end + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8),0,0); + `endif + endtask -bit [`DATA_DLENGTH-1:0] sdi_2_fifo_data [2-1:0]= '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_2_fifo_data_store [2-1:0]; -bit [`DATA_DLENGTH-1:0] foo; -task fifo_double_read_test(); + //--------------------------------------------------------------------------- + // Echo SCLK generation - we need this only if ECHO_SCLK is enabled + //--------------------------------------------------------------------------- + `ifdef DEF_ECHO_SCLK + assign #(`ECHO_SCLK_DELAY * 1ns) spi_engine_echo_sclk = spi_engine_spi_sclk; + `endif - #100ns + //--------------------------------------------------------------------------- + // FIFO SPI Test + //--------------------------------------------------------------------------- + + bit [`DATA_DLENGTH-1:0] sdi_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data [`NUM_OF_WORDS-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store [`NUM_OF_WORDS-1:0]; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store [`NUM_OF_WORDS-1:0]; + bit [`DATA_DLENGTH-1:0] rx_data; + bit [`DATA_DLENGTH-1:0] tx_data; + + task fifo_init_test(); + // Start spi clk generator + axi_write (`SPI_ENGINE_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), + `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | + `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) + ); + + // Enable SPI Engine + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + + // Set up the interrupts + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_MASK), + `SET_AXI_SPI_ENGINE_IRQ_MASK_SYNC_EVENT(1) | + `SET_AXI_SPI_ENGINE_IRQ_MASK_OFFLOAD_SYNC_ID_PENDING(1) + ); + + #100ns + + // send cmd before data + generate_init_transfer_cmd(1); + + // write sdo fifo + for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin + tx_data = ((i%6) == 5) ? 8'hFE : 8'hFF; + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); + sdo_fifo_data_store[i] = tx_data; + end + `INFO(("Wait for SPI VIP receiving data"), ADI_VERBOSITY_LOW); + for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin + spi_receive(sdo_fifo_data[i]); + end + if (sdo_fifo_data !== sdo_fifo_data_store) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data, sdo_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end + `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask - for (int i = 0; i<(2) ; i=i+1) begin - rx_data = $urandom; - spi_send(rx_data); - sdi_2_fifo_data_store[i] = rx_data; - end + bit [`DATA_DLENGTH-1:0] sdo_2_fifo_data [2-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdo_2_fifo_data_store [2-1:0]; + task fifo_double_write_test(); - generate_double_rtransfer_cmd(1); + #100ns - `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); - spi_wait_send(); - `INFO(("SPI sent"), ADI_VERBOSITY_LOW); + // send cmd before data + generate_double_wtransfer_cmd(1); - for (int i = 0; i<(2) ; i=i+1) begin - spi_receive(foo); // dummy tx, just for clearing the VIP queue - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_2_fifo_data[i]); - end + // write sdo fifo + for (int i = 0; i<(2) ; i=i+1) begin + tx_data = $urandom; + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); + sdo_2_fifo_data_store[i] = tx_data; + end - if (sdi_2_fifo_data !== sdi_2_fifo_data_store) begin - `INFO(("sdi_2_fifo_data: %x; sdi_2_fifo_data_store %x", sdi_2_fifo_data, sdi_2_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Double Read Test FAILED")); - end - `INFO(("Double Read Test PASSED"), ADI_VERBOSITY_LOW); -endtask + `INFO(("Wait for SPI VIP receiving data"), ADI_VERBOSITY_LOW); + for (int i = 0; i<(2) ; i=i+1) begin + spi_receive(sdo_2_fifo_data[i]); + end -bit [`DATA_DLENGTH-1:0] sdi_1_fifo_data = '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_1_fifo_data_store ; -task fifo_single_read_test(); + if (sdo_2_fifo_data !== sdo_2_fifo_data_store) begin + `INFO(("sdo_2_fifo_data: %x; sdo_2_fifo_data_store %x", sdo_2_fifo_data, sdo_2_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Double Write Test FAILED")); + end + `INFO(("Double Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask - #100ns + bit [`DATA_DLENGTH-1:0] sdi_2_fifo_data [2-1:0]= '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_2_fifo_data_store [2-1:0]; + bit [`DATA_DLENGTH-1:0] foo; + task fifo_double_read_test(); - rx_data = $urandom; - spi_send(rx_data); - sdi_1_fifo_data_store = rx_data; + #100ns - generate_single_rtransfer_cmd(1); - `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); - spi_wait_send(); - `INFO(("SPI sent"), ADI_VERBOSITY_LOW); - spi_receive(foo); // dummy tx, just for clearing the VIP queue - axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_1_fifo_data); + for (int i = 0; i<(2) ; i=i+1) begin + rx_data = $urandom; + spi_send(rx_data); + sdi_2_fifo_data_store[i] = rx_data; + end - if (sdi_1_fifo_data !== sdi_1_fifo_data_store) begin - `INFO(("sdi_1_fifo_data: %x; sdi_1_fifo_data_store %x", sdi_1_fifo_data, sdi_1_fifo_data_store), ADI_VERBOSITY_LOW); - `ERROR(("Single Read Test FAILED")); - end - `INFO(("Single Read Test PASSED"), ADI_VERBOSITY_LOW); -endtask + generate_double_rtransfer_cmd(1); -//--------------------------------------------------------------------------- -// Offload SPI Test -//--------------------------------------------------------------------------- + `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); + spi_wait_send(); + `INFO(("SPI sent"), ADI_VERBOSITY_LOW); -bit [`DATA_DLENGTH-1:0] sdi_read_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdo_write_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; -bit [`DATA_DLENGTH-1:0] sdi_read_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; -bit [`DATA_DLENGTH-1:0] sdo_write_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; -bit [`DATA_DLENGTH-1:0] rx_data; -bit [`DATA_DLENGTH-1:0] tx_data; - -task offload_spi_test(); - - // Config pwm - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d105)); // set PWM period - axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration - `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - - //Configure DMA - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), - `SET_DMAC_FLAGS_TLAST(1) | - `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) - ); // Use TLAST - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); - env.mng.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); - - // Configure the Offload module - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); - if (`CS_ACTIVE_HIGH) begin - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); - end - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_WRD); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); + for (int i = 0; i<(2) ; i=i+1) begin + spi_receive(foo); // dummy tx, just for clearing the VIP queue + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_2_fifo_data[i]); + end + + if (sdi_2_fifo_data !== sdi_2_fifo_data_store) begin + `INFO(("sdi_2_fifo_data: %x; sdi_2_fifo_data_store %x", sdi_2_fifo_data, sdi_2_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Double Read Test FAILED")); + end + `INFO(("Double Read Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + bit [`DATA_DLENGTH-1:0] sdi_1_fifo_data = '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_1_fifo_data_store ; + task fifo_single_read_test(); + + #100ns - // Enqueue transfers transfers to DUT - for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin rx_data = $urandom; spi_send(rx_data); - sdi_read_data_store[i] = rx_data; - tx_data = $urandom; - `ifdef DEF_SDO_STREAMING - sdo_stream_gen(tx_data); - sdo_write_data_store[i] = tx_data; - `else - if (i<(`NUM_OF_WORDS)) begin - sdo_write_data_store[i] = tx_data; - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), sdo_write_data_store[i]); - end else begin - sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; - end - `endif - end + sdi_1_fifo_data_store = rx_data; + + generate_single_rtransfer_cmd(1); + + `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); + spi_wait_send(); + `INFO(("SPI sent"), ADI_VERBOSITY_LOW); + + spi_receive(foo); // dummy tx, just for clearing the VIP queue + axi_read (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), sdi_1_fifo_data); - // Start the offload - #100ns - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); - `INFO(("Offload started."), ADI_VERBOSITY_LOW); + if (sdi_1_fifo_data !== sdi_1_fifo_data_store) begin + `INFO(("sdi_1_fifo_data: %x; sdi_1_fifo_data_store %x", sdi_1_fifo_data, sdi_1_fifo_data_store), ADI_VERBOSITY_LOW); + `FATAL(("Single Read Test FAILED")); + end + `INFO(("Single Read Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // Offload SPI Test + //--------------------------------------------------------------------------- + + bit [`DATA_DLENGTH-1:0] sdi_read_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdo_write_data [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0] = '{default:'0}; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1 :0]; + bit [`DATA_DLENGTH-1:0] rx_data; + bit [`DATA_DLENGTH-1:0] tx_data; + + task offload_spi_test(); + + // Config pwm + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('d105)); // set PWM period + axi_write (`SPI_ENGINE_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_LOAD_CONFIG(1)); // load AXI_PWM_GEN configuration + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + //Configure DMA + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_FLAGS), + `SET_DMAC_FLAGS_TLAST(1) | + `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) + ); // Use TLAST + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); + + // Configure the Offload module + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFE)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_PRESCALE); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS_INV_MASK(8'hFF)); + end + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_WRD); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_CS(8'hFF)); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_DLENGTH); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_SYNC | 2); + + // Enqueue transfers transfers to DUT + for (int i = 0; i<((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)) ; i=i+1) begin + rx_data = $urandom; + spi_send(rx_data); + sdi_read_data_store[i] = rx_data; + tx_data = $urandom; + `ifdef DEF_SDO_STREAMING + sdo_stream_gen(tx_data); + sdo_write_data_store[i] = tx_data; + `else + if (i<(`NUM_OF_WORDS)) begin + sdo_write_data_store[i] = tx_data; + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), sdo_write_data_store[i]); + end else begin + sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; + end + `endif + end - spi_wait_send(); + // Start the offload + #100ns + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); + `INFO(("Offload started."), ADI_VERBOSITY_LOW); - axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); + spi_wait_send(); - `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); + axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); - #2000ns + `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); - if (irq_pending == 'h0) begin - `ERROR(("IRQ Test FAILED")); - end else begin - `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); - end + #2000ns - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - sdi_read_data[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); - if (sdi_read_data[i] != sdi_read_data_store[i]) begin - `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", i, sdi_read_data[i], i, sdi_read_data_store[i]), ADI_VERBOSITY_LOW); - `ERROR(("Offload Read Test FAILED")); + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); end - end - `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - spi_receive(sdo_write_data[i]); - if (sdo_write_data[i] != sdo_write_data_store[i]) begin - `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", i, sdo_write_data[i], i, sdo_write_data_store[i]), ADI_VERBOSITY_LOW); - `ERROR(("Offload Write Test FAILED")); + for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + sdi_read_data[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); + if (sdi_read_data[i] != sdi_read_data_store[i]) begin + `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", i, sdi_read_data[i], i, sdi_read_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Read Test FAILED")); + end end - end - `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); -endtask + `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); + + for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + spi_receive(sdo_write_data[i]); + if (sdo_write_data[i] != sdo_write_data_store[i]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", i, sdo_write_data[i], i, sdo_write_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + end + `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask -endprogram \ No newline at end of file +endprogram diff --git a/testbenches/ip/spi_engine/waves/cfg01.wcfg b/testbenches/ip/spi_engine/waves/cfg01.wcfg index 274ebdb8..c8dac025 100644 --- a/testbenches/ip/spi_engine/waves/cfg01.wcfg +++ b/testbenches/ip/spi_engine/waves/cfg01.wcfg @@ -12,7 +12,7 @@ - + diff --git a/testbenches/ip/spi_engine/waves/cfg_inv_cs.wcfg b/testbenches/ip/spi_engine/waves/cfg_inv_cs.wcfg index 9ae838f3..3bb16eb9 100644 --- a/testbenches/ip/spi_engine/waves/cfg_inv_cs.wcfg +++ b/testbenches/ip/spi_engine/waves/cfg_inv_cs.wcfg @@ -12,7 +12,7 @@ - + diff --git a/testbenches/ip/spi_engine/waves/cfg_sdo_streaming.wcfg b/testbenches/ip/spi_engine/waves/cfg_sdo_streaming.wcfg index 6d15b161..e7262c34 100644 --- a/testbenches/ip/spi_engine/waves/cfg_sdo_streaming.wcfg +++ b/testbenches/ip/spi_engine/waves/cfg_sdo_streaming.wcfg @@ -20,7 +20,7 @@ - + diff --git a/testbenches/ip/util_axis_fifo/Makefile b/testbenches/ip/util_axis_fifo/Makefile new file mode 100644 index 00000000..55ee4501 --- /dev/null +++ b/testbenches/ip/util_axis_fifo/Makefile @@ -0,0 +1,42 @@ +#################################################################################### +#################################################################################### +## Copyright (C) 2022 Analog Devices, Inc. +#################################################################################### +#################################################################################### + +# Makeincludes +include ../../../scripts/make_tb_path.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_common.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_axis.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_scoreboard.mk + +# Remaining test-bench dependencies except test programs +SV_DEPS += environment.sv + +LIB_DEPS := util_cdc +LIB_DEPS += util_axis_fifo + +# default test program +TP := test_program + +# config files should have the following format +# cfg__.tcl +CFG_FILES := $(notdir $(wildcard cfgs/cfg*.tcl)) +#$(warning $(CFG_FILES)) + +# List of tests and configuration combinations that has to be run +# Format is: : +TESTS := $(foreach cfg, $(basename $(CFG_FILES)), $(cfg):$(TP)) + +include ../../../scripts/project-sim.mk + +# usage : +# +# run specific test on a specific configuration in gui mode +# make CFG=cfg2_fsync TST=test_frame_delay MODE=gui +# +# run all test from a configuration +# make cfg1_mm2mm_default + +#################################################################################### +#################################################################################### diff --git a/testbenches/ip/util_axis_fifo/README.md b/testbenches/ip/util_axis_fifo/README.md new file mode 100644 index 00000000..f1495cb4 --- /dev/null +++ b/testbenches/ip/util_axis_fifo/README.md @@ -0,0 +1,27 @@ +Usage : + +Run all tests in batch mode: + + make + + +Run all tests in GUI mode: + + make MODE=gui + + +Run specific test on a specific configuration in gui mode: + + make CFG= TST= MODE=gui + + +Run all test from a configuration: + + make + + +Where: + + * is a file from the cfgs directory without the tcl extension of format cfg\* + * is a file from the tests directory without the tcl extension + diff --git a/testbenches/ip/util_axis_fifo/cfgs/cfg_rand.tcl b/testbenches/ip/util_axis_fifo/cfgs/cfg_rand.tcl new file mode 100644 index 00000000..157dc77e --- /dev/null +++ b/testbenches/ip/util_axis_fifo/cfgs/cfg_rand.tcl @@ -0,0 +1,27 @@ +global ad_project_params + +set async_clk [expr int(rand()*2)] +set ad_project_params(ASYNC_CLK) $async_clk + +set tkeep_en [expr int(rand()*2)] +set ad_project_params(TKEEP_EN) $tkeep_en + +set tlast_en [expr int(rand()*2)] +set ad_project_params(TLAST_EN) $tlast_en + +set random_width [expr int(8*pow(2, int(7.0*rand()+1)))] +set DATA_WIDTH $random_width +set ad_project_params(DATA_WIDTH) $DATA_WIDTH + +set random_width [expr int(5.0*rand())] +set ad_project_params(ADDRESS_WIDTH) $random_width + +set input_clk [expr int(rand()*9)+1] +set ad_project_params(INPUT_CLK) $input_clk + +if {$async_clk} { + set output_clk [expr int(rand()*9)+1] + set ad_project_params(OUTPUT_CLK) $output_clk +} else { + set ad_project_params(OUTPUT_CLK) $input_clk +} diff --git a/testbenches/ip/util_axis_fifo/environment.sv b/testbenches/ip/util_axis_fifo/environment.sv new file mode 100644 index 00000000..41412bea --- /dev/null +++ b/testbenches/ip/util_axis_fifo/environment.sv @@ -0,0 +1,148 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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 "axis_definitions.svh" + +package environment_pkg; + + import logger_pkg::*; + import adi_environment_pkg::*; + import axi4stream_vip_pkg::*; + import m_axis_sequencer_pkg::*; + import s_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; + import scoreboard_pkg::*; + + class util_axis_fifo_environment #(`AXIS_VIP_PARAM_DECL(input_axis), `AXIS_VIP_PARAM_DECL(output_axis), int INPUT_CLK, int OUTPUT_CLK) extends adi_environment; + + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(INPUT_CLK)) input_clk_vip_if; + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(OUTPUT_CLK)) output_clk_vip_if; + + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(input_axis)) input_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(output_axis)) output_axis_agent; + + scoreboard #(logic [7:0]) scoreboard_inst; + + //============================================================================ + // Constructor + //============================================================================ + function new ( + input string name, + + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(INPUT_CLK)) input_clk_vip_if, + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(OUTPUT_CLK)) output_clk_vip_if, + + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(input_axis)) input_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(output_axis)) output_axis_vip_if); + + // creating the agents + super.new(name); + + this.input_clk_vip_if = input_clk_vip_if; + this.output_clk_vip_if = output_clk_vip_if; + + this.input_axis_agent = new("Input AXI Stream Agent", input_axis_vip_if, this); + this.output_axis_agent = new("Output AXI Stream Agent", output_axis_vip_if, this); + + this.scoreboard_inst = new("Util AXIS FIFO Scoreboard", this); + endfunction + + //============================================================================ + // Configure environment + //============================================================================ + task configure(); + // configuration for input + this.input_axis_agent.sequencer.set_stop_policy(STOP_POLICY_PACKET); + this.input_axis_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); + this.input_axis_agent.sequencer.set_descriptor_gen_mode(1); + this.input_axis_agent.sequencer.set_data_beat_delay(0); + this.input_axis_agent.sequencer.set_descriptor_delay(0); + this.input_axis_agent.sequencer.set_inactive_drive_output_0(); + + // configuration for output + this.output_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + + // this.output_axis_agent.sequencer.set_use_variable_ranges(); + // this.output_axis_agent.sequencer.set_high_time_range(1,1); + // this.output_axis_agent.sequencer.set_low_time_range(0,0); + + // this.output_axis_agent.sequencer.clr_use_variable_ranges(); + // this.output_axis_agent.sequencer.set_high_time(1); + // this.output_axis_agent.sequencer.set_low_time(1); + endtask + + //============================================================================ + // Start environment + // - Connect all the agents to the scoreboard + // - Start the agents + //============================================================================ + task start(); + this.input_clk_vip_if.start_clock(); + this.output_clk_vip_if.start_clock(); + + this.input_axis_agent.start(); + this.output_axis_agent.start(); + + this.input_axis_agent.monitor.publisher.subscribe(this.scoreboard_inst.subscriber_source); + this.output_axis_agent.monitor.publisher.subscribe(this.scoreboard_inst.subscriber_sink); + endtask + + //============================================================================ + // Run subroutine + //============================================================================ + task run(); + fork + this.input_axis_agent.run(); + this.output_axis_agent.run(); + + this.scoreboard_inst.run(); + join_none + endtask + + //============================================================================ + // Stop subroutine + //============================================================================ + task stop(); + this.input_clk_vip_if.stop_clock(); + this.output_clk_vip_if.stop_clock(); + + this.input_axis_agent.stop(); + this.output_axis_agent.stop(); + endtask + + endclass + +endpackage diff --git a/testbenches/ip/util_axis_fifo/system_bd.tcl b/testbenches/ip/util_axis_fifo/system_bd.tcl new file mode 100644 index 00000000..32bbcb7a --- /dev/null +++ b/testbenches/ip/util_axis_fifo/system_bd.tcl @@ -0,0 +1,122 @@ +# *************************************************************************** +# *************************************************************************** +# Copyright (C) 2022 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. +# +# *************************************************************************** +# *************************************************************************** + +global ad_project_params + +set ASYNC_CLK $ad_project_params(ASYNC_CLK) +set TKEEP_EN $ad_project_params(TKEEP_EN) +set TLAST_EN $ad_project_params(TLAST_EN) +set DATA_WIDTH $ad_project_params(DATA_WIDTH) +set ADDRESS_WIDTH $ad_project_params(ADDRESS_WIDTH) +set INPUT_CLK $ad_project_params(INPUT_CLK) +set OUTPUT_CLK $ad_project_params(OUTPUT_CLK) + +# Input clock +ad_ip_instance clk_vip input_clk_vip [ list \ + INTERFACE_MODE {MASTER} \ + FREQ_HZ [expr pow(10, 9)/$INPUT_CLK] \ +] +adi_sim_add_define "INPUT_CLK_VIP=input_clk_vip" + +ad_ip_instance clk_vip output_clk_vip [ list \ + INTERFACE_MODE {MASTER} \ + FREQ_HZ [expr pow(10, 9)/$OUTPUT_CLK] \ +] +adi_sim_add_define "OUTPUT_CLK_VIP=output_clk_vip" + +ad_connect input_clk input_clk_vip/clk_out +ad_connect output_clk output_clk_vip/clk_out + +ad_ip_instance proc_sys_reset input_rstgen +ad_ip_parameter input_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +ad_ip_instance proc_sys_reset output_rstgen +ad_ip_parameter output_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +ad_connect sys_rst_vip/rst_out input_rstgen/ext_reset_in +ad_connect sys_rst_vip/rst_out output_rstgen/ext_reset_in + +ad_connect input_clk input_rstgen/slowest_sync_clk +ad_connect output_clk output_rstgen/slowest_sync_clk + +ad_connect input_resetn input_rstgen/peripheral_aresetn +ad_connect output_resetn output_rstgen/peripheral_aresetn + +ad_ip_instance util_axis_fifo util_axis_fifo_DUT [list \ + ASYNC_CLK $ASYNC_CLK \ + DATA_WIDTH $DATA_WIDTH \ + ADDRESS_WIDTH $ADDRESS_WIDTH \ + M_AXIS_REGISTERED 1 \ + ALMOST_EMPTY_THRESHOLD 0 \ + ALMOST_FULL_THRESHOLD 0 \ + TLAST_EN $TLAST_EN \ + TKEEP_EN $TKEEP_EN \ + REMOVE_NULL_BEAT_EN 0 \ +] + +ad_connect input_clk util_axis_fifo_DUT/s_axis_aclk +ad_connect input_resetn util_axis_fifo_DUT/s_axis_aresetn + +ad_connect output_clk util_axis_fifo_DUT/m_axis_aclk +ad_connect output_resetn util_axis_fifo_DUT/m_axis_aresetn + +ad_ip_instance axi4stream_vip input_axis [list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY {1} \ + TDEST_WIDTH {0} \ + TID_WIDTH {0} \ + HAS_TLAST $TLAST_EN \ + HAS_TKEEP $TKEEP_EN \ + TDATA_NUM_BYTES [expr {$DATA_WIDTH/8}] \ +] +adi_sim_add_define "INPUT_AXIS=input_axis" + +ad_connect input_clk input_axis/aclk +ad_connect input_resetn input_axis/aresetn + +ad_connect util_axis_fifo_DUT/s_axis input_axis/m_axis + +ad_ip_instance axi4stream_vip output_axis [list \ + INTERFACE_MODE {SLAVE} \ + HAS_TLAST $TLAST_EN \ + HAS_TKEEP $TKEEP_EN \ + TDATA_NUM_BYTES [expr {$DATA_WIDTH/8}] \ +] +adi_sim_add_define "OUTPUT_AXIS=output_axis" + +ad_connect output_clk output_axis/aclk +ad_connect output_resetn output_axis/aresetn + +ad_connect util_axis_fifo_DUT/m_axis output_axis/s_axis diff --git a/testbenches/ip/util_axis_fifo/system_project.tcl b/testbenches/ip/util_axis_fifo/system_project.tcl new file mode 100644 index 00000000..86b8f596 --- /dev/null +++ b/testbenches/ip/util_axis_fifo/system_project.tcl @@ -0,0 +1,31 @@ +source ../../../scripts/adi_sim.tcl + +if {$argc < 1} { + puts "Expecting at least one argument that specifies the test configuration" + exit 1 +} else { + set cfg_file [lindex $argv 0] +} + +# Read config file +source "cfgs/${cfg_file}" + +# Set the project name +set project_name [file rootname $cfg_file] + +# Create the project +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 + +# Add test files to the project +adi_sim_project_files [list \ + "environment.sv" \ + "tests/test_program.sv" \ +] + +#set a default test program +adi_sim_add_define "TEST_PROGRAM=test_program" + +adi_sim_generate $project_name diff --git a/testbenches/ip/util_axis_fifo/system_tb.sv b/testbenches/ip/util_axis_fifo/system_tb.sv new file mode 100644 index 00000000..57d8c109 --- /dev/null +++ b/testbenches/ip/util_axis_fifo/system_tb.sv @@ -0,0 +1,46 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2014 - 2022 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 responsabilities 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. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +`include "utils.svh" + +module system_tb(); + + `TEST_PROGRAM test(); + + test_harness `TH (); + +endmodule diff --git a/testbenches/ip/util_axis_fifo/tests/test_program.sv b/testbenches/ip/util_axis_fifo/tests/test_program.sv new file mode 100644 index 00000000..7caf952a --- /dev/null +++ b/testbenches/ip/util_axis_fifo/tests/test_program.sv @@ -0,0 +1,143 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 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 responsabilities 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 "axis_definitions.svh" + +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import environment_pkg::*; +import watchdog_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +import `PKGIFY(test_harness, input_axis)::*; +import `PKGIFY(test_harness, output_axis)::*; + +program test_program (); + + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + util_axis_fifo_environment #(`AXIS_VIP_PARAMS(test_harness, input_axis), `AXIS_VIP_PARAMS(test_harness, output_axis), `INPUT_CLK, `OUTPUT_CLK) uaf_env; + + watchdog send_data_wd; + + initial begin + + // create environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + uaf_env = new("Util AXIS FIFO Environment", + `TH.`INPUT_CLK_VIP.inst.IF, + `TH.`OUTPUT_CLK_VIP.inst.IF, + `TH.`INPUT_AXIS.inst.IF, + `TH.`OUTPUT_AXIS.inst.IF); + + setLoggerVerbosity(ADI_VERBOSITY_NONE); + + base_env.start(); + uaf_env.start(); + + base_env.sys_reset(); + + uaf_env.configure(); + + if (!`TKEEP_EN) begin + uaf_env.input_axis_agent.sequencer.set_keep_some(); + end else begin + uaf_env.input_axis_agent.sequencer.set_keep_all(); + end + + uaf_env.run(); + + send_data_wd = new("Util AXIS FIFO Watchdog", 500000, "Send data"); + + send_data_wd.start(); + + uaf_env.input_axis_agent.sequencer.start(); + + // stimulus + repeat($urandom_range(5,10)) begin + send_data_wd.reset(); + + if (!`TKEEP_EN) begin + repeat($urandom_range(1,5)) begin + uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_sample_count($urandom_range(1,128), `TLAST_EN, 0); + end + end else begin + repeat($urandom_range(1,5)) begin + uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_byte_count($urandom_range(1,1024), `TLAST_EN, 0); + end + end + + #($urandom_range(1,10)*1us); + + uaf_env.input_axis_agent.sequencer.clear_descriptor_queue(); + uaf_env.input_axis_agent.sequencer.wait_empty_descriptor_queue(); + + uaf_env.scoreboard_inst.wait_until_complete(); + + `INFO(("Packet finished."), ADI_VERBOSITY_LOW); + end + + send_data_wd.stop(); + + #100ns; + + uaf_env.stop(); + base_env.stop(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); + + end + +endprogram diff --git a/testbenches/ip/util_axis_fifo/waves/cfg_rand.wcfg b/testbenches/ip/util_axis_fifo/waves/cfg_rand.wcfg new file mode 100644 index 00000000..9b1d7fa9 --- /dev/null +++ b/testbenches/ip/util_axis_fifo/waves/cfg_rand.wcfg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + STYLE_ENUM_TRANSACTION + fff,fff=blank + true + #00E600 + /system_tb/test_harness/util_axis_fifo_DUT/s_axis.streamWaveData + 2 + /system_tb/test_harness/util_axis_fifo_DUT/s_axis.linkStarve + #99E600 + /system_tb/test_harness/util_axis_fifo_DUT/s_axis.linkStall + #E64C00 + /system_tb/test_harness/util_axis_fifo_DUT/s_axis.streamTooltipData + s_axis + s_axis + + + m_axis + m_axis + + diff --git a/testbenches/ip/util_axis_fifo_asym/Makefile b/testbenches/ip/util_axis_fifo_asym/Makefile new file mode 100644 index 00000000..b5bf4cd6 --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/Makefile @@ -0,0 +1,43 @@ +#################################################################################### +#################################################################################### +## Copyright (C) 2022 Analog Devices, Inc. +#################################################################################### +#################################################################################### + +# Makeincludes +include ../../../scripts/make_tb_path.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_common.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_axis.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_scoreboard.mk + +# Remaining test-bench dependencies except test programs +SV_DEPS += environment.sv + +LIB_DEPS := util_cdc +LIB_DEPS += util_axis_fifo +LIB_DEPS += util_axis_fifo_asym + +# default test program +TP := test_program + +# config files should have the following format +# cfg__.tcl +CFG_FILES := $(notdir $(wildcard cfgs/cfg*.tcl)) +#$(warning $(CFG_FILES)) + +# List of tests and configuration combinations that has to be run +# Format is: : +TESTS := $(foreach cfg, $(basename $(CFG_FILES)), $(cfg):$(TP)) + +include ../../../scripts/project-sim.mk + +# usage : +# +# run specific test on a specific configuration in gui mode +# make CFG=cfg2_fsync TST=test_frame_delay MODE=gui +# +# run all test from a configuration +# make cfg1_mm2mm_default + +#################################################################################### +#################################################################################### diff --git a/testbenches/ip/util_axis_fifo_asym/README.md b/testbenches/ip/util_axis_fifo_asym/README.md new file mode 100644 index 00000000..f1495cb4 --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/README.md @@ -0,0 +1,27 @@ +Usage : + +Run all tests in batch mode: + + make + + +Run all tests in GUI mode: + + make MODE=gui + + +Run specific test on a specific configuration in gui mode: + + make CFG= TST= MODE=gui + + +Run all test from a configuration: + + make + + +Where: + + * is a file from the cfgs directory without the tcl extension of format cfg\* + * is a file from the tests directory without the tcl extension + diff --git a/testbenches/ip/util_axis_fifo_asym/cfgs/cfg_rand.tcl b/testbenches/ip/util_axis_fifo_asym/cfgs/cfg_rand.tcl new file mode 100644 index 00000000..9cfd760c --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/cfgs/cfg_rand.tcl @@ -0,0 +1,44 @@ +global ad_project_params + +set async_clk [expr int(rand()*2)] +set ad_project_params(ASYNC_CLK) $async_clk + +set tkeep_en [expr int(rand()*2)] +set ad_project_params(TKEEP_EN) $tkeep_en + +set tlast_en [expr int(rand()*2)] +set ad_project_params(TLAST_EN) $tlast_en + +set random_width [expr int(8*pow(2, int(7.0*rand()+1)))] +set INPUT_WIDTH $random_width +set ad_project_params(INPUT_WIDTH) $INPUT_WIDTH + +set random_width [expr int(8*pow(2, int(7.0*rand()+1)))] +set OUTPUT_WIDTH $random_width +set ad_project_params(OUTPUT_WIDTH) $OUTPUT_WIDTH + +set fifo_limited [expr int(rand()*2)] +set ad_project_params(FIFO_LIMITED) $fifo_limited + +if {$fifo_limited} { + if {$INPUT_WIDTH > $OUTPUT_WIDTH} { + set RATIO $INPUT_WIDTH/$OUTPUT_WIDTH + } else { + set RATIO $OUTPUT_WIDTH/$INPUT_WIDTH + } +} else { + set RATIO 1 +} + +set random_width [expr int(int(log($RATIO)/log(2))+4.0*rand()+1)] +set ad_project_params(ADDRESS_WIDTH) $random_width + +set input_clk [expr int(rand()*9)+1] +set ad_project_params(INPUT_CLK) $input_clk + +if {$async_clk} { + set output_clk [expr int(rand()*9)+1] + set ad_project_params(OUTPUT_CLK) $output_clk +} else { + set ad_project_params(OUTPUT_CLK) $input_clk +} diff --git a/testbenches/ip/util_axis_fifo_asym/environment.sv b/testbenches/ip/util_axis_fifo_asym/environment.sv new file mode 100644 index 00000000..40e014ed --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/environment.sv @@ -0,0 +1,148 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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 "axis_definitions.svh" + +package environment_pkg; + + import logger_pkg::*; + import adi_environment_pkg::*; + import axi4stream_vip_pkg::*; + import m_axis_sequencer_pkg::*; + import s_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; + import scoreboard_pkg::*; + + class util_axis_fifo_environment #(`AXIS_VIP_PARAM_DECL(input_axis), `AXIS_VIP_PARAM_DECL(output_axis), int INPUT_CLK, int OUTPUT_CLK) extends adi_environment; + + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(INPUT_CLK)) input_clk_vip_if; + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(OUTPUT_CLK)) output_clk_vip_if; + + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(input_axis)) input_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(output_axis)) output_axis_agent; + + scoreboard #(logic [7:0]) scoreboard_inst; + + //============================================================================ + // Constructor + //============================================================================ + function new ( + input string name, + + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(INPUT_CLK)) input_clk_vip_if, + virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(OUTPUT_CLK)) output_clk_vip_if, + + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(input_axis)) input_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(output_axis)) output_axis_vip_if); + + // creating the agents + super.new(name); + + this.input_clk_vip_if = input_clk_vip_if; + this.output_clk_vip_if = output_clk_vip_if; + + this.input_axis_agent = new("Input AXI Stream Agent", input_axis_vip_if, this); + this.output_axis_agent = new("Output AXI Stream Agent", output_axis_vip_if, this); + + this.scoreboard_inst = new("Util AXIS FIFO Scoreboard", this); + endfunction + + //============================================================================ + // Configure environment + //============================================================================ + task configure(); + // configuration for input + this.input_axis_agent.sequencer.set_stop_policy(STOP_POLICY_PACKET); + this.input_axis_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); + this.input_axis_agent.sequencer.set_descriptor_gen_mode(1); + this.input_axis_agent.sequencer.set_data_beat_delay(0); + this.input_axis_agent.sequencer.set_descriptor_delay(0); + this.input_axis_agent.sequencer.set_inactive_drive_output_0(); + + // configuration for output + this.output_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + + // this.output_axis_agent.sequencer.set_use_variable_ranges(); + // this.output_axis_agent.sequencer.set_high_time_range(1,1); + // this.output_axis_agent.sequencer.set_low_time_range(0,0); + + // this.output_axis_agent.sequencer.clr_use_variable_ranges(); + // this.output_axis_agent.sequencer.set_high_time(1); + // this.output_axis_agent.sequencer.set_low_time(1); + endtask + + //============================================================================ + // Start environment + // - Connect all the agents to the scoreboard + // - Start the agents + //============================================================================ + task start(); + this.input_clk_vip_if.start_clock(); + this.output_clk_vip_if.start_clock(); + + this.input_axis_agent.start(); + this.output_axis_agent.start(); + + this.input_axis_agent.monitor.publisher.subscribe(this.scoreboard_inst.subscriber_source); + this.output_axis_agent.monitor.publisher.subscribe(this.scoreboard_inst.subscriber_sink); + endtask + + //============================================================================ + // Run subroutine + //============================================================================ + task run(); + fork + this.input_axis_agent.run(); + this.output_axis_agent.run(); + + this.scoreboard_inst.run(); + join_none + endtask + + //============================================================================ + // Stop subroutine + //============================================================================ + task stop(); + this.input_clk_vip_if.stop_clock(); + this.output_clk_vip_if.stop_clock(); + + this.input_axis_agent.stop(); + this.output_axis_agent.stop(); + endtask + + endclass + +endpackage diff --git a/testbenches/ip/util_axis_fifo_asym/system_bd.tcl b/testbenches/ip/util_axis_fifo_asym/system_bd.tcl new file mode 100644 index 00000000..5352fb0d --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/system_bd.tcl @@ -0,0 +1,126 @@ +# *************************************************************************** +# *************************************************************************** +# Copyright (C) 2022 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. +# +# *************************************************************************** +# *************************************************************************** + +global ad_project_params + +set ASYNC_CLK $ad_project_params(ASYNC_CLK) +set TKEEP_EN $ad_project_params(TKEEP_EN) +set TLAST_EN $ad_project_params(TLAST_EN) +set INPUT_WIDTH $ad_project_params(INPUT_WIDTH) +set OUTPUT_WIDTH $ad_project_params(OUTPUT_WIDTH) +set FIFO_LIMITED $ad_project_params(FIFO_LIMITED) +set ADDRESS_WIDTH $ad_project_params(ADDRESS_WIDTH) +set INPUT_CLK $ad_project_params(INPUT_CLK) +set OUTPUT_CLK $ad_project_params(OUTPUT_CLK) + +# Input clock +ad_ip_instance clk_vip input_clk_vip [ list \ + INTERFACE_MODE {MASTER} \ + FREQ_HZ [expr pow(10, 9)/$INPUT_CLK] \ +] +adi_sim_add_define "INPUT_CLK_VIP=input_clk_vip" + +ad_ip_instance clk_vip output_clk_vip [ list \ + INTERFACE_MODE {MASTER} \ + FREQ_HZ [expr pow(10, 9)/$OUTPUT_CLK] \ +] +adi_sim_add_define "OUTPUT_CLK_VIP=output_clk_vip" + +ad_connect input_clk input_clk_vip/clk_out +ad_connect output_clk output_clk_vip/clk_out + +ad_ip_instance proc_sys_reset input_rstgen +ad_ip_parameter input_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +ad_ip_instance proc_sys_reset output_rstgen +ad_ip_parameter output_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +ad_connect sys_rst_vip/rst_out input_rstgen/ext_reset_in +ad_connect sys_rst_vip/rst_out output_rstgen/ext_reset_in + +ad_connect input_clk input_rstgen/slowest_sync_clk +ad_connect output_clk output_rstgen/slowest_sync_clk + +ad_connect input_resetn input_rstgen/peripheral_aresetn +ad_connect output_resetn output_rstgen/peripheral_aresetn + +ad_ip_instance util_axis_fifo_asym util_axis_fifo_asym_DUT [list \ + ASYNC_CLK $ASYNC_CLK \ + S_DATA_WIDTH $INPUT_WIDTH \ + ADDRESS_WIDTH $ADDRESS_WIDTH \ + M_DATA_WIDTH $OUTPUT_WIDTH \ + M_AXIS_REGISTERED 1 \ + ALMOST_EMPTY_THRESHOLD 0 \ + ALMOST_FULL_THRESHOLD 0 \ + TLAST_EN $TLAST_EN \ + TKEEP_EN $TKEEP_EN \ + FIFO_LIMITED $FIFO_LIMITED \ + ADDRESS_WIDTH_PERSPECTIVE 0 \ +] + +ad_connect input_clk util_axis_fifo_asym_DUT/s_axis_aclk +ad_connect input_resetn util_axis_fifo_asym_DUT/s_axis_aresetn + +ad_connect output_clk util_axis_fifo_asym_DUT/m_axis_aclk +ad_connect output_resetn util_axis_fifo_asym_DUT/m_axis_aresetn + +ad_ip_instance axi4stream_vip input_axis [list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY {1} \ + TDEST_WIDTH {0} \ + TID_WIDTH {0} \ + HAS_TLAST $TLAST_EN \ + HAS_TKEEP $TKEEP_EN \ + TDATA_NUM_BYTES [expr {$INPUT_WIDTH/8}] \ +] +adi_sim_add_define "INPUT_AXIS=input_axis" + +ad_connect input_clk input_axis/aclk +ad_connect input_resetn input_axis/aresetn + +ad_connect util_axis_fifo_asym_DUT/s_axis input_axis/m_axis + +ad_ip_instance axi4stream_vip output_axis [list \ + INTERFACE_MODE {SLAVE} \ + HAS_TLAST $TLAST_EN \ + HAS_TKEEP $TKEEP_EN \ + TDATA_NUM_BYTES [expr {$OUTPUT_WIDTH/8}] \ +] +adi_sim_add_define "OUTPUT_AXIS=output_axis" + +ad_connect output_clk output_axis/aclk +ad_connect output_resetn output_axis/aresetn + +ad_connect util_axis_fifo_asym_DUT/m_axis output_axis/s_axis diff --git a/testbenches/ip/util_axis_fifo_asym/system_project.tcl b/testbenches/ip/util_axis_fifo_asym/system_project.tcl new file mode 100644 index 00000000..86b8f596 --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/system_project.tcl @@ -0,0 +1,31 @@ +source ../../../scripts/adi_sim.tcl + +if {$argc < 1} { + puts "Expecting at least one argument that specifies the test configuration" + exit 1 +} else { + set cfg_file [lindex $argv 0] +} + +# Read config file +source "cfgs/${cfg_file}" + +# Set the project name +set project_name [file rootname $cfg_file] + +# Create the project +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 + +# Add test files to the project +adi_sim_project_files [list \ + "environment.sv" \ + "tests/test_program.sv" \ +] + +#set a default test program +adi_sim_add_define "TEST_PROGRAM=test_program" + +adi_sim_generate $project_name diff --git a/testbenches/ip/util_axis_fifo_asym/system_tb.sv b/testbenches/ip/util_axis_fifo_asym/system_tb.sv new file mode 100644 index 00000000..57d8c109 --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/system_tb.sv @@ -0,0 +1,46 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2014 - 2022 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 responsabilities 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. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +`include "utils.svh" + +module system_tb(); + + `TEST_PROGRAM test(); + + test_harness `TH (); + +endmodule diff --git a/testbenches/ip/util_axis_fifo_asym/tests/test_program.sv b/testbenches/ip/util_axis_fifo_asym/tests/test_program.sv new file mode 100644 index 00000000..3c95833f --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/tests/test_program.sv @@ -0,0 +1,138 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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 "axis_definitions.svh" + +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import environment_pkg::*; +import watchdog_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +import `PKGIFY(test_harness, input_axis)::*; +import `PKGIFY(test_harness, output_axis)::*; + +program test_program (); + + // declare the class instances + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + util_axis_fifo_environment #(`AXIS_VIP_PARAMS(test_harness, input_axis), `AXIS_VIP_PARAMS(test_harness, output_axis), `INPUT_CLK, `OUTPUT_CLK) uaf_env; + + watchdog send_data_wd; + + initial begin + + // create environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + uaf_env = new("Util AXIS FIFO Environment", + `TH.`INPUT_CLK_VIP.inst.IF, + `TH.`OUTPUT_CLK_VIP.inst.IF, + `TH.`INPUT_AXIS.inst.IF, + `TH.`OUTPUT_AXIS.inst.IF); + + setLoggerVerbosity(ADI_VERBOSITY_NONE); + + base_env.start(); + uaf_env.start(); + + base_env.sys_reset(); + + uaf_env.configure(); + uaf_env.input_axis_agent.sequencer.set_keep_some(); + + uaf_env.run(); + + send_data_wd = new("Util AXIS FIFO Watchdog", 500000, "Send data"); + + send_data_wd.start(); + + uaf_env.input_axis_agent.sequencer.start(); + + // stimulus + repeat($urandom_range(5,10)) begin + send_data_wd.reset(); + + if ((!`TKEEP_EN || !`TLAST_EN) && `INPUT_WIDTH < `OUTPUT_WIDTH) begin + repeat($urandom_range(1,5)) begin + uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_sample_count($urandom_range(1,128)*`OUTPUT_WIDTH/`INPUT_WIDTH, `TLAST_EN, 0); + end + end else begin + repeat($urandom_range(1,5)) begin + uaf_env.input_axis_agent.sequencer.add_xfer_descriptor_byte_count($urandom_range(1,1024), `TLAST_EN, 0); + end + end + + #($urandom_range(1,10)*1us); + + uaf_env.input_axis_agent.sequencer.clear_descriptor_queue(); + uaf_env.input_axis_agent.sequencer.wait_empty_descriptor_queue(); + + uaf_env.scoreboard_inst.wait_until_complete(); + + `INFO(("Packet finished."), ADI_VERBOSITY_LOW); + end + + send_data_wd.stop(); + + #100ns; + + uaf_env.stop(); + base_env.stop(); + + `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); + $finish(); + + end + +endprogram diff --git a/testbenches/ip/util_axis_fifo_asym/waves/cfg_rand.wcfg b/testbenches/ip/util_axis_fifo_asym/waves/cfg_rand.wcfg new file mode 100644 index 00000000..f762d66c --- /dev/null +++ b/testbenches/ip/util_axis_fifo_asym/waves/cfg_rand.wcfg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + STYLE_ENUM_TRANSACTION + fff,fff=blank + true + #00E600 + /system_tb/test_harness/util_axis_fifo_asym_DUT/s_axis.streamWaveData + 2 + /system_tb/test_harness/util_axis_fifo_asym_DUT/s_axis.linkStarve + #99E600 + /system_tb/test_harness/util_axis_fifo_asym_DUT/s_axis.linkStall + #E64C00 + /system_tb/test_harness/util_axis_fifo_asym_DUT/s_axis.streamTooltipData + s_axis + s_axis + + + m_axis + m_axis + + diff --git a/testbenches/ip/util_pack/Makefile b/testbenches/ip/util_pack/Makefile index 34d6d9ed..4a5d1227 100644 --- a/testbenches/ip/util_pack/Makefile +++ b/testbenches/ip/util_pack/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2024(c) Analog Devices, Inc. +## Copyright (C) 2024 Analog Devices, Inc. #################################################################################### #################################################################################### diff --git a/testbenches/ip/util_pack/environment.sv b/testbenches/ip/util_pack/environment.sv index 5543cd5f..2be4feae 100644 --- a/testbenches/ip/util_pack/environment.sv +++ b/testbenches/ip/util_pack/environment.sv @@ -1,49 +1,61 @@ +// *************************************************************************** +// *************************************************************************** +// 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 responsabilities 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" package environment_pkg; - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import m_axis_sequencer_pkg::*; - import s_axis_sequencer_pkg::*; import logger_pkg::*; + import adi_environment_pkg::*; - import axi_vip_pkg::*; import axi4stream_vip_pkg::*; - import test_harness_env_pkg::*; + import m_axis_sequencer_pkg::*; + import s_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; import scoreboard_pack_pkg::*; - import x_monitor_pkg::*; - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; - - import `PKGIFY(test_harness, tx_src_axis)::*; - import `PKGIFY(test_harness, tx_dst_axis)::*; - import `PKGIFY(test_harness, rx_src_axis)::*; - import `PKGIFY(test_harness, rx_dst_axis)::*; - - class environment extends test_harness_env; + class util_pack_environment #(`AXIS_VIP_PARAM_DECL(tx_src_axis), `AXIS_VIP_PARAM_DECL(tx_dst_axis), `AXIS_VIP_PARAM_DECL(rx_src_axis), `AXIS_VIP_PARAM_DECL(rx_dst_axis)) extends adi_environment; // agents and sequencers - `AGENT(test_harness, tx_src_axis, mst_t) tx_src_axis_agent; - `AGENT(test_harness, tx_dst_axis, slv_t) tx_dst_axis_agent; - `AGENT(test_harness, rx_src_axis, mst_t) rx_src_axis_agent; - `AGENT(test_harness, rx_dst_axis, slv_t) rx_dst_axis_agent; + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(tx_src_axis)) tx_src_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(tx_dst_axis)) tx_dst_axis_agent; + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(rx_src_axis)) rx_src_axis_agent; + adi_axis_slave_agent #(`AXIS_VIP_PARAM_ORDER(rx_dst_axis)) rx_dst_axis_agent; - m_axis_sequencer #(`AGENT(test_harness, tx_src_axis, mst_t), - `AXIS_VIP_PARAMS(test_harness, tx_src_axis)) tx_src_axis_seq; - s_axis_sequencer #(`AGENT(test_harness, tx_dst_axis, slv_t)) tx_dst_axis_seq; - m_axis_sequencer #(`AGENT(test_harness, rx_src_axis, mst_t), - `AXIS_VIP_PARAMS(test_harness, rx_src_axis)) rx_src_axis_seq; - s_axis_sequencer #(`AGENT(test_harness, rx_dst_axis, slv_t)) rx_dst_axis_seq; - - x_axis_monitor #(`AGENT(test_harness, tx_src_axis, mst_t)) tx_src_axis_mon; - x_axis_monitor #(`AGENT(test_harness, tx_dst_axis, slv_t)) tx_dst_axis_mon; - x_axis_monitor #(`AGENT(test_harness, rx_src_axis, mst_t)) rx_src_axis_mon; - x_axis_monitor #(`AGENT(test_harness, rx_dst_axis, slv_t)) rx_dst_axis_mon; - - scoreboard_pack scoreboard_tx; - scoreboard_pack scoreboard_rx; + scoreboard_pack #(logic [7:0]) scoreboard_tx; + scoreboard_pack #(logic [7:0]) scoreboard_rx; //============================================================================ // Constructor @@ -51,48 +63,21 @@ package environment_pkg; function new ( input string name, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, - - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, tx_src_axis)) tx_src_axis_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, tx_dst_axis)) tx_dst_axis_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, rx_src_axis)) rx_src_axis_vip_if, - virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness, rx_dst_axis)) rx_dst_axis_vip_if - ); + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(tx_src_axis)) tx_src_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(tx_dst_axis)) tx_dst_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(rx_src_axis)) rx_src_axis_vip_if, + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(rx_dst_axis)) rx_dst_axis_vip_if); // creating the agents - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); - - tx_src_axis_agent = new("TX Source AXI Stream Agent", tx_src_axis_vip_if); - tx_dst_axis_agent = new("TX Destination AXI Stream Agent", tx_dst_axis_vip_if); - rx_src_axis_agent = new("RX Source AXI Stream Agent", rx_src_axis_vip_if); - rx_dst_axis_agent = new("RX Destination AXI Stream Agent", rx_dst_axis_vip_if); - - tx_src_axis_seq = new("TX Source AXI Stream Agent", tx_src_axis_agent, this); - tx_dst_axis_seq = new("TX Destination AXI Stream Agent", tx_dst_axis_agent, this); - rx_src_axis_seq = new("RX Source AXI Stream Agent", rx_src_axis_agent, this); - rx_dst_axis_seq = new("RX Destination AXI Stream Agent", rx_dst_axis_agent, this); - - tx_src_axis_mon = new("TX Source AXIS Transaction Monitor", tx_src_axis_agent, this); - tx_dst_axis_mon = new("TX Destination AXIS Transaction Monitor", tx_dst_axis_agent, this); - rx_src_axis_mon = new("RX Source AXIS Transaction Monitor", rx_src_axis_agent, this); - rx_dst_axis_mon = new("RX Destination AXIS Transaction Monitor", rx_dst_axis_agent, this); - - scoreboard_tx = new("TX Scoreboard", `CHANNELS, `SAMPLES, `WIDTH, CPACK, this); - scoreboard_rx = new("RX Scoreboard", `CHANNELS, `SAMPLES, `WIDTH, UPACK, this); + super.new(name); + + this.tx_src_axis_agent = new("TX Source AXI Stream Agent", tx_src_axis_vip_if, this); + this.tx_dst_axis_agent = new("TX Destination AXI Stream Agent", tx_dst_axis_vip_if, this); + this.rx_src_axis_agent = new("RX Source AXI Stream Agent", rx_src_axis_vip_if, this); + this.rx_dst_axis_agent = new("RX Destination AXI Stream Agent", rx_dst_axis_vip_if, this); + this.scoreboard_tx = new("TX Scoreboard", `CHANNELS, `SAMPLES, `WIDTH, CPACK, this); + this.scoreboard_rx = new("RX Scoreboard", `CHANNELS, `SAMPLES, `WIDTH, UPACK, this); endfunction //============================================================================ @@ -100,19 +85,17 @@ package environment_pkg; // - Configure the sequencer VIPs with an initial configuration before starting them //============================================================================ task configure(int bytes_to_generate); - // TX stubs - tx_src_axis_seq.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - tx_src_axis_seq.add_xfer_descriptor(bytes_to_generate, 0, 0); + this.tx_src_axis_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); + this.tx_src_axis_agent.sequencer.add_xfer_descriptor_byte_count(bytes_to_generate, 0, 0); - tx_dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + this.tx_dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); // RX stub - rx_src_axis_seq.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); - rx_src_axis_seq.add_xfer_descriptor(bytes_to_generate, 0, 0); - - rx_dst_axis_seq.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); + this.rx_src_axis_agent.sequencer.set_data_gen_mode(DATA_GEN_MODE_AUTO_INCR); + this.rx_src_axis_agent.sequencer.add_xfer_descriptor_byte_count(bytes_to_generate, 0, 0); + this.rx_dst_axis_agent.sequencer.set_mode(XIL_AXI4STREAM_READY_GEN_NO_BACKPRESSURE); endtask //============================================================================ @@ -121,83 +104,44 @@ package environment_pkg; // - Start the agents //============================================================================ task start(); + this.tx_src_axis_agent.agent.start_master(); + this.tx_dst_axis_agent.agent.start_slave(); + this.rx_src_axis_agent.agent.start_master(); + this.rx_dst_axis_agent.agent.start_slave(); - super.start(); - - tx_src_axis_agent.start_master(); - tx_dst_axis_agent.start_slave(); - rx_src_axis_agent.start_master(); - rx_dst_axis_agent.start_slave(); - - scoreboard_tx.set_source_stream(tx_src_axis_mon); - scoreboard_tx.set_sink_stream(tx_dst_axis_mon); - - scoreboard_rx.set_source_stream(rx_src_axis_mon); - scoreboard_rx.set_sink_stream(rx_dst_axis_mon); + this.tx_src_axis_agent.monitor.publisher.subscribe(this.scoreboard_tx.subscriber_source); + this.tx_dst_axis_agent.monitor.publisher.subscribe(this.scoreboard_tx.subscriber_sink); - endtask - - //============================================================================ - // Start the test - // - start the RX scoreboard and sequencer - // - start the TX scoreboard and sequencer - // - setup the RX DMA - // - setup the TX DMA - //============================================================================ - task test(); - - fork - tx_src_axis_seq.run(); - tx_dst_axis_seq.run(); - rx_src_axis_seq.run(); - rx_dst_axis_seq.run(); - - tx_src_axis_mon.run(); - tx_dst_axis_mon.run(); - rx_src_axis_mon.run(); - rx_dst_axis_mon.run(); - - scoreboard_tx.run(); - scoreboard_rx.run(); - join_none - - endtask - - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - // Evaluate the scoreboard's results + this.rx_src_axis_agent.monitor.publisher.subscribe(this.scoreboard_rx.subscriber_source); + this.rx_dst_axis_agent.monitor.publisher.subscribe(this.scoreboard_rx.subscriber_sink); endtask //============================================================================ // Run subroutine //============================================================================ - task run; - - //pre_test(); - test(); + task run(); + fork + this.tx_src_axis_agent.sequencer.run(); + this.tx_dst_axis_agent.sequencer.run(); + this.rx_src_axis_agent.sequencer.run(); + this.rx_dst_axis_agent.sequencer.run(); + this.scoreboard_tx.run(); + this.scoreboard_rx.run(); + join_none endtask //============================================================================ // Stop subroutine //============================================================================ - task stop; - - super.stop(); - - tx_src_axis_seq.stop(); - rx_src_axis_seq.stop(); - - tx_src_axis_agent.stop_master(); - tx_dst_axis_agent.stop_slave(); - rx_src_axis_agent.stop_master(); - rx_dst_axis_agent.stop_slave(); - - post_test(); - + task stop(); + this.tx_src_axis_agent.sequencer.stop(); + this.rx_src_axis_agent.sequencer.stop(); + + this.tx_src_axis_agent.agent.stop_master(); + this.tx_dst_axis_agent.agent.stop_slave(); + this.rx_src_axis_agent.agent.stop_master(); + this.rx_dst_axis_agent.agent.stop_slave(); endtask endclass diff --git a/testbenches/ip/util_pack/system_bd.tcl b/testbenches/ip/util_pack/system_bd.tcl index e1bd41d9..f0f0e29d 100644 --- a/testbenches/ip/util_pack/system_bd.tcl +++ b/testbenches/ip/util_pack/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2024 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/ip/util_pack/system_tb.sv b/testbenches/ip/util_pack/system_tb.sv index b2e0c285..0ad34c87 100644 --- a/testbenches/ip/util_pack/system_tb.sv +++ b/testbenches/ip/util_pack/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2024 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/ip/util_pack/tests/test_program.sv b/testbenches/ip/util_pack/tests/test_program.sv index 8562e7e9..a0ce7f92 100644 --- a/testbenches/ip/util_pack/tests/test_program.sv +++ b/testbenches/ip/util_pack/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 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 @@ -26,28 +26,41 @@ // // 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/master/LICENSE_ADIBSD +// 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" -import axi_vip_pkg::*; -import axi4stream_vip_pkg::*; import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import environment_pkg::*; import dmac_api_pkg::*; import watchdog_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +import `PKGIFY(test_harness, tx_src_axis)::*; +import `PKGIFY(test_harness, tx_dst_axis)::*; +import `PKGIFY(test_harness, rx_src_axis)::*; +import `PKGIFY(test_harness, rx_dst_axis)::*; + program test_program; // declare the class instances - environment env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + + util_pack_environment #(`AXIS_VIP_PARAMS(test_harness, tx_src_axis), `AXIS_VIP_PARAMS(test_harness, tx_dst_axis), `AXIS_VIP_PARAMS(test_harness, rx_src_axis), `AXIS_VIP_PARAMS(test_harness, rx_dst_axis)) pack_env; watchdog packer_scoreboard_wd; @@ -61,35 +74,41 @@ program test_program; setLoggerVerbosity(ADI_VERBOSITY_NONE); // create environment - env = new("Util Pack Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - - `TH.`TX_SRC_AXIS.inst.IF, - `TH.`TX_DST_AXIS.inst.IF, - `TH.`RX_SRC_AXIS.inst.IF, - `TH.`RX_DST_AXIS.inst.IF - ); - - dmac_tx = new("DMAC TX 0", env.mng, `TX_DMA_BA); - dmac_rx = new("DMAC RX 0", env.mng, `RX_DMA_BA); - - env.start(); - env.sys_reset(); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + pack_env = new("Util Pack Environment", + `TH.`TX_SRC_AXIS.inst.IF, + `TH.`TX_DST_AXIS.inst.IF, + `TH.`RX_SRC_AXIS.inst.IF, + `TH.`RX_DST_AXIS.inst.IF); + + dmac_tx = new("DMAC TX 0", base_env.mng.master_sequencer, `TX_DMA_BA); + dmac_rx = new("DMAC RX 0", base_env.mng.master_sequencer, `RX_DMA_BA); + + base_env.start(); + pack_env.start(); + + base_env.sys_reset(); // configure environment sequencers - env.configure(data_length); + pack_env.configure(data_length); `INFO(("Bring up IPs from reset."), ADI_VERBOSITY_LOW); systemBringUp(); // Start the ADC/DAC stubs `INFO(("Call the run() ..."), ADI_VERBOSITY_LOW); - env.run(); + pack_env.run(); // Generate DMA transfers `INFO(("Start DMAs"), ADI_VERBOSITY_LOW); @@ -97,8 +116,8 @@ program test_program; tx_dma_transfer(data_length); // start generating data - env.tx_src_axis_seq.start(); - env.rx_src_axis_seq.start(); + pack_env.tx_src_axis_agent.sequencer.start(); + pack_env.rx_src_axis_agent.sequencer.start(); // prepare watchdog with 20 us of wait time packer_scoreboard_wd = new("Packer watchdog", 20000, "Packers Scoreboard"); @@ -108,13 +127,14 @@ program test_program; // wait for scoreboards to finish fork - env.scoreboard_rx.wait_until_complete(); - env.scoreboard_tx.wait_until_complete(); + pack_env.scoreboard_rx.wait_until_complete(); + pack_env.scoreboard_tx.wait_until_complete(); join packer_scoreboard_wd.stop(); - env.stop(); + pack_env.stop(); + base_env.stop(); `INFO(("Test bench done!"), ADI_VERBOSITY_NONE); $finish(); @@ -122,12 +142,10 @@ program test_program; end task systemBringUp(); - `INFO(("Bring up RX DMAC 0"), ADI_VERBOSITY_LOW); dmac_rx.enable_dma(); `INFO(("Bring up TX DMAC 0"), ADI_VERBOSITY_LOW); dmac_tx.enable_dma(); - endtask // RX DMA transfer generator diff --git a/testbenches/ip/util_pack/waves/cfg1.wcfg b/testbenches/ip/util_pack/waves/cfg1.wcfg index 6319d37f..2ef4b934 100644 --- a/testbenches/ip/util_pack/waves/cfg1.wcfg +++ b/testbenches/ip/util_pack/waves/cfg1.wcfg @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/testbenches/ip/util_pack/waves/cfg_rand.wcfg b/testbenches/ip/util_pack/waves/cfg_rand.wcfg index 6319d37f..2ef4b934 100644 --- a/testbenches/ip/util_pack/waves/cfg_rand.wcfg +++ b/testbenches/ip/util_pack/waves/cfg_rand.wcfg @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/testbenches/project/ad463x/Makefile b/testbenches/project/ad463x/Makefile index ba422b1e..a76023b9 100644 --- a/testbenches/project/ad463x/Makefile +++ b/testbenches/project/ad463x/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -21,12 +21,9 @@ LIB_DEPS += ad463x_data_capture LIB_DEPS += axi_dmac LIB_DEPS += util_pack/util_upack2 LIB_DEPS += util_pack/util_cpack2 -LIB_DEPS += axi_sysid -LIB_DEPS += sysid_rom LIB_DEPS += axi_clkgen LIB_DEPS += axi_i2s_adi LIB_DEPS += axi_pwm_gen -LIB_DEPS += axi_sysid LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_axis_reorder LIB_DEPS += spi_engine/spi_engine_execution diff --git a/testbenches/project/ad463x/system_bd.tcl b/testbenches/project/ad463x/system_bd.tcl index 68071e82..9d43872f 100644 --- a/testbenches/project/ad463x/system_bd.tcl +++ b/testbenches/project/ad463x/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/ad463x/system_tb.sv b/testbenches/project/ad463x/system_tb.sv index 81a65aaf..b36523b1 100644 --- a/testbenches/project/ad463x/system_tb.sv +++ b/testbenches/project/ad463x/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/ad463x/tests/test_program.sv b/testbenches/project/ad463x/tests/test_program.sv index ab354508..77b29b14 100644 --- a/testbenches/project/ad463x/tests/test_program.sv +++ b/testbenches/project/ad463x/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -46,6 +46,10 @@ import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -98,7 +102,10 @@ program test_program ( input ad463x_spi_clk, input [(`NUM_OF_SDI - 1):0] ad463x_spi_sdi); -test_harness_env env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verify @@ -107,14 +114,14 @@ task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -124,7 +131,7 @@ task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -133,22 +140,22 @@ endtask initial begin //creating environment - env = new("AD463X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("AD463X Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - #100 + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -160,10 +167,10 @@ initial begin offload_spi_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -254,7 +261,7 @@ bit [31:0] sdi_preg[$]; bit [31:0] sdi_nreg[$]; initial begin - while(1) begin + forever begin @(posedge ad463x_spi_clk); m_spi_csn_int_d <= m_spi_csn_int_s; end @@ -272,7 +279,7 @@ assign end_of_word = (CPOL ^ CPHA) ? (spi_sclk_neg_counter == DATA_DLENGTH); initial begin - while(1) begin + forever begin @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_pos_counter <= 8'b0; @@ -283,7 +290,7 @@ initial begin end initial begin - while(1) begin + forever begin @(negedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_neg_counter <= 8'b0; @@ -295,7 +302,7 @@ end // SDI shift register initial begin - while(1) begin + forever begin // synchronization if (CPHA ^ CPOL) @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); @@ -347,7 +354,7 @@ bit [31:0] sdi_shiftreg_old; assign sdi_shiftreg2 = {1'b0, sdi_shiftreg[31:1]}; initial begin - while(1) begin + forever begin @(posedge ad463x_echo_sclk); sdi_data_store <= {sdi_shiftreg[27:0], 4'b0}; if (sdi_data_store == 'h0 && shiftreg_sampled == 'h1 && sdi_shiftreg != 'h0) begin @@ -430,7 +437,7 @@ end bit [31:0] offload_transfer_cnt; initial begin - while(1) begin + forever begin @(posedge shiftreg_sampled && offload_status); offload_transfer_cnt <= offload_transfer_cnt + 'h1; end @@ -446,14 +453,14 @@ bit [31:0] offload_captured_word_arr [(2 * NUM_OF_TRANSFERS) -1 :0]; task offload_spi_test(); //Configure DMA - env.mng.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*2)-1)); // X_LENGHTH = 1024-1 - env.mng.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - env.mng.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*2)-1)); // X_LENGHTH = 1024-1 + base_env.mng.master_sequencer.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`AD469X_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA // Configure the Offload module @@ -486,7 +493,7 @@ task offload_spi_test(); for (int i=0; i<=((2 * NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - offload_captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + offload_captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end if (irq_pending == 'h0) begin diff --git a/testbenches/project/ad57xx/Makefile b/testbenches/project/ad57xx/Makefile index 45db572c..15fd8b7e 100644 --- a/testbenches/project/ad57xx/Makefile +++ b/testbenches/project/ad57xx/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2024(c) Analog Devices, Inc. +## Copyright (C) 2024 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -19,13 +19,11 @@ SV_DEPS += ad57xx_environment.sv LIB_DEPS += axi_clkgen LIB_DEPS += axi_pwm_gen LIB_DEPS += axi_dmac -LIB_DEPS += axi_sysid LIB_DEPS += util_axis_fifo LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_engine_execution LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload -LIB_DEPS += sysid_rom SIM_LIB_DEPS += spi_vip diff --git a/testbenches/project/ad57xx/ad57xx_environment.sv b/testbenches/project/ad57xx/ad57xx_environment.sv index b30a885e..e5da6dae 100644 --- a/testbenches/project/ad57xx/ad57xx_environment.sv +++ b/testbenches/project/ad57xx/ad57xx_environment.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// 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 @@ -37,24 +37,16 @@ package ad57xx_environment_pkg; - import axi_vip_pkg::*; - import axi4stream_vip_pkg::*; - import m_axi_sequencer_pkg::*; - import s_axi_sequencer_pkg::*; - import s_spi_sequencer_pkg::*; + import logger_pkg::*; + import adi_environment_pkg::*; + import adi_spi_vip_pkg::*; - import test_harness_env_pkg::*; - import `PKGIFY(test_harness, mng_axi_vip)::*; - import `PKGIFY(test_harness, ddr_axi_vip)::*; - import `PKGIFY(test_harness, spi_s_vip)::*; + import adi_spi_vip_if_base_pkg::*; - class ad57xx_environment extends test_harness_env; + class ad57xx_environment extends adi_environment; // Agents - adi_spi_agent #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_agent; - - // Sequencers - s_spi_sequencer #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_seq; + adi_spi_agent spi_agent; //============================================================================ // Constructor @@ -62,30 +54,12 @@ package ad57xx_environment_pkg; function new( input string name, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(10)) sys_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(5)) dma_clk_vip_if, - virtual interface clk_vip_if #(.C_CLK_CLOCK_PERIOD(2.5)) ddr_clk_vip_if, - - virtual interface rst_vip_if #(.C_ASYNCHRONOUS(1), .C_RST_POLARITY(1)) sys_rst_vip_if, + adi_spi_vip_if_base spi_s_vip_if); - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, mng_axi_vip)) mng_vip_if, - virtual interface axi_vip_if #(`AXI_VIP_IF_PARAMS(test_harness, ddr_axi_vip)) ddr_vip_if, - virtual interface spi_vip_if #(`SPI_VIP_PARAMS(test_harness, spi_s_vip)) spi_s_vip_if - ); - - super.new(name, - sys_clk_vip_if, - dma_clk_vip_if, - ddr_clk_vip_if, - sys_rst_vip_if, - mng_vip_if, - ddr_vip_if); + super.new(name); // Creating the agents - spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); - - // Creating the sequencers - spi_seq = new("SPI VIP Sequencer", spi_agent, this); + this.spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); endfunction @@ -95,43 +69,14 @@ package ad57xx_environment_pkg; // - Start the agents //============================================================================ task start(); - super.start(); - spi_agent.start(); - endtask - - //============================================================================ - // Start the test - // - start the scoreboard - // - start the sequencers - //============================================================================ - task test(); - super.test(); - fork - - join_none - endtask - - //============================================================================ - // Post test subroutine - //============================================================================ - task post_test(); - super.post_test(); - endtask - - //============================================================================ - // Run subroutine - //============================================================================ - task run; - test(); - post_test(); + this.spi_agent.start(); endtask //============================================================================ // Stop subroutine //============================================================================ - task stop; - spi_agent.stop(); - super.stop(); + task stop(); + this.spi_agent.stop(); endtask endclass diff --git a/testbenches/project/ad57xx/system_bd.tcl b/testbenches/project/ad57xx/system_bd.tcl index 0fc21b31..20ec4742 100644 --- a/testbenches/project/ad57xx/system_bd.tcl +++ b/testbenches/project/ad57xx/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2024 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 diff --git a/testbenches/project/ad57xx/tests/test_program.sv b/testbenches/project/ad57xx/tests/test_program.sv index e1bdb3e1..debbfe11 100644 --- a/testbenches/project/ad57xx/tests/test_program.sv +++ b/testbenches/project/ad57xx/tests/test_program.sv @@ -35,6 +35,10 @@ `include "utils.svh" +import logger_pkg::*; +import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; +import ad57xx_environment_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import adi_regmap_pkg::*; @@ -42,11 +46,12 @@ import adi_regmap_clkgen_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; -import logger_pkg::*; -import ad57xx_environment_pkg::*; import spi_engine_instr_pkg::*; import adi_spi_vip_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- @@ -60,7 +65,12 @@ timeprecision 100ps; typedef enum {DATA_MODE_RANDOM, DATA_MODE_RAMP, DATA_MODE_PATTERN} offload_test_t; -ad57xx_environment env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + +ad57xx_environment spi_env; // -------------------------- // Wrapper function for AXI read verify @@ -68,13 +78,13 @@ ad57xx_environment env; task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -83,7 +93,7 @@ endtask task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -91,7 +101,7 @@ endtask // -------------------------- task spi_receive( output [`DATA_DLENGTH:0] data); - env.spi_seq.receive_data(data); + spi_env.spi_agent.sequencer.receive_data(data); endtask // -------------------------- @@ -99,14 +109,14 @@ endtask // -------------------------- task spi_send( input [`DATA_DLENGTH:0] data); - env.spi_seq.send_data(data); + spi_env.spi_agent.sequencer.send_data(data); endtask // -------------------------- // Wrapper function for waiting for all SPI // -------------------------- task spi_wait_send(); - env.spi_seq.flush_send(); + spi_env.spi_agent.sequencer.flush_send(); endtask @@ -117,21 +127,29 @@ endtask initial begin //creating environment - env = new("Axis Sequencers Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF, - `TH.`SPI_S.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) + + spi_env = new("SPI Environment", + `TH.`SPI_S.inst.IF.vif); setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.spi_seq.set_default_miso_data('h0); + base_env.start(); + spi_env.start(); + + spi_env.spi_agent.sequencer.set_default_miso_data('h0); - env.sys_reset(); + base_env.sys_reset(); sanity_test(); @@ -143,10 +161,11 @@ initial begin offload_spi_test(`TEST_DATA_MODE); - env.stop(); + spi_env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -268,21 +287,21 @@ task offload_spi_test( temp_data = {4'b0001,dac_word,2'b00}; sdo_write_data_store [i] = temp_data; - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(.addr(`DDR_BA + 4*i), + base_env.ddr.slave_sequencer.set_reg_data_in_mem(.addr(`DDR_BA + 4*i), .payload(temp_data), .strb('1)); spi_send('0); end //Configure TX DMA - env.mng.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); - env.mng.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); - env.mng.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_SRC_ADDRESS), `SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(`DDR_BA)); - env.mng.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_SRC_ADDRESS), `SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(`DDR_BA)); + base_env.mng.master_sequencer.RegWrite32(`SPI_ENGINE_TX_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Configure the Offload module axi_write (`SPI_ENGINE_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `INST_CFG); diff --git a/testbenches/project/ad57xx/waves/cfg1.wcfg b/testbenches/project/ad57xx/waves/cfg1.wcfg index ac78db12..7b6f8893 100644 --- a/testbenches/project/ad57xx/waves/cfg1.wcfg +++ b/testbenches/project/ad57xx/waves/cfg1.wcfg @@ -20,7 +20,7 @@ - + diff --git a/testbenches/project/ad738x/Makefile b/testbenches/project/ad738x/Makefile index a15dd306..8946fadb 100644 --- a/testbenches/project/ad738x/Makefile +++ b/testbenches/project/ad738x/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2021(c) Analog Devices, Inc. +## Copyright (C) 2021 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -18,12 +18,10 @@ LIB_DEPS += axi_clkgen LIB_DEPS += axi_dmac LIB_DEPS += axi_i2s_adi LIB_DEPS += axi_pwm_gen -LIB_DEPS += axi_sysid LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_engine_execution LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload -LIB_DEPS += sysid_rom LIB_DEPS += util_axis_upscale LIB_DEPS += util_pulse_gen diff --git a/testbenches/project/ad738x/system_bd.tcl b/testbenches/project/ad738x/system_bd.tcl index bdab458f..bb842441 100644 --- a/testbenches/project/ad738x/system_bd.tcl +++ b/testbenches/project/ad738x/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2024 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/ad738x/system_tb.sv b/testbenches/project/ad738x/system_tb.sv index b63b2f1b..667e6827 100644 --- a/testbenches/project/ad738x/system_tb.sv +++ b/testbenches/project/ad738x/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/ad738x/tests/test_program.sv b/testbenches/project/ad738x/tests/test_program.sv index 49ce5017..bf0ee60d 100644 --- a/testbenches/project/ad738x/tests/test_program.sv +++ b/testbenches/project/ad738x/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2024 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -46,6 +46,10 @@ import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -98,7 +102,10 @@ program test_program ( input ad738x_spi_cs); -test_harness_env env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -107,14 +114,14 @@ task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -124,7 +131,7 @@ task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -133,22 +140,22 @@ endtask initial begin //creating environment - env = new("AD738X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - #100 + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -160,10 +167,10 @@ initial begin offload_spi_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -250,7 +257,7 @@ end // Add an arbitrary delay to the echo_sclk signal initial begin - while(1) begin + forever begin @(posedge delay_clk) begin echo_delay_sclk <= {echo_delay_sclk, m_rx_sclk}; end @@ -259,7 +266,7 @@ end assign ad738x_echo_sclk = echo_delay_sclk[SDI_PHY_DELAY-1]; initial begin - while(1) begin + forever begin #0.5 delay_clk = ~delay_clk; end end @@ -280,7 +287,7 @@ bit [31:0] sdi_preg[$]; bit [31:0] sdi_nreg[$]; initial begin - while(1) begin + forever begin @(posedge ad738x_spi_clk); m_spi_csn_int_d <= m_spi_csn_int_s; end @@ -298,7 +305,7 @@ assign end_of_word = (CPOL ^ CPHA) ? (spi_sclk_neg_counter == DATA_DLENGTH); initial begin - while(1) begin + forever begin @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_pos_counter <= 8'b0; @@ -309,7 +316,7 @@ initial begin end initial begin - while(1) begin + forever begin @(negedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_neg_counter <= 8'b0; @@ -321,7 +328,7 @@ end // SDI shift register initial begin - while(1) begin + forever begin // synchronization if (CPHA ^ CPOL) @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); @@ -373,7 +380,7 @@ bit [31:0] sdi_shiftreg_old; assign sdi_shiftreg2 = {1'b0, sdi_shiftreg[31:1]}; initial begin - while(1) begin + forever begin @(posedge ad738x_echo_sclk); sdi_data_store <= {sdi_shiftreg[27:0], 4'b0}; if (sdi_data_store == 'h0 && shiftreg_sampled == 'h1 && sdi_shiftreg != 'h0) begin @@ -400,7 +407,7 @@ end bit [31:0] offload_transfer_cnt; initial begin - while(1) begin + forever begin @(posedge shiftreg_sampled && offload_status); offload_transfer_cnt <= offload_transfer_cnt + 'h1; end @@ -420,14 +427,14 @@ task offload_spi_test(); `INFO(("Axi_pwm_gen started"), ADI_VERBOSITY_LOW); //Configure DMA - env.mng.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*2)-1)); // X_LENGHTH = 1024-1 - env.mng.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - env.mng.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*2)-1)); // X_LENGHTH = 1024-1 + base_env.mng.master_sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA // Configure the Offload module axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CFG); @@ -455,7 +462,7 @@ task offload_spi_test(); for (int i=0; i<=((2* NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - offload_captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + offload_captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end if (offload_captured_word_arr [(2 * NUM_OF_TRANSFERS) - 1:2] != offload_sdi_data_store_arr [(2 * NUM_OF_TRANSFERS) - 1:2]) begin diff --git a/testbenches/project/ad7606x/Makefile b/testbenches/project/ad7606x/Makefile index 879ba8d2..3ee06a16 100755 --- a/testbenches/project/ad7606x/Makefile +++ b/testbenches/project/ad7606x/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2022 (c) Analog Devices, Inc. +## Copyright (C) 2022 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -26,8 +26,6 @@ LIB_DEPS += axi_hdmi_tx LIB_DEPS += axi_i2s_adi LIB_DEPS += axi_pwm_gen LIB_DEPS += axi_spdif_tx -LIB_DEPS += axi_sysid -LIB_DEPS += sysid_rom LIB_DEPS += util_i2c_mixer LIB_DEPS += util_pack/util_cpack2 LIB_DEPS += util_cdc diff --git a/testbenches/project/ad7606x/system_bd.tcl b/testbenches/project/ad7606x/system_bd.tcl index 46d20621..c0f8b635 100755 --- a/testbenches/project/ad7606x/system_bd.tcl +++ b/testbenches/project/ad7606x/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2022 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/ad7606x/system_tb.sv b/testbenches/project/ad7606x/system_tb.sv index db6083ae..bfbb0f8b 100755 --- a/testbenches/project/ad7606x/system_tb.sv +++ b/testbenches/project/ad7606x/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/ad7606x/tests/test_program_4ch.sv b/testbenches/project/ad7606x/tests/test_program_4ch.sv index 0bcedcfb..6f694cac 100755 --- a/testbenches/project/ad7606x/tests/test_program_4ch.sv +++ b/testbenches/project/ad7606x/tests/test_program_4ch.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -41,13 +41,17 @@ import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import adi_regmap_adc_pkg::*; import adi_regmap_common_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; -localparam SIMPLE_STATUS_CRC = 0; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +parameter SIMPLE_STATUS_CRC = 0; localparam CH0 = 8'h00 * 4; localparam CH1 = 8'h10 * 4; @@ -69,7 +73,10 @@ program test_program_4ch ( output rx_busy, output logic [2:0] adc_config_mode); - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -78,14 +85,14 @@ program test_program_4ch ( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -95,7 +102,7 @@ program test_program_4ch ( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -103,19 +110,23 @@ program test_program_4ch ( // -------------------------- initial begin - //creating environment - env = new("AD7606X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -133,10 +144,10 @@ program test_program_4ch ( #100 db_transmission_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end diff --git a/testbenches/project/ad7606x/tests/test_program_6ch.sv b/testbenches/project/ad7606x/tests/test_program_6ch.sv index 2613b3bc..cf60751d 100755 --- a/testbenches/project/ad7606x/tests/test_program_6ch.sv +++ b/testbenches/project/ad7606x/tests/test_program_6ch.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -41,13 +41,17 @@ import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import adi_regmap_adc_pkg::*; import adi_regmap_common_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; -localparam SIMPLE_STATUS_CRC = 0; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +parameter SIMPLE_STATUS_CRC = 0; localparam CH0 = 8'h00 * 4; localparam CH1 = 8'h10 * 4; @@ -71,7 +75,10 @@ program test_program_6ch ( output rx_busy, output logic [2:0] adc_config_mode); - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -80,14 +87,14 @@ program test_program_6ch ( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -97,7 +104,7 @@ program test_program_6ch ( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -105,19 +112,23 @@ program test_program_6ch ( // -------------------------- initial begin - //creating environment - env = new("AD7606X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -135,8 +146,10 @@ program test_program_6ch ( #100 db_transmission_test(); + base_env.stop(); + `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end diff --git a/testbenches/project/ad7606x/tests/test_program_8ch.sv b/testbenches/project/ad7606x/tests/test_program_8ch.sv index df553d99..c8240cd8 100755 --- a/testbenches/project/ad7606x/tests/test_program_8ch.sv +++ b/testbenches/project/ad7606x/tests/test_program_8ch.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -41,13 +41,17 @@ import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import adi_regmap_adc_pkg::*; import adi_regmap_common_pkg::*; import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; -localparam SIMPLE_STATUS_CRC = 0; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + +parameter SIMPLE_STATUS_CRC = 0; localparam CH0 = 8'h00 * 4; localparam CH1 = 8'h10 * 4; @@ -73,7 +77,10 @@ program test_program_8ch ( output rx_busy, output logic [2:0] adc_config_mode); - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -82,14 +89,14 @@ program test_program_8ch ( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -99,7 +106,7 @@ program test_program_8ch ( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -107,19 +114,23 @@ program test_program_8ch ( // -------------------------- initial begin - //creating environment - env = new("AD7606X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -137,8 +148,10 @@ program test_program_8ch ( #100 db_transmission_test(); + base_env.stop(); + `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end diff --git a/testbenches/project/ad7606x/tests/test_program_si.sv b/testbenches/project/ad7606x/tests/test_program_si.sv index fed5120c..571aed1d 100755 --- a/testbenches/project/ad7606x/tests/test_program_si.sv +++ b/testbenches/project/ad7606x/tests/test_program_si.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -46,6 +46,10 @@ import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -100,7 +104,10 @@ program test_program_si ( input rx_busy, output rx_cnvst_n); - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verify @@ -109,14 +116,14 @@ program test_program_si ( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -126,7 +133,7 @@ program test_program_si ( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -134,19 +141,23 @@ program test_program_si ( // -------------------------- initial begin - //creating environment - env = new("AD7606X Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + //creating environment + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - env.sys_reset(); + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -158,8 +169,10 @@ program test_program_si ( offload_spi_test(); + base_env.stop(); + `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -430,14 +443,14 @@ program test_program_si ( task offload_spi_test(); //Configure DMA - env.mng.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*`NUM_OF_SDI)-1)); // X_LENGHTH - env.mng.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - env.mng.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4*`NUM_OF_SDI)-1)); // X_LENGHTH + base_env.mng.master_sequencer.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`AD7606X_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA // Configure the Offload module axi_write (`SPI_AD7606_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CFG); @@ -466,7 +479,7 @@ program test_program_si ( for (int i=0; i<=((`NUM_OF_SDI * NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - offload_captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + offload_captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end if (offload_captured_word_arr != offload_sdi_data_store_arr) begin `ERROR(("Offload Test FAILED")); diff --git a/testbenches/project/ad7606x/waves/system_tb_behav.wcfg b/testbenches/project/ad7606x/waves/system_tb_behav.wcfg index b675d7af..5461ca48 100644 --- a/testbenches/project/ad7606x/waves/system_tb_behav.wcfg +++ b/testbenches/project/ad7606x/waves/system_tb_behav.wcfg @@ -17,7 +17,7 @@ - + diff --git a/testbenches/project/ad7616/Makefile b/testbenches/project/ad7616/Makefile index f9e4de96..2d6e09c4 100755 --- a/testbenches/project/ad7616/Makefile +++ b/testbenches/project/ad7616/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2022 (c) Analog Devices, Inc. +## Copyright (C) 2022 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -22,12 +22,10 @@ LIB_DEPS += axi_clkgen LIB_DEPS += axi_ad7616 LIB_DEPS += axi_pwm_gen LIB_DEPS += axi_dmac -LIB_DEPS += axi_sysid LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_engine_execution LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload -LIB_DEPS += sysid_rom # default test program TP := test_program_si diff --git a/testbenches/project/ad7616/cfgs/cfg_pi.tcl b/testbenches/project/ad7616/cfgs/cfg_pi.tcl index 49b70d8e..e447cce9 100755 --- a/testbenches/project/ad7616/cfgs/cfg_pi.tcl +++ b/testbenches/project/ad7616/cfgs/cfg_pi.tcl @@ -1,3 +1,3 @@ global ad_project_params -set ad_project_params(SER_PAR_N) 0 +set ad_project_params(INTF) 0 diff --git a/testbenches/project/ad7616/cfgs/cfg_si.tcl b/testbenches/project/ad7616/cfgs/cfg_si.tcl index ce97f85c..b1f2479c 100755 --- a/testbenches/project/ad7616/cfgs/cfg_si.tcl +++ b/testbenches/project/ad7616/cfgs/cfg_si.tcl @@ -1,3 +1,3 @@ global ad_project_params -set ad_project_params(SER_PAR_N) 1 +set ad_project_params(INTF) 1 diff --git a/testbenches/project/ad7616/system_bd.tcl b/testbenches/project/ad7616/system_bd.tcl index 5d5c5336..26c8695d 100755 --- a/testbenches/project/ad7616/system_bd.tcl +++ b/testbenches/project/ad7616/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2022 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # @@ -36,7 +36,7 @@ global ad_project_params # system level parameters -set SER_PAR_N $ad_project_params(SER_PAR_N) +set INTF $ad_project_params(INTF) adi_project_files [list \ "$ad_hdl_dir/library/common/ad_edge_detect.v" \ @@ -48,7 +48,7 @@ adi_project_files [list \ source $ad_hdl_dir/projects/ad7616_sdz/common/ad7616_bd.tcl -if {$SER_PAR_N == 1} { +if {$INTF == 1} { create_bd_port -dir O spi_clk create_bd_port -dir O ad7616_irq @@ -63,8 +63,6 @@ if {$SER_PAR_N == 1} { } else { create_bd_port -dir O sys_clk - ad_disconnect spi_clk ad7616_pwm_gen/ext_clk - ad_connect sys_cpu_clk ad7616_pwm_gen/ext_clk ad_connect sys_clk sys_cpu_clk set BA_AD7616 0x44A80000 @@ -80,7 +78,3 @@ adi_sim_add_define "AD7616_DMA_BA=[format "%d" ${BA_DMA}]" set BA_PWM 0x44B00000 set_property offset $BA_PWM [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_ad7616_pwm_gen}] adi_sim_add_define "AD7616_PWM_GEN_BA=[format "%d" ${BA_PWM}]" - -set BA_CLKGEN 0x44A70000 -set_property offset $BA_CLKGEN [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_spi_clkgen}] -adi_sim_add_define "AD7616_AXI_CLKGEN_BA=[format "%d" ${BA_CLKGEN}]" diff --git a/testbenches/project/ad7616/system_project.tcl b/testbenches/project/ad7616/system_project.tcl index 931ccbf7..378c3ba9 100755 --- a/testbenches/project/ad7616/system_project.tcl +++ b/testbenches/project/ad7616/system_project.tcl @@ -16,12 +16,12 @@ set project_name [file rootname $cfg_file] # Set project params global ad_project_params -set SER_PAR_N $ad_project_params(SER_PAR_N) +set INTF $ad_project_params(INTF) #set a default test program -if {$SER_PAR_N == 1} { +if {$INTF == 1} { adi_sim_add_define "TEST_PROGRAM=test_program_si" -} elseif {$SER_PAR_N == 0} { +} elseif {$INTF == 0} { adi_sim_add_define "TEST_PROGRAM=test_program_pi" } else { adi_sim_add_define "TEST_PROGRAM=test_program_si" diff --git a/testbenches/project/ad7616/system_tb.sv b/testbenches/project/ad7616/system_tb.sv index 8d4d43c6..21f79533 100755 --- a/testbenches/project/ad7616/system_tb.sv +++ b/testbenches/project/ad7616/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -39,7 +39,7 @@ module system_tb(); generate - if (`SER_PAR_N == 1) begin //serial interface + if (`INTF == 1) begin //serial interface wire ad7616_spi_sclk; wire ad7616_spi_sdo; wire [1:0] ad7616_spi_sdi; diff --git a/testbenches/project/ad7616/tests/test_program_pi.sv b/testbenches/project/ad7616/tests/test_program_pi.sv index 3fa69e9c..31d14c82 100755 --- a/testbenches/project/ad7616/tests/test_program_pi.sv +++ b/testbenches/project/ad7616/tests/test_program_pi.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -46,6 +46,10 @@ import adi_regmap_dmac_pkg::*; import adi_regmap_pwm_gen_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; localparam AD7616_CTRL_RESETN = 1; localparam AD7616_CTRL_CNVST_EN = 2; @@ -61,7 +65,10 @@ program test_program_pi ( input sys_clk, input rx_busy); -test_harness_env env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -70,14 +77,14 @@ task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -87,7 +94,7 @@ task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -96,22 +103,22 @@ endtask initial begin //creating environment - env = new("AD7616 Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - #100 + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -119,10 +126,10 @@ initial begin data_acquisition_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -138,7 +145,7 @@ bit transfer_status = 0; assign rx_db_i = tx_data_buf; initial begin - while(1) begin + forever begin @(posedge sys_clk); rx_rd_n_tmp <= rx_rd_n; fork @@ -151,7 +158,7 @@ assign rx_rd_n_negedge_s = ~rx_rd_n & rx_rd_n_d; assign rx_rd_n_posedge_s = rx_rd_n & ~rx_rd_n_d; initial begin - while(1) begin + forever begin @(negedge rx_rd_n); tx_data_buf <= tx_data_buf + 16'h0808; if (transfer_status) @@ -180,7 +187,7 @@ endtask //--------------------------------------------------------------------------- initial begin - while(1) begin + forever begin @(posedge rx_rd_n); if (transfer_status) transfer_cnt <= transfer_cnt + 'h1; @@ -197,12 +204,6 @@ bit [31:0] captured_word_arr [(NUM_OF_TRANSFERS) -1 :0]; task data_acquisition_test(); - // Start spi clk generator - axi_write (`AD7616_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); - // Configure pwm gen axi_write (`AD7616_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_RSTN), `SET_AXI_PWM_GEN_REG_RSTN_RESET(1)); // PWM_GEN reset in regmap (ACTIVE HIGH) axi_write (`AD7616_PWM_GEN_BA + GetAddrs(AXI_PWM_GEN_REG_PULSE_X_PERIOD), `SET_AXI_PWM_GEN_REG_PULSE_X_PERIOD_PULSE_X_PERIOD('h64)); // set PWM period @@ -210,13 +211,13 @@ task data_acquisition_test(); `INFO(("Axi_pwm_gen started"), ADI_VERBOSITY_LOW); // Configure DMA - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS // Configure AXI_AD7616 axi_write (`AXI_AD7616_BA + GetAddrs(AXI_AD7616_REG_UP_CNTRL), @@ -233,7 +234,7 @@ task data_acquisition_test(); transfer_status = 1; - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA wait(transfer_cnt == 2 * NUM_OF_TRANSFERS ); @@ -254,10 +255,12 @@ task data_acquisition_test(); for (int i=0; i<=((NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end - if (captured_word_arr != dma_data_store_arr) begin + `INFO(("captured_word_arr: %x; dma_data_store_arr %x", captured_word_arr, dma_data_store_arr), ADI_VERBOSITY_LOW); + + if (captured_word_arr != dma_data_store_arr) begin `ERROR(("Data Acquisition Test FAILED")); end else begin `INFO(("Data Acquisition Test PASSED"), ADI_VERBOSITY_LOW); diff --git a/testbenches/project/ad7616/tests/test_program_si.sv b/testbenches/project/ad7616/tests/test_program_si.sv index 4f8cf554..143a74e1 100755 --- a/testbenches/project/ad7616/tests/test_program_si.sv +++ b/testbenches/project/ad7616/tests/test_program_si.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2022 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2022 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -46,6 +46,10 @@ import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -101,7 +105,10 @@ program test_program_si ( output rx_busy); -test_harness_env env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verif @@ -110,14 +117,14 @@ task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -127,7 +134,7 @@ task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -136,22 +143,22 @@ endtask initial begin //creating environment - env = new("AD7616 Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - #100 + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -163,10 +170,10 @@ initial begin offload_spi_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -253,7 +260,7 @@ end // Add an arbitrary delay to the echo_sclk signal initial begin - while(1) begin + forever begin @(posedge delay_clk) begin echo_delay_sclk <= {echo_delay_sclk, m_rx_sclk}; end @@ -262,7 +269,7 @@ end assign ad7616_echo_sclk = echo_delay_sclk[SDI_PHY_DELAY-1]; initial begin - while(1) begin + forever begin #0.5 delay_clk = ~delay_clk; end end @@ -284,7 +291,7 @@ bit [31:0] sdi_preg[$]; bit [31:0] sdi_nreg[$]; initial begin - while(1) begin + forever begin @(posedge spi_clk); m_spi_csn_int_d <= m_spi_csn_int_s; end @@ -300,7 +307,7 @@ assign end_of_word = (CPOL ^ CPHA) ? (rx_sclk_neg_counter == 16); initial begin - while(1) begin + forever begin @(posedge rx_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin rx_sclk_pos_counter <= 8'b0; @@ -311,7 +318,7 @@ initial begin end initial begin - while(1) begin + forever begin @(negedge rx_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin rx_sclk_neg_counter <= 8'b0; @@ -323,7 +330,7 @@ end // SDI shift register initial begin - while(1) begin + forever begin // synchronization if (CPHA ^ CPOL) @(posedge rx_sclk_bfm or posedge m_spi_csn_negedge_s); @@ -372,7 +379,7 @@ bit [31:0] sdi_fifo_data_store; bit [31:0] sdi_data_store; initial begin - while(1) begin + forever begin @(posedge rx_sclk_bfm); sdi_data_store <= {sdi_shiftreg[13:0], 2'b00}; if (sdi_data_store == 'h0 && shiftreg_sampled == 'h1 && sdi_shiftreg != 'h0) begin @@ -400,7 +407,7 @@ end bit [31:0] offload_transfer_cnt; initial begin - while(1) begin + forever begin @(posedge shiftreg_sampled && offload_status); offload_transfer_cnt <= offload_transfer_cnt + 'h1; end @@ -420,14 +427,14 @@ task offload_spi_test(); `INFO(("Axi_pwm_gen started"), ADI_VERBOSITY_LOW); //Configure DMA - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - env.mng.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`AD7616_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA // Configure the Offload module axi_write (`SPI_AD7616_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CFG); @@ -456,7 +463,7 @@ task offload_spi_test(); for (int i=0; i<=((NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - offload_captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + offload_captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end if (offload_captured_word_arr [(NUM_OF_TRANSFERS) - 1:2] != offload_sdi_data_store_arr [(NUM_OF_TRANSFERS) - 1:2]) begin @@ -473,12 +480,6 @@ endtask bit [31:0] sdi_fifo_data = 0; task fifo_spi_test(); - // Start spi clk generator - axi_write (`AD7616_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); - // Enable SPI Engine axi_write (`SPI_AD7616_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); diff --git a/testbenches/project/ad7616/waves/cfg_pi.wcfg b/testbenches/project/ad7616/waves/cfg_pi.wcfg index 74cfc7aa..9e48c1fc 100644 --- a/testbenches/project/ad7616/waves/cfg_pi.wcfg +++ b/testbenches/project/ad7616/waves/cfg_pi.wcfg @@ -12,7 +12,7 @@ - + diff --git a/testbenches/project/ad7616/waves/cfg_si.wcfg b/testbenches/project/ad7616/waves/cfg_si.wcfg index 31026027..22e7c6b7 100644 --- a/testbenches/project/ad7616/waves/cfg_si.wcfg +++ b/testbenches/project/ad7616/waves/cfg_si.wcfg @@ -12,7 +12,7 @@ - + diff --git a/testbenches/project/ad9083/Makefile b/testbenches/project/ad9083/Makefile index 79078678..8d54f115 100644 --- a/testbenches/project/ad9083/Makefile +++ b/testbenches/project/ad9083/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -29,8 +29,6 @@ LIB_DEPS += util_pack/util_upack2 LIB_DEPS += util_pack/util_cpack2 LIB_DEPS += xilinx/axi_adxcvr LIB_DEPS += xilinx/util_adxcvr -LIB_DEPS += axi_sysid -LIB_DEPS += sysid_rom # default test program TP := test_program diff --git a/testbenches/project/ad9083/system_bd.tcl b/testbenches/project/ad9083/system_bd.tcl index 7b199bb6..c978ab69 100644 --- a/testbenches/project/ad9083/system_bd.tcl +++ b/testbenches/project/ad9083/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/ad9083/system_tb.sv b/testbenches/project/ad9083/system_tb.sv index 29d4246f..e95c19ab 100644 --- a/testbenches/project/ad9083/system_tb.sv +++ b/testbenches/project/ad9083/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/ad9083/tests/test_program.sv b/testbenches/project/ad9083/tests/test_program.sv index 4b089441..5bce0d52 100644 --- a/testbenches/project/ad9083/tests/test_program.sv +++ b/testbenches/project/ad9083/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,18 +26,17 @@ // // 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/master/LICENSE_ADIBSD +// 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" import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; @@ -52,11 +51,19 @@ import adi_regmap_xcvr_pkg::*; import adi_jesd204_pkg::*; import adi_xcvr_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + parameter RX_OUT_BYTES = 8; parameter TX_OUT_BYTES = 8; + program test_program; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + bit [31:0] val; int link_clk_freq; int device_clk_freq; @@ -70,22 +77,21 @@ program test_program; initial begin //creating environment - env = new("AD9083 Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - #2ps; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); - setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) - `TH.`SYS_CLK.inst.IF.start_clock; - `TH.`DMA_CLK.inst.IF.start_clock; - `TH.`DDR_CLK.inst.IF.start_clock; + setLoggerVerbosity(ADI_VERBOSITY_NONE); + + base_env.start(); link_clk_freq = lane_rate/40; data_path_width = 4; @@ -97,18 +103,12 @@ program test_program; `TH.`DEVICE_CLK.inst.IF.set_clk_frq(.user_frequency(device_clk_freq)); `TH.`SYSREF_CLK.inst.IF.set_clk_frq(.user_frequency(sysref_freq)); - `TH.`DRP_CLK.inst.IF.start_clock; - `TH.`REF_CLK.inst.IF.start_clock; - `TH.`DEVICE_CLK.inst.IF.start_clock; - `TH.`SYSREF_CLK.inst.IF.start_clock; - - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; + `TH.`DRP_CLK.inst.IF.start_clock(); + `TH.`REF_CLK.inst.IF.start_clock(); + `TH.`DEVICE_CLK.inst.IF.start_clock(); + `TH.`SYSREF_CLK.inst.IF.start_clock(); - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - - #1us; + base_env.sys_reset(); // ------------------------------------------------------- // Test DDS path @@ -118,29 +118,29 @@ program test_program; // // Enable Rx channel - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), `SET_ADC_CHANNEL_REG_CHAN_CNTRL_ENABLE(1)); // Select DDS as source - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(0)); // Configure tone amplitude and frequency - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_1), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_1_DDS_SCALE_1(32'h00000fff)); - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_2), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_2_DDS_INIT_1(16'h0000)| `SET_DAC_CHANNEL_REG_CHAN_CNTRL_2_DDS_INCR_1(16'h0100)); // Pull out TPL cores from reset - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), `SET_DAC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_DAC_COMMON_REG_RSTN_RSTN(1)); - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), `SET_ADC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_ADC_COMMON_REG_RSTN_RSTN(1)); // Sync DDS cores - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_CNTRL_1), `SET_DAC_COMMON_REG_CNTRL_1_SYNC(1)); // @@ -148,25 +148,25 @@ program test_program; // //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(1)); //SYSREFCONF - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_CONF), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_CONF), `SET_JESD_TX_SYSREF_CONF_SYSREF_DISABLE(0)); // Enable SYSREF handling //CONF0 - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF0), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF0), `SET_JESD_TX_LINK_CONF0_OCTETS_PER_FRAME(`TX_JESD_F-1)| `SET_JESD_TX_LINK_CONF0_OCTETS_PER_MULTIFRAME(`TX_JESD_F*`TX_JESD_K-1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF4), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF4), `SET_JESD_TX_LINK_CONF4_TPL_BEATS_PER_MULTIFRAME((`TX_JESD_F*`TX_JESD_K)/TX_OUT_BYTES-1)); //CONF1 - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF1), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_CONF1), `SET_JESD_TX_LINK_CONF1_SCRAMBLER_DISABLE(0)); // Scrambler enable //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(0)); // @@ -174,39 +174,39 @@ program test_program; // //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(1)); //SYSREFCONF - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_CONF), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_CONF), `SET_JESD_RX_SYSREF_CONF_SYSREF_DISABLE(0)); // Enable SYSREF handling //CONF0 - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF0), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF0), `SET_JESD_RX_LINK_CONF0_OCTETS_PER_FRAME(`RX_JESD_F-1)| `SET_JESD_RX_LINK_CONF0_OCTETS_PER_MULTIFRAME(`RX_JESD_F*`RX_JESD_K-1)); - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF4), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF4), `SET_JESD_RX_LINK_CONF4_TPL_BEATS_PER_MULTIFRAME((`RX_JESD_F*`RX_JESD_K)/RX_OUT_BYTES-1)); // Beats per multiframe //CONF1 - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF1), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_CONF1), `SET_JESD_RX_LINK_CONF1_DESCRAMBLER_DISABLE(0)); // Scrambler enable //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(0)); //XCVR INIT //REG CTRL - env.mng.RegWrite32(`RX_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`RX_XCVR_BA + GetAddrs(XCVR_CONTROL), `SET_XCVR_CONTROL_LPM_DFE_N(1)| `SET_XCVR_CONTROL_OUTCLK_SEL(4)); // RXOUTCLK uses DIV2 - env.mng.RegWrite32(`TX_XCVR_BA + GetAddrs(XCVR_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`TX_XCVR_BA + GetAddrs(XCVR_CONTROL), `SET_XCVR_CONTROL_LPM_DFE_N(1)| `SET_XCVR_CONTROL_OUTCLK_SEL(4)); // TXOUTCLK uses DIV2 - env.mng.RegWrite32(`RX_XCVR_BA + GetAddrs(XCVR_RESETN), + base_env.mng.master_sequencer.RegWrite32(`RX_XCVR_BA + GetAddrs(XCVR_RESETN), `SET_XCVR_RESETN_RESETN(1)); - env.mng.RegWrite32(`TX_XCVR_BA + GetAddrs(XCVR_RESETN), + base_env.mng.master_sequencer.RegWrite32(`TX_XCVR_BA + GetAddrs(XCVR_RESETN), `SET_XCVR_RESETN_RESETN(1)); // Give time the PLLs to lock @@ -214,22 +214,22 @@ program test_program; //Read status back // Check SYSREF_STATUS - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); // Check if in DATA state and SYNC is 1 - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_STATUS), `SET_JESD_RX_LINK_STATUS_STATUS_STATE(3)); - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_STATUS), `SET_JESD_TX_LINK_STATUS_STATUS_SYNC(1)| `SET_JESD_TX_LINK_STATUS_STATUS_STATE(3)); //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(1)); // ------------------------------------------------------- @@ -240,85 +240,85 @@ program test_program; // .step (1), // .max_sample(2048) for (int i=0;i<2048*2 ;i=i+2) begin - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BA+i*2,(((i+1)) << 16) | i ,15); + base_env.ddr.slave_sequencer.set_reg_data_in_mem(xil_axi_uint'(`DDR_BA+i*2),(((i+1)) << 16) | i ,15); end #5us; // Reset TPL cores - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), `SET_DAC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_DAC_COMMON_REG_RSTN_RSTN(0)); - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), `SET_ADC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_ADC_COMMON_REG_RSTN_RSTN(0)); // Pull out TPL cores from reset - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_COMMON_REG_RSTN), `SET_DAC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_DAC_COMMON_REG_RSTN_RSTN(1)); - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_COMMON_REG_RSTN), `SET_ADC_COMMON_REG_RSTN_MMCM_RSTN(1)| `SET_ADC_COMMON_REG_RSTN_RSTN(1)); // Configure Transport Layer for DMA - env.mng.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), + base_env.mng.master_sequencer.RegWrite32(`DAC_TPL_BA + GetAddrs(DAC_CHANNEL_REG_CHAN_CNTRL_7), `SET_DAC_CHANNEL_REG_CHAN_CNTRL_7_DAC_DDS_SEL(2)); #1us; // Configure TX DMA - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_CYCLIC(0)| `SET_DMAC_FLAGS_TLAST(1)); // use TLAST, disable CYCLIC - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_X_LENGTH), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(32'h000003DF)); // X_LENGTH = 992-1 - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_SRC_ADDRESS), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_SRC_ADDRESS), `SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(`DDR_BA)); // SRC_ADDRESS - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer // Configure RX DMA - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_CYCLIC(0)| `SET_DMAC_FLAGS_TLAST(1)); // use TLAST, disable CYCLIC - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_X_LENGTH), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(32'h000003DF)); // X_LENGTH = 992-1 - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_DEST_ADDRESS), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA+32'h00001000)); // DEST_ADDRESS - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(0)); #25us; //Read status back // Check SYSREF_STATUS - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_SYSREF_STATUS), `SET_JESD_RX_SYSREF_STATUS_SYSREF_DETECTED(1)); - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_SYSREF_STATUS), `SET_JESD_TX_SYSREF_STATUS_SYSREF_DETECTED(1)); #1us; // Check if in DATA state and SYNC is 1 - env.mng.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_STATUS), `SET_JESD_RX_LINK_STATUS_STATUS_STATE(3)); - env.mng.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_STATUS), + base_env.mng.master_sequencer.RegReadVerify32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_STATUS), `SET_JESD_TX_LINK_STATUS_STATUS_SYNC(1)| `SET_JESD_TX_LINK_STATUS_STATUS_STATE(3)); #5us; - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), `SET_ADC_CHANNEL_REG_CHAN_CNTRL_ENABLE(0)); #5us; @@ -331,45 +331,45 @@ program test_program; //LINK DISABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(1)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(1)); - env.mng.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), + base_env.mng.master_sequencer.RegWrite32(`ADC_TPL_BA + GetAddrs(ADC_CHANNEL_REG_CHAN_CNTRL), `SET_ADC_CHANNEL_REG_CHAN_CNTRL_ENABLE(1)); #5us; // Configure TX DMA - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_CYCLIC(0)| `SET_DMAC_FLAGS_TLAST(1)); // use TLAST, disable CYCLIC - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_X_LENGTH), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(32'h000003DF)); // X_LENGTH = 992-1 - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_SRC_ADDRESS), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_SRC_ADDRESS), `SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(`DDR_BA)); // SRC_ADDRESS - env.mng.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), + base_env.mng.master_sequencer.RegWrite32(`TX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer // Configure RX DMA - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_CONTROL), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_CYCLIC(0)| `SET_DMAC_FLAGS_TLAST(1)); // use TLAST, disable CYCLIC - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_X_LENGTH), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH(32'h000003DF)); // X_LENGTH = 992-1 - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_DEST_ADDRESS), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA+32'h00002000)); // DEST_ADDRESS - env.mng.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), + base_env.mng.master_sequencer.RegWrite32(`RX_DMA_BA+GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA //LINK ENABLE - env.mng.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_RX_BA + GetAddrs(JESD_RX_LINK_DISABLE), `SET_JESD_RX_LINK_DISABLE_LINK_DISABLE(0)); - env.mng.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), + base_env.mng.master_sequencer.RegWrite32(`AXI_JESD_TX_BA + GetAddrs(JESD_TX_LINK_DISABLE), `SET_JESD_TX_LINK_DISABLE_LINK_DISABLE(0)); #10us; @@ -380,11 +380,16 @@ program test_program; .step (1), .max_sample(496) ); + + base_env.stop(); - env.stop(); + `TH.`DRP_CLK.inst.IF.stop_clock(); + `TH.`REF_CLK.inst.IF.stop_clock(); + `TH.`DEVICE_CLK.inst.IF.stop_clock(); + `TH.`SYSREF_CLK.inst.IF.stop_clock(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -403,7 +408,7 @@ program test_program; for (int i=0;i - + @@ -19,7 +19,7 @@ - + diff --git a/testbenches/project/fmcomms2/Makefile b/testbenches/project/fmcomms2/Makefile index 7e64b79b..e3dd8868 100644 --- a/testbenches/project/fmcomms2/Makefile +++ b/testbenches/project/fmcomms2/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2018(c) Analog Devices, Inc. +## Copyright (C) 2018 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -16,8 +16,6 @@ SV_DEPS += $(TB_LIBRARY_PATH)/regmaps/adi_regmap_common_pkg.sv LIB_DEPS += axi_ad9361 LIB_DEPS += axi_dmac -LIB_DEPS += axi_sysid -LIB_DEPS += sysid_rom LIB_DEPS += util_pack/util_cpack2 LIB_DEPS += util_pack/util_upack2 LIB_DEPS += util_rfifo diff --git a/testbenches/project/fmcomms2/system_bd.tcl b/testbenches/project/fmcomms2/system_bd.tcl index 1fdd39b0..07429f7d 100644 --- a/testbenches/project/fmcomms2/system_bd.tcl +++ b/testbenches/project/fmcomms2/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2018 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/fmcomms2/system_tb.sv b/testbenches/project/fmcomms2/system_tb.sv index 1d23bbed..af75692e 100644 --- a/testbenches/project/fmcomms2/system_tb.sv +++ b/testbenches/project/fmcomms2/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2018 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/fmcomms2/tests/test_program.sv b/testbenches/project/fmcomms2/tests/test_program.sv index 137b92b0..d9b10825 100644 --- a/testbenches/project/fmcomms2/tests/test_program.sv +++ b/testbenches/project/fmcomms2/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014 - 2023 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 @@ -26,18 +26,17 @@ // // 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/master/LICENSE_ADIBSD +// 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" import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import adi_regmap_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; @@ -47,6 +46,9 @@ import adi_regmap_dac_pkg::*; import adi_regmap_adc_pkg::*; import adi_regmap_common_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + program test_program; parameter R1_MODE = 0; @@ -66,8 +68,11 @@ program test_program; parameter TDD1 = `AXI_AD9361_BA + 'h12_00 * 4; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; - test_harness_env env; bit [31:0] val; // -------------------------- @@ -77,7 +82,7 @@ program test_program; input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask // -------------------------- @@ -87,7 +92,7 @@ program test_program; input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask integer rate; @@ -101,29 +106,28 @@ program test_program; initial begin //creating environment - env = new("FMCOMMS2 Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); - #2ps; + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + + base_env.start(); //set source synchronous interface clock frequency `TH.`SSI_CLK.inst.IF.set_clk_frq(.user_frequency(80000000)); - `TH.`SSI_CLK.inst.IF.start_clock; + `TH.`SSI_CLK.inst.IF.start_clock(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; + base_env.sys_reset(); - #1us; // This is required since the AD9361 interface always requires to receive // something first before transmitting. This is not possible in loopback mode. force system_tb.test_harness.axi_ad9361.inst.i_tx.dac_sync_enable = 1'b1; @@ -136,10 +140,11 @@ program test_program; dma_test(); - env.stop(); + base_env.stop(); + `TH.`SSI_CLK.inst.IF.stop_clock(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -357,7 +362,7 @@ program test_program; // Init test data for (int i=0;i<2048*2 ;i=i+2) begin - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BA+i*2,(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361_BA + base_env.ddr.slave_sequencer.set_reg_data_in_mem(xil_axi_uint'(`DDR_BA+i*2),(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361_BA end // Configure TX DMA @@ -465,7 +470,7 @@ program test_program; for (int i=0;i - + @@ -21,7 +21,7 @@ - + diff --git a/testbenches/project/pluto/system_bd.tcl b/testbenches/project/pluto/system_bd.tcl index 89a966c9..f2b1add1 100644 --- a/testbenches/project/pluto/system_bd.tcl +++ b/testbenches/project/pluto/system_bd.tcl @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/pluto/system_tb.sv b/testbenches/project/pluto/system_tb.sv index 9d80b90f..653a1155 100644 --- a/testbenches/project/pluto/system_tb.sv +++ b/testbenches/project/pluto/system_tb.sv @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/pluto/tests/test_program.sv b/testbenches/project/pluto/tests/test_program.sv index 19414756..e2095ccf 100644 --- a/testbenches/project/pluto/tests/test_program.sv +++ b/testbenches/project/pluto/tests/test_program.sv @@ -26,18 +26,17 @@ // // 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/master/LICENSE_ADIBSD +// 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" import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; import axi_vip_pkg::*; import axi4stream_vip_pkg::*; import logger_pkg::*; @@ -48,6 +47,9 @@ import adi_regmap_adc_pkg::*; import adi_regmap_common_pkg::*; import adi_regmap_tdd_gen_pkg::*; +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; + program test_program; localparam CH0 = 8'h00; @@ -61,7 +63,11 @@ program test_program; localparam TX1_CHANNEL = `AXI_AD9361_BA + 'h4000; localparam TDD1 = `AXI_AD9361_BA + 'h8000; - test_harness_env env; + test_harness_env base_env; + + adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; + adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; + bit [31:0] val = 32'h0; int r1_mode, rate; @@ -72,7 +78,7 @@ program test_program; input [31:0] raddr, output [31:0] rdata); - env.mng.RegRead32(raddr,rdata); + base_env.mng.master_sequencer.RegRead32(raddr,rdata); endtask // -------------------------- @@ -82,7 +88,7 @@ program test_program; input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask // -------------------------- @@ -92,7 +98,7 @@ program test_program; input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -101,25 +107,27 @@ program test_program; initial begin // Creating environment - env = new("Pluto Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); - #2ps; + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); + base_env.start(); // Set source synchronous interface clock frequency `TH.`SSI_CLK.inst.IF.set_clk_frq(.user_frequency(61440000)); - `TH.`SSI_CLK.inst.IF.start_clock; + `TH.`SSI_CLK.inst.IF.start_clock(); // Initial system reset - env.sys_reset(); + base_env.sys_reset(); // This is required since the AD9361 interface always requires to receive // something first before transmitting. This is not possible in loopback mode. @@ -147,10 +155,11 @@ program test_program; tdd_test(); - env.stop(); + base_env.stop(); + `TH.`SSI_CLK.inst.IF.stop_clock(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -375,7 +384,7 @@ program test_program; // Init test data for (int i=0;i<2048*2 ;i=i+2) begin - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BA+i*2,(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361 + base_env.ddr.slave_sequencer.set_reg_data_in_mem(xil_axi_uint'(`DDR_BA+i*2),(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361 end // Configure TX DMA @@ -484,7 +493,7 @@ program test_program; // Init test data for (int i=0;i<2048*2 ;i=i+2) begin - env.ddr_axi_agent.mem_model.backdoor_memory_write_4byte(`DDR_BA+i*2,(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361 + base_env.ddr.slave_sequencer.set_reg_data_in_mem(xil_axi_uint'(`DDR_BA+i*2),(((i+1)<<4) << 16) | i<<4 ,15); // (<< 4) - 4 LSBs are dropped in the AXI_AD9361 end link_setup(); @@ -640,7 +649,7 @@ program test_program; for (int i=0;i - + diff --git a/testbenches/project/pulsar_adc_pmdz/Makefile b/testbenches/project/pulsar_adc_pmdz/Makefile index ffaeb4e1..3dfa2edf 100755 --- a/testbenches/project/pulsar_adc_pmdz/Makefile +++ b/testbenches/project/pulsar_adc_pmdz/Makefile @@ -1,6 +1,6 @@ #################################################################################### #################################################################################### -## Copyright 2021(c) Analog Devices, Inc. +## Copyright (C) 2021 Analog Devices, Inc. #################################################################################### #################################################################################### @@ -20,7 +20,6 @@ ENV_DEPS += $(HDL_LIBRARY_PATH)/common/ad_edge_detect.v LIB_DEPS += axi_clkgen LIB_DEPS += axi_pwm_gen LIB_DEPS += axi_dmac -LIB_DEPS += axi_sysid LIB_DEPS += util_cdc LIB_DEPS += util_axis_fifo LIB_DEPS += axi_pulsar_lvds @@ -28,7 +27,6 @@ LIB_DEPS += spi_engine/axi_spi_engine LIB_DEPS += spi_engine/spi_engine_execution LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload -LIB_DEPS += sysid_rom # default test programs # Format is: diff --git a/testbenches/project/pulsar_adc_pmdz/spi_engine.svh b/testbenches/project/pulsar_adc_pmdz/spi_engine.svh index 5d6096e0..beb517bc 100644 --- a/testbenches/project/pulsar_adc_pmdz/spi_engine.svh +++ b/testbenches/project/pulsar_adc_pmdz/spi_engine.svh @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/pulsar_adc_pmdz/system_bd.tcl b/testbenches/project/pulsar_adc_pmdz/system_bd.tcl index 64517339..40e64e4d 100755 --- a/testbenches/project/pulsar_adc_pmdz/system_bd.tcl +++ b/testbenches/project/pulsar_adc_pmdz/system_bd.tcl @@ -1,6 +1,6 @@ # *************************************************************************** # *************************************************************************** -# Copyright 2021 (c) Analog Devices, Inc. All rights reserved. +# Copyright (C) 2021 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 @@ -26,7 +26,7 @@ # # 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/master/LICENSE_ADIBSD +# 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. # diff --git a/testbenches/project/pulsar_adc_pmdz/system_tb.sv b/testbenches/project/pulsar_adc_pmdz/system_tb.sv index 3b05f965..646f19d2 100755 --- a/testbenches/project/pulsar_adc_pmdz/system_tb.sv +++ b/testbenches/project/pulsar_adc_pmdz/system_tb.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2021 - 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2021 - 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // diff --git a/testbenches/project/pulsar_adc_pmdz/tests/test_program.sv b/testbenches/project/pulsar_adc_pmdz/tests/test_program.sv index d652b53c..8969f9eb 100755 --- a/testbenches/project/pulsar_adc_pmdz/tests/test_program.sv +++ b/testbenches/project/pulsar_adc_pmdz/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2021 - 2023 (c) Analog Devices, Inc. All rights reserved. +// Copyright (C) 2021 - 2023 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 @@ -26,7 +26,7 @@ // // 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/master/LICENSE_ADIBSD +// 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. // @@ -47,6 +47,10 @@ import adi_regmap_pwm_gen_pkg::*; import adi_regmap_spi_engine_pkg::*; import logger_pkg::*; import test_harness_env_pkg::*; +import adi_axi_agent_pkg::*; + +import `PKGIFY(test_harness, mng_axi_vip)::*; +import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters @@ -98,7 +102,10 @@ program test_program ( input pulsar_adc_spi_clk, input [(`NUM_OF_SDI - 1):0] pulsar_adc_spi_sdi); -test_harness_env env; +test_harness_env base_env; + +adi_axi_master_agent #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip)) mng; +adi_axi_slave_mem_agent #(`AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) ddr; // -------------------------- // Wrapper function for AXI read verify @@ -107,14 +114,14 @@ task axi_read_v( input [31:0] raddr, input [31:0] vdata); - env.mng.RegReadVerify32(raddr,vdata); + base_env.mng.master_sequencer.RegReadVerify32(raddr,vdata); endtask task axi_read( input [31:0] raddr, output [31:0] data); - env.mng.RegRead32(raddr,data); + base_env.mng.master_sequencer.RegRead32(raddr,data); endtask // -------------------------- @@ -124,7 +131,7 @@ task axi_write( input [31:0] waddr, input [31:0] wdata); - env.mng.RegWrite32(waddr,wdata); + base_env.mng.master_sequencer.RegWrite32(waddr,wdata); endtask // -------------------------- @@ -133,22 +140,22 @@ endtask initial begin //creating environment - env = new("Pulsar Environment", - `TH.`SYS_CLK.inst.IF, - `TH.`DMA_CLK.inst.IF, - `TH.`DDR_CLK.inst.IF, - `TH.`SYS_RST.inst.IF, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env = new("Base Environment", + `TH.`SYS_CLK.inst.IF, + `TH.`DMA_CLK.inst.IF, + `TH.`DDR_CLK.inst.IF, + `TH.`SYS_RST.inst.IF); + + mng = new("", `TH.`MNG_AXI.inst.IF); + ddr = new("", `TH.`DDR_AXI.inst.IF); + + `LINK(mng, base_env, mng) + `LINK(ddr, base_env, ddr) setLoggerVerbosity(ADI_VERBOSITY_NONE); - env.start(); - //asserts all the resets for 100 ns - `TH.`SYS_RST.inst.IF.assert_reset; - #100 - `TH.`SYS_RST.inst.IF.deassert_reset; - #100 + base_env.start(); + base_env.sys_reset(); sanity_test(); @@ -160,10 +167,10 @@ initial begin offload_spi_test(); - env.stop(); + base_env.stop(); `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish; + $finish(); end @@ -250,7 +257,7 @@ end // Add an arbitrary delay to the echo_sclk signal initial begin - while(1) begin + forever begin @(posedge delay_clk) begin echo_delay_sclk <= {echo_delay_sclk, m_spi_sclk}; end @@ -259,7 +266,7 @@ end assign pulsar_adc_echo_sclk = echo_delay_sclk[SDI_PHY_DELAY-1]; initial begin - while(1) begin + forever begin #0.5 delay_clk = ~delay_clk; end end @@ -280,7 +287,7 @@ bit [31:0] sdi_preg[$]; bit [31:0] sdi_nreg[$]; initial begin - while(1) begin + forever begin @(posedge pulsar_adc_spi_clk); m_spi_csn_int_d <= m_spi_csn_int_s; end @@ -298,7 +305,7 @@ assign end_of_word = (CPOL ^ CPHA) ? (spi_sclk_neg_counter == DATA_DLENGTH); initial begin - while(1) begin + forever begin @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_pos_counter <= 8'b0; @@ -309,7 +316,7 @@ initial begin end initial begin - while(1) begin + forever begin @(negedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); if (m_spi_csn_negedge_s) begin spi_sclk_neg_counter <= 8'b0; @@ -321,7 +328,7 @@ end // SDI shift register initial begin - while(1) begin + forever begin // synchronization if (CPHA ^ CPOL) @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); @@ -367,7 +374,7 @@ bit [31:0] sdi_fifo_data_store; bit [DATA_DLENGTH-1:0] sdi_data_store; initial begin - while(1) begin + forever begin @(posedge pulsar_adc_echo_sclk); sdi_data_store <= {sdi_shiftreg[27:0], 4'b0}; if (sdi_data_store == 'h0 && shiftreg_sampled == 'h1 && sdi_shiftreg != 'h0) begin @@ -393,7 +400,7 @@ end bit [31:0] offload_transfer_cnt; initial begin - while(1) begin + forever begin @(posedge shiftreg_sampled && offload_status); offload_transfer_cnt <= offload_transfer_cnt + 'h1; end @@ -407,14 +414,14 @@ bit [31:0] offload_captured_word_arr [(NUM_OF_TRANSFERS) -1 :0]; task offload_spi_test(); //Configure DMA - env.mng.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - env.mng.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_FLAGS), + base_env.mng.master_sequencer.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA + base_env.mng.master_sequencer.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_FLAGS), `SET_DMAC_FLAGS_TLAST(1) | `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) ); // Use TLAST - env.mng.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 - env.mng.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - env.mng.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + base_env.mng.master_sequencer.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_X_LENGTH), `SET_DMAC_X_LENGTH_X_LENGTH((NUM_OF_TRANSFERS*4)-1)); // X_LENGHTH = 1024-1 + base_env.mng.master_sequencer.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS + base_env.mng.master_sequencer.RegWrite32(`PULSAR_ADC_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA // Configure the Offload module axi_write (`PULSAR_ADC_SPI_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CFG); @@ -443,7 +450,7 @@ task offload_spi_test(); for (int i=0; i<=((NUM_OF_TRANSFERS) -1); i=i+1) begin #1 - offload_captured_word_arr[i] = env.ddr_axi_agent.mem_model.backdoor_memory_read_4byte(`DDR_BA + 4*i); + offload_captured_word_arr[i] = base_env.ddr.slave_sequencer.get_reg_data_from_mem(xil_axi_uint'(`DDR_BA + 4*i)); end if (irq_pending == 'h0) begin diff --git a/testbenches/project/pulsar_adc_pmdz/waves/cfg1.wcfg b/testbenches/project/pulsar_adc_pmdz/waves/cfg1.wcfg index c17b4aeb..f36391be 100755 --- a/testbenches/project/pulsar_adc_pmdz/waves/cfg1.wcfg +++ b/testbenches/project/pulsar_adc_pmdz/waves/cfg1.wcfg @@ -12,7 +12,7 @@ - +