feat: add formal properties for sysctrl and update related files

- Introduced  to define formal properties for the sysctrl module.
- Updated  to include new formal properties and source files.
- Renamed  to  in the bus module and created a new  file.
- Implemented a testbench for  in .
- Removed the obsolete  test file.
- Updated test scripts to reference the new  instead of the old RAM module.
- Adjusted various test files to ensure compatibility with the new structure and naming conventions.
This commit is contained in:
maksyuki committed 2026-08-04 12:50:39 +08:00
1 parent 1b4b53c650
commit d51d58dd25
25 files changed
+128 -363

No files matched your search

@@ -1,6 +1,6 @@
`timescale 1ns / 1ps
module soc_rib_ram_tb;
module soc_rib2ram_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic [31:0] memory [0:31];
@@ -19,7 +19,7 @@ module soc_rib_ram_tb;
if (ram.wstrb[3]) memory[ram.addr][31:24] <= ram.wdata[31:24];
end
soc_rib_ram u_dut (
soc_rib2ram u_dut (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.rib (rib),
-117
View File
@@ -1,117 +0,0 @@
`timescale 1ns / 1ps
module spill_register_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic flush_i = 1'b0;
logic valid_i = 1'b0;
logic ready_o;
logic [31:0] data_i = '0;
logic valid_o;
logic ready_i = 1'b0;
logic [31:0] data_o;
logic [31:0] expected [0:511];
integer head = 0;
integer tail = 0;
integer cycle;
logic held_valid = 1'b0;
logic [31:0] held_data = '0;
logic [31:0] lfsr = 32'h1ACE_B00C;
always #5 clk_i = ~clk_i;
spill_register #(
.DATA_WIDTH(32),
.BYPASS (1'b0)
) u_dut (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.flush_i(flush_i),
.valid_i(valid_i),
.ready_o(ready_o),
.data_i (data_i),
.valid_o(valid_o),
.ready_i(ready_i),
.data_o (data_o)
);
task automatic check_cycle;
begin
@(posedge clk_i);
if (held_valid && !flush_i && (!valid_o || (data_o !== held_data))) begin
$fatal(1, "spill register changed output while stalled");
end
if (valid_o && ready_i) begin
if (head == tail || data_o !== expected[head]) begin
$fatal(1, "spill register output ordering failure");
end
head = head + 1;
end
if (valid_i && ready_o) begin
expected[tail] = data_i;
tail = tail + 1;
end
if (flush_i) begin
head = tail;
end
held_valid = valid_o && !ready_i && !flush_i;
held_data = data_o;
end
endtask
initial begin
repeat (2) @(posedge clk_i);
@(negedge clk_i);
rst_n_i = 1'b1;
// Sustained one-word-per-cycle traffic exercises simultaneous push/pop.
for (cycle = 0; cycle < 16; cycle = cycle + 1) begin
valid_i = 1'b1;
ready_i = 1'b1;
data_i = 32'h1000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
// Fill both entries, hold the output, and check stability under pressure.
ready_i = 1'b0;
for (cycle = 0; cycle < 8; cycle = cycle + 1) begin
valid_i = 1'b1;
data_i = 32'h2000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
valid_i = 1'b1;
data_i = 32'hDEAD_BEEF;
flush_i = 1'b1;
check_cycle();
if (valid_o || ready_o) begin
$fatal(1, "spill register accepted a transfer while flushing");
end
@(negedge clk_i);
flush_i = 1'b0;
// Deterministic randomized backpressure covers all occupancy transitions.
for (cycle = 0; cycle < 256; cycle = cycle + 1) begin
lfsr = {lfsr[30:0], lfsr[31] ^ lfsr[21] ^ lfsr[1] ^ lfsr[0]};
valid_i = lfsr[0] | lfsr[3];
ready_i = lfsr[1] | lfsr[5];
data_i = 32'h3000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
valid_i = 1'b0;
ready_i = 1'b1;
while (head != tail || valid_o) begin
check_cycle();
@(negedge clk_i);
end
$display("spill register ready/valid test passed");
$finish;
end
endmodule
+13 -16
View File
@@ -74,12 +74,12 @@ module tc_pdk_cells_tb;
`endif
`ifdef PDK_ICS55
logic ics55_od_i;
logic ics55_od_oe;
logic ics55_od_mode;
logic ics55_pu;
logic ics55_pd;
tri ics55_pad;
logic ics55_od_i;
logic ics55_od_oe;
logic ics55_od_mode;
logic ics55_pu;
logic ics55_pd;
tri ics55_pad;
logic [2:0] ics55_mux_inputs;
logic ics55_mux_y;
@@ -202,11 +202,11 @@ module tc_pdk_cells_tb;
gf180_seq_reset_n = 1'b0;
`endif
`ifdef PDK_ICS55
ics55_od_i = 1'b1;
ics55_od_oe = 1'b0;
ics55_od_mode = 1'b1;
ics55_pu = 1'b0;
ics55_pd = 1'b0;
ics55_od_i = 1'b1;
ics55_od_oe = 1'b0;
ics55_od_mode = 1'b1;
ics55_pu = 1'b0;
ics55_pd = 1'b0;
ics55_mux_inputs = 3'b000;
`endif
@@ -309,11 +309,8 @@ module tc_pdk_cells_tb;
for (int mux_vector = 0; mux_vector < 8; mux_vector++) begin
ics55_mux_inputs = mux_vector[2:0];
#1;
expect_bit(
ics55_mux_y,
~(ics55_mux_inputs[2] ? ics55_mux_inputs[1] : ics55_mux_inputs[0]),
$sformatf("ICS55 MUXI2 vector %0d", mux_vector)
);
expect_bit(ics55_mux_y, ~(ics55_mux_inputs[2] ? ics55_mux_inputs[1] : ics55_mux_inputs[0]),
$sformatf("ICS55 MUXI2 vector %0d", mux_vector));
end
`endif
+1 -1
View File
@@ -121,7 +121,7 @@ def test_bus_fault_responder_handles_reserved_and_unmapped_addresses(tmp_path: P
str(ROOT / "rtl/mini/top/soc_ribl2rib.sv"),
str(ROOT / "rtl/mini/top/soc_rib2ribp.sv"),
str(ROOT / "rtl/mini/top/soc_rib_error_slave.sv"),
str(ROOT / "rtl/mini/top/soc_rib_ram.sv"),
str(ROOT / "rtl/mini/top/soc_rib2ram.sv"),
str(ROOT / "rtl/mini/top/bus.sv"),
str(ROOT / "tests/rtl/bus_fault_tb.sv"),
"",
+7 -31
View File
@@ -48,7 +48,7 @@ def test_bus_preserves_incr4_and_rejects_illegal_bursts(tmp_path: Path) -> None:
str(ROOT / "rtl/mini/top/soc_ribl2rib.sv"),
str(ROOT / "rtl/mini/top/soc_rib2ribp.sv"),
str(ROOT / "rtl/mini/top/soc_rib_error_slave.sv"),
str(ROOT / "rtl/mini/top/soc_rib_ram.sv"),
str(ROOT / "rtl/mini/top/soc_rib2ram.sv"),
str(ROOT / "rtl/mini/top/bus.sv"),
str(ROOT / "tests/rtl/rib_bus_tb.sv"),
"",
@@ -77,37 +77,13 @@ def test_bus_preserves_incr4_and_rejects_illegal_bursts(tmp_path: Path) -> None:
assert "RIB burst arbitration and protocol test passed" in result.stdout
def test_common_spill_register_preserves_ready_valid_data(tmp_path: Path) -> None:
iverilog = shutil.which("iverilog")
vvp = shutil.which("vvp")
if iverilog is None or vvp is None:
return
simulation = tmp_path / "spill_register_tb"
subprocess.run(
[
iverilog,
"-g2012",
"-s",
"spill_register_tb",
"-o",
str(simulation),
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/spill_register.sv"),
str(ROOT / "tests/rtl/spill_register_tb.sv"),
],
check=True,
)
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
assert "spill register ready/valid test passed" in result.stdout
def test_burst_sram_preserves_data_and_backpressure(tmp_path: Path) -> None:
iverilog = shutil.which("iverilog")
vvp = shutil.which("vvp")
if iverilog is None or vvp is None:
return
source_list = tmp_path / "soc_rib_ram.fl"
source_list = tmp_path / "soc_rib2ram.fl"
source_list.write_text(
"\n".join(
[
@@ -118,14 +94,14 @@ def test_burst_sram_preserves_data_and_backpressure(tmp_path: Path) -> None:
str(ROOT / "rtl/mini/top/soc_rib_if.sv"),
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/register.sv"),
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/spill_register.sv"),
str(ROOT / "rtl/mini/top/soc_rib_ram.sv"),
str(ROOT / "tests/rtl/soc_rib_ram_tb.sv"),
str(ROOT / "rtl/mini/top/soc_rib2ram.sv"),
str(ROOT / "tests/rtl/soc_rib2ram_tb.sv"),
"",
]
),
encoding="utf-8",
)
converted = tmp_path / "soc_rib_ram_tb.v"
converted = tmp_path / "soc_rib2ram_tb.v"
subprocess.run(
[
sys.executable,
@@ -137,9 +113,9 @@ def test_burst_sram_preserves_data_and_backpressure(tmp_path: Path) -> None:
],
check=True,
)
simulation = tmp_path / "soc_rib_ram_tb"
simulation = tmp_path / "soc_rib2ram_tb"
subprocess.run(
[iverilog, "-g2012", "-s", "soc_rib_ram_tb", "-o", str(simulation), str(converted)],
[iverilog, "-g2012", "-s", "soc_rib2ram_tb", "-o", str(simulation), str(converted)],
check=True,
)
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
+3 -10
View File
@@ -181,7 +181,6 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
bus_filelist = tmp_path / "bus.fl"
rib_adapter_filelist = tmp_path / "rib_adapter.fl"
spill_register_filelist = tmp_path / "spill_register.fl"
rib2apb_filelist = tmp_path / "ribp2apb.fl"
sysctrl_filelist = tmp_path / "sysctrl.fl"
pll_rcu_filelist = tmp_path / "pll_rcu.fl"
@@ -190,9 +189,6 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
assert generate_formal_filelist(
"rib_adapter", rib_adapter_filelist, memory_map, topology, user_extensions
)
assert generate_formal_filelist(
"spill_register", spill_register_filelist, memory_map, topology, user_extensions
)
assert generate_formal_filelist(
"ribp2apb", rib2apb_filelist, memory_map, topology, user_extensions
)
@@ -208,7 +204,6 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
bus = parse_filelists([bus_filelist], require_files=False)
rib_adapter = parse_filelists([rib_adapter_filelist], require_files=False)
spill_register = parse_filelists([spill_register_filelist], require_files=False)
ribp2apb = parse_filelists([rib2apb_filelist], require_files=False)
sysctrl = parse_filelists([sysctrl_filelist], require_files=False)
pll_rcu = parse_filelists([pll_rcu_filelist], require_files=False)
@@ -221,11 +216,6 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
assert ROOT / "rtl/mini/formal/bus_formal.sv" in bus.files
assert ROOT / "rtl/mini/top/soc_rib2ribp.sv" in rib_adapter.files
assert ROOT / "rtl/mini/formal/rib_adapter_formal.sv" in rib_adapter.files
assert (
ROOT / "rtl/managed/clusterip/common/rtl/utils/spill_register.sv"
in spill_register.files
)
assert ROOT / "rtl/mini/formal/spill_register_formal.sv" in spill_register.files
assert ROOT / "rtl/ip/ribp/interconnect/ribp2apb.sv" in ribp2apb.files
assert ROOT / "rtl/mini/formal/ribp2apb_formal.sv" in ribp2apb.files
assert ROOT / "rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv" in ribp2apb.files
@@ -233,6 +223,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
assert ROOT / "rtl/mini/formal/sysctrl_formal.sv" in sysctrl.files
assert ROOT / "rtl/mini/top/rcu.sv" in pll_rcu.files
assert ROOT / "rtl/managed/clusterip/common/rtl/cdc/cdc_2phase.sv" in pll_rcu.files
assert ROOT / "rtl/managed/clusterip/common/rtl/clkrst/rst_sync.sv" in pll_rcu.files
assert ROOT / "rtl/ip/ribp/peripheral/gpio.sv" in gpio_user.files
assert ROOT / "rtl/managed/clusterip/common/rtl/cdc/cdc_sync.sv" in gpio_user.files
assert ROOT / "rtl/mini/formal/gpio_user_formal.sv" in gpio_user.files
@@ -548,6 +539,7 @@ def test_format_file_scope_is_tracked_and_self_owned() -> None:
Path("rtl/ip/ribp/peripheral/sysctrl.sv"),
Path("rtl/tech/tc_clk.sv"),
Path("rtl/demo/reference.v"),
Path("tests/rtl/bus_fault_tb.sv"),
Path("rtl/managed/clusterip/common/rtl/utils/register.sv"),
Path("rtl/managed/third_party/core.v"),
Path("rtl/mini/filelist.f"),
@@ -562,6 +554,7 @@ def test_format_file_scope_is_tracked_and_self_owned() -> None:
Path("rtl/ip/ribp/peripheral/sysctrl.sv"),
Path("rtl/mini/top/retrosoc.sv"),
Path("rtl/tech/tc_clk.sv"),
Path("tests/rtl/bus_fault_tb.sv"),
]
+1 -1
View File
@@ -147,7 +147,7 @@ def test_topology_always_adds_the_user_apb_target(tmp_path: Path) -> None:
declarations = (tmp_path / "rtl/soc_apb_declarations.svh").read_text(encoding="utf-8")
response = (tmp_path / "rtl/soc_apb_response_mux.svh").read_text(encoding="utf-8")
formal_design = (ROOT / "rtl/mini/formal/ribp2apb_formal.sv").read_text(encoding="utf-8")
formal_properties = (ROOT / "rtl/mini/formal/ribp2apb_formal_props.v").read_text(
formal_properties = (ROOT / "rtl/mini/formal/ribp2apb_formal_props.sv").read_text(
encoding="utf-8"
)