Skip to content

Commit 9a50001

Browse files
mndstrmrmarnovandermaas
authored andcommitted
[dv/formal] Remove -fun2wires 2:rX
Previously we used -fun2wires 2:rX so that we could track which registers were being used. This was leading to combinational loops, and so had already been removed from CHERIoT-Ibex. We can still 'track' them using Ibex's own interpretation of which registers are relevant, and marking the rest as x.
1 parent cd1f6c5 commit 9a50001

File tree

5 files changed

+72
-78
lines changed

5 files changed

+72
-78
lines changed

dv/formal/Makefile

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ PSGEN_FLAGS=-root riscv -task
1111

1212
SAIL_EXTRA_SRCS=../spec/main.sail
1313

14-
SAIL_SV_FLAGS=-sv -sv-comb -sv-inregs -sv-outregs -sv-nostrings -sv-nopacked -sv-nomem -Oconstant_fold -memo-z3 \
15-
-sv-unreachable translate -sv-unreachable lookup_TLB -sv-unreachable translate_tlb_miss -sv-unreachable translate_tlb_hit -sv-unreachable pt_walk \
16-
-sv-fun2wires 2:read_ram \
17-
-sv-fun2wires 2:write_ram \
18-
-sv-fun2wires wX \
19-
-sv-fun2wires 2:rX \
14+
# -sv, use the SystemVerilog backend
15+
# --sv-comb, generate a always_comb instead of an initial block
16+
# --sv-inregs --sv-outregs, produce inputs and outputs for every Sail register
17+
# --sv-nostrings, --sv-nopacked, --sv-nomem, avoid generating some things Jasper doesn't like (FIXME: --sv-nopacked might be better removed?)
18+
# -Oconstrant_fold, do basic optimisation
19+
# -memo-z3, resolving types requires a sat solver, this helps speed up those queries
20+
# --sv-unreachable, remove the implementations of functions to either make the design smaller or avoid recursion loops (FIXME: Still necessary?)
21+
# --sv-fun2wires (n:)?f, transform a function into ports, with n (or 1) slots
22+
SAIL_SV_FLAGS=-sv --sv-comb --sv-inregs --sv-outregs --sv-nostrings --sv-nopacked --sv-nomem -Oconstant_fold -memo-z3 \
23+
--sv-unreachable translate --sv-unreachable lookup_TLB --sv-unreachable translate_tlb_miss --sv-unreachable translate_tlb_hit --sv-unreachable pt_walk \
24+
--sv-fun2wires 2:read_ram \
25+
--sv-fun2wires 2:write_ram \
26+
--sv-fun2wires wX
2027

2128
# Use fusesoc to resolve the tree of components, copy all resolved source files into the build/ directory,
2229
# and then generate a filelist for jasper to ingest.

dv/formal/check/spec_instance.sv

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,33 @@ always_comb begin
1919
else main_mode = MAIN_IDEX;
2020
end
2121

22+
// Some registers are not driven. Only those that have reg_driven[i] high are
23+
// given real values, the rest are left free (i.e. the spec cannot depend on
24+
// them). For wraparound purposes it does not matter what reg_driven[i] is:
25+
// - If too many registers are driven they all must pass checks anyway (since
26+
// they are checked as inputs)
27+
// - If too few registers are driven instructions will fail to be spec
28+
// conformant
29+
// Note that while it again does not matter how they are defined, but only
30+
// registers matching one of `CR.rf_raddr_{a, b} can be driven.
31+
32+
logic [31:0] reg_driven;
33+
assign reg_driven[0] = 1'b0;
34+
35+
for (genvar i = 1; i < 32; i++) begin: g_regs_cut
36+
logic [31:0] free; // Undriven
37+
assign reg_driven[i] = (`CR.rf_raddr_a == i && `CR.rf_ren_a) || (`CR.rf_raddr_b == i && `CR.rf_ren_b);
38+
assign pre_regs_cut[i] = reg_driven[i] ? pre_regs[i] : free;
39+
end
40+
2241
spec_api #(
2342
.NREGS(32)
2443
) spec_api_i (
2544
.int_err_o(spec_int_err),
2645
.main_mode(main_mode),
2746

2847
.insn_bits(ex_compressed_instr),
29-
30-
.rx_a_en_o(spec_rx_a_en),
31-
.rx_a_addr_o(spec_rx_a_addr),
32-
.rx_a_i(spec_rx_a),
33-
.rx_b_en_o(spec_rx_b_en),
34-
.rx_b_addr_o(spec_rx_b_addr),
35-
.rx_b_i(spec_rx_b),
48+
.regs_i(pre_regs_cut),
3649

3750
.wx_o(spec_post_wX),
3851
.wx_addr_o(spec_post_wX_addr),

dv/formal/check/top.sv

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ WFIStart: assume property (`IDC.ctrl_fsm_cs == SLEEP |-> (
179179

180180
// Pre state is the architectural state of Ibex at the start of the cycle
181181
logic [31:0] pre_regs[32];
182+
logic [31:0] pre_regs_cut[31:1];
182183
logic [31:0] pre_nextpc;
183184
logic [31:0] pre_mip;
184185

@@ -313,17 +314,6 @@ logic wbexc_handling_irq; // Check the results of handling an IRQ
313314

314315
////////////////////// Spec Post //////////////////////
315316

316-
// These cause combinational cycles, but not severe ones. The problem is fixed in CherIoT-Ibex
317-
logic spec_rx_a_en;
318-
logic [4:0] spec_rx_a_addr;
319-
logic [31:0] spec_rx_a;
320-
assign spec_rx_a = pre_regs[spec_rx_a_addr];
321-
322-
logic spec_rx_b_en;
323-
logic [4:0] spec_rx_b_addr;
324-
logic [31:0] spec_rx_b;
325-
assign spec_rx_b = pre_regs[spec_rx_b_addr];
326-
327317
logic [31:0] spec_post_wX;
328318
logic [4:0] spec_post_wX_addr;
329319
logic spec_post_wX_en;

dv/formal/spec/spec_api.sv

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,7 @@ module spec_api #(
2323
) (
2424
input t_MainMode main_mode,
2525

26-
output logic rx_a_en_o,
27-
output logic [4:0] rx_a_addr_o,
28-
input logic [31:0] rx_a_i,
29-
output logic rx_b_en_o,
30-
output logic [4:0] rx_b_addr_o,
31-
input logic [31:0] rx_b_i,
26+
input [31:0] regs_i [31:1],
3227

3328
output logic wx_en_o,
3429
output logic [31:0] wx_o,
@@ -99,16 +94,6 @@ module spec_api #(
9994
output logic [3:0] mem_write_snd_be_o
10095
);
10196

102-
bit rX_sail_invoke[2];
103-
logic [31:0] rX_sail_invoke_ret[2];
104-
logic [63:0] rX_sail_invoke_arg_0[2];
105-
assign rx_a_en_o = rX_sail_invoke[0];
106-
assign rx_a_addr_o = rX_sail_invoke_arg_0[0][4:0];
107-
assign rX_sail_invoke_ret[0] = rx_a_i;
108-
assign rx_b_en_o = rX_sail_invoke[1];
109-
assign rx_b_addr_o = rX_sail_invoke_arg_0[1][4:0];
110-
assign rX_sail_invoke_ret[1] = rx_b_i;
111-
11297
logic wX_sail_invoke[1];
11398
logic [63:0] wX_sail_invoke_arg_0[1];
11499
logic [31:0] wX_sail_invoke_arg_1[1];
@@ -272,78 +257,77 @@ sail_ibexspec spec_i(
272257
.stvec_out(),
273258
.tselect_in(),
274259
.tselect_out(),
275-
.x1_in(),
260+
.mtime_in(),
261+
.mtime_out(),
262+
263+
.x1_in(regs_i[1]),
276264
.x1_out(),
277-
.x2_in(),
265+
.x2_in(regs_i[2]),
278266
.x2_out(),
279-
.x3_in(),
267+
.x3_in(regs_i[3]),
280268
.x3_out(),
281-
.x4_in(),
269+
.x4_in(regs_i[4]),
282270
.x4_out(),
283-
.x5_in(),
271+
.x5_in(regs_i[5]),
284272
.x5_out(),
285-
.x6_in(),
273+
.x6_in(regs_i[6]),
286274
.x6_out(),
287-
.x7_in(),
275+
.x7_in(regs_i[7]),
288276
.x7_out(),
289-
.x8_in(),
277+
.x8_in(regs_i[8]),
290278
.x8_out(),
291-
.x9_in(),
279+
.x9_in(regs_i[9]),
292280
.x9_out(),
293-
.x10_in(),
281+
.x10_in(regs_i[10]),
294282
.x10_out(),
295-
.x11_in(),
283+
.x11_in(regs_i[11]),
296284
.x11_out(),
297-
.x12_in(),
285+
.x12_in(regs_i[12]),
298286
.x12_out(),
299-
.x13_in(),
287+
.x13_in(regs_i[13]),
300288
.x13_out(),
301-
.x14_in(),
289+
.x14_in(regs_i[14]),
302290
.x14_out(),
303-
.x15_in(),
291+
.x15_in(regs_i[15]),
304292
.x15_out(),
305-
.x16_in(),
293+
.x16_in(regs_i[16]),
306294
.x16_out(),
307-
.x17_in(),
295+
.x17_in(regs_i[17]),
308296
.x17_out(),
309-
.x18_in(),
297+
.x18_in(regs_i[18]),
310298
.x18_out(),
311-
.x19_in(),
299+
.x19_in(regs_i[19]),
312300
.x19_out(),
313-
.x20_in(),
301+
.x20_in(regs_i[20]),
314302
.x20_out(),
315-
.x21_in(),
303+
.x21_in(regs_i[21]),
316304
.x21_out(),
317-
.x22_in(),
305+
.x22_in(regs_i[22]),
318306
.x22_out(),
319-
.x23_in(),
307+
.x23_in(regs_i[23]),
320308
.x23_out(),
321-
.x24_in(),
309+
.x24_in(regs_i[24]),
322310
.x24_out(),
323-
.x25_in(),
311+
.x25_in(regs_i[25]),
324312
.x25_out(),
325-
.x26_in(),
313+
.x26_in(regs_i[26]),
326314
.x26_out(),
327-
.x27_in(),
315+
.x27_in(regs_i[27]),
328316
.x27_out(),
329-
.x28_in(),
317+
.x28_in(regs_i[28]),
330318
.x28_out(),
331-
.x29_in(),
319+
.x29_in(regs_i[29]),
332320
.x29_out(),
333-
.x30_in(),
321+
.x30_in(regs_i[30]),
334322
.x30_out(),
335-
.x31_in(),
323+
.x31_in(regs_i[31]),
336324
.x31_out(),
337-
325+
338326
.wX_sail_invoke,
339327
.wX_sail_invoke_ret(),
340328
.wX_sail_invoke_arg_0,
341329
.wX_sail_invoke_arg_1,
342330

343-
.rX_sail_invoke,
344-
.rX_sail_invoke_ret,
345-
.rX_sail_invoke_arg_0,
346-
347331
.write_ram_sail_invoke,
348332
.write_ram_sail_invoke_ret(),
349333
.write_ram_sail_invoke_arg_0(),

dv/formal/thm/riscv.proof

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ lemma riscv
172172
Pc:(pc)
173173
have (has_spec_past |-> pre_``X == spec_past_``X)
174174

175-
RegA: have (spec_rx_a_en && (spec_rx_a_addr != 0) && spec_past_has_reg[spec_rx_a_addr] |-> spec_rx_a == spec_past_regs[spec_rx_a_addr])
176-
RegB: have (spec_rx_b_en && (spec_rx_b_addr != 0) && spec_past_has_reg[spec_rx_b_addr] |-> spec_rx_b == spec_past_regs[spec_rx_b_addr])
175+
RegA: have (reg_driven[`CR.rf_raddr_a] && spec_past_has_reg[`CR.rf_raddr_a] |-> spec_past_regs[`CR.rf_raddr_a] == pre_regs_cut[`CR.rf_raddr_a])
176+
RegB: have (reg_driven[`CR.rf_raddr_b] && spec_past_has_reg[`CR.rf_raddr_b] |-> spec_past_regs[`CR.rf_raddr_b] == pre_regs_cut[`CR.rf_raddr_b])
177177

178178
# Live: have (always (##[1:157 + 2*`WFI_BOUND + 17*`TIME_LIMIT] spec_en))
179179

0 commit comments

Comments
 (0)