diff --git a/docs/testbenches/project_based/ad463x/index.rst b/docs/testbenches/project_based/ad463x/index.rst index af81a3a66..01d3c2749 100644 --- a/docs/testbenches/project_based/ad463x/index.rst +++ b/docs/testbenches/project_based/ad463x/index.rst @@ -35,7 +35,7 @@ The following parameters of this project that can be configured: - CLK_MODE: defines clocking mode of the device's digital interface: Options: 0 - SPI mode, 1 - Echo-clock or Master clock mode -- NUM_OF_SDI: defines the number of MOSI lines of the SPI interface: +- NUM_OF_SDIO: defines the number of MOSI lines of the SPI interface: Options: 1 - Interleaved mode, 2 - 1 lane per channel, 4 - 2 lanes per channel, 8 - 4 lanes per channel - CAPTURE_ZONE: defines the capture zone of the next sample. @@ -54,30 +54,30 @@ The following configuration files are available: +-----------------------+-----------------------------------------------+ | Configuration mode | Parameters | | +----------+------------+--------------+--------+ - | | CLK_MODE | NUM_OF_SDI | CAPTURE_ZONE | DDR_EN | - +=======================+==========+============+==============+========+ - | cfg_cm0_sdi2_cz1_ddr0 | 0 | 2 | 1 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm0_sdi2_cz2_ddr0 | 0 | 2 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm0_sdi4_cz2_ddr0 | 0 | 4 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm0_sdi8_cz2_ddr0 | 0 | 8 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi1_cz2_ddr0 | 1 | 1 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi2_cz2_ddr0 | 1 | 2 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi2_cz2_ddr1 | 1 | 2 | 2 | 1 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi4_cz2_ddr0 | 1 | 4 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi4_cz2_ddr1 | 1 | 4 | 2 | 1 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi8_cz2_ddr0 | 1 | 8 | 2 | 0 | - +-----------------------+----------+------------+--------------+--------+ - | cfg_cm1_sdi8_cz2_ddr1 | 1 | 8 | 2 | 1 | - +-----------------------+----------+------------+--------------+--------+ + | | CLK_MODE | NUM_OF_SDIO | CAPTURE_ZONE | DDR_EN | + +=======================+==========+=============+==============+========+ + | cfg_cm0_sdi2_cz1_ddr0 | 0 | 2 | 1 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm0_sdi2_cz2_ddr0 | 0 | 2 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm0_sdi4_cz2_ddr0 | 0 | 4 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm0_sdi8_cz2_ddr0 | 0 | 8 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi1_cz2_ddr0 | 1 | 1 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi2_cz2_ddr0 | 1 | 2 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi2_cz2_ddr1 | 1 | 2 | 2 | 1 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi4_cz2_ddr0 | 1 | 4 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi4_cz2_ddr1 | 1 | 4 | 2 | 1 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi8_cz2_ddr0 | 1 | 8 | 2 | 0 | + +-----------------------+----------+-------------+--------------+--------+ + | cfg_cm1_sdi8_cz2_ddr1 | 1 | 8 | 2 | 1 | + +-----------------------+----------+-------------+--------------+--------+ Tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/testbenches/project_based/ad738x/index.rst b/docs/testbenches/project_based/ad738x/index.rst index 01ae5be86..19382a78c 100644 --- a/docs/testbenches/project_based/ad738x/index.rst +++ b/docs/testbenches/project_based/ad738x/index.rst @@ -36,7 +36,7 @@ The following parameters of this project that can be configured: - ALERT_SPI_N: defines if a known pin will operate as a serial data output pin or alert indication pin: Options: 0 - Serial Data Output Pin, 1 - Alert Indication Ouput Pin -- NUM_OF_SDI: defines the number of MOSI lines of the SPI interface: +- NUM_OF_SDIO: defines the number of MOSI lines of the SPI interface: Options: 1 - Interleaved mode, 2 - 1 lane per channel, 4 - 2 lanes per channel @@ -45,13 +45,13 @@ Configuration files The following configuration files are available: - +-----------------------+--------------------------+ - | Configuration mode | Parameters | - | +----------+---------------+ - | | ALERT_SPI_N | NUM_OF_SDI | - +=======================+=============+============+ - | cfg1 | 0 | 2 | - +-----------------------+-------------+------------+ + +-----------------------+---------------------------+ + | Configuration mode | Parameters | + | +----------+----------------+ + | | ALERT_SPI_N | NUM_OF_SDIO | + +=======================+=============+=============+ + | cfg1 | 0 | 2 | + +-----------------------+-------------+-------------+ Tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/testbenches/project_based/ad7606/index.rst b/docs/testbenches/project_based/ad7606/index.rst index 5d18ad2ab..92119e0c0 100644 --- a/docs/testbenches/project_based/ad7606/index.rst +++ b/docs/testbenches/project_based/ad7606/index.rst @@ -39,7 +39,7 @@ The following parameters of this project that can be configured: Options: 0 - without external clock, 1 - with external clock - INTF: defines the interface type: Options: 0 - Parallel, 1 - Serial -- NUM_OF_SDI: defines the number of MOSI lines of the SPI interface: +- NUM_OF_SDIO: defines the number of MOSI lines of the SPI interface: Options: 1 - Interleaved mode, 2 - 1 lane per channel, 4 - 2 lanes per channel, 8 - 4 lanes per channel @@ -50,15 +50,15 @@ The following configuration files are available: +-----------------------+------------------------------------------+ | Configuration mode | Parameters | - | +------------+---------+------+------------+ - | | DEV_CONFIG | EXT_CLK | INTF | NUM_OF_SDI | - +=======================+============+=========+======+============+ - | cfg1 | 0 | 0 | 0 | 1 | - +-----------------------+------------+---------+------+------------+ - | cfg2 | 1 | 0 | 0 | 1 | - +-----------------------+------------+---------+------+------------+ - | cfg3 | 2 | 0 | 0 | 1 | - +-----------------------+------------+---------+------+------------+ + | +------------+---------+------+-------------+ + | | DEV_CONFIG | EXT_CLK | INTF | NUM_OF_SDIO | + +=======================+============+=========+======+=============+ + | cfg1 | 0 | 0 | 0 | 1 | + +-----------------------+------------+---------+------+-------------+ + | cfg2 | 1 | 0 | 0 | 1 | + +-----------------------+------------+---------+------+-------------+ + | cfg3 | 2 | 0 | 0 | 1 | + +-----------------------+------------+---------+------+-------------+ Tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/testbenches/project_based/pulsar_adc/index.rst b/docs/testbenches/project_based/pulsar_adc/index.rst index 54716a630..6d1c7d369 100644 --- a/docs/testbenches/project_based/pulsar_adc/index.rst +++ b/docs/testbenches/project_based/pulsar_adc/index.rst @@ -33,7 +33,7 @@ The following parameters of this project that can be configured: - CLK_MODE: defines clocking mode of the device's digital interface: Options: 0 - SPI mode -- NUM_OF_SDI: defines the number of MOSI lines of the SPI interface: +- NUM_OF_SDIO: defines the number of MOSI lines of the SPI interface: Options: 1 - Interleaved mode - CAPTURE_ZONE: defines the capture zone of the next sample. There are two capture zones: 1 - from negative edge of the BUSY line @@ -50,7 +50,7 @@ The following configuration file is available: +-----------------------+-----------------------------------------------+ | Configuration mode | Parameters | | +----------+------------+--------------+--------+ - | | CLK_MODE | NUM_OF_SDI | CAPTURE_ZONE | DDR_EN | + | | CLK_MODE |NUM_OF_SDIO | CAPTURE_ZONE | DDR_EN | +=======================+==========+============+==============+========+ | cfg1 | 0 | 2 | 1 | 0 | +-----------------------+----------+------------+--------------+--------+ diff --git a/docs/testbenches/project_based/template/_index.rst b/docs/testbenches/project_based/template/_index.rst index 6d9d344dc..d73d0cdff 100644 --- a/docs/testbenches/project_based/template/_index.rst +++ b/docs/testbenches/project_based/template/_index.rst @@ -52,7 +52,7 @@ The following parameters of this project that can be configured: - CLK_MODE: defines clocking mode of the device's digital interface: Options: 0 - SPI mode, 1 - Echo-clock or Master clock mode -- NUM_OF_SDI: defines the number of MOSI lines of the SPI interface: +- NUM_OF_SDIO: defines the number of MOSI lines of the SPI interface: Options: 1 - Interleaved mode, 2 - 1 lane per channel, 4 - 2 lanes per channel, 8 - 4 lanes per channel - CAPTURE_ZONE: defines the capture zone of the next sample. @@ -75,7 +75,7 @@ The following are available configurations for the testbench: +-----------------------+-----------------------------------------------+ | Configuration mode | Parameters | | +----------+------------+--------------+--------+ - | | CLK_MODE | NUM_OF_SDI | CAPTURE_ZONE | DDR_EN | + | | CLK_MODE |NUM_OF_SDIO | CAPTURE_ZONE | DDR_EN | +=======================+==========+============+==============+========+ | cfg_cm0_sdi2_cz1_ddr0 | 0 | 2 | 1 | 0 | +-----------------------+----------+------------+--------------+--------+ @@ -112,7 +112,7 @@ The following are available configurations for the testbench: - * - - CLK_MODE - - NUM_OF_SDI + - NUM_OF_SDIO - CAPTURE_ZONE - DDR_EN * - cfg_cm0_sdi2_cz1_ddr0 diff --git a/library/drivers/spi_engine/spi_engine_api_pkg.sv b/library/drivers/spi_engine/spi_engine_api_pkg.sv index cac276f11..c67df1bea 100644 --- a/library/drivers/spi_engine/spi_engine_api_pkg.sv +++ b/library/drivers/spi_engine/spi_engine_api_pkg.sv @@ -86,17 +86,23 @@ package spi_engine_api_pkg; this.axi_write(GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), `SET_AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO_OFFLOAD0_CDM_FIFO(cmd)); endtask - task sdo_offload_fifo_write(input bit [31:0] data); - this.axi_write(GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), `SET_AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO_OFFLOAD0_SDO_FIFO(data)); + task sdo_offload_fifo_write(input bit [31:0] data[]); + foreach (data[i]) begin + this.axi_write(GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO), `SET_AXI_SPI_ENGINE_OFFLOAD0_SDO_FIFO_OFFLOAD0_SDO_FIFO(data[i])); + end endtask - task sdo_fifo_write(input bit [31:0] data); - this.axi_write(GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), `SET_AXI_SPI_ENGINE_SDO_FIFO_SDO_FIFO(data)); + task sdo_fifo_write(input bit [31:0] data[]); + foreach (data[i]) begin + this.axi_write(GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), `SET_AXI_SPI_ENGINE_SDO_FIFO_SDO_FIFO(data[i])); + end endtask - task sdi_fifo_read(output logic [31:0] data); - this.axi_read(GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), val); - data = `GET_AXI_SPI_ENGINE_SDI_FIFO_SDI_FIFO(val); + task sdi_fifo_read(ref logic [31:0] data[]); + foreach (data[i]) begin + this.axi_read(GetAddrs(AXI_SPI_ENGINE_SDI_FIFO), val); + data[i] = `GET_AXI_SPI_ENGINE_SDI_FIFO_SDI_FIFO(val); + end endtask task offload_mem_assert_reset(); diff --git a/library/drivers/spi_engine/spi_engine_instr_pkg.sv b/library/drivers/spi_engine/spi_engine_instr_pkg.sv index c8600ecd4..4e0486ebc 100644 --- a/library/drivers/spi_engine/spi_engine_instr_pkg.sv +++ b/library/drivers/spi_engine/spi_engine_instr_pkg.sv @@ -12,10 +12,14 @@ package spi_engine_instr_pkg; `define INST_WRD (32'h0000_0300 | (`NUM_OF_WORDS-1)) // Configuration register instructions -`define INST_CFG (32'h0000_2100 | (`SDO_IDLE_STATE << 3) | (`THREE_WIRE << 2) | (`CPOL << 1) | `CPHA) -`define INST_PRESCALE (32'h0000_2000 | `CLOCK_DIVIDER) -`define INST_DLENGTH (32'h0000_2200 | `DATA_DLENGTH) -`define SET_DLENGTH(d) ((`INST_DLENGTH) & ~32'hFF | (d & 8'hFF)) +`define INST_CFG (32'h0000_2100 | (`SDO_IDLE_STATE << 3) | (`THREE_WIRE << 2) | (`CPOL << 1) | `CPHA) +`define INST_PRESCALE (32'h0000_2000 | `CLOCK_DIVIDER) +`define INST_DLENGTH (32'h0000_2200 | `DATA_DLENGTH) +`define SET_DLENGTH(d) ((`INST_DLENGTH) & ~32'hFF | (d & 8'hFF)) +`define INST_SDI_LANE_MASK (32'h0000_2300 | `SDI_LANE_MASK) +`define SET_SDI_LANE_MASK(m) ((`INST_SDI_LANE_MASK) & ~32'hFF | (m & 8'hFF)) +`define INST_SDO_LANE_MASK (32'h0000_2400 | `SDO_LANE_MASK) +`define SET_SDO_LANE_MASK(m) ((`INST_SDO_LANE_MASK) & ~32'hFF | (m & 8'hFF)) // Synchronization `define INST_SYNC (32'h0000_3000) diff --git a/library/regmaps/adi_regmap_spi_engine_pkg.sv b/library/regmaps/adi_regmap_spi_engine_pkg.sv index 67be38ad7..15d904afe 100644 --- a/library/regmaps/adi_regmap_spi_engine_pkg.sv +++ b/library/regmaps/adi_regmap_spi_engine_pkg.sv @@ -42,9 +42,9 @@ package adi_regmap_spi_engine_pkg; /* SPI Engine (axi_spi_engine) */ const reg_t AXI_SPI_ENGINE_VERSION = '{ 'h0000, "VERSION" , '{ - "VERSION_MAJOR": '{ 31, 16, RO, 'h00000001 }, - "VERSION_MINOR": '{ 15, 8, RO, 'h00000005 }, - "VERSION_PATCH": '{ 7, 0, RO, 'h00000001 }}}; + "VERSION_MAJOR": '{ 31, 16, RO, 'h00000002 }, + "VERSION_MINOR": '{ 15, 8, RO, 'h00000000 }, + "VERSION_PATCH": '{ 7, 0, RO, 'h00000000 }}}; `define SET_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR(x) SetField(AXI_SPI_ENGINE_VERSION,"VERSION_MAJOR",x) `define GET_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR(x) GetField(AXI_SPI_ENGINE_VERSION,"VERSION_MAJOR",x) `define DEFAULT_AXI_SPI_ENGINE_VERSION_VERSION_MAJOR GetResetValue(AXI_SPI_ENGINE_VERSION,"VERSION_MAJOR") @@ -73,12 +73,12 @@ package adi_regmap_spi_engine_pkg; `define UPDATE_AXI_SPI_ENGINE_SCRATCH_SCRATCH(x,y) UpdateField(AXI_SPI_ENGINE_SCRATCH,"SCRATCH",x,y) const reg_t AXI_SPI_ENGINE_DATA_WIDTH = '{ 'h000c, "DATA_WIDTH" , '{ - "NUM_OF_SDI": '{ 7, 4, RO, 0 }, + "NUM_OF_SDIO": '{ 7, 4, RO, 0 }, "DATA_WIDTH": '{ 3, 0, RO, 0 }}}; - `define SET_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x) SetField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDI",x) - `define GET_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x) GetField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDI",x) - `define DEFAULT_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI GetResetValue(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDI") - `define UPDATE_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x,y) UpdateField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDI",x,y) + `define SET_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x) SetField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDIO",x) + `define GET_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x) GetField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDIO",x) + `define DEFAULT_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI GetResetValue(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDIO") + `define UPDATE_AXI_SPI_ENGINE_DATA_WIDTH_NUM_OF_SDI(x,y) UpdateField(AXI_SPI_ENGINE_DATA_WIDTH,"NUM_OF_SDIO",x,y) `define SET_AXI_SPI_ENGINE_DATA_WIDTH_DATA_WIDTH(x) SetField(AXI_SPI_ENGINE_DATA_WIDTH,"DATA_WIDTH",x) `define GET_AXI_SPI_ENGINE_DATA_WIDTH_DATA_WIDTH(x) GetField(AXI_SPI_ENGINE_DATA_WIDTH,"DATA_WIDTH",x) `define DEFAULT_AXI_SPI_ENGINE_DATA_WIDTH_DATA_WIDTH GetResetValue(AXI_SPI_ENGINE_DATA_WIDTH,"DATA_WIDTH") diff --git a/library/vip/adi/spi_vip/adi_spi_vip.sv b/library/vip/adi/spi_vip/adi_spi_vip.sv index 40bcc7a1f..4cea3b09c 100644 --- a/library/vip/adi/spi_vip/adi_spi_vip.sv +++ b/library/vip/adi/spi_vip/adi_spi_vip.sv @@ -34,25 +34,29 @@ // *************************************************************************** module adi_spi_vip #( - parameter MODE = 0, // SLAVE=0 - parameter CPOL = 0, - parameter CPHA = 0, - parameter INV_CS = 0, - parameter DATA_DLENGTH = 16, - parameter SLAVE_TIN = 0, - parameter SLAVE_TOUT = 0, - parameter MASTER_TIN = 0, - parameter MASTER_TOUT = 0, - parameter CS_TO_MISO = 0, + parameter MODE = 0, // SLAVE=0 + parameter CPOL = 0, + parameter CPHA = 0, + parameter INV_CS = 0, + parameter DATA_DLENGTH = 16, + parameter NUM_OF_SDI = 1, + parameter NUM_OF_SDO = 1, + parameter SDI_LANE_MASK = 8'hFF, + parameter SDO_LANE_MASK = 8'hFF, + parameter SLAVE_TIN = 0, + parameter SLAVE_TOUT = 0, + parameter MASTER_TIN = 0, + parameter MASTER_TOUT = 0, + parameter CS_TO_MISO = 0, parameter DEFAULT_MISO_DATA = 'hCAFE ) ( input logic s_spi_sclk, - input logic s_spi_mosi, - output wire s_spi_miso, + input logic [NUM_OF_SDO-1:0] s_spi_mosi, + output wire [NUM_OF_SDI-1:0] s_spi_miso, input logic s_spi_cs, output logic m_spi_sclk, - output logic m_spi_mosi, - input wire m_spi_miso, + output logic [NUM_OF_SDO-1:0] m_spi_mosi, + input wire [NUM_OF_SDI-1:0] m_spi_miso, output logic m_spi_cs ); @@ -66,6 +70,10 @@ module adi_spi_vip #( .CPHA (CPHA), .INV_CS (INV_CS), .DATA_DLENGTH (DATA_DLENGTH), + .NUM_OF_SDI (NUM_OF_SDI), + .NUM_OF_SDO (NUM_OF_SDO), + .SDI_LANE_MASK (SDI_LANE_MASK), + .SDO_LANE_MASK (SDO_LANE_MASK), .SLAVE_TIN (SLAVE_TIN), .SLAVE_TOUT (SLAVE_TOUT), .MASTER_TIN (MASTER_TIN), 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 index c19130067..66ff35f05 100644 --- 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 @@ -35,6 +35,7 @@ package adi_spi_vip_if_base_pkg; typedef enum {SPI_MODE_SLAVE, SPI_MODE_MASTER, SPI_MODE_MONITOR} spi_mode_t; + typedef logic mosi_array_t []; virtual class adi_spi_vip_if_base; @@ -51,6 +52,14 @@ package adi_spi_vip_if_base_pkg; pure virtual function int get_param_DATA_DLENGTH(); + pure virtual function int get_param_NUM_OF_SDI(); + + pure virtual function int get_param_NUM_OF_SDO(); + + pure virtual function int get_param_SDI_LANE_MASK(); + + pure virtual function int get_param_SDO_LANE_MASK(); + pure virtual function int get_param_SLAVE_TIN(); pure virtual function int get_param_SLAVE_TOUT(); @@ -73,11 +82,11 @@ package adi_spi_vip_if_base_pkg; pure virtual task wait_for_sample_edge(); - pure virtual function logic get_mosi_delayed(); + pure virtual function mosi_array_t get_mosi_delayed(); - pure virtual task set_miso_drive(bit val); + pure virtual task set_miso_drive(bit val[]); - pure virtual task set_miso_drive_instantaneous(bit val); + pure virtual task set_miso_drive_instantaneous(bit val[]); pure virtual task wait_for_drive_edge(); 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 d48c506ba..7e069a94f 100644 --- a/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv +++ b/library/vip/adi/spi_vip/adi_spi_vip_pkg.sv @@ -48,8 +48,8 @@ package adi_spi_vip_pkg; class adi_spi_driver extends adi_driver; typedef bit bitqueue_t [$]; - protected mailbox mosi_mbx; - mailbox miso_mbx; + protected mailbox #(int) mosi_mbx[]; + mailbox #(int) miso_mbx[]; protected bit active; protected bit stop_flag; protected int default_miso_data; @@ -68,8 +68,14 @@ package adi_spi_vip_pkg; this.active = 0; this.stop_flag = 0; this.default_miso_data = vif.get_param_DEFAULT_MISO_DATA(); - this.miso_mbx = new(); - this.mosi_mbx = new(); + this.miso_mbx = new[vif.get_param_NUM_OF_SDI()]; + this.mosi_mbx = new[vif.get_param_NUM_OF_SDO()]; + foreach (miso_mbx[i]) begin + this.miso_mbx[i] = new(); + end + foreach (mosi_mbx[i]) begin + this.mosi_mbx[i] = new(); + end endfunction @@ -86,27 +92,36 @@ package adi_spi_vip_pkg; endfunction : clear_active protected task rx_mosi(); - bitqueue_t mosi_bits; - logic mosi_logic; - bit mosi_bit; + bitqueue_t mosi_bit_queue[] = new [vif.get_param_NUM_OF_SDO()]; + mosi_array_t mosi_logic; + bit mosi_bit = 0; + int aux = 0; forever begin if (vif.get_mode() == SPI_MODE_SLAVE) begin vif.wait_cs_active(); while (vif.get_cs_active()) begin for (int i = 0; itx_mbx_updated; endtask task get_rx_data( - output int unsigned data); - mosi_mbx.get(data); + ref int unsigned data[]); + for (int i = 0; i < vif.get_param_NUM_OF_SDO(); i++) begin + mosi_mbx[i].get(data[i]); + end endtask task flush_tx(); - wait (miso_mbx.num()==0); + fork + begin: isolation_process + foreach (miso_mbx[i]) begin + fork + automatic int k = i; + begin + wait (miso_mbx[k].num() == 0); + end + join_none + end + wait fork; + end : isolation_process + join endtask task start(); @@ -309,19 +370,21 @@ package adi_spi_vip_pkg; this.driver = driver; endfunction: new - virtual task automatic 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 automatic receive_data(output int unsigned data); + virtual task automatic receive_data(ref 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; + virtual task automatic receive_data_verify(input int unsigned expected[]); + int unsigned received[] = new[expected.size()]; this.driver.get_rx_data(received); - if (received !== expected) begin - this.error($sformatf("Data mismatch. Received : %h; expected %h", received, expected)); + foreach (received[i]) begin + if (received[i] !== expected[i]) begin + this.error($sformatf("Data mismatch. Received : %h; expected %h", received[i], expected[i])); + end end endtask : receive_data_verify diff --git a/library/vip/adi/spi_vip/spi_vip_if.sv b/library/vip/adi/spi_vip/spi_vip_if.sv index 5f51a6582..967ab4af7 100644 --- a/library/vip/adi/spi_vip/spi_vip_if.sv +++ b/library/vip/adi/spi_vip/spi_vip_if.sv @@ -38,6 +38,10 @@ interface spi_vip_if #( CPHA = 0, INV_CS = 0, DATA_DLENGTH = 16, + NUM_OF_SDI = 1, + NUM_OF_SDO = 1, + SDI_LANE_MASK = 8'hFF, + SDO_LANE_MASK = 8'hFF, SLAVE_TIN = 0, SLAVE_TOUT = 0, MASTER_TIN = 0, @@ -48,27 +52,32 @@ interface spi_vip_if #( 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; + wire [NUM_OF_SDI-1:0] s_miso; // need net types here in case tb wants to tristate this + logic [NUM_OF_SDO-1:0] 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; + wire [NUM_OF_SDI-1:0] m_miso; // need net types here in case tb wants to tristate this + logic [NUM_OF_SDO-1:0] m_mosi; logic m_cs; // internal spi_mode_t spi_mode; logic miso_oen; - logic miso_drive; - logic mosi_drive = 1'b0; + logic [NUM_OF_SDI-1:0] miso_drive; + logic [NUM_OF_SDI-1:0] miso_drive_delayed; + logic [NUM_OF_SDO-1:0] mosi_drive = 1'b0; logic cs_drive = 1'b0; logic sclk_drive = 1'b0; logic cs_active; - logic s_mosi_delayed; + logic [NUM_OF_SDO-1:0] s_mosi_delayed; + mosi_array_t s_mosi_unpacked; wire sclk; wire cs; + localparam CS_ACTIVE_LEVEL = (INV_CS) ? 1'b1 : 1'b0; + // localparam DEFAULT_MASK_SDI_SPI_LANE = (2 ** NUM_OF_SDI) - 1; //by default all lanes are enabled + // localparam DEFAULT_MASK_SDO_SPI_LANE = (2 ** NUM_OF_SDO) - 1; //by default all lanes are enabled // cs, sclk sources assign cs = (spi_mode != SPI_MODE_SLAVE) ? m_cs : s_cs; @@ -82,7 +91,7 @@ interface spi_vip_if #( // miso drive handling assign s_miso = (spi_mode != SPI_MODE_SLAVE) ? m_miso - : (miso_oen) ? miso_drive + : (miso_oen) ? miso_drive_delayed /*default*/ : 'z; // mosi drive handling @@ -100,6 +109,7 @@ interface spi_vip_if #( class adi_spi_vip_if #(int dummy = 10) extends adi_spi_vip_if_base; function new(); + s_mosi_unpacked = new [NUM_OF_SDO]; endfunction virtual function int get_param_MODE(); @@ -122,6 +132,22 @@ interface spi_vip_if #( return DATA_DLENGTH; endfunction + virtual function int get_param_NUM_OF_SDI(); + return NUM_OF_SDI; + endfunction + + virtual function int get_param_NUM_OF_SDO(); + return NUM_OF_SDO; + endfunction + + virtual function int get_param_SDI_LANE_MASK(); + return SDI_LANE_MASK; + endfunction + + virtual function int get_param_SDO_LANE_MASK(); + return SDO_LANE_MASK; + endfunction + virtual function int get_param_SLAVE_TIN(); return SLAVE_TIN; endfunction @@ -150,20 +176,27 @@ interface spi_vip_if #( return spi_mode; endfunction - virtual function logic get_mosi_delayed(); - return s_mosi_delayed; + virtual function mosi_array_t get_mosi_delayed(); + {<<{s_mosi_unpacked}} = s_mosi_delayed; + return s_mosi_unpacked; endfunction virtual function logic get_cs_active(); return cs_active; endfunction - virtual task set_miso_drive(bit val); - miso_drive <= #(SLAVE_TOUT) val; + virtual task set_miso_drive(bit val[]); + foreach (val[i]) begin + miso_drive[i] = val[i]; + end + miso_drive_delayed <= #(SLAVE_TOUT * 1ns) miso_drive; endtask - virtual task set_miso_drive_instantaneous(bit val); - miso_drive <= val; + virtual task set_miso_drive_instantaneous(bit val[]); + foreach (val[i]) begin + miso_drive[i] = val[i]; + end + miso_drive_delayed <= miso_drive; endtask virtual task wait_cs_active(); diff --git a/testbenches/ip/spi_engine/cfgs/cfg00.tcl b/testbenches/ip/spi_engine/cfgs/cfg00.tcl index b7af208b3..96e48be3f 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg00.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg00.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 0 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 -set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(DATA_MEM_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 0 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 0 set ad_project_params(NUM_OF_WORDS) 5 set ad_project_params(NUM_OF_TRANSFERS) 5 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/cfgs/cfg01.tcl b/testbenches/ip/spi_engine/cfgs/cfg01.tcl index 14dc96427..0c565a393 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg01.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg01.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 1 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 0 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 2 set ad_project_params(NUM_OF_WORDS) 3 set ad_project_params(NUM_OF_TRANSFERS) 5 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/cfgs/cfg10.tcl b/testbenches/ip/spi_engine/cfgs/cfg10.tcl index 3f15e6fcf..8b2581335 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg10.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg10.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 1 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 0 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 2 set ad_project_params(NUM_OF_WORDS) 3 set ad_project_params(NUM_OF_TRANSFERS) 5 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/cfgs/cfg11.tcl b/testbenches/ip/spi_engine/cfgs/cfg11.tcl index 8cde67840..2e4b025bb 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg11.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg11.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 1 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 0 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 2 set ad_project_params(NUM_OF_WORDS) 3 set ad_project_params(NUM_OF_TRANSFERS) 5 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/cfgs/cfg_inv_cs.tcl b/testbenches/ip/spi_engine/cfgs/cfg_inv_cs.tcl index 8e18ab159..0c565a393 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg_inv_cs.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg_inv_cs.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 1 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 0 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 2 set ad_project_params(NUM_OF_WORDS) 3 set ad_project_params(NUM_OF_TRANSFERS) 5 -set ad_project_params(CS_ACTIVE_HIGH) 1 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf +set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/cfgs/cfg_sdo_streaming.tcl b/testbenches/ip/spi_engine/cfgs/cfg_sdo_streaming.tcl index 523eadfc7..8305a5e90 100644 --- a/testbenches/ip/spi_engine/cfgs/cfg_sdo_streaming.tcl +++ b/testbenches/ip/spi_engine/cfgs/cfg_sdo_streaming.tcl @@ -4,14 +4,14 @@ global ad_project_params set ad_project_params(DATA_WIDTH) 32 set ad_project_params(ASYNC_SPI_CLK) 1 set ad_project_params(NUM_OF_CS) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(NUM_OF_SDI) 4 +set ad_project_params(NUM_OF_SDO) 4 set ad_project_params(SDI_DELAY) 1 set ad_project_params(ECHO_SCLK) 0 set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 set ad_project_params(DATA_MEM_ADDR_WIDTH) 4 -set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 -set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +set ad_project_params(SDI_FIFO_ADDR_WIDTH) 7 +set ad_project_params(SDO_FIFO_ADDR_WIDTH) 7 set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 set ad_project_params(SDO_STREAMING) 1 @@ -30,20 +30,26 @@ set ad_project_params(CS_TO_MISO) 0 set ad_project_params(CLOCK_DIVIDER) 2 set ad_project_params(NUM_OF_WORDS) 5 set ad_project_params(NUM_OF_TRANSFERS) 3 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'hf set ad_project_params(CS_ACTIVE_HIGH) 0 set ad_project_params(ECHO_SCLK_DELAY) 0.1 set spi_s_vip_cfg [ list \ - MODE 0 \ - CPOL $ad_project_params(CPOL) \ - CPHA $ad_project_params(CPHA) \ - INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ - SLAVE_TIN $ad_project_params(SLAVE_TIN) \ - SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ - MASTER_TIN $ad_project_params(MASTER_TIN) \ - MASTER_TOUT $ad_project_params(MASTER_TOUT) \ - CS_TO_MISO $ad_project_params(CS_TO_MISO) \ - DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ ] set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg diff --git a/testbenches/ip/spi_engine/spi_engine_test_bd.tcl b/testbenches/ip/spi_engine/spi_engine_test_bd.tcl index 7fd10fa19..dc2754b22 100644 --- a/testbenches/ip/spi_engine/spi_engine_test_bd.tcl +++ b/testbenches/ip/spi_engine/spi_engine_test_bd.tcl @@ -48,7 +48,7 @@ ad_ip_parameter axi_spi_engine_dma CONFIG.SYNC_TRANSFER_START 0 ad_ip_parameter axi_spi_engine_dma CONFIG.AXI_SLICE_SRC 0 ad_ip_parameter axi_spi_engine_dma CONFIG.AXI_SLICE_DEST 1 ad_ip_parameter axi_spi_engine_dma CONFIG.DMA_2D_TRANSFER 0 -ad_ip_parameter axi_spi_engine_dma CONFIG.DMA_DATA_WIDTH_SRC $data_width +ad_ip_parameter axi_spi_engine_dma CONFIG.DMA_DATA_WIDTH_SRC [expr {$data_width * $num_sdi}] ad_ip_parameter axi_spi_engine_dma CONFIG.DMA_DATA_WIDTH_DEST 64 ad_connect $sys_cpu_clk spi_clkgen/clk diff --git a/testbenches/ip/spi_engine/system_project.tcl b/testbenches/ip/spi_engine/system_project.tcl index 93b4e1fc8..d05db77b7 100644 --- a/testbenches/ip/spi_engine/system_project.tcl +++ b/testbenches/ip/spi_engine/system_project.tcl @@ -28,6 +28,7 @@ adi_sim_project_files [list \ "tests/test_program.sv" \ "tests/test_sleep_delay.sv" \ "tests/test_slowdata.sv" \ + "tests/test_lanes.sv" \ ] #set a default test program diff --git a/testbenches/ip/spi_engine/system_tb.sv b/testbenches/ip/spi_engine/system_tb.sv index 5cee51b3e..7100513df 100644 --- a/testbenches/ip/spi_engine/system_tb.sv +++ b/testbenches/ip/spi_engine/system_tb.sv @@ -36,15 +36,15 @@ `include "utils.svh" module system_tb(); - wire spi_engine_spi_cs; - wire spi_engine_spi_sclk; - wire spi_engine_spi_clk; - wire spi_engine_spi_sdi; - wire spi_engine_spi_sdo; - wire spi_engine_irq; -`ifdef DEF_ECHO_SCLK - wire spi_engine_echo_sclk; -`endif + wire spi_engine_spi_sclk; + wire spi_engine_spi_clk; + wire [(`NUM_OF_CS-1) :0] spi_engine_spi_cs; + wire [(`NUM_OF_SDI-1):0] spi_engine_spi_sdi; + wire [(`NUM_OF_SDO-1):0] spi_engine_spi_sdo; + wire spi_engine_irq; + `ifdef DEF_ECHO_SCLK + wire spi_engine_echo_sclk; + `endif `TEST_PROGRAM test( .spi_engine_irq(spi_engine_irq), diff --git a/testbenches/ip/spi_engine/tests/test_lanes.sv b/testbenches/ip/spi_engine/tests/test_lanes.sv new file mode 100644 index 000000000..8d3c8bb85 --- /dev/null +++ b/testbenches/ip/spi_engine/tests/test_lanes.sv @@ -0,0 +1,549 @@ +// *************************************************************************** +// *************************************************************************** +// 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 +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" + +import logger_pkg::*; +import test_harness_env_pkg::*; +import spi_environment_pkg::*; +import axi4stream_vip_pkg::*; +import spi_engine_api_pkg::*; +import dmac_api_pkg::*; +import pwm_gen_api_pkg::*; +import clk_gen_api_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 +//--------------------------------------------------------------------------- +program test_lanes ( + inout spi_engine_irq, + inout spi_engine_spi_sclk, + inout [(`NUM_OF_CS - 1):0] spi_engine_spi_cs, + inout spi_engine_spi_clk, + `ifdef DEF_ECHO_SCLK + inout spi_engine_echo_sclk, + `endif + inout [(`NUM_OF_SDI-1):0] spi_engine_spi_sdi); + + timeunit 1ns; + timeprecision 100ps; + + // declare the class instances + test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; + spi_environment spi_env; + spi_engine_api spi_api; + dmac_api dma_api; + pwm_gen_api pwm_api; + clk_gen_api clkgen_api; + + //--------------------------------------------------------------------------- + // 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 + + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task automatic spi_receive( + ref int unsigned data[]); + spi_env.spi_agent.sequencer.receive_data(data); + endtask + + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH-1: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 + + bit [ 7:0] sdi_lane_mask; + bit [ 7:0] sdo_lane_mask; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] rx_data []; + bit [`DATA_DLENGTH-1:0] tx_data []; + logic [ `DATA_WIDTH-1:0] rx_data_cast []; + int unsigned tx_data_cast []; + int unsigned receive_data []; + int num_of_active_sdi_lanes = $countones(`SDI_LANE_MASK); + int num_of_active_sdo_lanes = $countones(`SDO_LANE_MASK); + + // -------------------------- + // Main procedure + // -------------------------- + initial begin + + setLoggerVerbosity(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, + `TH.`MNG_AXI.inst.IF, + `TH.`DDR_AXI.inst.IF); + + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); + + spi_api = new("SPI Engine API", + base_env.mng.sequencer, + `SPI_ENGINE_SPI_REGMAP_BA); + + dma_api = new("RX DMA API", + base_env.mng.sequencer, + `SPI_ENGINE_DMA_BA); + + clkgen_api = new("CLKGEN API", + base_env.mng.sequencer, + `SPI_ENGINE_AXI_CLKGEN_BA); + + pwm_api = new("PWM API", + base_env.mng.sequencer, + `SPI_ENGINE_PWM_GEN_BA); + + 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_tests(); + + init(); + + #100ns; + + fifo_spi_test(); + sdi_lane_mask = {`NUM_OF_SDI{1'b1}}; + sdo_lane_mask = {`NUM_OF_SDO{1'b1}}; + num_of_active_sdi_lanes = $countones(sdi_lane_mask); + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask));//guarantee all SDO lanes must be active + + #100ns; + + offload_spi_test(); + + spi_env.stop(); + base_env.stop(); + + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); + + end + + //--------------------------------------------------------------------------- + // SPI Engine generate transfer + //--------------------------------------------------------------------------- + task generate_transfer_cmd( + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); + + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); + // assert CSN + spi_api.fifo_command(`SET_CS(8'hFE)); + // transfer data + spi_api.fifo_command(`INST_WRD); + // de-assert CSN + spi_api.fifo_command(`SET_CS(8'hFF)); + // SYNC command to generate interrupt + spi_api.fifo_command(`INST_SYNC | sync_id); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // SPI Engine SDO data + //--------------------------------------------------------------------------- + task sdo_stream_gen( + input [`DATA_DLENGTH-1:0] tx_data[]); + xil_axi4stream_data_byte data[((`DATA_WIDTH/8) * (`NUM_OF_SDO))-1:0]; + `ifdef DEF_SDO_STREAMING + for (int i = 0; i < `NUM_OF_SDO; i++) begin + for (int j = 0; j < (`DATA_WIDTH/8); j++) begin + data[i * (`DATA_WIDTH/8) + j] = (tx_data[i] & (8'hFF << 8*j)) >> 8*j; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i * (`DATA_WIDTH/8) + j]); + end + end + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8) * (`NUM_OF_SDO),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 + spi_api.get_irq_pending(irq_pending); + // IRQ launched by Offload SYNC command + if (spi_api.check_irq_offload_sync_id_pending(irq_pending)) begin + spi_api.get_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 (spi_api.check_irq_sync_event(irq_pending)) begin + spi_api.get_sync_id(sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDI FIFO + if (spi_api.check_irq_sdi_almost_full(irq_pending)) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (spi_api.check_irq_sdo_almost_empty(irq_pending)) begin + `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by CMD FIFO + if (spi_api.check_irq_cmd_almost_empty(irq_pending)) begin + `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // Clear all pending IRQs + spi_api.clear_irq_pending(irq_pending); + end + end + + //--------------------------------------------------------------------------- + // Sanity Tests + //--------------------------------------------------------------------------- + task sanity_tests(); + spi_api.sanity_test(); + dma_api.sanity_test(); + pwm_api.sanity_test(); + endtask + + //--------------------------------------------------------------------------- + // Offload SPI Test + //--------------------------------------------------------------------------- + bit [`DATA_DLENGTH-1:0] sdi_read_data []; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store []; + bit [ `DATA_WIDTH-1:0] sdo_write_data []; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store []; + + task offload_spi_test(); + + tx_data_cast = new [num_of_active_sdo_lanes]; + tx_data = new [num_of_active_sdo_lanes]; + sdo_write_data = new [`NUM_OF_SDO]; + rx_data = new [`NUM_OF_SDI]; + sdi_read_data = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)* num_of_active_sdi_lanes]; + sdi_read_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)* num_of_active_sdi_lanes]; + + `ifdef DEF_SDO_STREAMING + sdo_write_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `else + sdo_write_data_store = new [(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `endif + + //Configure DMA + dma_api.enable_dma(); + dma_api.set_flags( + .cyclic(1'b0), + .tlast(1'b1), + .partial_reporting_en(1'b1) + ); + dma_api.set_lengths(((`NUM_OF_TRANSFERS) * (`NUM_OF_WORDS) * (`NUM_OF_SDI) * (`DATA_WIDTH/8))-1,0); + dma_api.set_dest_addr(`DDR_BA); + dma_api.transfer_start(); + + // Configure the Offload module + spi_api.fifo_offload_command(`INST_CFG); + spi_api.fifo_offload_command(`INST_PRESCALE); + spi_api.fifo_offload_command(`INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + spi_api.fifo_offload_command(`SET_CS_INV_MASK(8'hFF)); + end + spi_api.fifo_offload_command(`SET_CS(8'hFE)); + spi_api.fifo_offload_command(`INST_WRD); + spi_api.fifo_offload_command(`SET_CS(8'hFF)); + spi_api.fifo_offload_command(`INST_SYNC | 2); + + // Enqueue transfers to DUT + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0, k = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = sdi_lane_mask[j] ? $urandom : `SDO_IDLE_STATE; //easier to debug + if (sdi_lane_mask[j]) begin + sdi_read_data_store[i * num_of_active_sdi_lanes + k] = rx_data[j]; + k++; + end + end + + spi_send(rx_data); + + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = $urandom; + tx_data_cast[j] = tx_data[j]; + end + + `ifdef DEF_SDO_STREAMING + sdo_stream_gen(tx_data); + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[k]; // all of valid random words will be used + k++; + end else begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = `SDO_IDLE_STATE; + end + end + `else + if (i < (`NUM_OF_WORDS)) begin + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[k]; //only the first NUM_OF_WORDS random words will be used for all transfers + k++; + end else begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = `SDO_IDLE_STATE; + end + end + spi_api.sdo_offload_fifo_write(tx_data_cast); + end + `endif + end + + #100ns; + spi_api.start_offload(); + `INFO(("Offload started."), ADI_VERBOSITY_LOW); + spi_wait_send(); + spi_api.stop_offload(); + `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); + + #2000ns; + + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); + end + + for (int i = 0, k = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)); i++) begin + if (sdi_lane_mask[i%(`NUM_OF_SDI)]) begin + sdi_read_data[k] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(xil_axi_uint'(`DDR_BA + 4*i)); + if (sdi_read_data[k] != sdi_read_data_store[k]) begin //one word at a time comparison + `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", + k, sdi_read_data[k], + k, sdi_read_data_store[k]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Read Test FAILED")); + end + k++; + end + end + `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); + + for (int i = 0; i < (`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS); i++) begin + spi_receive(sdo_write_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + `ifdef DEF_SDO_STREAMING + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + (i * `NUM_OF_SDO + j), + sdo_write_data_store[(i * `NUM_OF_SDO + j)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `else + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + ((i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)), + sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `endif + end + end + `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // FIFO SPI Test + //--------------------------------------------------------------------------- + task fifo_spi_test(); + + //This test forces a wrong lane mask, then generates data + //and much time later starts execution with the correct lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(8'hC)); //wrong lane mask on purpose + spi_api.fifo_command(`SET_SDO_LANE_MASK(8'hE)); //wrong lane mask on purpose + sdi_lane_mask = 8'h1; //new mask defining the active lanes (right lane mask) + sdo_lane_mask = 8'h8; //new mask defining the active lanes (right lane mask) + num_of_active_sdi_lanes = $countones(sdi_lane_mask); + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + + rx_data_cast = new [num_of_active_sdi_lanes]; + rx_data = new [(`NUM_OF_SDI)]; + sdi_fifo_data = new [num_of_active_sdi_lanes * `NUM_OF_WORDS]; + sdi_fifo_data_store = new [num_of_active_sdi_lanes * `NUM_OF_WORDS]; + tx_data = new [num_of_active_sdo_lanes]; + tx_data_cast = new [num_of_active_sdo_lanes]; + receive_data = new [`NUM_OF_SDO]; + sdo_fifo_data = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + sdo_fifo_data_store = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + + // Generate a FIFO transaction, write SDO first + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + for (int j = 0, k = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = sdi_lane_mask[j] ? $urandom : `SDO_IDLE_STATE; //easier to debug + if (sdi_lane_mask[j]) begin + sdi_fifo_data_store[i * num_of_active_sdi_lanes + k] = rx_data[j]; + k++; + end + end + + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = $urandom; + tx_data_cast[j] = tx_data[j]; //a cast is necessary for the SPI API + end + + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = tx_data[k]; + k++; + end else begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = `SDO_IDLE_STATE; + end + end + + spi_api.sdo_fifo_write((tx_data_cast));// << API is expecting 32 bits, only active lanes are written + spi_send(rx_data); + end + + //wait a long time before starting execution with the correct lane mask + #500ns; + generate_transfer_cmd(1, sdi_lane_mask, sdo_lane_mask); //generate transfer with specific spi lane mask + + `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++) begin + spi_api.sdi_fifo_read(rx_data_cast); //API always returns 32 bits + spi_receive(receive_data); + for (int j = 0; j < num_of_active_sdi_lanes; j++) begin + sdi_fifo_data[i * num_of_active_sdi_lanes + j] = rx_data_cast[j]; + end + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + sdo_fifo_data[i * (`NUM_OF_SDO) + j] = receive_data[j]; + end + end + + foreach (sdi_fifo_data[i]) begin + if (sdi_fifo_data[i] !== sdi_fifo_data_store[i]) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data[i], sdi_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Read Test FAILED")); + end + end + `INFO(("Fifo Read Test PASSED"), ADI_VERBOSITY_LOW); + + foreach (sdo_fifo_data[i]) begin + if (sdo_fifo_data[i] !== sdo_fifo_data_store[i]) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data[i], sdo_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end + end + `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // Test initialization + //--------------------------------------------------------------------------- + task init(); + // Start spi clk generator + clkgen_api.enable_clkgen(); + + // Config pwm + pwm_api.reset(); + pwm_api.pulse_period_config(0,'d121); // config channel 0 period + pwm_api.load_config(); + pwm_api.start(); + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + // Enable SPI Engine + spi_api.enable_spi_engine(); + + // Configure the execution module + spi_api.fifo_command(`INST_CFG); + spi_api.fifo_command(`INST_PRESCALE); + spi_api.fifo_command(`INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); + end + + // Set up the interrupts + spi_api.set_interrup_mask(.sync_event(1'b1),.offload_sync_id_pending(1'b1)); + + endtask + +endprogram diff --git a/testbenches/ip/spi_engine/tests/test_program.sv b/testbenches/ip/spi_engine/tests/test_program.sv index 365ca8903..d0f8c736c 100644 --- a/testbenches/ip/spi_engine/tests/test_program.sv +++ b/testbenches/ip/spi_engine/tests/test_program.sv @@ -57,7 +57,6 @@ import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- - program test_program ( inout spi_engine_irq, inout spi_engine_spi_sclk, @@ -66,7 +65,7 @@ program test_program ( `ifdef DEF_ECHO_SCLK inout spi_engine_echo_sclk, `endif - inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); + inout [(`NUM_OF_SDI-1):0] spi_engine_spi_sdi); timeunit 1ns; timeprecision 100ps; @@ -79,19 +78,26 @@ program test_program ( pwm_gen_api pwm_api; clk_gen_api clkgen_api; + //--------------------------------------------------------------------------- + // 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 + // -------------------------- // Wrapper function for SPI receive (from DUT) // -------------------------- - task spi_receive( - output [`DATA_DLENGTH:0] data); - spi_env.spi_agent.sequencer.receive_data(data); + task automatic spi_receive( + ref int unsigned 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); + input [`DATA_DLENGTH-1:0] data[]); spi_env.spi_agent.sequencer.send_data(data); endtask @@ -102,6 +108,19 @@ program test_program ( spi_env.spi_agent.sequencer.flush_send(); endtask + bit [ 7:0] sdi_lane_mask; + bit [ 7:0] sdo_lane_mask; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] rx_data []; + bit [`DATA_DLENGTH-1:0] tx_data []; + logic [ `DATA_WIDTH-1:0] rx_data_cast []; + int unsigned tx_data_cast []; + int unsigned receive_data []; + int num_of_active_sdi_lanes = $countones(`SDI_LANE_MASK); + int num_of_active_sdo_lanes = $countones(`SDO_LANE_MASK); // -------------------------- // Main procedure @@ -164,6 +183,10 @@ program test_program ( #100ns; fifo_spi_test(); + sdi_lane_mask = (2 ** `NUM_OF_SDI)-1; + sdo_lane_mask = (2 ** `NUM_OF_SDI)-1; + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask));//guarantee all SDO lanes must be active #100ns; @@ -180,9 +203,14 @@ program test_program ( //--------------------------------------------------------------------------- // SPI Engine generate transfer //--------------------------------------------------------------------------- - task generate_transfer_cmd( - input [7:0] sync_id); + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); + + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // assert CSN spi_api.fifo_command(`SET_CS(8'hFE)); // transfer data @@ -197,23 +225,23 @@ program test_program ( //--------------------------------------------------------------------------- // SPI Engine SDO data //--------------------------------------------------------------------------- - task sdo_stream_gen( - input [`DATA_DLENGTH:0] tx_data); - xil_axi4stream_data_byte data[(`DATA_WIDTH/8)-1:0]; + input [`DATA_DLENGTH-1:0] tx_data[]); + xil_axi4stream_data_byte data[((`DATA_WIDTH/8) * (`NUM_OF_SDO))-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]); + for (int i = 0; i < `NUM_OF_SDO; i++) begin + for (int j = 0; j < (`DATA_WIDTH/8); j++) begin + data[i * (`DATA_WIDTH/8) + j] = (tx_data[i] & (8'hFF << 8*j)) >> 8*j; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i * (`DATA_WIDTH/8) + j]); + end end - spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8),0,0); + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8) * (`NUM_OF_SDO),0,0); `endif endtask //--------------------------------------------------------------------------- // IRQ callback //--------------------------------------------------------------------------- - reg [4:0] irq_pending = 0; reg [7:0] sync_id = 0; @@ -249,13 +277,6 @@ program test_program ( 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 - //--------------------------------------------------------------------------- // Sanity Tests //--------------------------------------------------------------------------- @@ -268,22 +289,34 @@ program test_program ( //--------------------------------------------------------------------------- // 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; + bit [`DATA_DLENGTH-1:0] sdi_read_data []; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store []; + bit [ `DATA_WIDTH-1:0] sdo_write_data []; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store []; task offload_spi_test(); + + tx_data_cast = new [`NUM_OF_SDO]; + tx_data = new [`NUM_OF_SDO]; + sdo_write_data = new [`NUM_OF_SDO]; + rx_data = new [`NUM_OF_SDI]; + sdi_read_data = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)]; + sdi_read_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)]; + + `ifdef DEF_SDO_STREAMING + sdo_write_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `else + sdo_write_data_store = new [(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `endif + //Configure DMA dma_api.enable_dma(); dma_api.set_flags( .cyclic(1'b0), .tlast(1'b1), - .partial_reporting_en(1'b1)); - dma_api.set_lengths(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1,0); + .partial_reporting_en(1'b1) + ); + dma_api.set_lengths(((`NUM_OF_TRANSFERS) * (`NUM_OF_WORDS) * (`NUM_OF_SDI) * (`DATA_WIDTH/8))-1,0); dma_api.set_dest_addr(`DDR_BA); dma_api.transfer_start(); @@ -299,21 +332,31 @@ program test_program ( spi_api.fifo_offload_command(`SET_CS(8'hFF)); spi_api.fifo_offload_command(`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; + // Enqueue transfers to DUT + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = {$urandom}; + sdi_read_data_store[i * (`NUM_OF_SDI) + j] = rx_data[j]; + end + spi_send(rx_data); - sdi_read_data_store[i] = rx_data; - tx_data = $urandom; + + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + tx_data[j] = {$urandom}; + tx_data_cast[j] = tx_data[j]; + end + `ifdef DEF_SDO_STREAMING sdo_stream_gen(tx_data); - sdo_write_data_store[i] = tx_data; + for (int j = 0; j < `NUM_OF_SDO; j++) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[j]; // all of the random words will be used + end `else - if (i<(`NUM_OF_WORDS)) begin - sdo_write_data_store[i] = tx_data; - spi_api.sdo_offload_fifo_write(sdo_write_data_store[i]); - end else begin - sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; + if (i < (`NUM_OF_WORDS)) begin + for (int j = 0; j < `NUM_OF_SDO; j++) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[j]; //only the first NUM_OF_WORDS random words will be used for all transfers + end + spi_api.sdo_offload_fifo_write(tx_data_cast); end `endif end @@ -333,20 +376,37 @@ program test_program ( `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); end - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)); i++) begin sdi_read_data[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(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")); + if (sdi_read_data[i] != sdi_read_data_store[i]) begin //one word at a time comparison + `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 `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); i++) begin + spi_receive(sdo_write_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + `ifdef DEF_SDO_STREAMING + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + (i * `NUM_OF_SDO + j), + sdo_write_data_store[(i * `NUM_OF_SDO + j)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `else + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + ((i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)), + sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `endif end end `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); @@ -355,44 +415,77 @@ program test_program ( //--------------------------------------------------------------------------- // FIFO SPI Test //--------------------------------------------------------------------------- + task 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]; + sdi_lane_mask = (2**`NUM_OF_SDI)-1; //new mask defining the active lanes + sdo_lane_mask = (2**`NUM_OF_SDO)-1; //new mask defining the active lanes + num_of_active_sdo_lanes = $countones(sdo_lane_mask); - task fifo_spi_test(); + rx_data_cast = new [(`NUM_OF_SDI)]; + rx_data = new [(`NUM_OF_SDI)]; + sdi_fifo_data = new [(`NUM_OF_SDI) * `NUM_OF_WORDS]; + sdi_fifo_data_store = new [(`NUM_OF_SDI) * `NUM_OF_WORDS]; + tx_data = new [num_of_active_sdo_lanes]; + tx_data_cast = new [num_of_active_sdo_lanes]; + receive_data = new [`NUM_OF_SDO]; + sdo_fifo_data = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + sdo_fifo_data_store = new [`NUM_OF_SDO * `NUM_OF_WORDS]; // 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; - spi_api.sdo_fifo_write((tx_data));// << (`DATA_WIDTH - `DATA_DLENGTH))); + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = sdo_lane_mask[j] ? $urandom : `SDO_IDLE_STATE; + sdi_fifo_data_store[i * (`NUM_OF_SDI) + j] = rx_data[j]; + end + + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = $urandom; + tx_data_cast[j] = tx_data[j]; //a cast is necessary for the SPI API + end + + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = tx_data[k]; + k++; + end else begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = `SDO_IDLE_STATE; + end + end + + spi_api.sdo_fifo_write((tx_data_cast));// << API is expecting 32 bits, only active lanes are written 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, sdi_lane_mask, sdo_lane_mask); //generate transfer with specific spi lane mask `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 - spi_api.sdi_fifo_read(sdi_fifo_data[i]); - spi_receive(sdo_fifo_data[i]); + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + spi_api.sdi_fifo_read(rx_data_cast); //API always returns 32 bits + spi_receive(receive_data); + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + sdi_fifo_data[i * (`NUM_OF_SDI) + j] = rx_data_cast[j]; + end + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + sdo_fifo_data[i * (`NUM_OF_SDO) + j] = receive_data[j]; + end 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); - `FATAL(("Fifo Read Test FAILED")); + foreach (sdi_fifo_data[i]) begin + if (sdi_fifo_data[i] !== sdi_fifo_data_store[i]) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data[i], sdi_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Read Test FAILED")); + end 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); - `FATAL(("Fifo Write Test FAILED")); + foreach (sdo_fifo_data[i]) begin + if (sdo_fifo_data[i] !== sdo_fifo_data_store[i]) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data[i], sdo_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end end `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); endtask @@ -400,7 +493,6 @@ program test_program ( //--------------------------------------------------------------------------- // Test initialization //--------------------------------------------------------------------------- - task init(); // Start spi clk generator clkgen_api.enable_clkgen(); diff --git a/testbenches/ip/spi_engine/tests/test_sleep_delay.sv b/testbenches/ip/spi_engine/tests/test_sleep_delay.sv index 91f72050f..aaac8698b 100644 --- a/testbenches/ip/spi_engine/tests/test_sleep_delay.sv +++ b/testbenches/ip/spi_engine/tests/test_sleep_delay.sv @@ -55,7 +55,6 @@ import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- - program test_sleep_delay ( inout spi_engine_irq, inout spi_engine_spi_sclk, @@ -64,7 +63,7 @@ program test_sleep_delay ( `ifdef DEF_ECHO_SCLK inout spi_engine_echo_sclk, `endif - inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); + inout [(`NUM_OF_SDI-1):0] spi_engine_spi_sdi); timeunit 1ns; timeprecision 100ps; @@ -80,16 +79,16 @@ program test_sleep_delay ( // -------------------------- // Wrapper function for SPI receive (from DUT) // -------------------------- - task spi_receive( - output [`DATA_DLENGTH:0] data); - spi_env.spi_agent.sequencer.receive_data(data); + task automatic spi_receive( + ref int unsigned 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); + input [`DATA_DLENGTH-1:0] data[]); spi_env.spi_agent.sequencer.send_data(data); endtask @@ -104,6 +103,8 @@ program test_sleep_delay ( // -------------------------- // Main procedure // -------------------------- + bit [7:0] sdi_lane_mask; + bit [7:0] sdo_lane_mask; initial begin setLoggerVerbosity(ADI_VERBOSITY_NONE); @@ -118,10 +119,10 @@ program test_sleep_delay ( `TH.`DDR_AXI.inst.IF); spi_env = new("SPI Engine Environment", - `ifdef DEF_SDO_STREAMING - `TH.`SDO_SRC.inst.IF, - `endif - `TH.`SPI_S.inst.IF.vif); + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); spi_api = new("SPI Engine API", base_env.mng.sequencer, @@ -162,7 +163,10 @@ program test_sleep_delay ( #100ns; sleep_delay_test(7); - + sdi_lane_mask = (2 ** `NUM_OF_SDI)-1; + sdo_lane_mask = (2 ** `NUM_OF_SDO)-1; + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask));//guarantee all SDO lanes must be active cs_delay_test(3,3); spi_env.stop(); @@ -176,7 +180,6 @@ program test_sleep_delay ( //--------------------------------------------------------------------------- // IRQ callback //--------------------------------------------------------------------------- - reg [4:0] irq_pending = 0; reg [7:0] sync_id = 0; @@ -351,26 +354,29 @@ program test_sleep_delay ( //--------------------------------------------------------------------------- // 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]; + bit [`DATA_DLENGTH-1:0] offload_captured_word_arr[]; + bit [`DATA_DLENGTH-1:0] offload_sdi_data_store_arr[]; 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; + bit [`DATA_DLENGTH-1:0] temp_data []; task cs_delay_test( input [1:0] cs_activate_delay, input [1:0] cs_deactivate_delay); + temp_data = new [`NUM_OF_SDO]; + offload_captured_word_arr = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + offload_sdi_data_store_arr = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + //Configure DMA dma_api.enable_dma(); dma_api.set_flags( .cyclic(1'b0), .tlast(1'b1), .partial_reporting_en(1'b1)); - dma_api.set_lengths(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1,0); + dma_api.set_lengths(((`NUM_OF_TRANSFERS) * (`NUM_OF_WORDS) * (`NUM_OF_SDI) * (`DATA_WIDTH/8))-1,0); dma_api.set_dest_addr(`DDR_BA); dma_api.transfer_start(); @@ -392,10 +398,13 @@ program test_sleep_delay ( 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; + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + temp_data[j] = {$urandom}; + offload_sdi_data_store_arr[i * (`NUM_OF_SDO) + j] = temp_data[j]; + end + spi_send(temp_data); - offload_sdi_data_store_arr[i] = temp_data; end #100ns; @@ -409,18 +418,20 @@ program test_sleep_delay ( #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] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(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 (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")); + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)); i++) begin + offload_captured_word_arr[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(xil_axi_uint'(`DDR_BA + 4*i)); + if (offload_captured_word_arr[i] !== offload_sdi_data_store_arr[i]) begin //one word at a time comparison + `INFO(("offload_captured_word_arr[%d]: %x; offload_sdi_data_store_arr[%d]: %x", + i, offload_captured_word_arr[i], + i, offload_sdi_data_store_arr[i]), ADI_VERBOSITY_LOW); + `FATAL(("CS Delay Test FAILED: bad data")); + end end repeat (`NUM_OF_TRANSFERS) begin @@ -445,15 +456,18 @@ program test_sleep_delay ( spi_api.fifo_offload_command(`SET_CS_DELAY(8'hFF,cs_deactivate_delay)); spi_api.fifo_offload_command(`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) + // breakdown: cs_activate_delay*(1+`CLOCK_DIVIDER)*2, times 2 since it's before and after cs transition, and added 2 cycles for the internal delay 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; + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + temp_data[j] = {$urandom}; + offload_sdi_data_store_arr[i * (`NUM_OF_SDO) + j] = temp_data[j]; + end + spi_send(temp_data); - offload_sdi_data_store_arr[i] = temp_data; end #100ns; @@ -467,19 +481,22 @@ program test_sleep_delay ( #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] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(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 (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")); + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)); i++) begin + offload_captured_word_arr[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(xil_axi_uint'(`DDR_BA + 4*i)); + if (offload_captured_word_arr[i] !== offload_sdi_data_store_arr[i]) begin //one word at a time comparison + `INFO(("offload_captured_word_arr[%d]: %x; offload_sdi_data_store_arr[%d]: %x", + i, offload_captured_word_arr[i], + i, offload_sdi_data_store_arr[i]), ADI_VERBOSITY_LOW); + `FATAL(("CS Delay Test FAILED: bad data")); + end end + repeat (`NUM_OF_TRANSFERS) begin cs_activate_time = cs_instr_time.pop_back(); cs_deactivate_time = cs_instr_time.pop_back(); diff --git a/testbenches/ip/spi_engine/tests/test_slowdata.sv b/testbenches/ip/spi_engine/tests/test_slowdata.sv index 9be9a3a53..ec7fe9df1 100644 --- a/testbenches/ip/spi_engine/tests/test_slowdata.sv +++ b/testbenches/ip/spi_engine/tests/test_slowdata.sv @@ -32,8 +32,6 @@ // // *************************************************************************** // *************************************************************************** -// -// `include "utils.svh" `include "axi_definitions.svh" @@ -57,7 +55,6 @@ import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- - program test_slowdata ( inout spi_engine_irq, inout spi_engine_spi_sclk, @@ -66,11 +63,12 @@ program test_slowdata ( `ifdef DEF_ECHO_SCLK inout spi_engine_echo_sclk, `endif - inout [(`NUM_OF_SDI - 1):0] spi_engine_spi_sdi); + inout [(`NUM_OF_SDI-1):0] spi_engine_spi_sdi); timeunit 1ns; timeprecision 100ps; + // declare the class instances test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; spi_environment spi_env; spi_engine_api spi_api; @@ -78,19 +76,26 @@ program test_slowdata ( pwm_gen_api pwm_api; clk_gen_api clkgen_api; + //--------------------------------------------------------------------------- + // 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 + // -------------------------- // Wrapper function for SPI receive (from DUT) // -------------------------- - task spi_receive( - output [`DATA_DLENGTH:0] data); - spi_env.spi_agent.sequencer.receive_data(data); + task automatic spi_receive( + ref int unsigned 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); + input [`DATA_DLENGTH-1:0] data[]); spi_env.spi_agent.sequencer.send_data(data); endtask @@ -101,6 +106,19 @@ program test_slowdata ( spi_env.spi_agent.sequencer.flush_send(); endtask + bit [ 7:0] sdi_lane_mask; + bit [ 7:0] sdo_lane_mask; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] rx_data []; + bit [`DATA_DLENGTH-1:0] tx_data []; + logic [ `DATA_WIDTH-1:0] rx_data_cast []; + int unsigned tx_data_cast []; + int unsigned receive_data []; + int num_of_active_sdi_lanes = $countones(`SDI_LANE_MASK); + int num_of_active_sdo_lanes = $countones(`SDO_LANE_MASK); // -------------------------- // Main procedure @@ -179,6 +197,10 @@ program test_slowdata ( #100ns; fifo_double_write_test(); + sdi_lane_mask = (2 ** `NUM_OF_SDI)-1; + sdo_lane_mask = (2 ** `NUM_OF_SDO)-1; + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask));//guarantee all SDO lanes must be active #100ns; @@ -197,13 +219,16 @@ program test_slowdata ( //--------------------------------------------------------------------------- // SPI Engine generate transfer //--------------------------------------------------------------------------- - task generate_init_transfer_cmd( - input [7:0] sync_id); + input [7:0] sync_id, + input [7:0] sdo_lane_mask); + // configure cs if (`CS_ACTIVE_HIGH) begin spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); end + // define spi lane mask + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // write cfg spi_api.fifo_command(`INST_CFG); // assert CSN @@ -222,11 +247,16 @@ program test_slowdata ( endtask task generate_single_rtransfer_cmd( - input [7:0] sync_id); + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); // configure cs if (`CS_ACTIVE_HIGH) begin spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); end + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // write cfg spi_api.fifo_command(`INST_CFG); // assert CSN @@ -246,11 +276,16 @@ program test_slowdata ( task generate_double_rtransfer_cmd( - input [7:0] sync_id); + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); // configure cs if (`CS_ACTIVE_HIGH) begin spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); end + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // write cfg spi_api.fifo_command(`INST_CFG); // assert CSN @@ -271,11 +306,14 @@ program test_slowdata ( endtask task generate_double_wtransfer_cmd( - input [7:0] sync_id); + input [7:0] sync_id, + input [7:0] sdo_lane_mask); // configure cs if (`CS_ACTIVE_HIGH) begin spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); end + // define spi lane mask + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // write cfg spi_api.fifo_command(`INST_CFG); // assert CSN @@ -296,9 +334,25 @@ program test_slowdata ( endtask //--------------------------------------------------------------------------- - // IRQ callback + // SPI Engine SDO data //--------------------------------------------------------------------------- + task sdo_stream_gen( + input [`DATA_DLENGTH-1:0] tx_data[]); + xil_axi4stream_data_byte data[((`DATA_WIDTH/8) * (`NUM_OF_SDO))-1:0]; + `ifdef DEF_SDO_STREAMING + for (int i = 0; i < `NUM_OF_SDO; i++) begin + for (int j = 0; j < (`DATA_WIDTH/8); j++) begin + data[i * (`DATA_WIDTH/8) + j] = (tx_data[i] & (8'hFF << 8*j)) >> 8*j; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i * (`DATA_WIDTH/8) + j]); + end + end + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8) * (`NUM_OF_SDO),0,0); + `endif + endtask + //--------------------------------------------------------------------------- + // IRQ callback + //--------------------------------------------------------------------------- reg [4:0] irq_pending = 0; reg [7:0] sync_id = 0; @@ -337,7 +391,6 @@ program test_slowdata ( //--------------------------------------------------------------------------- // Sanity Tests //--------------------------------------------------------------------------- - task sanity_tests(); spi_api.sanity_test(); dma_api.sanity_test(); @@ -345,246 +398,331 @@ program test_slowdata ( endtask //--------------------------------------------------------------------------- - // SPI Engine SDO data + // Offload SPI Test //--------------------------------------------------------------------------- + bit [`DATA_DLENGTH-1:0] sdi_read_data []; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store []; + bit [ `DATA_WIDTH-1:0] sdo_write_data []; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store []; + + task offload_spi_test(); + + tx_data_cast = new [`NUM_OF_SDO]; + tx_data = new [`NUM_OF_SDO]; + sdo_write_data = new [`NUM_OF_SDO]; + rx_data = new [`NUM_OF_SDI]; + sdi_read_data = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)]; + sdi_read_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)]; - 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); + sdo_write_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `else + sdo_write_data_store = new [(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; `endif - endtask - //--------------------------------------------------------------------------- - // 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 + // Config pwm + pwm_api.reset(); + pwm_api.pulse_period_config(0,'d105); // config channel 0 period + pwm_api.load_config(); + pwm_api.start(); + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - //--------------------------------------------------------------------------- - // FIFO SPI Test - //--------------------------------------------------------------------------- + //Configure DMA + dma_api.enable_dma(); + dma_api.set_flags( + .cyclic(1'b0), + .tlast(1'b1), + .partial_reporting_en(1'b1) + ); + dma_api.set_lengths(((`NUM_OF_TRANSFERS) * (`NUM_OF_WORDS) * (`NUM_OF_SDI) * (`DATA_WIDTH/8))-1,0); + dma_api.set_dest_addr(`DDR_BA); + dma_api.transfer_start(); - 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; + // Configure the Offload module + spi_api.fifo_offload_command(`INST_CFG); + spi_api.fifo_offload_command(`INST_PRESCALE); + spi_api.fifo_offload_command(`INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + spi_api.fifo_offload_command(`SET_CS_INV_MASK(8'hFF)); + end + spi_api.fifo_offload_command(`SET_CS(8'hFE)); + spi_api.fifo_offload_command(`INST_WRD); + spi_api.fifo_offload_command(`SET_CS(8'hFF)); + spi_api.fifo_offload_command(`INST_SYNC | 2); - task fifo_init_test(); + // Enqueue transfers to DUT + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = {$urandom}; + sdi_read_data_store[i * (`NUM_OF_SDI) + j] = rx_data[j]; + end - // send cmd before data - generate_init_transfer_cmd(1); + spi_send(rx_data); - // write sdo fifo - for (int i = 0; i<(`NUM_OF_WORDS) ; i=i+1) begin - tx_data = ((i%6) == 5) ? 8'hFE : 8'hFF; - spi_api.sdo_fifo_write(tx_data);// << (`DATA_WIDTH - `DATA_DLENGTH))); - sdo_fifo_data_store[i] = tx_data; + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + tx_data[j] = {$urandom}; + tx_data_cast[j] = tx_data[j]; + end + + `ifdef DEF_SDO_STREAMING + sdo_stream_gen(tx_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[j]; // all of the random words will be used + end + `else + if (i < (`NUM_OF_WORDS)) begin + for (int j = 0; j < `NUM_OF_SDO; j++) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[j]; //only the first NUM_OF_WORDS random words will be used for all transfers + end + spi_api.sdo_offload_fifo_write(tx_data_cast); + end + `endif 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]); + #100ns; + spi_api.start_offload(); + `INFO(("Offload started."), ADI_VERBOSITY_LOW); + spi_wait_send(); + spi_api.stop_offload(); + `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); + + #2000ns; + + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); + end else begin + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); 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")); + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDI)); i++) begin + sdi_read_data[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(xil_axi_uint'(`DDR_BA + 4*i)); + if (sdi_read_data[i] != sdi_read_data_store[i]) begin //one word at a time comparison + `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 - `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); + + for (int i = 0; i < (`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS); i++) begin + spi_receive(sdo_write_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + `ifdef DEF_SDO_STREAMING + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + (i * `NUM_OF_SDO + j), + sdo_write_data_store[(i * `NUM_OF_SDO + j)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `else + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + ((i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)), + sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `endif + end + end + `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); endtask - 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(); + //--------------------------------------------------------------------------- + // FIFO SPI Test - Init Test + //--------------------------------------------------------------------------- + task fifo_init_test(); + + sdo_lane_mask = (2**`NUM_OF_SDO)-1; //new mask defining the active lanes + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + tx_data = new [num_of_active_sdo_lanes]; + tx_data_cast = new [num_of_active_sdo_lanes]; + receive_data = new [`NUM_OF_SDO]; + sdo_fifo_data = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + sdo_fifo_data_store = new [`NUM_OF_SDO * `NUM_OF_WORDS]; // send cmd before data - generate_double_wtransfer_cmd(1); + generate_init_transfer_cmd(1, sdo_lane_mask); // write sdo fifo - for (int i = 0; i<(2) ; i=i+1) begin - tx_data = $urandom; - spi_api.sdo_fifo_write(tx_data);// << (`DATA_WIDTH - `DATA_DLENGTH))); - sdo_2_fifo_data_store[i] = tx_data; + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = ((i%6) == 5) ? 8'hFE : 8'hFF; + tx_data_cast[j] = tx_data[j]; //a cast is necessary for the SPI API + end + + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = tx_data[k]; + k++; + end else begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = `SDO_IDLE_STATE; + end + end + + spi_api.sdo_fifo_write((tx_data_cast));// << API is expecting 32 bits 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]); + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + spi_receive(receive_data); + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + sdo_fifo_data[i * (`NUM_OF_SDO) + j] = receive_data[j]; + 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); - `FATAL(("Double Write Test FAILED")); + foreach (sdo_fifo_data[i]) begin + if (sdo_fifo_data[i] !== sdo_fifo_data_store[i]) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data[i], sdo_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end end - `INFO(("Double Write Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); 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; + //--------------------------------------------------------------------------- + // FIFO SPI Test - Double Write Test + //--------------------------------------------------------------------------- + task fifo_double_write_test(); - task fifo_double_read_test(); + sdo_lane_mask = (2**`NUM_OF_SDO)-1; //new mask defining the active lanes + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + tx_data = new [num_of_active_sdo_lanes]; + tx_data_cast = new [num_of_active_sdo_lanes]; + receive_data = new [`NUM_OF_SDO]; + sdo_fifo_data = new [`NUM_OF_SDO * 2]; + sdo_fifo_data_store = new [`NUM_OF_SDO * 2]; - 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 + // send cmd before data + generate_double_wtransfer_cmd(1, sdo_lane_mask); - generate_double_rtransfer_cmd(1); + // write sdo fifo + for (int i = 0; i < 2; i++) begin + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = ((i%6) == 5) ? 8'hFE : 8'hFF; + tx_data_cast[j] = tx_data[j]; //a cast is necessary for the SPI API + end - `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); - spi_wait_send(); - `INFO(("SPI sent"), ADI_VERBOSITY_LOW); + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = tx_data[k]; + k++; + end else begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = `SDO_IDLE_STATE; + end + end + + spi_api.sdo_fifo_write((tx_data_cast));// << API is expecting 32 bits + end - for (int i = 0; i<(2) ; i=i+1) begin - spi_receive(foo); // dummy tx, just for clearing the VIP queue - spi_api.sdi_fifo_read(sdi_2_fifo_data[i]); + `INFO(("Wait for SPI VIP receiving data"), ADI_VERBOSITY_LOW); + for (int i = 0; i < 2; i++) begin + spi_receive(receive_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + sdo_fifo_data[i * `NUM_OF_SDO + j] = receive_data[j]; + end 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")); + foreach (sdo_fifo_data[i]) begin + if (sdo_fifo_data[i] !== sdo_fifo_data_store[i]) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data[i], sdo_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Double Write Test FAILED")); + end end - `INFO(("Double Read Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("Double Write 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 ; + //--------------------------------------------------------------------------- + // FIFO SPI Test - Single read Test + //--------------------------------------------------------------------------- task fifo_single_read_test(); - rx_data = $urandom; + sdi_lane_mask = (2**`NUM_OF_SDI)-1; //new mask defining the active lanes + sdo_lane_mask = (2**`NUM_OF_SDO)-1; //new mask defining the active lanes + num_of_active_sdi_lanes = $countones(sdi_lane_mask); + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + tx_data_cast = new [num_of_active_sdo_lanes]; + rx_data = new [`NUM_OF_SDI]; + rx_data_cast = new [`NUM_OF_SDI]; + sdi_fifo_data = new [`NUM_OF_SDI]; + sdi_fifo_data_store = new [`NUM_OF_SDI]; + + for (int i = 0; i < num_of_active_sdi_lanes; i++) begin + rx_data[i] = {$urandom}; + sdi_fifo_data_store[i] = rx_data[i]; + end spi_send(rx_data); - sdi_1_fifo_data_store = rx_data; - generate_single_rtransfer_cmd(1); + generate_single_rtransfer_cmd(1, sdi_lane_mask, sdo_lane_mask); - `INFO(("Wait for SPI VIP data send"), ADI_VERBOSITY_LOW); + `INFO(("Waiting for SPI VIP send..."), ADI_VERBOSITY_LOW); spi_wait_send(); `INFO(("SPI sent"), ADI_VERBOSITY_LOW); - spi_receive(foo); // dummy tx, just for clearing the VIP queue - spi_api.sdi_fifo_read(sdi_1_fifo_data); + spi_receive(tx_data_cast); // dummy tx, just for clearing the VIP queue + spi_api.sdi_fifo_read(rx_data_cast); - 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")); + foreach (sdi_fifo_data[i]) begin + sdi_fifo_data[i] = rx_data_cast[i]; + if (sdi_fifo_data[i] !== sdi_fifo_data_store[i]) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data[i], sdi_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Single Read Test FAILED")); + end end `INFO(("Single Read Test PASSED"), ADI_VERBOSITY_LOW); endtask //--------------------------------------------------------------------------- - // Offload SPI Test + // FIFO SPI Test - Double Read Test //--------------------------------------------------------------------------- + task fifo_double_read_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 - pwm_api.reset(); - pwm_api.pulse_period_config(0,'d105); // config channel 0 period - pwm_api.load_config(); - pwm_api.start(); - `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); - - //Configure DMA - dma_api.enable_dma(); - dma_api.set_flags( - .cyclic(1'b0), - .tlast(1'b1), - .partial_reporting_en(1'b1)); - dma_api.set_lengths(((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*4)-1,0); - dma_api.set_dest_addr(`DDR_BA); - dma_api.transfer_start(); - - // Configure the Offload module - spi_api.fifo_offload_command(`INST_CFG); - spi_api.fifo_offload_command(`INST_PRESCALE); - spi_api.fifo_offload_command(`INST_DLENGTH); - if (`CS_ACTIVE_HIGH) begin - spi_api.fifo_offload_command(`SET_CS_INV_MASK(8'hFF)); - end - spi_api.fifo_offload_command(`SET_CS(8'hFE)); - spi_api.fifo_offload_command(`INST_WRD); - spi_api.fifo_offload_command(`SET_CS(8'hFF)); - spi_api.fifo_offload_command(`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; + sdi_lane_mask = (2**`NUM_OF_SDI)-1; //new mask defining the active lanes + sdo_lane_mask = (2**`NUM_OF_SDO)-1; //new mask defining the active lanes + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + tx_data_cast = new [num_of_active_sdo_lanes]; + rx_data = new [`NUM_OF_SDI]; + rx_data_cast = new [`NUM_OF_SDI]; + sdi_fifo_data = new [`NUM_OF_SDI * 2]; + sdi_fifo_data_store = new [`NUM_OF_SDI * 2]; + + for (int i = 0; i < 2; i++) begin + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + rx_data[j] = {$urandom}; + sdi_fifo_data_store[i * (`NUM_OF_SDI) + j] = rx_data[j]; + end + 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; - spi_api.sdo_offload_fifo_write(sdo_write_data_store[i]); - end else begin - sdo_write_data_store[i] = sdo_write_data_store[i%(`NUM_OF_WORDS)]; - end - `endif end - // Start the offload - #100ns; - spi_api.start_offload(); - `INFO(("Offload started."), ADI_VERBOSITY_LOW); + generate_double_rtransfer_cmd(1, sdi_lane_mask, sdo_lane_mask); + `INFO(("Waiting for SPI VIP send..."), ADI_VERBOSITY_LOW); spi_wait_send(); + `INFO(("SPI sent"), ADI_VERBOSITY_LOW); - spi_api.stop_offload(); - - `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); - - #2000ns; - - if (irq_pending == 'h0) begin - `FATAL(("IRQ Test FAILED")); - end else begin - `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); - end - - for (int i=0; i<=((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS) -1); i=i+1) begin - sdi_read_data[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(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")); + for (int i = 0; i < 2; i++) begin + spi_api.sdi_fifo_read(rx_data_cast); //API always returns 32 bits + spi_receive(tx_data_cast); // dummy tx, just for clearing the VIP queue + for (int j = 0; j < (`NUM_OF_SDI); j++) begin + sdi_fifo_data[i * (`NUM_OF_SDI) + j] = rx_data_cast[j]; 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); - `FATAL(("Offload Write Test FAILED")); + foreach (sdi_fifo_data[i]) begin + if (sdi_fifo_data[i] !== sdi_fifo_data_store[i]) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data[i], sdi_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Double Read Test FAILED")); end end - `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("Double Read Test PASSED"), ADI_VERBOSITY_LOW); endtask - //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- // Test initialization //--------------------------------------------------------------------------- - task init(); // Start spi clk generator clkgen_api.enable_clkgen(); diff --git a/testbenches/ip/spi_engine/waves/cfg_num_sdi.wcfg b/testbenches/ip/spi_engine/waves/cfg_num_sdi.wcfg new file mode 100644 index 000000000..b5f979e16 --- /dev/null +++ b/testbenches/ip/spi_engine/waves/cfg_num_sdi.wcfg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + spi_engine_spi_clk + spi_engine_spi_clk + + + spi_engine_spi_cs + spi_engine_spi_cs + + + spi_engine_spi_sclk + spi_engine_spi_sclk + + + spi_engine_spi_sdi + spi_engine_spi_sdi + + + spi_engine_spi_sdo + spi_engine_spi_sdo + + + spi_engine_irq + spi_engine_irq + + + WRITE_SPI_REGMAP + label + + + s_axi_awaddr[15:0] + s_axi_awaddr[15:0] + HEXRADIX + #FF00FF + true + + + s_axi_awvalid + s_axi_awvalid + #FF00FF + true + + + s_axi_awready + s_axi_awready + #FF00FF + true + + + s_axi_wdata[31:0] + s_axi_wdata[31:0] + HEXRADIX + #FF00FF + true + + + s_axi_wvalid + s_axi_wvalid + #FF00FF + true + + + s_axi_wready + s_axi_wready + #FF00FF + true + + + READ_SPI_REGMAP + label + + + s_axi_araddr[15:0] + s_axi_araddr[15:0] + #00FFFF + true + + + s_axi_arvalid + s_axi_arvalid + #00FFFF + true + + + s_axi_arready + s_axi_arready + #00FFFF + true + + + s_axi_rdata[31:0] + s_axi_rdata[31:0] + #00FFFF + true + + + s_axi_rvalid + s_axi_rvalid + #00FFFF + true + + + s_axi_rready + s_axi_rready + #00FFFF + true + + diff --git a/testbenches/project/ad463x/Makefile b/testbenches/project/ad463x/Makefile index a76023b95..d73f8f248 100644 --- a/testbenches/project/ad463x/Makefile +++ b/testbenches/project/ad463x/Makefile @@ -7,12 +7,14 @@ # 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_dmac.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_pwm_gen.mk +include $(TB_LIBRARY_PATH)/includes/Makeinclude_clk_gen.mk include $(TB_LIBRARY_PATH)/includes/Makeinclude_spi_engine.mk # Remaining test-bench dependencies except test programs -SV_DEPS += $(TB_LIBRARY_PATH)/regmaps/adi_regmap_clkgen_pkg.sv -SV_DEPS += $(TB_LIBRARY_PATH)/regmaps/adi_regmap_pwm_gen_pkg.sv +SV_DEPS += spi_environment.sv ENV_DEPS += $(HDL_LIBRARY_PATH)/util_cdc/sync_bits.v ENV_DEPS += $(HDL_LIBRARY_PATH)/common/ad_edge_detect.v diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr0.tcl new file mode 100644 index 000000000..539952442 --- /dev/null +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr0.tcl @@ -0,0 +1,97 @@ +global ad_project_params + +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 1 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 1 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 + +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +# set ad_project_params(SLAVE_TOUT) 18 +# set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SLAVE_TOUT : $ECHO_CLK_SDR_SLAVE_TOUT) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +# set ad_project_params(CS_TO_MISO) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h1 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +# set ad_project_params(ECHO_SCLK_DELAY) 18 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr1.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr1.tcl index 739b3472b..9d61fbc79 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr1.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi1_cz1_ddr0_nr1.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(CAPTURE_ZONE) 1 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 1 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 1 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 1 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 1 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h1 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr0.tcl index 8067a59ac..b4159079d 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 2 -set ad_project_params(CAPTURE_ZONE) 1 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 2 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 1 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h3 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr1.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr1.tcl index bae0b301d..bed15c776 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr1.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz1_ddr0_nr1.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 2 -set ad_project_params(CAPTURE_ZONE) 1 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 1 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 2 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 1 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 1 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h3 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz2_ddr0_nr0.tcl index 473cadd79..da31c1e9e 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi2_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 2 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 2 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h3 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi4_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi4_cz2_ddr0_nr0.tcl index 0254fa61d..a9f673661 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi4_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi4_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 4 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 4 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi8_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi8_cz2_ddr0_nr0.tcl index 0f7080cae..2f68d52f6 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm0_sdi8_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm0_sdi8_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 0 -set ad_project_params(NUM_OF_SDI) 8 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 0 +set ad_project_params(NUM_OF_SDIO) 8 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hff +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi1_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi1_cz2_ddr0_nr0.tcl index 0fa1d0d02..777689a51 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi1_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi1_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 1 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 1 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h1 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr0_nr0.tcl index f5ebff6e8..81e31cd5c 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 2 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 2 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h3 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr1_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr1_nr0.tcl index 88876567b..19260979b 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr1_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi2_cz2_ddr1_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 2 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 1 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 2 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 1 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'h3 +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr0_nr0.tcl index b95b1657d..f6d9860f0 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 4 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 4 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr1_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr1_nr0.tcl index b0db4b53e..46762a86e 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr1_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi4_cz2_ddr1_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 4 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 1 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 4 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 1 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hf +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr0_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr0_nr0.tcl index 2ff6ae8a6..89146b56d 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr0_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr0_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 8 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 0 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 8 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 0 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hff +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr1_nr0.tcl b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr1_nr0.tcl index 43a7a4727..a8bc1796c 100644 --- a/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr1_nr0.tcl +++ b/testbenches/project/ad463x/cfgs/cfg_cm1_sdi8_cz2_ddr1_nr0.tcl @@ -1,8 +1,93 @@ global ad_project_params -set ad_project_params(CLK_MODE) 1 -set ad_project_params(NUM_OF_SDI) 8 -set ad_project_params(CAPTURE_ZONE) 2 -set ad_project_params(DDR_EN) 1 -set ad_project_params(NO_REORDER) 0 +# SPI Engine DUT parameters +set ad_project_params(CLK_MODE) 1 +set ad_project_params(NUM_OF_SDIO) 8 +set ad_project_params(NUM_OF_SDO) 1 +set ad_project_params(CAPTURE_ZONE) 2 +set ad_project_params(DDR_EN) 1 +set ad_project_params(NO_REORDER) 0 +set ad_project_params(DATA_WIDTH) 32 +set ad_project_params(ASYNC_SPI_CLK) 1 +set ad_project_params(NUM_OF_CS) 1 +# default values for the SPI ENGINE DUT parameters +# set ad_project_params(CMD_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDO_DATA_MEM_ADDR_WIDTH) 4 +# set ad_project_params(SDI_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SDO_FIFO_ADDR_WIDTH) 5 +# set ad_project_params(SYNC_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(CMD_FIFO_ADDR_WIDTH) 4 +# set ad_project_params(SDO_STREAMING) 0 + +# Delay parameters in ns (VIO = 1.8V, VADJ = 2.5V) +set U9 5.6 +set U10 5.1 +set U11 4.5 +set LENGTH 32 +set SKEW 1 +set SPI_MODE_TDSDO 5.6 +set SPI_MODE_TCSEN 6.8 +set ECHO_CLK_SDR_TCSSCK 9.8 +set ECHO_CLK_SDR_TDSDO 5.6 +set ECHO_CLK_DDR_TCSSCK 12.3 +set ECHO_CLK_DDR_TDSDO 6.2 +set SPI_MODE_ECHO_SCK [expr { $U9 + $U11}] +set ECHO_CLK_SDR_SCK [expr { $U9 + $ECHO_CLK_SDR_TDSDO + $U11}] +set ECHO_CLK_DDR_SCK [expr { $U9 + $ECHO_CLK_DDR_TDSDO + $U11}] +set SPI_MODE_CS_TO_MISO_DELAY [expr { $SPI_MODE_TCSEN + $U9}] +set ECHO_CLK_SDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_SDR_TCSSCK + $ECHO_CLK_SDR_TDSDO + $U9}] +set ECHO_CLK_DDR_CS_TO_MISO_DELAY [expr { $ECHO_CLK_DDR_TCSSCK + $ECHO_CLK_DDR_TDSDO + $U9}] +set SPI_MODE_SLAVE_TOUT [expr { $SPI_MODE_TDSDO + $U10}] +set ECHO_CLK_SDR_SLAVE_TOUT [expr { $ECHO_CLK_SDR_TDSDO + $U10}] +set ECHO_CLK_DDR_SLAVE_TOUT [expr { $ECHO_CLK_DDR_TDSDO + $U10}] + +# Test parameters +set ad_project_params(NUM_OF_SDI) $ad_project_params(NUM_OF_SDIO) +set ad_project_params(DATA_DLENGTH_SDR) [expr {$ad_project_params(NUM_OF_SDIO) > 1 ? $LENGTH / ($ad_project_params(NUM_OF_SDIO)/2) : $LENGTH}] +set ad_project_params(DATA_DLENGTH_DDR) [expr $ad_project_params(DATA_DLENGTH_SDR)/2] +set ad_project_params(DATA_DLENGTH) $ad_project_params(DATA_DLENGTH_SDR) +set ad_project_params(THREE_WIRE) 0 +set ad_project_params(CPOL) 0 +set ad_project_params(CPHA) 1 +set ad_project_params(SDO_IDLE_STATE) 0 +set ad_project_params(SLAVE_TIN) 0 +set ad_project_params(SLAVE_TOUT) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK - $SKEW : $ECHO_CLK_SDR_SCK - $SKEW) : $SPI_MODE_SLAVE_TOUT}] +set ad_project_params(MASTER_TIN) 0 +set ad_project_params(MASTER_TOUT) 0 +set ad_project_params(CS_TO_MISO) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_CS_TO_MISO_DELAY : $ECHO_CLK_SDR_CS_TO_MISO_DELAY) : $SPI_MODE_CS_TO_MISO_DELAY}] +set ad_project_params(CLOCK_DIVIDER) 0 +set ad_project_params(NUM_OF_WORDS) 1 +set ad_project_params(NUM_OF_TRANSFERS) 10 +set ad_project_params(SDI_LANE_MASK) 'hff +set ad_project_params(SDO_LANE_MASK) 'h1 +set ad_project_params(CS_ACTIVE_HIGH) 0 +set ad_project_params(ECHO_SCLK_DELAY) [expr {$ad_project_params(CLK_MODE) ? ($ad_project_params(DDR_EN) ? $ECHO_CLK_DDR_SCK : $ECHO_CLK_SDR_SCK) : $SPI_MODE_ECHO_SCK}] + +set spi_s_vip_cfg [ list \ + MODE 0 \ + CPOL $ad_project_params(CPOL) \ + CPHA $ad_project_params(CPHA) \ + INV_CS $ad_project_params(CS_ACTIVE_HIGH) \ + SLAVE_TIN $ad_project_params(SLAVE_TIN) \ + SLAVE_TOUT $ad_project_params(SLAVE_TOUT) \ + MASTER_TIN $ad_project_params(MASTER_TIN) \ + MASTER_TOUT $ad_project_params(MASTER_TOUT) \ + CS_TO_MISO $ad_project_params(CS_TO_MISO) \ + DATA_DLENGTH $ad_project_params(DATA_DLENGTH) \ + NUM_OF_SDI $ad_project_params(NUM_OF_SDI) \ + NUM_OF_SDO $ad_project_params(NUM_OF_SDO) \ + SDI_LANE_MASK $ad_project_params(SDI_LANE_MASK) \ + SDO_LANE_MASK $ad_project_params(SDO_LANE_MASK) \ +] +set ad_project_params(spi_s_vip_cfg) $spi_s_vip_cfg + +set axis_sdo_src_vip_cfg [ list \ + INTERFACE_MODE {MASTER} \ + HAS_TREADY 1 \ + HAS_TLAST 0 \ + TDATA_NUM_BYTES [expr $ad_project_params(DATA_WIDTH)/8] \ + TDEST_WIDTH 0 \ + TID_WIDTH 0 \ +] +set ad_project_params(axis_sdo_src_vip_cfg) $axis_sdo_src_vip_cfg diff --git a/testbenches/project/ad463x/spi_environment.sv b/testbenches/project/ad463x/spi_environment.sv new file mode 100644 index 000000000..5ffe96698 --- /dev/null +++ b/testbenches/project/ad463x/spi_environment.sv @@ -0,0 +1,134 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2023-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. +// +// *************************************************************************** +// *************************************************************************** + +`include "utils.svh" +`include "axis_definitions.svh" + +package spi_environment_pkg; + + import logger_pkg::*; + import adi_environment_pkg::*; + + import m_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; + import adi_spi_vip_pkg::*; + import adi_spi_vip_if_base_pkg::*; + + `ifdef DEF_SDO_STREAMING + import `PKGIFY(test_harness, sdo_src)::*; + `endif + + class spi_environment extends adi_environment; + + // Agents + adi_spi_agent spi_agent; + `ifdef DEF_SDO_STREAMING + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(test_harness_sdo_src_0)) sdo_src_agent; + `endif + + //============================================================================ + // Constructor + //============================================================================ + function new( + input string name, + + `ifdef DEF_SDO_STREAMING + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness_sdo_src_0)) sdo_src_axis_vip_if, + `endif + adi_spi_vip_if_base spi_s_vip_if); + + super.new(name); + + // Creating the agents + this.spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); + `ifdef DEF_SDO_STREAMING + 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(); + `endif + endfunction + + //============================================================================ + // Configure environment + // - Configure the sequencers with an initial configuration before starting + //============================================================================ + task configure(); + `ifdef DEF_SDO_STREAMING + 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 + + //============================================================================ + // Start environment + // - Connect all the agents to the scoreboard + // - Start the agents + //============================================================================ + task start(); + this.spi_agent.start(); + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.start(); + `endif + endtask + + //============================================================================ + // Run subroutine + //============================================================================ + task run(); + fork + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.run(); + `endif + join_none + endtask + + //============================================================================ + // Stop subroutine + //============================================================================ + task stop(); + this.spi_agent.stop(); + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.stop(); + `endif + endtask + + endclass + +endpackage diff --git a/testbenches/project/ad463x/system_bd.tcl b/testbenches/project/ad463x/system_bd.tcl index 9d43872f7..13feef3e6 100644 --- a/testbenches/project/ad463x/system_bd.tcl +++ b/testbenches/project/ad463x/system_bd.tcl @@ -46,19 +46,61 @@ adi_project_files [list \ # source $ad_hdl_dir/projects/ad4630_fmc/common/ad463x_bd.tcl +create_bd_port -dir I ad463x_ddr_sclk create_bd_port -dir O ad463x_spi_clk create_bd_port -dir O ad463x_irq ad_connect ad463x_spi_clk spi_clkgen/clk_0 ad_connect ad463x_irq spi_ad463x/irq +ad_ip_instance adi_spi_vip spi_s_vip $ad_project_params(spi_s_vip_cfg) +adi_sim_add_define "SPI_S=spi_s_vip" + +# Create a new interface with Monitor mode +create_bd_intf_port -mode Monitor -vlnv analog.com:interface:spi_engine_rtl:1.0 ad463x_spi_vip + +ad_disconnect spi_ad463x/spi_ad463x_execution/sclk ad463x_spi_sclk +ad_disconnect spi_ad463x/spi_ad463x_execution/sdo ad463x_spi_sdo +ad_disconnect spi_ad463x/spi_ad463x_execution/cs ad463x_spi_cs +ad_disconnect spi_ad463x/spi_ad463x_execution/sdi ad463x_spi_sdi + +ad_disconnect spi_ad463x/ad463x_spi_sclk ad463x_spi_sclk +ad_disconnect spi_ad463x/ad463x_spi_sdo ad463x_spi_sdo +ad_disconnect spi_ad463x/ad463x_spi_cs ad463x_spi_cs +ad_disconnect spi_ad463x/ad463x_spi_sdi ad463x_spi_sdi + +if {$ad_project_params(CLK_MODE) == 0} { + ad_connect spi_s_vip/s_spi spi_ad463x/m_spi + ad_connect ad463x_spi_vip spi_ad463x/m_spi +} else { + ad_connect spi_s_vip/s_spi spi_ad463x/m_spi + ad_connect ad463x_spi_vip spi_ad463x/m_spi + if {$ad_project_params(DDR_EN) == 1} { + ad_connect ad463x_ddr_sclk spi_s_vip/s_spi_sclk + } else { + ad_connect spi_ad463x/m_spi_sclk spi_s_vip/s_spi_sclk + } + ad_disconnect ad463x_spi_sdi data_capture/data_in + ad_disconnect ad463x_spi_cs data_capture/csn + ad_connect spi_s_vip/s_spi_miso data_capture/data_in + ad_connect spi_ad463x/m_spi_cs data_capture/csn + + ad_connect spi_s_vip/s_spi_miso spi_ad463x/m_spi_sdi + ad_connect spi_s_vip/s_spi_mosi spi_ad463x/m_spi_sdo + ad_connect spi_s_vip/s_spi_cs spi_ad463x/m_spi_cs + ad_connect ad463x_spi_vip_sclk spi_ad463x/m_spi_sclk + ad_connect ad463x_spi_vip_sdi spi_s_vip/s_spi_miso + ad_connect ad463x_spi_vip_sdo spi_ad463x/m_spi_sdo + ad_connect ad463x_spi_vip_cs spi_ad463x/m_spi_cs +} + set BA_SPI_REGMAP 0x44A00000 set_property offset $BA_SPI_REGMAP [get_bd_addr_segs {mng_axi_vip/Master_AXI/spi_ad463x_axi_regmap}] -adi_sim_add_define "SPI_AD469X_REGMAP_BA=[format "%d" ${BA_SPI_REGMAP}]" +adi_sim_add_define "SPI_AD463X_REGMAP_BA=[format "%d" ${BA_SPI_REGMAP}]" set BA_DMA 0x44A30000 set_property offset $BA_DMA [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_axi_ad463x_dma}] -adi_sim_add_define "AD469X_DMA_BA=[format "%d" ${BA_DMA}]" +adi_sim_add_define "AD463X_DMA_BA=[format "%d" ${BA_DMA}]" set BA_CLKGEN 0x44A70000 set_property offset $BA_CLKGEN [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_spi_clkgen}] @@ -66,5 +108,5 @@ adi_sim_add_define "AD463X_AXI_CLKGEN_BA=[format "%d" ${BA_CLKGEN}]" set BA_PWM 0x44B00000 set_property offset $BA_PWM [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_cnv_generator}] -adi_sim_add_define "AD469X_PWM_GEN_BA=[format "%d" ${BA_PWM}]" +adi_sim_add_define "AD463X_PWM_GEN_BA=[format "%d" ${BA_PWM}]" diff --git a/testbenches/project/ad463x/system_project.tcl b/testbenches/project/ad463x/system_project.tcl index fbc7a90d0..35bc48767 100644 --- a/testbenches/project/ad463x/system_project.tcl +++ b/testbenches/project/ad463x/system_project.tcl @@ -16,15 +16,17 @@ 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_dmac.tcl source $ad_tb_dir/library/includes/sp_include_spi_engine.tcl +source $ad_tb_dir/library/includes/sp_include_pwm_gen.tcl +source $ad_tb_dir/library/includes/sp_include_clk_gen.tcl # Add test files to the project adi_sim_project_files [list \ - "$ad_tb_dir/library/regmaps/adi_regmap_clkgen_pkg.sv" \ - "$ad_tb_dir/library/regmaps/adi_regmap_pwm_gen_pkg.sv" \ - "tests/test_program.sv" \ -] + "spi_environment.sv" \ + "tests/test_program.sv" \ + ] #set a default test program adi_sim_add_define "TEST_PROGRAM=test_program" diff --git a/testbenches/project/ad463x/system_tb.sv b/testbenches/project/ad463x/system_tb.sv index 86f36a524..d1f8bd722 100644 --- a/testbenches/project/ad463x/system_tb.sv +++ b/testbenches/project/ad463x/system_tb.sv @@ -37,24 +37,33 @@ module system_tb(); + reg clk_enable = 1'b0; + reg [31:0] sclk_edge_count = 0; + reg ad463x_spi_vip_cs_prev = 1'b1; + reg cs_active = 1'b0; wire ad463x_busy; wire ad463x_cnv; - wire ad463x_echo_sclk; + reg ad463x_busy_sclk; + reg ad463x_echo_sclk; reg ad463x_ext_clk = 0; - wire ad463x_spi_cs; - wire ad463x_spi_sclk; + wire ad463x_spi_vip_cs; + reg ad463x_spi_vip_sclk_int; + wire ad463x_spi_vip_sclk; + reg ad463x_spi_vip_1_div_4_sclk; + reg ad463x_ddr_sclk_int; + wire ad463x_ddr_sclk; wire ad463x_spi_clk; - wire [`NUM_OF_SDI-1:0] ad463x_spi_sdi; - wire ad463x_spi_sdo; + wire [`NUM_OF_SDI-1:0] ad463x_spi_vip_sdi; + wire ad463x_spi_vip_sdo; wire ad463x_irq; `TEST_PROGRAM test( .ad463x_irq(ad463x_irq), - .ad463x_echo_sclk(ad463x_echo_sclk), - .ad463x_spi_sclk(ad463x_spi_sclk), - .ad463x_spi_cs(ad463x_spi_cs), + .ad463x_echo_sclk(), + .ad463x_spi_sclk(ad463x_spi_vip_sclk), + .ad463x_spi_cs(ad463x_spi_vip_cs), .ad463x_spi_clk(ad463x_spi_clk), - .ad463x_spi_sdi(ad463x_spi_sdi)); + .ad463x_spi_sdi(ad463x_spi_vip_sdi)); test_harness `TH ( .ad463x_busy(ad463x_busy), @@ -62,11 +71,12 @@ module system_tb(); .ad463x_cnv(ad463x_cnv), .ad463x_echo_sclk(ad463x_echo_sclk), .ad463x_ext_clk(ad463x_ext_clk), - .ad463x_spi_cs(ad463x_spi_cs), - .ad463x_spi_sclk(ad463x_spi_sclk), + .ad463x_spi_vip_cs(ad463x_spi_vip_cs), + .ad463x_spi_vip_sclk(ad463x_spi_vip_sclk), + .ad463x_ddr_sclk(ad463x_ddr_sclk), .ad463x_spi_clk(ad463x_spi_clk), - .ad463x_spi_sdi(ad463x_spi_sdi), - .ad463x_spi_sdo(ad463x_spi_sdo)); + .ad463x_spi_vip_sdi(ad463x_spi_vip_sdi), + .ad463x_spi_vip_sdo(ad463x_spi_vip_sdo)); //--------------------------------------------------------------------------- // Echo SCLK generation - we need this only if ECHO_SCLK is enabled @@ -75,16 +85,53 @@ module system_tb(); reg [SDI_PHY_DELAY:0] echo_delay_sclk = {SDI_PHY_DELAY{1'b0}}; reg delay_clk = 0; - wire m_spi_sclk; - assign ad463x_busy = (`CAPTURE_ZONE == 2) ? ad463x_echo_sclk : ad463x_cnv; - assign m_spi_sclk = ad463x_spi_sclk; + assign ad463x_busy = (`CAPTURE_ZONE == 2) ? (ad463x_busy_sclk) : ad463x_cnv; + + initial begin + forever @(ad463x_spi_vip_sclk) begin + if (clk_enable) begin + ad463x_busy_sclk <= #((`ECHO_SCLK_DELAY) * 1ns) ad463x_spi_vip_sclk; + end else begin + ad463x_busy_sclk <= #(`ECHO_SCLK_DELAY * 1ns) `CPOL; // Keep clock low when disabled + end + ad463x_spi_vip_sclk_int <= ad463x_spi_vip_sclk; + ad463x_echo_sclk <= #((`ECHO_SCLK_DELAY) * 1ns) ad463x_spi_vip_sclk; + ad463x_spi_vip_1_div_4_sclk <= #(3.125ns) ad463x_spi_vip_sclk; //it only works for 12.5ns sclk period + end + end + + //it is necessary to create DDR SCLK without delay to feed the SPI VIP + assign ad463x_ddr_sclk = ad463x_spi_vip_sclk_int ^ ad463x_spi_vip_1_div_4_sclk; - // Add an arbitrary delay to the echo_sclk signal + // Detect CS falling edge (high to low transition) always @(posedge delay_clk) begin - echo_delay_sclk <= {echo_delay_sclk, m_spi_sclk}; + ad463x_spi_vip_cs_prev <= ad463x_spi_vip_cs; + if (ad463x_spi_vip_cs_prev == 1'b1 && ad463x_spi_vip_cs == 1'b0) begin + cs_active <= 1'b1; // CS falling edge detected, start counting + end else if (ad463x_spi_vip_cs == 1'b1) begin + cs_active <= 1'b0; // CS deasserted, stop counting + sclk_edge_count <= 0; + end + end + + // Count SCLK edges when CS is active + always @(posedge ad463x_spi_vip_sclk or negedge ad463x_spi_vip_sclk) begin + if (cs_active) begin // Count only after CS falling edge + sclk_edge_count <= sclk_edge_count + 1; + end + end + + // Gate the DDR clock to only toggle when CS is active and limit to half the cycles + // Enable DDR clock for only half the SCLK edges + always @(*) begin + if (`DDR_EN == 1) begin + // In DDR mode, only enable for half the edges (DATA_DLENGTH_DDR worth of cycles) + clk_enable = (ad463x_spi_vip_cs == 1'b0) && (sclk_edge_count < `DATA_DLENGTH_SDR); + end else begin + clk_enable = 1'b1; // Always enable in SDR mode + end end - assign ad463x_echo_sclk = echo_delay_sclk[SDI_PHY_DELAY-1]; always #0.5ns delay_clk = ~delay_clk; always #5ns ad463x_ext_clk = ~ad463x_ext_clk; diff --git a/testbenches/project/ad463x/tests/test_program.sv b/testbenches/project/ad463x/tests/test_program.sv index 7f2c27add..fca8a2d81 100644 --- a/testbenches/project/ad463x/tests/test_program.sv +++ b/testbenches/project/ad463x/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2014-2018 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 @@ -36,16 +36,20 @@ // `include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" -import axi_vip_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 test_harness_env_pkg::*; +import spi_environment_pkg::*; +import axi4stream_vip_pkg::*; +import spi_engine_api_pkg::*; +import dmac_api_pkg::*; +import pwm_gen_api_pkg::*; +import clk_gen_api_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)::*; @@ -53,514 +57,493 @@ import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- -localparam SAMPLE_PERIOD = 500; -localparam ASYNC_SPI_CLK = 1; -localparam DATA_WIDTH = 32; -localparam DATA_DLENGTH = 32; -localparam ECHO_SCLK = 1; -localparam SDI_PHY_DELAY = 18; -localparam SDI_DELAY = 0; -localparam NUM_OF_CS = 1; -localparam THREE_WIRE = 0; -localparam CPOL = 0; -localparam CPHA = 1; -localparam CLOCK_DIVIDER = 0; -localparam NUM_OF_WORDS = 1; -localparam NUM_OF_TRANSFERS = 10; - -//--------------------------------------------------------------------------- -// SPI Engine instructions -//--------------------------------------------------------------------------- - -// Chip select instructions -localparam INST_CS_OFF = 32'h0000_10FF; -localparam INST_CS_ON = 32'h0000_10FE; - -// Transfer instructions -localparam INST_WR = 32'h0000_0100 | (NUM_OF_WORDS-1); -localparam INST_RD = 32'h0000_0200 | (NUM_OF_WORDS-1); -localparam INST_WRD = 32'h0000_0300 | (NUM_OF_WORDS-1); - -// Configuration register instructions -localparam INST_CFG = 32'h0000_2100 | (THREE_WIRE << 2) | (CPOL << 1) | CPHA; -localparam INST_PRESCALE = 32'h0000_2000 | CLOCK_DIVIDER; -localparam INST_DLENGTH = 32'h0000_2200 | DATA_DLENGTH; - -// Synchronization -localparam INST_SYNC = 32'h0000_3000; - -// Sleep instruction -localparam INST_SLEEP = 32'h0000_3100; -`define sleep(a) = INST_SLEEP | (a & 8'hFF); - program test_program ( input ad463x_irq, - input ad463x_echo_sclk, + output logic ad463x_echo_sclk, input ad463x_spi_sclk, input ad463x_spi_cs, input ad463x_spi_clk, input [(`NUM_OF_SDI - 1):0] ad463x_spi_sdi); timeunit 1ns; - timeprecision 1ps; - -test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; - -// -------------------------- -// Wrapper function for AXI read verify -// -------------------------- -task axi_read_v( - input [31:0] raddr, - input [31:0] vdata); - - base_env.mng.sequencer.RegReadVerify32(raddr,vdata); -endtask - -task axi_read( - input [31:0] raddr, - output [31:0] data); - - base_env.mng.sequencer.RegRead32(raddr,data); -endtask - -// -------------------------- -// Wrapper function for AXI write -// -------------------------- -task axi_write( - input [31:0] waddr, - input [31:0] wdata); - - base_env.mng.sequencer.RegWrite32(waddr,wdata); -endtask - -// -------------------------- -// Main procedure -// -------------------------- -initial begin - - //creating environment - 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, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); - - setLoggerVerbosity(ADI_VERBOSITY_NONE); - - base_env.start(); - base_env.sys_reset(); - - sanity_test(); - - #100ns; - - fifo_spi_test(); - - #100ns; - - offload_spi_test(); - - base_env.stop(); - - `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish(); - -end - -//--------------------------------------------------------------------------- -// Sanity test reg interface -//--------------------------------------------------------------------------- + timeprecision 100ps; + + // declare the class instances + test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; + spi_environment spi_env; + spi_engine_api spi_api; + dmac_api dma_api; + pwm_gen_api pwm_api; + clk_gen_api clkgen_api; + + //--------------------------------------------------------------------------- + // Echo SCLK generation - we need this only if ECHO_SCLK is enabled + //--------------------------------------------------------------------------- + // `ifdef DEF_ECHO_SCLK + // assign #(`ECHO_SCLK_DELAY * 1ns) ad463x_echo_sclk = ad463x_spi_sclk; + // `endif + // assign #18ns ad463x_echo_sclk = ad463x_spi_sclk; + // initial begin + // forever begin + // ad463x_echo_sclk = 0; + // @(ad463x_spi_sclk); + // #18ns ad463x_echo_sclk = ad463x_spi_sclk; + // end + // end + + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task automatic spi_receive( + ref int unsigned data[]); + spi_env.spi_agent.sequencer.receive_data(data); + endtask + + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH-1: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 + + bit [ 7:0] sdi_lane_mask; + bit [ 7:0] sdo_lane_mask; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] rx_data []; + bit [`DATA_DLENGTH-1:0] tx_data []; + logic [ `DATA_WIDTH-1:0] rx_data_cast []; + int unsigned tx_data_cast []; + int unsigned receive_data []; + int num_of_active_sdo_lanes = $countones(`SDO_LANE_MASK); + + // -------------------------- + // Main procedure + // -------------------------- + initial begin + + setLoggerVerbosity(ADI_VERBOSITY_HIGH); + + //creating environment + 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, + `TH.`MNG_AXI.inst.IF, + `TH.`DDR_AXI.inst.IF); + + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); + + spi_api = new("SPI Engine API", + base_env.mng.sequencer, + `SPI_AD463X_REGMAP_BA); + + dma_api = new("RX DMA API", + base_env.mng.sequencer, + `AD463X_DMA_BA); + + clkgen_api = new("CLKGEN API", + base_env.mng.sequencer, + `AD463X_AXI_CLKGEN_BA); + + pwm_api = new("PWM API", + base_env.mng.sequencer, + `AD463X_PWM_GEN_BA); + + 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_tests(); + + init(); + + #100ns; + + sdi_lane_mask = {`NUM_OF_SDI{1'b1}}; + sdo_lane_mask = 8'h1; + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + // spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + // spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); + // fifo_spi_test(); + + #100ns; + + offload_spi_test(); -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_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); - axi_write (`SPI_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - axi_read_v (`SPI_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); -endtask + spi_env.stop(); + base_env.stop(); + + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); -//--------------------------------------------------------------------------- -// SPI Engine generate transfer -//--------------------------------------------------------------------------- - -task generate_transfer_cmd( - input [7:0] sync_id); + end + //--------------------------------------------------------------------------- + // SPI Engine generate transfer + //--------------------------------------------------------------------------- + task generate_transfer_cmd( + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); + + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // assert CSN - axi_write (`SPI_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_CS_ON); + spi_api.fifo_command(`SET_CS(8'hFE)); // transfer data - axi_write (`SPI_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_WRD); + spi_api.fifo_command(`INST_WRD); // de-assert CSN - axi_write (`SPI_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_CS_OFF); + spi_api.fifo_command(`SET_CS(8'hFF)); // SYNC command to generate interrupt - axi_write (`SPI_AD469X_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 - while (1) begin - @(posedge ad463x_irq); // TODO: Make sure irq resets even the source remain active after clearing the IRQ register - // read pending IRQs - axi_read (`SPI_AD469X_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_AD469X_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_AD469X_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_AD469X_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - end -end - -//--------------------------------------------------------------------------- -// SDI data generator -//--------------------------------------------------------------------------- - -wire end_of_word; -wire spi_sclk_bfm = (ECHO_SCLK) ? ad463x_echo_sclk : ad463x_spi_sclk; -wire m_spi_csn_negedge_s; -wire m_spi_csn_int_s = &ad463x_spi_cs; -bit m_spi_csn_int_d = 0; -bit [31:0] sdi_shiftreg; -bit [7:0] spi_sclk_pos_counter = 0; -bit [7:0] spi_sclk_neg_counter = 0; -bit [31:0] sdi_preg[$]; -bit [31:0] sdi_nreg[$]; - -initial begin - forever begin - @(posedge ad463x_spi_clk); - m_spi_csn_int_d <= m_spi_csn_int_s; - end -end - -assign m_spi_csn_negedge_s = ~m_spi_csn_int_s & m_spi_csn_int_d; - -genvar i; -for (i = 0; i < `NUM_OF_SDI; i++) begin - assign ad463x_spi_sdi[i] = sdi_shiftreg[31]; // all SDI lanes got the same data -end - -assign end_of_word = (CPOL ^ CPHA) ? - (spi_sclk_pos_counter == DATA_DLENGTH) : - (spi_sclk_neg_counter == DATA_DLENGTH); - -initial 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; - end else begin - spi_sclk_pos_counter <= (spi_sclk_pos_counter == DATA_DLENGTH) ? 0 : spi_sclk_pos_counter+1; - end - end -end - -initial 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; - end else begin - spi_sclk_neg_counter <= (spi_sclk_neg_counter == DATA_DLENGTH) ? 0 : spi_sclk_neg_counter+1; - end - end -end - -// SDI shift register -initial begin - forever begin - // synchronization - if (CPHA ^ CPOL) - @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); - else - @(negedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); - if ((m_spi_csn_negedge_s) || (end_of_word)) begin - // delete the last word at end_of_word - if (end_of_word) begin - sdi_preg.pop_back(); - sdi_nreg.pop_back(); + spi_api.fifo_command((`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 ad463x_irq); + // read pending IRQs + spi_api.get_irq_pending(irq_pending); + // IRQ launched by Offload SYNC command + if (spi_api.check_irq_offload_sync_id_pending(irq_pending)) begin + spi_api.get_sync_id(sync_id); + `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (m_spi_csn_negedge_s) begin - // NOTE: assuming queue is empty - repeat (NUM_OF_WORDS) begin - sdi_preg.push_front($urandom); - sdi_nreg.push_front($urandom); - end - #1step; // prevent race condition - sdi_shiftreg <= (CPOL ^ CPHA) ? - sdi_preg[$] : - sdi_nreg[$]; - end else begin - sdi_shiftreg <= (CPOL ^ CPHA) ? - sdi_preg[$] : - sdi_nreg[$]; + // IRQ launched by SYNC command + if (spi_api.check_irq_sync_event(irq_pending)) begin + spi_api.get_sync_id(sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (m_spi_csn_negedge_s) @(posedge spi_sclk_bfm); // NOTE: when PHA=1 first shift should be at the second positive edge - end else begin /* if ((m_spi_csn_negedge_s) || (end_of_word)) */ - sdi_shiftreg <= {sdi_shiftreg[30:0], 1'b0}; - end - end -end - -//--------------------------------------------------------------------------- -// Storing SDI Data for later comparison -//--------------------------------------------------------------------------- - -bit offload_status = 0; -bit shiftreg_sampled = 0; -bit [15:0] sdi_store_cnt = (`NUM_OF_SDI == 1) ? 'h1 : 'h0; -bit [31:0] offload_sdi_data_store_arr [(2 * NUM_OF_TRANSFERS) - 1:0]; -bit [31:0] sdi_fifo_data_store; -bit [31:0] sdi_data_store; -bit [31:0] sdi_shiftreg2; -bit [31:0] sdi_shiftreg_aux; -bit [31:0] sdi_shiftreg_aux_old; -bit [31:0] sdi_shiftreg_old; - -assign sdi_shiftreg2 = {1'b0, sdi_shiftreg[31:1]}; - -initial 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 - shiftreg_sampled <= 'h0; - if (offload_status) begin - if (`NUM_OF_SDI == 1) begin - sdi_store_cnt <= sdi_store_cnt + 1; - end else begin - sdi_store_cnt <= sdi_store_cnt + 2; - end + // IRQ launched by SDI FIFO + if (spi_api.check_irq_sdi_almost_full(irq_pending)) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); end - end else if (shiftreg_sampled == 'h0 && sdi_data_store != 'h0) begin - if (offload_status) begin - if (`NUM_OF_SDI == 1) begin - sdi_shiftreg_old <= sdi_shiftreg; - if (`NO_REORDER == 0) begin - if (sdi_store_cnt [0] == 'h1 ) begin - for (int i=0; i<16; i=i+1) begin - offload_sdi_data_store_arr[sdi_store_cnt-1][16 + i] = sdi_shiftreg[2*i+1]; - offload_sdi_data_store_arr[sdi_store_cnt-1][i] = sdi_shiftreg_old[2*i+1]; - offload_sdi_data_store_arr[sdi_store_cnt][i] = sdi_shiftreg_old[2*i]; - offload_sdi_data_store_arr[sdi_store_cnt][16 + i] = sdi_shiftreg[2*i]; - end - end - end else if (`NO_REORDER == 1) begin - offload_sdi_data_store_arr[sdi_store_cnt-1] = sdi_shiftreg; - end - end else if (`NUM_OF_SDI == 2) begin - if (`DDR_EN == 1) begin - 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" +`include "axis_definitions.svh" + +package spi_environment_pkg; + + import logger_pkg::*; + import adi_environment_pkg::*; + + import m_axis_sequencer_pkg::*; + import adi_axis_agent_pkg::*; + import adi_spi_vip_pkg::*; + import adi_spi_vip_if_base_pkg::*; + + `ifdef DEF_SDO_STREAMING + import `PKGIFY(test_harness, sdo_src)::*; + `endif + + class spi_environment extends adi_environment; + + // Agents + adi_spi_agent spi_agent; + `ifdef DEF_SDO_STREAMING + adi_axis_master_agent #(`AXIS_VIP_PARAM_ORDER(test_harness_sdo_src_0)) sdo_src_agent; + `endif + + //============================================================================ + // Constructor + //============================================================================ + function new( + input string name, + + `ifdef DEF_SDO_STREAMING + virtual interface axi4stream_vip_if #(`AXIS_VIP_IF_PARAMS(test_harness_sdo_src_0)) sdo_src_axis_vip_if, + `endif + adi_spi_vip_if_base spi_s_vip_if); + + super.new(name); + + // Creating the agents + this.spi_agent = new("SPI VIP Agent", spi_s_vip_if, this); + `ifdef DEF_SDO_STREAMING + 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(); + `endif + endfunction + + //============================================================================ + // Configure environment + // - Configure the sequencers with an initial configuration before starting + //============================================================================ + task configure(); + `ifdef DEF_SDO_STREAMING + 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 + + //============================================================================ + // Start environment + // - Connect all the agents to the scoreboard + // - Start the agents + //============================================================================ + task start(); + this.spi_agent.start(); + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.start(); + `endif + endtask + + //============================================================================ + // Run subroutine + //============================================================================ + task run(); + fork + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.run(); + `endif + join_none + endtask + + //============================================================================ + // Stop subroutine + //============================================================================ + task stop(); + this.spi_agent.stop(); + `ifdef DEF_SDO_STREAMING + this.sdo_src_agent.stop(); + `endif + endtask + + endclass + +endpackage diff --git a/testbenches/project/ad738x/system_bd.tcl b/testbenches/project/ad738x/system_bd.tcl index bb8424410..85aa091c5 100644 --- a/testbenches/project/ad738x/system_bd.tcl +++ b/testbenches/project/ad738x/system_bd.tcl @@ -41,11 +41,36 @@ global ad_project_params source $ad_hdl_dir/projects/ad738x_fmc/common/ad738x_bd.tcl - create_bd_port -dir O ad738x_spi_clk - create_bd_port -dir O ad738x_irq +# Add test-specific VIPs +puts "CPOL: " +puts [$ad_project_params(CPOL)] +puts "CPHA: " +puts [$ad_project_params(CPHA)] - ad_connect ad738x_spi_clk spi_clkgen/clk_0 - ad_connect ad738x_irq spi_ad738x_adc/irq +ad_ip_instance adi_spi_vip spi_s_vip $ad_project_params(spi_s_vip_cfg) +adi_sim_add_define "SPI_S=spi_s_vip" + +# Create a new interface with Monitor mode +create_bd_intf_port -mode Monitor -vlnv analog.com:interface:spi_engine_rtl:1.0 ad738x_spi_vip + +# it is necessary to remove the connection with the master interface of the quad_ada77681_bd +ad_disconnect ad738x_spi $hier_spi_engine/m_spi +ad_connect spi_s_vip/s_spi $hier_spi_engine/m_spi +ad_connect ad738x_spi_vip $hier_spi_engine/m_spi + +if ($ad_project_params(SDO_STREAMING)) { + ad_ip_instance axi4stream_vip sdo_src $ad_project_params(axis_sdo_src_vip_cfg) + adi_sim_add_define "SDO_SRC=sdo_src" + ad_connect spi_clk sdo_src/aclk + ad_connect sys_cpu_resetn sdo_src/aresetn + ad_connect sdo_src/m_axis $hier_spi_engine/s_axis_sample +} + +create_bd_port -dir O ad738x_spi_vip_clk +create_bd_port -dir O ad738x_irq + +ad_connect ad738x_spi_vip_clk spi_clkgen/clk_0 +ad_connect ad738x_irq $hier_spi_engine/irq set BA_SPI_REGMAP 0x44A00000 set_property offset $BA_SPI_REGMAP [get_bd_addr_segs {mng_axi_vip/Master_AXI/spi_ad738x_adc_axi_regmap}] @@ -55,10 +80,10 @@ set BA_DMA 0x44A30000 set_property offset $BA_DMA [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_axi_ad738x_dma}] adi_sim_add_define "AD738x_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_spi_trigger_gen}] -adi_sim_add_define "AD738x_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 "AD738x_AXI_CLKGEN_BA=[format "%d" ${BA_CLKGEN}]" + +set BA_PWM 0x44B00000 +set_property offset $BA_PWM [get_bd_addr_segs {mng_axi_vip/Master_AXI/SEG_data_spi_trigger_gen}] +adi_sim_add_define "AD738x_PWM_GEN_BA=[format "%d" ${BA_PWM}]" \ No newline at end of file diff --git a/testbenches/project/ad738x/system_project.tcl b/testbenches/project/ad738x/system_project.tcl index 86f3f6eb4..0583e5a2b 100644 --- a/testbenches/project/ad738x/system_project.tcl +++ b/testbenches/project/ad738x/system_project.tcl @@ -31,13 +31,15 @@ if {[expr {![info exists use_smartconnect]}]} { # Create the project adi_sim_project_xilinx $project_name "xc7z007sclg400-1" +source $ad_tb_dir/library/includes/sp_include_axis.tcl source $ad_tb_dir/library/includes/sp_include_dmac.tcl source $ad_tb_dir/library/includes/sp_include_spi_engine.tcl +source $ad_tb_dir/library/includes/sp_include_pwm_gen.tcl +source $ad_tb_dir/library/includes/sp_include_clk_gen.tcl # Add test files to the project adi_sim_project_files [list \ - "$ad_tb_dir/library/regmaps/adi_regmap_clkgen_pkg.sv" \ - "$ad_tb_dir/library/regmaps/adi_regmap_pwm_gen_pkg.sv" \ + "spi_environment.sv" \ "tests/test_program.sv" \ ] diff --git a/testbenches/project/ad738x/system_tb.sv b/testbenches/project/ad738x/system_tb.sv index 744a13c43..d8305afeb 100644 --- a/testbenches/project/ad738x/system_tb.sv +++ b/testbenches/project/ad738x/system_tb.sv @@ -37,27 +37,27 @@ module system_tb(); - wire ad738x_spi_sclk; - wire ad738x_spi_sdo; - wire [`NUM_OF_SDI-1:0] ad738x_spi_sdi; - wire ad738x_spi_cs; - wire ad738x_spi_clk; - wire ad738x_irq; + wire ad738x_irq; + wire ad738x_spi_sclk; + wire [(`NUM_OF_CS - 1):0] ad738x_spi_cs; + wire ad738x_spi_clk; + wire ad738x_spi_sdo; + wire [`NUM_OF_SDIO-1:0] ad738x_spi_sdi; `TEST_PROGRAM test( - .ad738x_spi_clk (ad738x_spi_clk), .ad738x_irq (ad738x_irq), - .ad738x_spi_sdi(ad738x_spi_sdi), + .ad738x_spi_sclk (ad738x_spi_sclk), .ad738x_spi_cs (ad738x_spi_cs), - .ad738x_spi_sclk (ad738x_spi_sclk)); + .ad738x_spi_clk (ad738x_spi_clk), + .ad738x_spi_sdi(ad738x_spi_sdi)); test_harness `TH ( - .ad738x_spi_clk (ad738x_spi_clk), .irq (), .ad738x_irq(ad738x_irq), - .ad738x_spi_sdo (ad738x_spi_sdo), - .ad738x_spi_sdi (ad738x_spi_sdi), - .ad738x_spi_cs (ad738x_spi_cs), - .ad738x_spi_sclk (ad738x_spi_sclk)); + .ad738x_spi_vip_sclk (ad738x_spi_sclk), + .ad738x_spi_vip_cs (ad738x_spi_cs), + .ad738x_spi_vip_clk (ad738x_spi_clk), + .ad738x_spi_vip_sdo (ad738x_spi_sdo), + .ad738x_spi_vip_sdi (ad738x_spi_sdi)); endmodule diff --git a/testbenches/project/ad738x/tests/test_program.sv b/testbenches/project/ad738x/tests/test_program.sv index 165208808..11edc1810 100644 --- a/testbenches/project/ad738x/tests/test_program.sv +++ b/testbenches/project/ad738x/tests/test_program.sv @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2024 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,16 +36,20 @@ // `include "utils.svh" +`include "axi_definitions.svh" +`include "axis_definitions.svh" -import axi_vip_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 test_harness_env_pkg::*; +import spi_environment_pkg::*; +import axi4stream_vip_pkg::*; +import spi_engine_api_pkg::*; +import dmac_api_pkg::*; +import pwm_gen_api_pkg::*; +import clk_gen_api_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)::*; @@ -53,468 +57,483 @@ import `PKGIFY(test_harness, ddr_axi_vip)::*; //--------------------------------------------------------------------------- // SPI Engine configuration parameters //--------------------------------------------------------------------------- -localparam SAMPLE_PERIOD = 500; -localparam ASYNC_SPI_CLK = 1; -localparam DATA_WIDTH = 32; -localparam DATA_DLENGTH = 32; -localparam ECHO_SCLK = 0; -localparam SDI_PHY_DELAY = 18; -localparam SDI_DELAY = 0; -localparam NUM_OF_CS = 1; -localparam THREE_WIRE = 0; -localparam CPOL = 0; -localparam CPHA = 1; -localparam CLOCK_DIVIDER = 0; -localparam NUM_OF_WORDS = 1; -localparam NUM_OF_TRANSFERS = 10; - -//--------------------------------------------------------------------------- -// SPI Engine instructions -//--------------------------------------------------------------------------- - -// Chip select instructions -localparam INST_CS_OFF = 32'h0000_10FF; -localparam INST_CS_ON = 32'h0000_10FE; - -// Transfer instructions -localparam INST_WR = 32'h0000_0100 | (NUM_OF_WORDS-1); -localparam INST_RD = 32'h0000_0200 | (NUM_OF_WORDS-1); -localparam INST_WRD = 32'h0000_0300 | (NUM_OF_WORDS-1); - -// Configuration register instructions -localparam INST_CFG = 32'h0000_2100 | (THREE_WIRE << 2) | (CPOL << 1) | CPHA; -localparam INST_PRESCALE = 32'h0000_2000 | CLOCK_DIVIDER; -localparam INST_DLENGTH = 32'h0000_2200 | DATA_DLENGTH; - -// Synchronization -localparam INST_SYNC = 32'h0000_3000; - -// Sleep instruction -localparam INST_SLEEP = 32'h0000_3100; -`define sleep(a) = INST_SLEEP | (a & 8'hFF); - program test_program ( - input ad738x_spi_clk, - input ad738x_irq, - input ad738x_spi_sclk, - input [(`NUM_OF_SDI - 1):0] ad738x_spi_sdi, - input ad738x_spi_cs); + inout ad738x_irq, + inout ad738x_spi_sclk, + inout [(`NUM_OF_CS - 1):0] ad738x_spi_cs, + inout ad738x_spi_clk, + inout [(`NUM_OF_SDIO-1):0] ad738x_spi_sdi); timeunit 1ns; - timeprecision 1ps; + timeprecision 100ps; + + // declare the class instances + test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; + spi_environment spi_env; + spi_engine_api spi_api; + dmac_api dma_api; + pwm_gen_api pwm_api; + clk_gen_api clkgen_api; + + // -------------------------- + // Wrapper function for SPI receive (from DUT) + // -------------------------- + task automatic spi_receive( + ref int unsigned data[]); + spi_env.spi_agent.sequencer.receive_data(data); + endtask + + // -------------------------- + // Wrapper function for SPI send (to DUT) + // -------------------------- + task spi_send( + input [`DATA_DLENGTH-1: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 + + bit [ 7:0] sdi_lane_mask; + bit [ 7:0] sdo_lane_mask; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data []; + bit [`DATA_DLENGTH-1:0] sdi_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] sdo_fifo_data_store []; + bit [`DATA_DLENGTH-1:0] rx_data []; + bit [`DATA_DLENGTH-1:0] tx_data []; + logic [ `DATA_WIDTH-1:0] rx_data_cast []; + int unsigned tx_data_cast []; + int unsigned receive_data []; + int num_of_active_sdi_lanes = $countones(`SDI_LANE_MASK); + int num_of_active_sdo_lanes = $countones(`SDO_LANE_MASK); + + // -------------------------- + // Main procedure + // -------------------------- + initial begin -test_harness_env #(`AXI_VIP_PARAMS(test_harness, mng_axi_vip), `AXI_VIP_PARAMS(test_harness, ddr_axi_vip)) base_env; + setLoggerVerbosity(ADI_VERBOSITY_NONE); -// -------------------------- -// Wrapper function for AXI read verif -// -------------------------- -task axi_read_v( - input [31:0] raddr, - input [31:0] vdata); + //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, + `TH.`MNG_AXI.inst.IF, + `TH.`DDR_AXI.inst.IF); - base_env.mng.sequencer.RegReadVerify32(raddr,vdata); -endtask + spi_env = new("SPI Engine Environment", + `ifdef DEF_SDO_STREAMING + `TH.`SDO_SRC.inst.IF, + `endif + `TH.`SPI_S.inst.IF.vif); -task axi_read( - input [31:0] raddr, - output [31:0] data); + spi_api = new("SPI Engine API", + base_env.mng.sequencer, + `SPI_AD738x_REGMAP_BA); - base_env.mng.sequencer.RegRead32(raddr,data); -endtask + dma_api = new("RX DMA API", + base_env.mng.sequencer, + `AD738x_DMA_BA); -// -------------------------- -// Wrapper function for AXI write -// -------------------------- -task axi_write( - input [31:0] waddr, - input [31:0] wdata); + clkgen_api = new("CLKGEN API", + base_env.mng.sequencer, + `AD738x_AXI_CLKGEN_BA); - base_env.mng.sequencer.RegWrite32(waddr,wdata); -endtask + pwm_api = new("PWM API", + base_env.mng.sequencer, + `AD738x_PWM_GEN_BA); -// -------------------------- -// Main procedure -// -------------------------- -initial begin + base_env.start(); + spi_env.start(); - //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, - `TH.`MNG_AXI.inst.IF, - `TH.`DDR_AXI.inst.IF); + base_env.sys_reset(); - setLoggerVerbosity(ADI_VERBOSITY_NONE); + spi_env.configure(); - base_env.start(); - base_env.sys_reset(); + spi_env.run(); - sanity_test(); + spi_env.spi_agent.sequencer.set_default_miso_data('h2AA55); - #100ns; + // start sdo source (will wait for data enqueued) + `ifdef DEF_SDO_STREAMING + spi_env.sdo_src_agent.sequencer.start(); + `endif - fifo_spi_test(); + sanity_tests(); - #100ns; + init(); - offload_spi_test(); + #100ns; - base_env.stop(); + fifo_spi_test(); + sdi_lane_mask = 8'h1; + sdo_lane_mask = 8'h1; + // sdi_lane_mask = (2 ** `NUM_OF_SDIO)-1; + // sdo_lane_mask = (2 ** `NUM_OF_SDO)-1; + num_of_active_sdi_lanes = $countones(sdi_lane_mask); + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask));//guarantee all SDI lanes must be active + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask));//guarantee only one SDO lane is active - `INFO(("Test Done"), ADI_VERBOSITY_NONE); - $finish(); + #100ns; -end + offload_spi_test(); -//--------------------------------------------------------------------------- -// 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_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_VERSION), pcore_version); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - axi_read_v (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SCRATCH), 32'hDEADBEEF); - `INFO(("Sanity Test Done"), ADI_VERBOSITY_LOW); -endtask + spi_env.stop(); + base_env.stop(); -//--------------------------------------------------------------------------- -// SPI Engine generate transfer -//--------------------------------------------------------------------------- + `INFO(("Test Done"), ADI_VERBOSITY_NONE); + $finish(); -task generate_transfer_cmd( - input [7:0] sync_id); + end + //--------------------------------------------------------------------------- + // SPI Engine generate transfer + //--------------------------------------------------------------------------- + task generate_transfer_cmd( + input [7:0] sync_id, + input [7:0] sdi_lane_mask, + input [7:0] sdo_lane_mask); + + // define spi lane mask + spi_api.fifo_command(`SET_SDI_LANE_MASK(sdi_lane_mask)); + spi_api.fifo_command(`SET_SDO_LANE_MASK(sdo_lane_mask)); // assert CSN - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_CS_ON); + spi_api.fifo_command(`SET_CS(8'hFE)); // transfer data - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_WRD); + spi_api.fifo_command(`INST_WRD); // de-assert CSN - axi_write (`SPI_AD738x_REGMAP_BA+ GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_CS_OFF); + spi_api.fifo_command(`SET_CS(8'hFF)); // SYNC command to generate interrupt - axi_write (`SPI_AD738x_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 - while (1) begin - @(posedge ad738x_irq); - // read pending IRQs - axi_read (`SPI_AD738x_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_AD738x_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_AD738x_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_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_IRQ_PENDING), irq_pending); - end -end - -//--------------------------------------------------------------------------- -// Echo SCLK generation - we need this only if ECHO_SCLK is enabled -//--------------------------------------------------------------------------- - - reg [SDI_PHY_DELAY:0] echo_delay_sclk = {SDI_PHY_DELAY{1'b0}}; - reg delay_clk = 0; - wire m_rx_sclk; + spi_api.fifo_command(`INST_SYNC | sync_id); + `INFO(("Transfer generation finished."), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // SPI Engine SDO data + //--------------------------------------------------------------------------- + task sdo_stream_gen( + input [`DATA_DLENGTH-1:0] tx_data[]); + xil_axi4stream_data_byte data[((`DATA_WIDTH/8) * (`NUM_OF_SDO))-1:0]; + `ifdef DEF_SDO_STREAMING + for (int i = 0; i < `NUM_OF_SDO; i++) begin + for (int j = 0; j < (`DATA_WIDTH/8); j++) begin + data[i * (`DATA_WIDTH/8) + j] = (tx_data[i] & (8'hFF << 8*j)) >> 8*j; + spi_env.sdo_src_agent.sequencer.push_byte_for_stream(data[i * (`DATA_WIDTH/8) + j]); + end + end + spi_env.sdo_src_agent.sequencer.add_xfer_descriptor_byte_count((`DATA_WIDTH/8) * (`NUM_OF_SDO),0,0); + `endif + endtask - assign m_rx_sclk = ad738x_spi_sclk; + //--------------------------------------------------------------------------- + // IRQ callback + //--------------------------------------------------------------------------- + reg [4:0] irq_pending = 0; + reg [7:0] sync_id = 0; - // Add an arbitrary delay to the echo_sclk signal initial begin forever begin - @(posedge delay_clk) begin - echo_delay_sclk <= {echo_delay_sclk, m_rx_sclk}; - end - end - end - assign ad738x_echo_sclk = echo_delay_sclk[SDI_PHY_DELAY-1]; - -initial begin - forever begin - #0.5ns delay_clk = ~delay_clk; - end -end - -//--------------------------------------------------------------------------- -// SDI data generator -//--------------------------------------------------------------------------- - -wire end_of_word; -wire spi_sclk_bfm = ad738x_echo_sclk; -wire m_spi_csn_negedge_s; -wire m_spi_csn_int_s = &ad738x_spi_cs; -bit m_spi_csn_int_d = 0; -bit [31:0] sdi_shiftreg; -bit [7:0] spi_sclk_pos_counter = 0; -bit [7:0] spi_sclk_neg_counter = 0; -bit [31:0] sdi_preg[$]; -bit [31:0] sdi_nreg[$]; - -initial begin - forever begin - @(posedge ad738x_spi_clk); - m_spi_csn_int_d <= m_spi_csn_int_s; - end -end - -assign m_spi_csn_negedge_s = ~m_spi_csn_int_s & m_spi_csn_int_d; - -genvar i; -for (i = 0; i < `NUM_OF_SDI; i++) begin - assign ad738x_spi_sdi[i] = sdi_shiftreg[31]; // all SDI lanes got the same data -end - -assign end_of_word = (CPOL ^ CPHA) ? - (spi_sclk_pos_counter == DATA_DLENGTH) : - (spi_sclk_neg_counter == DATA_DLENGTH); - -initial 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; - end else begin - spi_sclk_pos_counter <= (spi_sclk_pos_counter == DATA_DLENGTH) ? 0 : spi_sclk_pos_counter+1; - end - end -end - -initial 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; - end else begin - spi_sclk_neg_counter <= (spi_sclk_neg_counter == DATA_DLENGTH) ? 0 : spi_sclk_neg_counter+1; - end - end -end - -// SDI shift register -initial begin - forever begin - // synchronization - if (CPHA ^ CPOL) - @(posedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); - else - @(negedge spi_sclk_bfm or posedge m_spi_csn_negedge_s); - if ((m_spi_csn_negedge_s) || (end_of_word)) begin - // delete the last word at end_of_word - if (end_of_word) begin - sdi_preg.pop_back(); - sdi_nreg.pop_back(); + @(posedge ad738x_irq); + // read pending IRQs + spi_api.get_irq_pending(irq_pending); + // IRQ launched by Offload SYNC command + if (spi_api.check_irq_offload_sync_id_pending(irq_pending)) begin + spi_api.get_sync_id(sync_id); + `INFO(("Offload SYNC %d IRQ. An offload transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (m_spi_csn_negedge_s) begin - // NOTE: assuming queue is empty - repeat (NUM_OF_WORDS) begin - sdi_preg.push_front($urandom); - sdi_nreg.push_front($urandom); - end - #1step; // prevent race condition - sdi_shiftreg <= (CPOL ^ CPHA) ? - sdi_preg[$] : - sdi_nreg[$]; - end else begin - sdi_shiftreg <= (CPOL ^ CPHA) ? - sdi_preg[$] : - sdi_nreg[$]; + // IRQ launched by SYNC command + if (spi_api.check_irq_sync_event(irq_pending)) begin + spi_api.get_sync_id(sync_id); + `INFO(("SYNC %d IRQ. FIFO transfer just finished.", sync_id), ADI_VERBOSITY_LOW); end - if (m_spi_csn_negedge_s) @(posedge spi_sclk_bfm); // NOTE: when PHA=1 first shift should be at the second positive edge - end else begin /* if ((m_spi_csn_negedge_s) || (end_of_word)) */ - sdi_shiftreg <= {sdi_shiftreg[30:0], 1'b0}; - end - end -end - -//--------------------------------------------------------------------------- -// Storing SDI Data for later comparison -//--------------------------------------------------------------------------- - -bit offload_status = 0; -bit shiftreg_sampled = 0; -bit [15:0] sdi_store_cnt = 'h0; -bit [31:0] offload_sdi_data_store_arr [(2* NUM_OF_TRANSFERS) - 1:0]; -bit [31:0] sdi_fifo_data_store; -bit [31:0] sdi_data_store; -bit [31:0] sdi_shiftreg2; -bit [31:0] sdi_shiftreg_aux; -bit [31:0] sdi_shiftreg_aux_old; -bit [31:0] sdi_shiftreg_old; - -assign sdi_shiftreg2 = {1'b0, sdi_shiftreg[31:1]}; - -initial 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 - shiftreg_sampled <= 'h0; - if (offload_status) begin - sdi_store_cnt <= sdi_store_cnt + 2; + // IRQ launched by SDI FIFO + if (spi_api.check_irq_sdi_almost_full(irq_pending)) begin + `INFO(("SDI FIFO IRQ."), ADI_VERBOSITY_LOW); + end + // IRQ launched by SDO FIFO + if (spi_api.check_irq_sdo_almost_empty(irq_pending)) begin + `INFO(("SDO FIFO IRQ."), ADI_VERBOSITY_LOW); end - end else if (shiftreg_sampled == 'h0 && sdi_data_store != 'h0) begin - if (offload_status) begin - offload_sdi_data_store_arr [sdi_store_cnt] = sdi_shiftreg; - offload_sdi_data_store_arr [sdi_store_cnt + 1] = sdi_shiftreg; - end else begin - sdi_fifo_data_store = sdi_shiftreg; + // IRQ launched by CMD FIFO + if (spi_api.check_irq_cmd_almost_empty(irq_pending)) begin + `INFO(("CMD FIFO IRQ."), ADI_VERBOSITY_LOW); end - shiftreg_sampled <= 'h1; + // Clear all pending IRQs + spi_api.clear_irq_pending(irq_pending); end end -end - -//--------------------------------------------------------------------------- -// Offload Transfer Counter -//--------------------------------------------------------------------------- - -bit [31:0] offload_transfer_cnt; - -initial begin - forever begin - @(posedge shiftreg_sampled && offload_status); - offload_transfer_cnt <= offload_transfer_cnt + 'h1; - end -end - -//--------------------------------------------------------------------------- -// Offload SPI Test -//--------------------------------------------------------------------------- -bit [31:0] offload_captured_word_arr [(2* NUM_OF_TRANSFERS) -1 :0]; - -task offload_spi_test(); - // Configure pwm - axi_write (`AD738x_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 (`AD738x_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 - axi_write (`AD738x_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); + //--------------------------------------------------------------------------- + // Sanity Tests + //--------------------------------------------------------------------------- + task sanity_tests(); + spi_api.sanity_test(); + dma_api.sanity_test(); + pwm_api.sanity_test(); + endtask + + //--------------------------------------------------------------------------- + // Offload SPI Test + //--------------------------------------------------------------------------- + bit [`DATA_DLENGTH-1:0] sdi_read_data []; + bit [`DATA_DLENGTH-1:0] sdi_read_data_store []; + bit [ `DATA_WIDTH-1:0] sdo_write_data []; + bit [`DATA_DLENGTH-1:0] sdo_write_data_store []; + + task offload_spi_test(); + + tx_data_cast = new [num_of_active_sdo_lanes]; + tx_data = new [num_of_active_sdo_lanes]; + sdo_write_data = new [`NUM_OF_SDO]; + rx_data = new [`NUM_OF_SDIO]; + sdi_read_data = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)* num_of_active_sdi_lanes]; + sdi_read_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)* num_of_active_sdi_lanes]; + + `ifdef DEF_SDO_STREAMING + sdo_write_data_store = new [(`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `else + sdo_write_data_store = new [(`NUM_OF_WORDS)*(`NUM_OF_SDO)]; + `endif //Configure DMA - base_env.mng.sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_CONTROL), `SET_DMAC_CONTROL_ENABLE(1)); // Enable DMA - base_env.mng.sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_FLAGS), - `SET_DMAC_FLAGS_TLAST(1) | - `SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(1) - ); // Use TLAST - base_env.mng.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.sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_DEST_ADDRESS), `SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(`DDR_BA)); // DEST_ADDRESS - base_env.mng.sequencer.RegWrite32(`AD738x_DMA_BA + GetAddrs(DMAC_TRANSFER_SUBMIT), `SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1)); // Submit transfer DMA + dma_api.enable_dma(); + dma_api.set_flags( + .cyclic(1'b0), + .tlast(1'b1), + .partial_reporting_en(1'b1) + ); + dma_api.set_lengths(((`NUM_OF_TRANSFERS) * (`NUM_OF_WORDS) * (`NUM_OF_SDIO) * (`DATA_WIDTH/8))-1,0); + dma_api.set_dest_addr(`DDR_BA); + dma_api.transfer_start(); // Configure the Offload module - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CFG); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_PRESCALE); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_DLENGTH); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CS_ON); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_RD); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_CS_OFF); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_CDM_FIFO), INST_SYNC | 2); - - offload_status = 1; - - // Start the offload - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(1)); - `INFO(("Offload started"), ADI_VERBOSITY_LOW); + spi_api.fifo_offload_command(`INST_CFG); + spi_api.fifo_offload_command(`INST_PRESCALE); + spi_api.fifo_offload_command(`INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + spi_api.fifo_offload_command(`SET_CS_INV_MASK(8'hFF)); + end + spi_api.fifo_offload_command(`SET_CS(8'hFE)); + spi_api.fifo_offload_command(`INST_WRD); + spi_api.fifo_offload_command(`SET_CS(8'hFF)); + spi_api.fifo_offload_command(`INST_SYNC | 2); + + // Enqueue transfers to DUT + for (int i = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)); i++) begin + for (int j = 0, k = 0; j < (`NUM_OF_SDIO); j++) begin + rx_data[j] = sdi_lane_mask[j] ? $urandom : `SDO_IDLE_STATE; //easier to debug + if (sdi_lane_mask[j]) begin + sdi_read_data_store[i * num_of_active_sdi_lanes + k] = rx_data[j]; + k++; + end + end - wait(offload_transfer_cnt == NUM_OF_TRANSFERS); + spi_send(rx_data); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_OFFLOAD0_EN), `SET_AXI_SPI_ENGINE_OFFLOAD0_EN_OFFLOAD0_EN(0)); - offload_status = 0; + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = $urandom; + tx_data_cast[j] = tx_data[j]; + end + + `ifdef DEF_SDO_STREAMING + sdo_stream_gen(tx_data); + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[k]; // all of valid random words will be used + k++; + end else begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = `SDO_IDLE_STATE; + end + end + `else + if (i < (`NUM_OF_WORDS)) begin + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = tx_data[k]; //only the first NUM_OF_WORDS random words will be used for all transfers + k++; + end else begin + sdo_write_data_store[i * (`NUM_OF_SDO) + j] = `SDO_IDLE_STATE; + end + end + spi_api.sdo_offload_fifo_write(tx_data_cast); + end + `endif + end - `INFO(("Offload stopped"), ADI_VERBOSITY_LOW); + #100ns; + spi_api.start_offload(); + `INFO(("Offload started."), ADI_VERBOSITY_LOW); + spi_wait_send(); + spi_api.stop_offload(); + `INFO(("Offload stopped."), ADI_VERBOSITY_LOW); #2000ns; - for (int i=0; i<=((2* NUM_OF_TRANSFERS) -1); i=i+1) begin - offload_captured_word_arr[i] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(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 - `ERROR(("Offload Test FAILED")); + if (irq_pending == 'h0) begin + `FATAL(("IRQ Test FAILED")); end else begin - `INFO(("Offload Test PASSED"), ADI_VERBOSITY_LOW); + `INFO(("IRQ Test PASSED"), ADI_VERBOSITY_LOW); end -endtask - -//--------------------------------------------------------------------------- -// FIFO SPI Test -//--------------------------------------------------------------------------- -bit [31:0] sdi_fifo_data = 0; + for (int i = 0, k = 0; i < ((`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS)*(`NUM_OF_SDIO)); i++) begin + if (sdi_lane_mask[i%(`NUM_OF_SDIO)]) begin + sdi_read_data[k] = base_env.ddr.agent.mem_model.backdoor_memory_read_4byte(xil_axi_uint'(`DDR_BA + 4*i)); + if (sdi_read_data[k] != sdi_read_data_store[k]) begin //one word at a time comparison + `INFO(("sdi_read_data[%d]: %x; sdi_read_data_store[%d]: %x", + k, sdi_read_data[k], + k, sdi_read_data_store[k]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Read Test FAILED")); + end + k++; + end + end + `INFO(("Offload Read Test PASSED"), ADI_VERBOSITY_LOW); + + for (int i = 0; i < (`NUM_OF_TRANSFERS)*(`NUM_OF_WORDS); i++) begin + spi_receive(sdo_write_data); + for (int j = 0; j < `NUM_OF_SDO; j++) begin + `ifdef DEF_SDO_STREAMING + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + (i * `NUM_OF_SDO + j), + sdo_write_data_store[(i * `NUM_OF_SDO + j)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `else + if (sdo_write_data[j] != sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]) begin + `INFO(("sdo_write_data[%d]: %x; sdo_write_data_store[%d]: %x", + j, sdo_write_data[j], + ((i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)), + sdo_write_data_store[(i * `NUM_OF_SDO + j) % (`NUM_OF_WORDS * `NUM_OF_SDO)]), ADI_VERBOSITY_LOW); + `FATAL(("Offload Write Test FAILED")); + end + `endif + end + end + `INFO(("Offload Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // FIFO SPI Test + //--------------------------------------------------------------------------- + task fifo_spi_test(); + + sdi_lane_mask = 8'h1; + sdo_lane_mask = 8'h1; + num_of_active_sdi_lanes = $countones(sdi_lane_mask); + num_of_active_sdo_lanes = $countones(sdo_lane_mask); + + rx_data_cast = new [num_of_active_sdi_lanes]; + rx_data = new [(`NUM_OF_SDIO)]; + sdi_fifo_data = new [num_of_active_sdi_lanes * `NUM_OF_WORDS]; + sdi_fifo_data_store = new [num_of_active_sdi_lanes * `NUM_OF_WORDS]; + tx_data = new [num_of_active_sdo_lanes]; + tx_data_cast = new [num_of_active_sdo_lanes]; + receive_data = new [`NUM_OF_SDO]; + sdo_fifo_data = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + sdo_fifo_data_store = new [`NUM_OF_SDO * `NUM_OF_WORDS]; + + // Generate a FIFO transaction, write SDO first + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + for (int j = 0, k = 0; j < (`NUM_OF_SDIO); j++) begin + rx_data[j] = sdi_lane_mask[j] ? $urandom : `SDO_IDLE_STATE; //easier to debug + if (sdi_lane_mask[j]) begin + sdi_fifo_data_store[i * num_of_active_sdi_lanes + k] = rx_data[j]; + k++; + end + end -task fifo_spi_test(); - // Start spi clk generator - axi_write (`AD738x_AXI_CLKGEN_BA + GetAddrs(AXI_CLKGEN_REG_RSTN), - `SET_AXI_CLKGEN_REG_RSTN_MMCM_RSTN(1) | - `SET_AXI_CLKGEN_REG_RSTN_RSTN(1) - ); + for (int j = 0; j < num_of_active_sdo_lanes; j++) begin + tx_data[j] = $urandom; + tx_data_cast[j] = tx_data[j]; //a cast is necessary for the SPI API + end - // Enable SPI Engine - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_ENABLE), `SET_AXI_SPI_ENGINE_ENABLE_ENABLE(0)); + for (int j = 0, k = 0; j < `NUM_OF_SDO; j++) begin + if (sdo_lane_mask[j]) begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = tx_data[k]; + k++; + end else begin + sdo_fifo_data_store[i * `NUM_OF_SDO + j] = `SDO_IDLE_STATE; + end + end + + spi_api.sdo_fifo_write((tx_data_cast));// << API is expecting 32 bits, only active lanes are written + spi_send(rx_data); + end - // Configure the execution module - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_CFG); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_PRESCALE); - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_CMD_FIFO), INST_DLENGTH); + //wait a long time before starting execution with the correct lane mask + #500ns; + generate_transfer_cmd(1, sdi_lane_mask, sdo_lane_mask); //generate transfer with specific spi lane mask - // Set up the interrupts - axi_write (`SPI_AD738x_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) - ); + `INFO(("Waiting for SPI VIP send..."), ADI_VERBOSITY_LOW); + spi_wait_send(); + `INFO(("SPI sent"), ADI_VERBOSITY_LOW); - #100ns; - // Generate a FIFO transaction, write SDO first - repeat (NUM_OF_WORDS) begin - axi_write (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDO_FIFO), (16'hDEAD << (DATA_WIDTH - DATA_DLENGTH))); - end - - generate_transfer_cmd(1); + for (int i = 0; i < (`NUM_OF_WORDS); i++) begin + spi_api.sdi_fifo_read(rx_data_cast); //API always returns 32 bits + spi_receive(receive_data); + for (int j = 0; j < num_of_active_sdi_lanes; j++) begin + sdi_fifo_data[i * num_of_active_sdi_lanes + j] = rx_data_cast[j]; + end + for (int j = 0; j < (`NUM_OF_SDO); j++) begin + sdo_fifo_data[i * (`NUM_OF_SDO) + j] = receive_data[j]; + end + end - #100ns; - wait(sync_id == 1); - #100ns; + foreach (sdi_fifo_data[i]) begin + if (sdi_fifo_data[i] !== sdi_fifo_data_store[i]) begin + `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data[i], sdi_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Read Test FAILED")); + end + end + `INFO(("Fifo Read Test PASSED"), ADI_VERBOSITY_LOW); - repeat (NUM_OF_WORDS) begin - axi_read (`SPI_AD738x_REGMAP_BA + GetAddrs(AXI_SPI_ENGINE_SDI_FIFO_PEEK) , sdi_fifo_data); - end + foreach (sdo_fifo_data[i]) begin + if (sdo_fifo_data[i] !== sdo_fifo_data_store[i]) begin + `INFO(("sdo_fifo_data: %x; sdo_fifo_data_store %x", sdo_fifo_data[i], sdo_fifo_data_store[i]), ADI_VERBOSITY_LOW); + `FATAL(("Fifo Write Test FAILED")); + end + end + `INFO(("Fifo Write Test PASSED"), ADI_VERBOSITY_LOW); + endtask + + //--------------------------------------------------------------------------- + // Test initialization + //--------------------------------------------------------------------------- + task init(); + // Start spi clk generator + clkgen_api.enable_clkgen(); + + // Config pwm + pwm_api.reset(); + pwm_api.pulse_period_config(0,'h64); // config channel 0 period + pwm_api.load_config(); + pwm_api.start(); + `INFO(("axi_pwm_gen started."), ADI_VERBOSITY_LOW); + + // Enable SPI Engine + spi_api.enable_spi_engine(); + + // Configure the execution module + spi_api.fifo_command(`INST_CFG); + spi_api.fifo_command(`INST_PRESCALE); + spi_api.fifo_command(`INST_DLENGTH); + if (`CS_ACTIVE_HIGH) begin + spi_api.fifo_command(`SET_CS_INV_MASK(8'hFF)); + end - `INFO(("sdi_fifo_data: %x; sdi_fifo_data_store %x", sdi_fifo_data, sdi_fifo_data_store), ADI_VERBOSITY_LOW); + // Set up the interrupts + spi_api.set_interrup_mask(.sync_event(1'b1),.offload_sync_id_pending(1'b1)); - if (sdi_fifo_data != sdi_fifo_data_store) begin - `ERROR(("Fifo Read Test FAILED")); - end else begin - `INFO(("Fifo Read Test PASSED"), ADI_VERBOSITY_LOW); - end -endtask + endtask endprogram