Added some stuff from modem and added formal

This commit is contained in:
2026-02-28 18:23:39 +01:00
parent fa641b1eab
commit cf7e03b9fe
55 changed files with 3717 additions and 31 deletions

View File

@@ -0,0 +1,46 @@
`timescale 1ns/1ps
module formal_wb_mem32;
(* gclk *) reg i_clk;
(* anyseq *) reg i_rst;
(* anyseq *) reg i_wb_rst;
(* anyseq *) reg [31:0] i_wb_adr;
(* anyseq *) reg [31:0] i_wb_dat;
(* anyseq *) reg [3:0] i_wb_sel;
(* anyseq *) reg i_wb_we;
(* anyseq *) reg i_wb_stb;
(* anyseq *) reg i_wb_cyc;
wire [31:0] o_wb_rdt;
wire o_wb_ack;
wb_mem32 #(
.memsize(16),
.sim(1)
) dut (
.i_clk(i_clk),
.i_rst(i_rst),
.i_wb_rst(i_wb_rst),
.i_wb_adr(i_wb_adr),
.i_wb_dat(i_wb_dat),
.i_wb_sel(i_wb_sel),
.i_wb_we(i_wb_we),
.i_wb_stb(i_wb_stb),
.i_wb_cyc(i_wb_cyc),
.o_wb_rdt(o_wb_rdt),
.o_wb_ack(o_wb_ack)
);
formal_wb_slave_checker wb_checker (
.i_clk(i_clk),
.i_rst(i_rst),
.i_wb_rst(i_wb_rst),
.i_wb_adr(i_wb_adr),
.i_wb_dat(i_wb_dat),
.i_wb_sel(i_wb_sel),
.i_wb_we(i_wb_we),
.i_wb_stb(i_wb_stb),
.i_wb_cyc(i_wb_cyc),
.o_wb_rdt(o_wb_rdt),
.o_wb_ack(o_wb_ack)
);
endmodule

View File

@@ -0,0 +1,15 @@
[options]
mode prove
depth 8
[engines]
smtbmc z3 parallel.enable=true parallel.threads.max=8
[script]
read -formal clog2.vh
{{"-formal"|gen_reads}}
prep -top {{top_level}}
[files]
src/joppeb_util_clog2_1.0/clog2.vh
{{files}}

View File

@@ -0,0 +1,66 @@
`timescale 1ns/1ps
`include "clog2.vh"
module wb_mem32 #(
parameter memfile = "",
parameter memsize = 8192,
parameter sim = 1'b0
)(
input wire i_clk,
input wire i_rst,
input wire i_wb_rst,
input wire [31:0] i_wb_adr,
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_stb,
input wire i_wb_cyc,
output wire [31:0] o_wb_rdt,
output wire o_wb_ack
);
localparam integer mem_depth = memsize/4;
localparam integer mem_aw = (mem_depth <= 1) ? 1 : `CLOG2(mem_depth);
reg [31:0] mem [0:mem_depth-1] /* verilator public */;
reg [31:0] wb_rdt_r;
reg wb_ack_r;
wire [mem_aw-1:0] wb_word_adr = i_wb_adr[mem_aw+1:2];
assign o_wb_rdt = wb_rdt_r;
assign o_wb_ack = wb_ack_r;
always @(posedge i_clk) begin
if (i_rst || i_wb_rst) begin
wb_ack_r <= 1'b0;
wb_rdt_r <= 32'b0;
end else begin
wb_ack_r <= i_wb_stb & i_wb_cyc & ~wb_ack_r;
if (i_wb_stb & i_wb_cyc & ~wb_ack_r) begin
wb_rdt_r <= mem[wb_word_adr];
if (i_wb_we) begin
if (i_wb_sel[0]) mem[wb_word_adr][7:0] <= i_wb_dat[7:0];
if (i_wb_sel[1]) mem[wb_word_adr][15:8] <= i_wb_dat[15:8];
if (i_wb_sel[2]) mem[wb_word_adr][23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) mem[wb_word_adr][31:24] <= i_wb_dat[31:24];
end
end
end
end
integer i;
initial begin
if (sim == 1'b1) begin
for (i = 0; i < mem_depth; i = i + 1)
mem[i] = 32'h00000000;
end
if (|memfile) begin
$display("Preloading %m from %s", memfile);
$readmemh(memfile, mem);
end
wb_rdt_r = 32'b0;
wb_ack_r = 1'b0;
end
endmodule

View File

@@ -0,0 +1,178 @@
`timescale 1ns/1ps
module tb_wb_mem32;
reg i_clk;
reg i_rst;
reg i_wb_rst;
reg [31:0] i_wb_adr;
reg [31:0] i_wb_dat;
reg [3:0] i_wb_sel;
reg i_wb_we;
reg i_wb_stb;
reg i_wb_cyc;
wire [31:0] o_wb_rdt;
wire o_wb_ack;
reg [31:0] read_data;
wb_mem32 #(
.memsize(64),
.sim(1)
) dut (
.i_clk(i_clk),
.i_rst(i_rst),
.i_wb_rst(i_wb_rst),
.i_wb_adr(i_wb_adr),
.i_wb_dat(i_wb_dat),
.i_wb_sel(i_wb_sel),
.i_wb_we(i_wb_we),
.i_wb_stb(i_wb_stb),
.i_wb_cyc(i_wb_cyc),
.o_wb_rdt(o_wb_rdt),
.o_wb_ack(o_wb_ack)
);
initial i_clk = 1'b0;
always #5 i_clk = ~i_clk;
task automatic wb_write;
input [31:0] addr;
input [31:0] data;
input [3:0] sel;
begin
@(negedge i_clk);
i_wb_adr <= addr;
i_wb_dat <= data;
i_wb_sel <= sel;
i_wb_we <= 1'b1;
i_wb_stb <= 1'b1;
i_wb_cyc <= 1'b1;
@(posedge i_clk);
#1;
if (!o_wb_ack) begin
$display("ERROR: write ack missing at time %0t", $time);
$finish;
end
@(posedge i_clk);
i_wb_stb <= 1'b0;
i_wb_cyc <= 1'b0;
i_wb_we <= 1'b0;
i_wb_sel <= 4'b0000;
i_wb_dat <= 32'h0;
@(posedge i_clk);
#1;
if (o_wb_ack) begin
$display("ERROR: write ack did not clear at time %0t", $time);
$finish;
end
end
endtask
task automatic wb_read;
input [31:0] addr;
output [31:0] data;
begin
@(negedge i_clk);
i_wb_adr <= addr;
i_wb_dat <= 32'h0;
i_wb_sel <= 4'b1111;
i_wb_we <= 1'b0;
i_wb_stb <= 1'b1;
i_wb_cyc <= 1'b1;
@(posedge i_clk);
#1;
if (!o_wb_ack) begin
$display("ERROR: read ack missing at time %0t", $time);
$finish;
end
data = o_wb_rdt;
@(posedge i_clk);
i_wb_stb <= 1'b0;
i_wb_cyc <= 1'b0;
i_wb_sel <= 4'b0000;
@(posedge i_clk);
#1;
if (o_wb_ack) begin
$display("ERROR: read ack did not clear at time %0t", $time);
$finish;
end
end
endtask
initial begin
$dumpfile("wb_mem32.vcd");
$dumpvars(0, tb_wb_mem32);
i_rst = 1'b1;
i_wb_rst = 1'b0;
i_wb_adr = 32'h0;
i_wb_dat = 32'h0;
i_wb_sel = 4'b0000;
i_wb_we = 1'b0;
i_wb_stb = 1'b0;
i_wb_cyc = 1'b0;
repeat (2) @(posedge i_clk);
i_rst = 1'b0;
@(negedge i_clk);
i_wb_adr <= 32'h0000_0000;
i_wb_sel <= 4'b1111;
i_wb_stb <= 1'b1;
i_wb_cyc <= 1'b0;
@(posedge i_clk);
#1;
if (o_wb_ack) begin
$display("ERROR: ack asserted without cyc at time %0t", $time);
$finish;
end
@(negedge i_clk);
i_wb_stb <= 1'b0;
i_wb_sel <= 4'b0000;
wb_read(32'h0000_0000, read_data);
if (read_data !== 32'h0000_0000) begin
$display("ERROR: reset contents mismatch, got %08x", read_data);
$finish;
end
wb_write(32'h0000_0000, 32'hA1B2_C3D4, 4'b1111);
wb_read(32'h0000_0000, read_data);
if (read_data !== 32'hA1B2_C3D4) begin
$display("ERROR: full-word write mismatch, got %08x", read_data);
$finish;
end
wb_write(32'h0000_0000, 32'h5566_7788, 4'b0101);
wb_read(32'h0000_0000, read_data);
if (read_data !== 32'hA166_C388) begin
$display("ERROR: byte-enable write mismatch, got %08x", read_data);
$finish;
end
wb_write(32'h0000_0004, 32'hDEAD_BEEF, 4'b1111);
wb_read(32'h0000_0004, read_data);
if (read_data !== 32'hDEAD_BEEF) begin
$display("ERROR: second word mismatch, got %08x", read_data);
$finish;
end
wb_read(32'h0000_0000, read_data);
if (read_data !== 32'hA166_C388) begin
$display("ERROR: first word changed unexpectedly, got %08x", read_data);
$finish;
end
$display("PASS: wb_mem32 testbench completed successfully");
$finish;
end
endmodule

View File

@@ -0,0 +1,63 @@
CAPI=2:
name: joppeb:wb:wb_mem32:1.0
description: Wishbone classic block ram
filesets:
rtl:
depend:
- joppeb:util:clog2
files:
- rtl/wb_mem32.v
file_type: verilogSource
tb:
files:
- tb/tb_wb_mem32.v
file_type: verilogSource
formal_rtl:
depend:
- joppeb:wb:formal_checker
files:
- formal/formal_wb_mem32.v
file_type: verilogSource
formal_cfg:
files:
- formal/wb_mem32.sby
file_type: sbyConfigTemplate
targets:
default:
filesets:
- rtl
toplevel: wb_mem32
parameters:
- memfile
- memsize
- sim
sim:
default_tool: icarus
filesets:
- rtl
- tb
toplevel: tb_wb_mem32
formal:
default_tool: symbiyosys
filesets:
- rtl
- formal_rtl
- formal_cfg
toplevel: formal_wb_mem32
parameters:
memfile:
datatype: str
description: Data to fill the mem
paramtype: vlogparam
memsize:
datatype: int
description: Size of memory in bytes, should be a multiple of 32bit
paramtype: vlogparam
sim:
datatype: int
description: Simulation version, fills rest memory with 0
paramtype: vlogparam