Skip to content

Commit 7747b04

Browse files
committed
[tmp] Add SW-DV window dedicated AXI xbar port
Add SwDvWindow as a device on the main AXI crossbar in top_chip_system, separate from rest_of_chip. This removes the INST_SIM_SRAM CVA6-level interception hack, the axi_demux_simple from sim_sram_axi_sink (now a plain AXI slave), and the force statements in tb.sv. FPGA and simulation tops wire the new port to their respective hw_id handlers directly. Signed-off-by: martin-velay <mvelay@lowrisc.org>
1 parent 5d5185f commit 7747b04

7 files changed

Lines changed: 67 additions & 138 deletions

File tree

hw/top_chip/dv/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@ Because simulating the CPU boot ROM process is slow, we load the software binary
5757
## SW-to-DV Communication
5858
5959
To facilitate interactions between the Software and the DV environment, we utilize the **`sim_sram_axi`** module.
60-
This is a special hardware block inserted only during simulation that intercepts AXI traffic.
6160
6261
For more details, see: [sim_sram_axi/README.md](./sim_sram_axi/README.md)
6362
6463
### Mechanism
6564
66-
1. **Interception:** The module "swallows" traffic destined for a specific Simulation Address Range (`SW_DV_START_ADDR`).
67-
Traffic outside this range is transparently forwarded to the AXI Crossbar.
65+
1. **Dedicated crossbar port:** The SW-DV window (`0x2002_0000`, 256 bytes) is a first-class device on the main AXI crossbar inside `top_chip_system`.
66+
The crossbar routes all accesses to this range out via the `sw_dv_req_o`/`sw_dv_resp_i` port pair, keeping it completely separate from the rest-of-chip bus.
67+
In simulation, `tb.sv` connects `sim_sram_axi_sink` to this port as a plain AXI slave.
68+
On FPGA, `chip_mocha_genesys2` connects the same port to its hardware ID logic.
6869
2. **Binding:** In `tb.sv`, we `bind` verification interfaces (`sw_test_status_if` and `sw_logger_if`) to this module.
6970
7071
### Use Cases

hw/top_chip/dv/sim_sram_axi/sim_sram_axi_sink.sv

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,14 @@ module sim_sram_axi_sink #(
1414
input logic clk_i,
1515
input logic rst_ni,
1616

17-
// Interface from CVA6 CPU
18-
input top_pkg::axi_req_t cpu_req_i,
19-
output top_pkg::axi_resp_t cpu_resp_o,
20-
21-
// Interface to AXI Crossbar
22-
output top_pkg::axi_req_t xbar_req_o,
23-
input top_pkg::axi_resp_t xbar_resp_i
17+
// AXI slave port: receives only SW-DV window traffic from the crossbar
18+
input top_pkg::axi_req_t axi_req_i,
19+
output top_pkg::axi_resp_t axi_resp_o
2420
);
2521

2622
import top_pkg::*;
2723
import cva6_config_pkg::*;
2824

29-
// Internal AXI signals for the intercepted path
30-
axi_req_t sim_req;
31-
axi_resp_t sim_resp;
32-
33-
logic aw_select;
34-
logic ar_select;
35-
36-
// Selection Logic
37-
assign aw_select = (cpu_req_i.aw.addr >= u_sim_sram_if.start_addr) &&
38-
(cpu_req_i.aw.addr < u_sim_sram_if.start_addr + u_sim_sram_if.sw_dv_size);
39-
assign ar_select = (cpu_req_i.ar.addr >= u_sim_sram_if.start_addr) &&
40-
(cpu_req_i.ar.addr < u_sim_sram_if.start_addr + u_sim_sram_if.sw_dv_size);
41-
42-
// AXI Demux: index 0 = System Bus, index 1 = Sim Sink
43-
axi_demux_simple #(
44-
.AxiIdWidth (AxiIdWidth ),
45-
.AtopSupport (1'b0 ),
46-
.axi_req_t (axi_req_t ),
47-
.axi_resp_t (axi_resp_t ),
48-
.NoMstPorts (2 ),
49-
.MaxTrans (8 )
50-
) i_axi_demux (
51-
.clk_i,
52-
.rst_ni,
53-
.test_i (1'b0 ),
54-
.slv_req_i (cpu_req_i ),
55-
.slv_aw_select_i (aw_select ),
56-
.slv_ar_select_i (ar_select ),
57-
.slv_resp_o (cpu_resp_o ),
58-
.mst_reqs_o ({sim_req, xbar_req_o} ),
59-
.mst_resps_i ({sim_resp, xbar_resp_i})
60-
);
61-
6225
// AXI Protocol conversion to memory interface
6326
logic mem_req;
6427
logic mem_req_d;
@@ -92,8 +55,8 @@ module sim_sram_axi_sink #(
9255
.clk_i (clk_i ),
9356
.rst_ni (rst_ni ),
9457
.busy_o ( ), // Not used
95-
.axi_req_i (sim_req ),
96-
.axi_resp_o (sim_resp ),
58+
.axi_req_i (axi_req_i ),
59+
.axi_resp_o (axi_resp_o ),
9760
.mem_req_o (mem_req ),
9861
.mem_gnt_i (1'b1 ), // ALWAYS GRANT: Sim SRAM is never busy
9962
.mem_addr_o (mem_addr ),
@@ -158,7 +121,7 @@ module sim_sram_axi_sink #(
158121

159122
// Simulation SRAM Interface Instance
160123
sim_sram_axi_if u_sim_sram_if (.clk_i, .rst_ni);
161-
assign u_sim_sram_if.req = sim_req;
162-
assign u_sim_sram_if.resp = sim_resp;
124+
assign u_sim_sram_if.req = axi_req_i;
125+
assign u_sim_sram_if.resp = axi_resp_o;
163126

164127
endmodule : sim_sram_axi_sink

hw/top_chip/dv/tb/tb.sv

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ module tb;
6262
top_pkg::axi_dram_req_t dram_req;
6363
top_pkg::axi_dram_resp_t dram_resp;
6464

65+
// ------ SW-DV window ------
66+
top_pkg::axi_req_t sw_dv_req;
67+
top_pkg::axi_resp_t sw_dv_resp;
68+
6569
dram_wrapper_sim u_dram_wrapper (
6670
// Clock and reset.
6771
.clk_i (dut.clkmgr_clocks.clk_main_infra),
@@ -135,6 +139,9 @@ module tb;
135139
// DRAM.
136140
.dram_req_o (dram_req ),
137141
.dram_resp_i (dram_resp ),
142+
// SW-DV window AXI.
143+
.sw_dv_req_o (sw_dv_req ),
144+
.sw_dv_resp_i (sw_dv_resp ),
138145
// Rest of chip AXI tie-off.
139146
.rest_of_chip_req_o ( ),
140147
.rest_of_chip_resp_i ('0 ),
@@ -152,44 +159,14 @@ module tb;
152159
assign (strong0, weak1) scl = (scl_en_o) ? scl_o : 1'b1;
153160
assign (strong0, weak1) sda = (sda_en_o) ? sda_o : 1'b1;
154161

155-
// Signals to connect the sink
156-
logic sim_sram_clk;
157-
logic sim_sram_rst;
158-
top_pkg::axi_req_t sim_sram_cpu_req;
159-
top_pkg::axi_resp_t sim_sram_cpu_resp;
160-
top_pkg::axi_req_t sim_sram_xbar_req;
161-
top_pkg::axi_resp_t sim_sram_xbar_resp;
162-
163-
// CVA6 and Xbar uses clk_main_infra from clock manager and their request and response ports are
164-
// interfaced in sim_sram_axi_sink module. Thus, use the same clock and reset as them to stay in
165-
// sync.
166-
assign sim_sram_clk = dut.clkmgr_clocks.clk_main_infra;
167-
assign sim_sram_rst = dut.rstmgr_resets.rst_main_n[rstmgr_pkg::DomainMainSel];
168-
169-
// Instantiate the AXI sink to intercept the AXI traffic within the simulation memory range
170-
// to provide a dedicated channel for SW-to-DV communication.
162+
// SW-DV sink: receives only SW-DV window traffic from the crossbar.
171163
sim_sram_axi_sink u_sim_sram (
172-
.clk_i (sim_sram_clk ),
173-
.rst_ni (sim_sram_rst ),
174-
.cpu_req_i (sim_sram_cpu_req ),
175-
.cpu_resp_o (sim_sram_cpu_resp ),
176-
.xbar_req_o (sim_sram_xbar_req ),
177-
.xbar_resp_i (sim_sram_xbar_resp )
164+
.clk_i (dut.clkmgr_clocks.clk_main_infra ),
165+
.rst_ni (dut.rstmgr_resets.rst_main_n[rstmgr_pkg::DomainMainSel]),
166+
.axi_req_i (sw_dv_req ),
167+
.axi_resp_o (sw_dv_resp )
178168
);
179169

180-
// Capture inputs FROM the DUT (Monitoring)
181-
assign sim_sram_cpu_req = dut.cva6_to_sim_req;
182-
assign sim_sram_xbar_resp = dut.xbar_host_resp[top_pkg::CVA6];
183-
184-
// Force outputs INTO the DUT (Overriding)
185-
// We break the direct connection inside the RTL using forces
186-
initial begin
187-
// Ensure we wait for build/elaboration phases if necessary,
188-
// though force on static hierarchy works at time 0.
189-
force dut.xbar_host_req[top_pkg::CVA6] = sim_sram_xbar_req;
190-
force dut.sim_to_cva6_resp = sim_sram_cpu_resp;
191-
end
192-
193170
// ------ Memory backdoor accesses ------
194171
if (prim_pkg::PrimTechName == "Generic") begin : gen_mem_bkdr_utils
195172
initial begin

hw/top_chip/dv/verilator/top_chip_verilator.sv

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ module top_chip_verilator (
104104
.dram_req_o (dram_req),
105105
.dram_resp_i (dram_resp),
106106

107+
.sw_dv_req_o (sw_dv_req ),
108+
.sw_dv_resp_i (sw_dv_resp),
109+
107110
.rest_of_chip_req_o ( ), // Rest of chip AXI tie-off
108111
.rest_of_chip_resp_i ('0),
109112

@@ -197,31 +200,18 @@ module top_chip_verilator (
197200
// SW to adapt its behavior when running on Verilator vs other simulators or real hardware.
198201
localparam bit [31:0] VERILATOR_HW_ID = 32'h0000_001A;
199202

200-
// Signals to connect the sink
201-
top_pkg::axi_req_t sim_sram_cpu_req;
202-
top_pkg::axi_resp_t sim_sram_cpu_resp;
203-
top_pkg::axi_req_t sim_sram_xbar_req;
204-
top_pkg::axi_resp_t sim_sram_xbar_resp;
203+
// SW-DV window AXI signals: routed directly from the main crossbar via the dedicated port.
204+
top_pkg::axi_req_t sw_dv_req;
205+
top_pkg::axi_resp_t sw_dv_resp;
205206

206-
// Detect SW test termination.
207+
// SW-DV sink: receives only SW-DV window traffic from the crossbar.
207208
sim_sram_axi_sink u_sim_sram (
208-
.clk_i (`DUT.clkmgr_clocks.clk_main_infra),
209-
.rst_ni (`DUT.rstmgr_resets.rst_main_n[rstmgr_pkg::DomainMainSel]),
210-
.cpu_req_i (sim_sram_cpu_req ),
211-
.cpu_resp_o (sim_sram_cpu_resp ),
212-
.xbar_req_o (sim_sram_xbar_req ),
213-
.xbar_resp_i (sim_sram_xbar_resp )
209+
.clk_i (`DUT.clkmgr_clocks.clk_main_infra ),
210+
.rst_ni (`DUT.rstmgr_resets.rst_main_n[rstmgr_pkg::DomainMainSel]),
211+
.axi_req_i (sw_dv_req ),
212+
.axi_resp_o (sw_dv_resp )
214213
);
215214

216-
// Connect the sim SRAM directly at CVA6 AXI interface
217-
assign `DUT.sim_to_cva6_resp = sim_sram_cpu_resp;
218-
// Drive the request back into the DUT's Crossbar
219-
assign `DUT.xbar_host_req[top_pkg::CVA6] = sim_sram_xbar_req;
220-
221-
// Capture inputs FROM the DUT (Monitoring)
222-
assign sim_sram_cpu_req = `DUT.cva6_to_sim_req;
223-
assign sim_sram_xbar_resp = `DUT.xbar_host_resp[top_pkg::CVA6];
224-
225215
// Instantiate the SW test status interface & connect signals from sim_sram_if instance
226216
// instantiated inside sim_sram. Bind would have worked nicely here, but Verilator segfaults
227217
// when trace is enabled (#3951).

hw/top_chip/rtl/chip_mocha_genesys2.sv

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ module chip_mocha_genesys2 #(
9898
// Rest of chip AXI crossbar address mapping
9999
axi_pkg::xbar_rule_64_t [xbar_cfg.NoAddrRules-1:0] addr_map;
100100
assign addr_map = '{
101-
'{ idx: top_pkg::SwDvWindowDevIdx, start_addr: top_pkg::SwDvWindowBase, end_addr: top_pkg::SwDvWindowBase + top_pkg::SwDvWindowLength },
102-
'{ idx: top_pkg::Ethernet, start_addr: top_pkg::EthernetBase, end_addr: top_pkg::EthernetBase + top_pkg::EthernetLength }
101+
'{ idx: top_pkg::Ethernet, start_addr: top_pkg::EthernetBase, end_addr: top_pkg::EthernetBase + top_pkg::EthernetLength }
103102
};
104103

105104
// Internal clock signals
@@ -158,6 +157,8 @@ module chip_mocha_genesys2 #(
158157
logic ethernet_irq;
159158

160159
// SW-DV window AXI subordinate memory interface acting as a sink
160+
top_pkg::axi_req_t sw_dv_req;
161+
top_pkg::axi_resp_t sw_dv_resp;
161162
logic hw_id_mem_req;
162163
logic hw_id_mem_req_q;
163164
logic hw_id_mem_we;
@@ -294,6 +295,10 @@ module chip_mocha_genesys2 #(
294295
.dram_req_o (dram_req),
295296
.dram_resp_i (dram_resp),
296297

298+
// SW-DV window AXI
299+
.sw_dv_req_o (sw_dv_req ),
300+
.sw_dv_resp_i (sw_dv_resp),
301+
297302
// Rest of chip AXI
298303
.rest_of_chip_req_o (xbar_host_req[top_pkg::MochaAXICrossbar]),
299304
.rest_of_chip_resp_i (xbar_host_resp[top_pkg::MochaAXICrossbar]),
@@ -586,8 +591,8 @@ module chip_mocha_genesys2 #(
586591
.clk_i (u_top_chip_system.clkmgr_clocks.clk_main_infra ),
587592
.rst_ni (u_top_chip_system.rstmgr_resets.rst_main_n[rstmgr_pkg::DomainMainSel]),
588593
.busy_o ( ),
589-
.axi_req_i (xbar_device_req [top_pkg::SwDvWindowDevIdx] ),
590-
.axi_resp_o (xbar_device_resp[top_pkg::SwDvWindowDevIdx] ),
594+
.axi_req_i (sw_dv_req ),
595+
.axi_resp_o (sw_dv_resp ),
591596
.mem_req_o (hw_id_mem_req ),
592597
.mem_gnt_i (1'b1 ),
593598
.mem_addr_o (hw_id_mem_addr ),

hw/top_chip/rtl/top_chip_system.sv

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ module top_chip_system #(
6565
output top_pkg::axi_dram_req_t dram_req_o,
6666
input top_pkg::axi_dram_resp_t dram_resp_i,
6767

68+
// SW-DV window AXI interface.
69+
output top_pkg::axi_req_t sw_dv_req_o,
70+
input top_pkg::axi_resp_t sw_dv_resp_i,
71+
6872
// Rest of chip AXI interface.
6973
output top_pkg::axi_req_t rest_of_chip_req_o,
7074
input top_pkg::axi_resp_t rest_of_chip_resp_i,
@@ -143,6 +147,7 @@ module top_chip_system #(
143147
'{ idx: top_pkg::RomCtrlMem, start_addr: top_pkg::RomCtrlMemBase, end_addr: top_pkg::RomCtrlMemBase + top_pkg::RomCtrlMemLength },
144148
'{ idx: top_pkg::SRAM, start_addr: top_pkg::SRAMBase, end_addr: top_pkg::SRAMBase + top_pkg::SRAMLength },
145149
'{ idx: top_pkg::Mailbox, start_addr: top_pkg::MailboxBase, end_addr: top_pkg::MailboxBase + top_pkg::MailboxLength },
150+
'{ idx: top_pkg::SwDvWindow, start_addr: top_pkg::SwDvWindowBase, end_addr: top_pkg::SwDvWindowBase + top_pkg::SwDvWindowLength },
146151
'{ idx: top_pkg::RestOfChip, start_addr: top_pkg::RestOfChipBase, end_addr: top_pkg::RestOfChipBase + top_pkg::RestOfChipLength },
147152
'{ idx: top_pkg::TlCrossbar, start_addr: top_pkg::TlCrossbarBase, end_addr: top_pkg::TlCrossbarBase + top_pkg::TlCrossbarLength },
148153
'{ idx: top_pkg::DRAM, start_addr: top_pkg::DRAMBase, end_addr: top_pkg::DRAMBase + top_pkg::DRAMUsableLength }
@@ -289,9 +294,6 @@ module top_chip_system #(
289294
logic intr_timer;
290295
logic [1:0] intr;
291296

292-
// Signals to intercept AXI traffic from CVA6 for DV puprose
293-
top_pkg::axi_req_t cva6_to_sim_req;
294-
top_pkg::axi_resp_t sim_to_cva6_resp;
295297

296298
// Define the signals used by the clock, reset and power managers.
297299
clkmgr_pkg::clkmgr_cg_en_t clkmgr_cg_en;
@@ -356,23 +358,10 @@ module top_chip_system #(
356358
.rvfi_probes_o ( ),
357359
.cvxif_req_o ( ),
358360
.cvxif_resp_i ('0),
359-
.noc_req_o (cva6_to_sim_req),
360-
.noc_resp_i (sim_to_cva6_resp)
361+
.noc_req_o (xbar_host_req[top_pkg::CVA6]),
362+
.noc_resp_i (xbar_host_resp[top_pkg::CVA6])
361363
);
362364

363-
// Interception point for connecting simulation SRAM by disconnecting the AXI output. The
364-
// disconnection is done only if `SYNTHESIS is NOT defined AND `INST_SIM_SRAM is defined.
365-
// This define is used only for Verilator as it does not support forces.
366-
`ifdef INST_SIM_SRAM
367-
`ifdef SYNTHESIS
368-
// Induce a compilation error by instantiating a non-existent module.
369-
illegal_preprocessor_branch_taken u_illegal_preprocessor_branch_taken ();
370-
`endif
371-
`else
372-
assign xbar_host_req[top_pkg::CVA6] = cva6_to_sim_req;
373-
assign sim_to_cva6_resp = xbar_host_resp[top_pkg::CVA6];
374-
`endif
375-
376365
// AXI SRAM
377366
axi_sram #(
378367
.AddrWidth ( SramAddrWidth ),
@@ -386,6 +375,10 @@ module top_chip_system #(
386375
.axi_resp_o (xbar_device_resp[top_pkg::SRAM])
387376
);
388377

378+
// SW-DV window AXI passthrough
379+
assign sw_dv_req_o = xbar_device_req[top_pkg::SwDvWindow];
380+
assign xbar_device_resp[top_pkg::SwDvWindow] = sw_dv_resp_i;
381+
389382
// Rest of chip AXI passthrough
390383
assign rest_of_chip_req_o = xbar_device_req[top_pkg::RestOfChip];
391384
assign xbar_device_resp[top_pkg::RestOfChip] = rest_of_chip_resp_i;

hw/top_chip/rtl/top_pkg.sv

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ package top_pkg;
3333

3434
// Mocha AXI crossbar parameters
3535
localparam int AxiXbarHosts = 1;
36-
localparam int AxiXbarDevices = 6;
36+
localparam int AxiXbarDevices = 7;
3737

3838
// Mocha AXI crossbar hosts and devices
3939
typedef enum int unsigned {
@@ -44,17 +44,19 @@ package top_pkg;
4444
RomCtrlMem = 0,
4545
SRAM = 1,
4646
Mailbox = 2,
47-
RestOfChip = 3,
48-
TlCrossbar = 4,
49-
DRAM = 5
47+
SwDvWindow = 3,
48+
RestOfChip = 4,
49+
TlCrossbar = 5,
50+
DRAM = 6
5051
} axi_devices_t;
5152

5253
typedef enum longint unsigned {
5354
RomCtrlMemBase = 64'h0008_0000,
5455
SRAMBase = 64'h1000_0000,
5556
DebugMemBase = 64'h2000_0000,
5657
MailboxBase = 64'h2001_0000,
57-
RestOfChipBase = 64'h2002_0000,
58+
SwDvWindowBase = 64'h2002_0000,
59+
RestOfChipBase = 64'h3000_0000,
5860
TlCrossbarBase = 64'h4000_0000,
5961
DRAMBase = 64'h8000_0000
6062
} axi_addr_start_t;
@@ -64,7 +66,8 @@ package top_pkg;
6466
localparam longint unsigned SRAMLength = 64'h0002_0000;
6567
localparam longint unsigned DebugMemLength = 64'h0000_1000;
6668
localparam longint unsigned MailboxLength = 64'h0001_0000;
67-
localparam longint unsigned RestOfChipLength = 64'h0FFE_8000; // 0x2002_0000 to 0x3000_7FFF
69+
localparam longint unsigned SwDvWindowLength = 64'h0000_0100;
70+
localparam longint unsigned RestOfChipLength = 64'h0000_8000;
6871
localparam longint unsigned TlCrossbarLength = 64'h1000_0000;
6972
localparam longint unsigned DRAMPhysicalLength = 64'h4000_0000;
7073

@@ -78,26 +81,23 @@ package top_pkg;
7881

7982
// Rest of chip AXI crossbar parameters
8083
localparam int RestOfChipAxiXbarHosts = 1;
81-
localparam int RestOfChipAxiXbarDevices = 2;
84+
localparam int RestOfChipAxiXbarDevices = 1;
8285

8386
// Rest of chip AXI crossbar hosts and devices
8487
typedef enum int unsigned {
8588
MochaAXICrossbar = 0
8689
} rest_of_chip_axi_hosts_t;
8790

8891
typedef enum int unsigned {
89-
Ethernet = 0,
90-
SwDvWindowDevIdx = 1
92+
Ethernet = 0
9193
} rest_of_chip_axi_devices_t;
9294

9395
typedef enum longint unsigned {
94-
EthernetBase = 64'h3000_0000,
95-
SwDvWindowBase = 64'h2002_0000
96+
EthernetBase = 64'h3000_0000
9697
} rest_of_chip_axi_addr_start_t;
9798

9899
// Memory lengths
99-
localparam longint unsigned EthernetLength = 64'h0000_8000;
100-
localparam longint unsigned SwDvWindowLength = 64'h0000_0100;
100+
localparam longint unsigned EthernetLength = 64'h0000_8000;
101101

102102
// Memory address masks
103103
localparam longint unsigned EthernetMask = EthernetLength - 1;

0 commit comments

Comments
 (0)