Command filtering passthrough and start of scb for it
Signed-off-by: Kosta Kojdic <kosta.kojdic@ensilica.com>
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
index 5c73fde..fd1f8d1 100644
--- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_base_vseq.sv
@@ -77,9 +77,19 @@
core_spi_freq_ratio inside {[1:8]};
spi_freq_faster -> core_spi_freq_ratio <= 4;
}
+ // re-active sequence
+ spi_device_seq m_spi_device_seq;
`uvm_object_new
+ virtual task start_reactive_seq();
+ // start device seq's
+ fork
+ m_spi_device_seq = spi_device_seq::type_id::create("m_spi_device_seq");
+ m_spi_device_seq.start(p_sequencer.spi_sequencer_d);
+ join
+ endtask // start_reactive_seq
+
virtual task apply_reset(string kind = "HARD");
super.apply_reset(kind);
endtask
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_cmd_filtering_vseq.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_cmd_filtering_vseq.sv
new file mode 100644
index 0000000..9865ff8
--- /dev/null
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_pass_cmd_filtering_vseq.sv
@@ -0,0 +1,89 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Passthrough mode filtering of commands scenario, filter on and off
+class spi_device_pass_cmd_filtering_vseq extends spi_device_base_vseq;
+ `uvm_object_utils(spi_device_pass_cmd_filtering_vseq)
+ `uvm_object_new
+
+ virtual task cfg_cmd_filter(bit not_enable, bit[7:0] cmd);
+ bit [7:0] cmd_position;
+ bit [7:0] cmd_offset;
+ // Calculate filter bit position
+ cmd_position = cmd / 32;
+ cmd_offset = cmd % 32;
+ ral.cmd_filter[cmd_position].filter[cmd_offset].set(not_enable);
+ csr_update(.csr(ral.cmd_filter[cmd_position]));
+ endtask
+
+ virtual task body();
+ bit [31:0] device_word_rsp;
+ bit [7:0] pass_cmd;
+ bit [23:0] pass_addr;
+ bit [31:0] address_command;
+
+ bit [31:0] host_data;
+ bit [31:0] device_data;
+ bit [31:0] device_data_exp;
+ uint avail_bytes;
+ bit [31:0] host_data_exp_q[$];
+ fork
+ start_reactive_seq();
+ join_none
+
+ spi_device_init();
+
+ // Fixed config for this scenario
+ cfg.m_spi_agent_cfg.sck_polarity[0] = 0;
+ cfg.m_spi_agent_cfg.sck_phase[0] = 0;
+ cfg.m_spi_agent_cfg.host_bit_dir = 1;
+ cfg.m_spi_agent_cfg.device_bit_dir = 1;
+ ral.cfg.tx_order.set(1);
+ ral.cfg.rx_order.set(1);
+ ral.cfg.cpol.set(1'b0);
+ ral.cfg.cpha.set(1'b0);
+ csr_update(.csr(ral.cfg)); // TODO check if randomization possible
+
+ repeat (num_trans) begin
+ // Set the passthrough mode
+ ral.control.mode.set(PassthroughMode);
+ csr_update(.csr(ral.control));
+
+ // Randomize opcode and address
+ `DV_CHECK_STD_RANDOMIZE_FATAL(pass_addr)
+ `DV_CHECK_STD_RANDOMIZE_FATAL(pass_cmd)
+
+ // Configure unused CMD_INFO and enable this opcode
+ ral.cmd_info[11].valid.set(1'b1); // Enable this OPCODE
+ ral.cmd_info[11].opcode.set(pass_cmd);
+ ral.cmd_info[11].addr_mode.set(Addr3B); // 3B address for this scenario
+ csr_update(.csr(ral.cmd_info[11]));
+
+ // Make sure filter is not blocking command opcode
+ cfg_cmd_filter(0, pass_cmd);
+
+ // Prepare data for transfer
+ pass_cmd = {<<1{pass_cmd}};
+ pass_addr = {<<1{pass_addr}};
+ address_command = {pass_addr, pass_cmd};
+ spi_host_xfer_word(address_command, device_word_rsp);
+
+ cfg.clk_rst_vif.wait_clks(100);
+
+ // Set filtering of this command
+ cfg_cmd_filter(1, pass_cmd);
+ spi_host_xfer_word(address_command, device_word_rsp);
+
+ cfg.clk_rst_vif.wait_clks(100);
+
+ // Unset filtering and check if pass works again
+ cfg_cmd_filter(0, pass_cmd);
+ spi_host_xfer_word(address_command, device_word_rsp);
+
+ cfg.clk_rst_vif.wait_clks(100);
+ end
+
+ endtask : body
+
+endclass : spi_device_pass_cmd_filtering_vseq
diff --git a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv
index 5658f0b..9bfea8c 100644
--- a/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv
+++ b/hw/ip/spi_device/dv/env/seq_lib/spi_device_vseq_list.sv
@@ -22,3 +22,4 @@
`include "spi_device_abort_vseq.sv"
`include "spi_device_tpm_locality_vseq.sv"
`include "spi_device_tpm_read_vseq.sv"
+`include "spi_device_pass_cmd_filtering_vseq.sv"
diff --git a/hw/ip/spi_device/dv/env/spi_device_env.core b/hw/ip/spi_device/dv/env/spi_device_env.core
index ac61ce9..94056e5 100644
--- a/hw/ip/spi_device/dv/env/spi_device_env.core
+++ b/hw/ip/spi_device/dv/env/spi_device_env.core
@@ -38,6 +38,7 @@
- seq_lib/spi_device_abort_vseq.sv: {is_include_file: true}
- seq_lib/spi_device_tpm_locality_vseq.sv: {is_include_file: true}
- seq_lib/spi_device_tpm_read_vseq.sv: {is_include_file: true}
+ - seq_lib/spi_device_pass_cmd_filtering_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
generate:
diff --git a/hw/ip/spi_device/dv/env/spi_device_env.sv b/hw/ip/spi_device/dv/env/spi_device_env.sv
index 16afa6a..f36782b 100644
--- a/hw/ip/spi_device/dv/env/spi_device_env.sv
+++ b/hw/ip/spi_device/dv/env/spi_device_env.sv
@@ -33,6 +33,8 @@
scoreboard.host_spi_data_fifo.analysis_export);
m_spi_agent.monitor.device_analysis_port.connect(
scoreboard.device_spi_data_fifo.analysis_export);
+ spi_device_agent.monitor.host_analysis_port.connect(
+ scoreboard.pass_spi_data_fifo.analysis_export);
end
if (cfg.m_spi_agent_cfg.is_active) begin
virtual_sequencer.spi_sequencer_h = m_spi_agent.sequencer;
diff --git a/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv b/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv
index 2527bf8..fc76b39 100644
--- a/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv
+++ b/hw/ip/spi_device/dv/env/spi_device_env_pkg.sv
@@ -51,6 +51,13 @@
PassthroughMode
} device_mode_e;
+ typedef enum {
+ AddrDisabled,
+ AddrCfg,
+ Addr3B,
+ Addr4B
+ } addr_mode_e;
+
// alerts
parameter uint NUM_ALERTS = 1;
parameter string LIST_OF_ALERTS[] = {"fatal_fault"};
diff --git a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
index 68d5eb2..a3109b6 100644
--- a/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
+++ b/hw/ip/spi_device/dv/env/spi_device_scoreboard.sv
@@ -10,6 +10,7 @@
// TLM fifos to pick up the packets
uvm_tlm_analysis_fifo #(spi_item) host_spi_data_fifo;
uvm_tlm_analysis_fifo #(spi_item) device_spi_data_fifo;
+ uvm_tlm_analysis_fifo #(spi_item) pass_spi_data_fifo;
// mem model to save expected value
local mem_model tx_mem;
@@ -30,6 +31,7 @@
super.build_phase(phase);
host_spi_data_fifo = new("host_spi_data_fifo", this);
device_spi_data_fifo = new("device_spi_data_fifo", this);
+ pass_spi_data_fifo = new("pass_spi_data_fifo", this);
tx_mem = mem_model#()::type_id::create("tx_mem", this);
rx_mem = mem_model#()::type_id::create("rx_mem", this);
endfunction
@@ -39,6 +41,7 @@
fork
process_host_spi_fifo();
process_device_spi_fifo();
+ process_pass_spi_fifo();
join_none
endtask
@@ -62,6 +65,15 @@
end
endtask
+ virtual task process_pass_spi_fifo();
+ spi_item item;
+ forever begin
+ pass_spi_data_fifo.get(item);
+ //TODO Implement checking of passthrough data
+ `uvm_info(`gfn, $sformatf("received pass spi item:\n%0s", item.sprint()), UVM_HIGH)
+ end
+ endtask
+
// process_tl_access:this task processes incoming access into the IP over tl interface
// this is already called in cip_base_scoreboard::process_tl_a/d_chan_fifo tasks
virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name);
diff --git a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson
index e909f33..ba3ef0d 100644
--- a/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson
+++ b/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson
@@ -131,6 +131,11 @@
name: spi_device_tpm_read
uvm_test_seq: spi_device_tpm_read_vseq
}
+
+ {
+ name: spi_device_pass_cmd_filtering
+ uvm_test_seq: spi_device_pass_cmd_filtering_vseq
+ }
]
// List of regressions.
diff --git a/hw/ip/spi_device/dv/tests/spi_device_base_test.sv b/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
index 4c5bef3..d1e7453 100644
--- a/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
+++ b/hw/ip/spi_device/dv/tests/spi_device_base_test.sv
@@ -15,6 +15,7 @@
cfg.m_spi_agent_cfg.if_mode = Host;
// configure passthrough agent to be in Device mode
cfg.spi_device_agent_cfg.if_mode = Device;
+ cfg.spi_device_agent_cfg.has_req_fifo = 1'b1;
endfunction
endclass : spi_device_base_test