Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions hw/top_chip/dv/env/seq_lib/top_chip_dv_spi_device_base_vseq.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

class top_chip_dv_spi_device_base_vseq extends top_chip_dv_base_vseq;
`uvm_object_utils(top_chip_dv_spi_device_base_vseq)

// Standard SV/UVM methods
extern function new(string name="");
extern task pre_start();
extern task body();
endclass : top_chip_dv_spi_device_base_vseq


function top_chip_dv_spi_device_base_vseq::new(string name="");
super.new(name);
endfunction : new

task top_chip_dv_spi_device_base_vseq::body();
spi_device_seq m_device_seq;
super.body();

// Wait for reset before configuring
p_sequencer.cfg.peri_clk_vif.wait_for_reset();

// Create and start the spi_device sequence
m_device_seq = spi_device_seq::type_id::create("m_device_seq");
fork m_device_seq.start(p_sequencer.spi_device_sqr); join_none
endtask : body

task top_chip_dv_spi_device_base_vseq::pre_start();
// Select the first Csb for communication.
p_sequencer.cfg.m_spi_device_agent_cfg.csid = '0;

// While the selection of this value seems arbitrary, it is not.
// The spi agent has a concept of "transaction size" that is used by the
// monitor / driver to determine how it should view the number of collected
// bytes.
// The value 4 is chosen because the corresponding C test case does the following:
// - Transmit 4 bytes
// - Transmit and receive N bytes
// - Receive 4 bytes
// This sequence, when paired with the agent's 4 byte granularity playback,
// works well as a smoke test case for spi host activity.
p_sequencer.cfg.m_spi_device_agent_cfg.num_bytes_per_trans_in_mon = 4;

// Setting the byte order to 0 ensures that the 4 byte transaction sent to
// the agent from the DUT is played back in exactly the same order, thus
// making things easy to compare.
p_sequencer.cfg.m_spi_device_agent_cfg.byte_order = '0;
super.pre_start();
endtask : pre_start
1 change: 1 addition & 0 deletions hw/top_chip/dv/env/seq_lib/top_chip_dv_vseq_list.sv
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

`include "top_chip_dv_base_vseq.sv"
`include "top_chip_dv_uart_base_vseq.sv"
`include "top_chip_dv_spi_device_base_vseq.sv"
2 changes: 2 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env.core
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ filesets:
- lowrisc:dv:dv_utils
- lowrisc:dv:mem_bkdr_util
- lowrisc:dv:uart_agent
- lowrisc:dv:spi_agent
- lowrisc:dv:common_ifs
files:
- top_chip_dv_env_pkg.sv
Expand All @@ -22,6 +23,7 @@ filesets:
- seq_lib/top_chip_dv_vseq_list.sv: {is_include_file: true}
- seq_lib/top_chip_dv_base_vseq.sv: {is_include_file: true}
- seq_lib/top_chip_dv_uart_base_vseq.sv: {is_include_file: true}
- seq_lib/top_chip_dv_spi_device_base_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource

targets:
Expand Down
6 changes: 6 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class top_chip_dv_env extends uvm_env;

// Agents
uart_agent m_uart_agent;
spi_agent m_spi_device_agent;

// Standard SV/UVM methods
extern function new(string name="", uvm_component parent=null);
Expand Down Expand Up @@ -70,6 +71,10 @@ function void top_chip_dv_env::build_phase(uvm_phase phase);
m_uart_agent = uart_agent::type_id::create("m_uart_agent", this);
uvm_config_db#(uart_agent_cfg)::set(this, "m_uart_agent*", "cfg", cfg.m_uart_agent_cfg);

// Instantiate SPI device agent
m_spi_device_agent = spi_agent::type_id::create("m_spi_device_agent", this);
uvm_config_db#(spi_agent_cfg)::set(this, "m_spi_device_agent*", "cfg", cfg.m_spi_device_agent_cfg);

uvm_config_db#(top_chip_dv_env_cfg)::set(this, "", "cfg", cfg);

top_vsqr = top_chip_dv_virtual_sequencer::type_id::create("top_vsqr", this);
Expand All @@ -82,6 +87,7 @@ function void top_chip_dv_env::connect_phase(uvm_phase phase);
// Track specific agent sequencers in the virtual sequencer.
// Allows virtual sequences to use the agents to drive RX items.
top_vsqr.uart_sqr = m_uart_agent.sequencer;
top_vsqr.spi_device_sqr = m_spi_device_agent.sequencer;

// Connect monitor output to matching FIFO in the virtual sequencer.
// Allows virtual sequences to check TX items.
Expand Down
5 changes: 5 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class top_chip_dv_env_cfg extends uvm_object;

// External interface agent configs
rand uart_agent_cfg m_uart_agent_cfg;
rand spi_agent_cfg m_spi_device_agent_cfg;

`uvm_object_utils_begin(top_chip_dv_env_cfg)
`uvm_object_utils_end
Expand Down Expand Up @@ -42,6 +43,10 @@ function void top_chip_dv_env_cfg::initialize();
// Configuration is required to perform meaningful monitoring
m_uart_agent_cfg.en_tx_monitor = 0;
m_uart_agent_cfg.en_rx_monitor = 0;

// Create SPI device agent config obj
m_spi_device_agent_cfg = spi_agent_cfg::type_id::create("m_spi_device_agent_cfg");
m_spi_device_agent_cfg.if_mode = dv_utils_pkg::Device;
endfunction : initialize

function void top_chip_dv_env_cfg::get_mem_image_files_from_plusargs();
Expand Down
1 change: 1 addition & 0 deletions hw/top_chip/dv/env/top_chip_dv_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package top_chip_dv_env_pkg;
import mem_bkdr_util_pkg::*;
import sw_test_status_pkg::*;
import uart_agent_pkg::*;
import spi_agent_pkg::*;

// Macro includes
`include "uvm_macros.svh"
Expand Down
1 change: 1 addition & 0 deletions hw/top_chip/dv/env/top_chip_dv_virtual_sequencer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class top_chip_dv_virtual_sequencer extends uvm_sequencer;
// Handles to specific interface agent sequencers. Used by some virtual
// sequences to drive RX (to-chip) items.
uart_sequencer uart_sqr;
spi_sequencer spi_device_sqr;

// FIFOs for monitor output. Used by some virtual sequences to check
// TX (from-chip) items.
Expand Down
44 changes: 33 additions & 11 deletions hw/top_chip/dv/tb/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,51 @@ module tb;
wire rst_n;
wire peri_clk;
wire peri_rst_n;
wire [3:0] spi_device_sd_o;
wire [3:0] spi_device_sd_en_o;
wire [3:0] spi_device_sd_i;
wire csb;
wire tpm_csb;

// ------ Interfaces ------
clk_rst_if sys_clk_if(.clk(clk), .rst_n(rst_n));
clk_rst_if peri_clk_if(.clk(peri_clk), .rst_n(peri_rst_n));
uart_if uart_if();
spi_if spi_device_if(.rst_n(peri_rst_n));

// ------ DUT ------
top_chip_system #() dut (
// Clock and reset.
.clk_i (clk ),
.rst_ni (rst_n ),
.clk_i (clk ),
.rst_ni (rst_n ),
// UART receive and transmit.
.uart_rx_i (uart_if.uart_rx ),
.uart_tx_o (uart_if.uart_tx ),
.uart_rx_i (uart_if.uart_rx ),
.uart_tx_o (uart_if.uart_tx ),
// SPI device receive and transmit.
// TODO SPI device signals are currently tied off, need to be connected to a SPI agent
.spi_device_sck_i (1'b0 ),
.spi_device_csb_i (1'b1 ),
.spi_device_sd_o ( ),
.spi_device_sd_en_o ( ),
.spi_device_sd_i (4'hF ),
.spi_device_tpm_csb_i (1'b0 )
.spi_device_sck_i (spi_device_if.sck ),
.spi_device_csb_i (csb ),
.spi_device_sd_o (spi_device_sd_o ),
.spi_device_sd_en_o (spi_device_sd_en_o ),
.spi_device_sd_i (spi_device_sd_i ),
.spi_device_tpm_csb_i (tpm_csb )
);

assign csb = spi_device_if.csb[0];
assign tpm_csb = spi_device_if.csb[1];

// Convert sd_o, sd_en_o and sd_i to sio, as the SPI agent expect a bidirectional inout while
// top_chip_system propagates single direction inputs or outputs
`define CONNECT_SPI_IO(_INTF, _SD_I, _SD_O, _SD_EN_O, _IDX) \
wire sd_en_o_``_IDX`` = _SD_EN_O[_IDX]; \
assign _INTF.sio[_IDX] = (sd_en_o_``_IDX``) ? _SD_O[_IDX] : 1'bz; \
assign _SD_I[_IDX] = _INTF.sio[_IDX];

`CONNECT_SPI_IO(spi_device_if, spi_device_sd_i, spi_device_sd_o, spi_device_sd_en_o, 0)
`CONNECT_SPI_IO(spi_device_if, spi_device_sd_i, spi_device_sd_o, spi_device_sd_en_o, 1)
`CONNECT_SPI_IO(spi_device_if, spi_device_sd_i, spi_device_sd_o, spi_device_sd_en_o, 2)
`CONNECT_SPI_IO(spi_device_if, spi_device_sd_i, spi_device_sd_o, spi_device_sd_en_o, 3)


// Signals to connect the sink
top_pkg::axi_req_t sim_sram_cpu_req;
top_pkg::axi_resp_t sim_sram_cpu_resp;
Expand Down Expand Up @@ -160,6 +181,7 @@ module tb;
uvm_config_db#(virtual clk_rst_if)::set(null, "*", "sys_clk_if", sys_clk_if);
uvm_config_db#(virtual clk_rst_if)::set(null, "*", "peri_clk_if", peri_clk_if);
uvm_config_db#(virtual uart_if)::set(null, "*.env.m_uart_agent*", "vif", uart_if);
uvm_config_db#(virtual spi_if)::set(null, "*.env.m_spi_device_agent*", "vif", spi_device_if);

// SW logger and test status interfaces.
uvm_config_db#(virtual sw_test_status_if)::set(
Expand Down
18 changes: 17 additions & 1 deletion hw/top_chip/dv/top_chip_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,35 @@
uvm_test_seq: top_chip_dv_uart_base_vseq
run_opts: ["+ChipMemSRAM_image_file={proj_root}/build/sw/device/tests/uart_smoketest.vmem"]
}
{
name: spi_device_smoke
uvm_test_seq: top_chip_dv_spi_device_base_vseq
run_opts: ["+ChipMemSRAM_image_file={proj_root}/build/sw/device/tests/spi_device_smoketest.vmem"]
}
{
name: spi_device_smoke_cheri
uvm_test_seq: top_chip_dv_spi_device_base_vseq
run_opts: ["+ChipMemSRAM_image_file={proj_root}/build/sw/device/tests/spi_device_smoke_cheri_test.vmem"]
}
]

// List of regressions.
regressions: [
{
name: smoke
tests: [
"uart_smoke"
"uart_smoke",
"spi_device_smoke",
"spi_device_smoke_cheri"
]
}
{
name: uart
tests: ["uart_smoke"]
}
{
name: spi
tests: ["spi_device_smoke", "spi_device_smoke_cheri"]
}
]
}
Loading