Skip to content

Commit abe8974

Browse files
committed
[dv] Add support for HW_ID for SW
- Related to issue #423 - This commit adds support for a HW_ID register that can be used by SW DV tests to identify the hardware they are running on. This is useful for SW DV tests that need to run on multiple hardware platforms and need a way to differentiate between them. - Add framework C test Signed-off-by: martin-velay <mvelay@lowrisc.org>
1 parent 9173e84 commit abe8974

6 files changed

Lines changed: 57 additions & 8 deletions

File tree

hw/top_chip/dv/env/top_chip_dv_env_pkg.sv

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ package top_chip_dv_env_pkg;
4141
// 50 MHz Peripheral clock
4242
parameter int unsigned PeriClkFreq = 50_000_000;
4343

44-
// SW DV special write locations for test status and logging will always fit in 32-bits
44+
// SW-DV special locations for test status, logging, and platform identification.
45+
// These are intercepted by sim_sram_axi_sink before the AXI crossbar.
4546
parameter bit [31:0] SW_DV_START_ADDR = 'h2002_0000;
4647
parameter bit [31:0] SW_DV_SIZE = 'h0000_0100; // 256 bytes reserved for SW DV
4748
parameter bit [31:0] SW_DV_TEST_STATUS_ADDR = SW_DV_START_ADDR + 'h00;
48-
parameter bit [31:0] SW_DV_LOG_ADDR = SW_DV_START_ADDR + 'h04;
49+
parameter bit [31:0] SW_DV_HW_ID_ADDR = SW_DV_START_ADDR + 'h04;
50+
parameter bit [31:0] SW_DV_LOG_ADDR = SW_DV_START_ADDR + 'h08;
51+
52+
parameter bit [31:0] SW_DV_HW_ID = 32'h0000_002A;
4953

5054
// File includes
5155
`include "mem_clear_util.sv"

hw/top_chip/dv/sim_sram_axi/sim_sram_axi_if.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface sim_sram_axi_if (
1515
// Control signals set by the Testbench
1616
logic [31:0] start_addr;
1717
logic [31:0] sw_dv_size;
18+
logic [31:0] hw_id_addr;
19+
logic [31:0] hw_id;
1820

1921
// Monitor signals driven by the Sink
2022
axi_req_t req;

hw/top_chip/dv/sim_sram_axi/sim_sram_axi_sink.sv

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ module sim_sram_axi_sink #(
6868
logic [top_pkg::AxiDataWidth-1:0] mem_rdata;
6969
logic [top_pkg::AxiStrbWidth-1:0] mem_be;
7070

71+
// True when the access targets the read-only HW_ID register.
72+
// axi_to_mem aligns addresses to AxiDataWidth/8 bytes, so compare against the
73+
// 8-byte aligned hw_id_addr (clearing the lower 3 bits for a 64-bit bus).
74+
logic hw_id_sel;
75+
assign hw_id_sel = (mem_addr[31:0] == {u_sim_sram_if.hw_id_addr[31:3], 3'b000});
76+
77+
// Insert one cycle delay to align with mem_req_d
78+
logic hw_id_sel_d;
79+
always_ff @(posedge clk_i or negedge rst_ni) begin
80+
if (!rst_ni) hw_id_sel_d <= 1'b0;
81+
else hw_id_sel_d <= mem_req && !mem_we && hw_id_sel;
82+
end
83+
7184
axi_to_mem #(
7285
.axi_req_t (top_pkg::axi_req_t ),
7386
.axi_resp_t (top_pkg::axi_resp_t ),
@@ -102,9 +115,9 @@ module sim_sram_axi_sink #(
102115
end
103116
end : delayed_mem_req
104117

105-
// Assert Error if ErrOnRead is set and a read occurs
118+
// Assert Error if ErrOnRead is set and a read occurs to a non-HW_ID address.
106119
if (ErrOnRead) begin : gen_err_on_read
107-
`ASSERT(ErrOnRead_A, mem_req |-> mem_we, clk_i, !rst_ni)
120+
`ASSERT(ErrOnRead_A, (mem_req && !hw_id_sel) |-> mem_we, clk_i, !rst_ni)
108121
end : gen_err_on_read
109122

110123
// Conditional SRAM Instantiation
@@ -138,9 +151,9 @@ module sim_sram_axi_sink #(
138151
);
139152
end : gen_sram
140153
else begin : gen_no_sram
141-
// If no SRAM, return 0s on read.
142-
// Handshaking is handled by the common logic and axi_to_mem.
143-
assign mem_rdata = '0;
154+
// If no SRAM, return hw_id for RO register reads, 0 otherwise.
155+
// hw_id at byte offset 4 occupies the upper 32 bits of the 64-bit AXI word [63:32].
156+
assign mem_rdata = hw_id_sel_d ? {u_sim_sram_if.hw_id, {(AxiDataWidth-32){1'b0}}} : '0;
144157
end : gen_no_sram
145158

146159
// Simulation SRAM Interface Instance

hw/top_chip/dv/tb/tb.sv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module tb;
1515
import top_chip_dv_env_pkg::SW_DV_START_ADDR;
1616
import top_chip_dv_env_pkg::SW_DV_TEST_STATUS_ADDR;
1717
import top_chip_dv_env_pkg::SW_DV_LOG_ADDR;
18+
import top_chip_dv_env_pkg::SW_DV_HW_ID_ADDR;
19+
import top_chip_dv_env_pkg::SW_DV_HW_ID;
1820

1921
// Macro includes
2022
`include "uvm_macros.svh"
@@ -271,6 +273,8 @@ module tb;
271273
// Set base of SW DV special write locations
272274
`SIM_SRAM_IF.start_addr = SW_DV_START_ADDR;
273275
`SIM_SRAM_IF.sw_dv_size = SW_DV_SIZE;
276+
`SIM_SRAM_IF.hw_id = SW_DV_HW_ID;
277+
`SIM_SRAM_IF.hw_id_addr = SW_DV_HW_ID_ADDR;
274278
`SIM_SRAM_IF.u_sw_test_status_if.sw_test_status_addr = SW_DV_TEST_STATUS_ADDR;
275279
`SIM_SRAM_IF.u_sw_logger_if.sw_log_addr = SW_DV_LOG_ADDR;
276280

hw/top_chip/dv/top_chip_sim_cfg.hjson

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@
103103
run_opts: ["+ChipMemSRAM_image_file={run_dir}/timer_interrupt_test_cheri_sram.vmem",
104104
"+ChipMemROM_image_file={run_dir}/bootrom_scrambled.vmem"]
105105
}
106+
{
107+
name: test_framework_test
108+
uvm_test_seq: top_chip_dv_base_vseq
109+
sw_images: ["test_framework_test_vanilla_sram:5" "bootrom:5"]
110+
run_opts: ["+ChipMemSRAM_image_file={run_dir}/test_framework_test_vanilla_sram.vmem",
111+
"+ChipMemROM_image_file={run_dir}/bootrom_scrambled.vmem"]
112+
}
113+
{
114+
name: test_framework_test_cheri
115+
uvm_test_seq: top_chip_dv_base_vseq
116+
sw_images: ["test_framework_test_cheri_sram:5" "bootrom:5"]
117+
run_opts: ["+ChipMemSRAM_image_file={run_dir}/test_framework_test_cheri_sram.vmem",
118+
"+ChipMemROM_image_file={run_dir}/bootrom_scrambled.vmem"]
119+
}
106120
{
107121
name: test_framework_exception_test
108122
uvm_test_seq: top_chip_dv_base_vseq
@@ -346,6 +360,8 @@
346360
"rv_timer_smoke_cheri",
347361
"rv_timer_irq",
348362
"rv_timer_irq_cheri",
363+
"test_framework_test",
364+
"test_framework_test_cheri",
349365
"test_framework_exception_test",
350366
"test_framework_exception_test_cheri",
351367
"spi_device_smoke",
@@ -398,6 +414,8 @@
398414
{
399415
name: test_framework
400416
tests: [
417+
"test_framework_test",
418+
"test_framework_test_cheri",
401419
"test_framework_exception_test",
402420
"test_framework_exception_test_cheri"
403421
]

hw/top_chip/dv/verilator/top_chip_verilator.sv

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,15 @@ module top_chip_verilator (
187187
`define DUT u_top_chip_system
188188
`define SIM_SRAM_IF u_sim_sram.u_sim_sram_if
189189

190+
// Special addresses for SW-DV communication
190191
localparam bit [31:0] VERILATOR_SW_DV_START_ADDR = 'h2002_0000;
191192
localparam bit [31:0] VERILATOR_SW_DV_SIZE = 'h0000_0100; // 256 bytes reserved
192193
localparam bit [31:0] VERILATOR_SW_DV_TEST_STATUS_ADDR = VERILATOR_SW_DV_START_ADDR + 'h00;
194+
localparam bit [31:0] VERILATOR_SW_DV_HW_ID_ADDR = VERILATOR_SW_DV_START_ADDR + 'h04;
195+
196+
// Specific ID for SW-DV to identify that it's running on Verilator. This can be used by
197+
// SW to adapt its behavior when running on Verilator vs other simulators or real hardware.
198+
localparam bit [31:0] VERILATOR_HW_ID = 32'h0000_001A;
193199

194200
// Signals to connect the sink
195201
top_pkg::axi_req_t sim_sram_cpu_req;
@@ -228,10 +234,12 @@ module top_chip_verilator (
228234
.data (`SIM_SRAM_IF.req.w.data[15:0] ) // Test status is 16-bits wide
229235
);
230236

231-
// Set the start address and the size of the simulation SRAM
237+
// Set special SW-DV registers
232238
initial begin
233239
`SIM_SRAM_IF.start_addr = VERILATOR_SW_DV_START_ADDR;
234240
`SIM_SRAM_IF.sw_dv_size = VERILATOR_SW_DV_SIZE;
241+
`SIM_SRAM_IF.hw_id_addr = VERILATOR_SW_DV_HW_ID_ADDR;
242+
`SIM_SRAM_IF.hw_id = VERILATOR_HW_ID;
235243
u_sw_test_status_if.sw_test_status_addr = VERILATOR_SW_DV_TEST_STATUS_ADDR;
236244
end
237245

0 commit comments

Comments
 (0)