Added some stuff from modem and added formal
This commit is contained in:
46
cores/wb/wb_mem32/formal/formal_wb_mem32.v
Normal file
46
cores/wb/wb_mem32/formal/formal_wb_mem32.v
Normal 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
|
||||
15
cores/wb/wb_mem32/formal/wb_mem32.sby
Normal file
15
cores/wb/wb_mem32/formal/wb_mem32.sby
Normal 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}}
|
||||
66
cores/wb/wb_mem32/rtl/wb_mem32.v
Normal file
66
cores/wb/wb_mem32/rtl/wb_mem32.v
Normal 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
|
||||
178
cores/wb/wb_mem32/tb/tb_wb_mem32.v
Normal file
178
cores/wb/wb_mem32/tb/tb_wb_mem32.v
Normal 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
|
||||
63
cores/wb/wb_mem32/wb_mem32.core
Normal file
63
cores/wb/wb_mem32/wb_mem32.core
Normal 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
|
||||
Reference in New Issue
Block a user