always @(*)
if (f_state == 2'b01)
begin
assert(f_first_addr_in_fifo);
assert(fifo_mem[f_first_addr]
== f_first_data);
assert(wr_addr == f_second_addr);
end
always @(*)
if (f_state == 2'b10)
begin
assert(f_first_addr_in_fifo);
assert(fifo_mem[f_first_addr]
== f_first_data);
//
assert(f_second_addr_in_fifo);
assert(fifo_mem[f_second_addr]
== f_second_data);
if (i_rd && rd_addr == f_first_addr)
assert(o_data == f_first_data);
end
always @(*)
if (f_state == 2'b11)
begin
assert(f_second_addr_in_fifo);
assert(fifo_mem[f_second_addr]
== f_second_data);
Question
rmccormack1
So I have code and block design for a FIFO.
module fifo(i_clk, i_wr, i_data, o_full, o_fill, i_rd, o_data, o_empty);
parameter BW=4; // Byte/data width
parameter LGFLEN=3;
input wire i_clk;
input wire i_wr;
input wire [(BW-1):0] i_data;
output reg o_full;
output reg [LGFLEN:0] o_fill;
input wire i_rd;
output reg [(BW-1):0] o_data;
output reg o_empty; // True if FIFO is empty
reg [(BW-1):0] fifo_mem[0:(1<<LGFLEN)-1];
reg [LGFLEN:0] wr_addr, rd_addr;
reg [LGFLEN-1:0] rd_next;
wire w_wr = (i_wr && !o_full);
wire w_rd = (i_rd && !o_empty);
initial wr_addr = 0;
always @(posedge i_clk)
if (w_wr)
wr_addr <= wr_addr + 1'b1;
always @(posedge i_clk)
if (w_wr)
fifo_mem[wr_addr[(LGFLEN-1):0]] <= i_data;
initial rd_addr = 0;
always @(posedge i_clk)
if (w_rd)
rd_addr <= rd_addr + 1;
always @(*)
o_data = fifo_mem[rd_addr[LGFLEN-1:0]];
always @(*)
o_fill = wr_addr - rd_addr;
always @(*)
o_full = o_fill == { 1'b1, {(LGFLEN){1'b0}} };
always @(*)
o_empty = (o_fill == 0);
always @(*)
rd_next = rd_addr[LGFLEN-1:0] + 1;
wire [LGFLEN-1:0] unused;
assign unused = rd_next;
`ifdef FORMAL
`ifdef SFIFO
`define ASSUME assume
`else
`define ASSUME assert
`endif
reg f_past_valid;
initial f_past_valid = 1'b0;
always @(posedge i_clk)
f_past_valid <= 1'b1;
wire [LGFLEN:0] f_fill, f_next, f_empty;
assign f_fill = wr_addr - rd_addr;
assign f_empty = (wr_addr == rd_addr);
assign f_next = rd_addr + 1'b1;
always @(*)
begin
assert(f_fill <= { 1'b1, {(LGFLEN){1'b0}}});
assert(o_fill == f_fill);
assert(o_full == (f_fill == {1'b1, {(LGFLEN){1'b0}}}));
assert(o_empty == (f_fill == 0));
assert(rd_next == f_next[LGFLEN-1:0]);
end
always @(*)
assert(fifo_mem[rd_addr] == o_data);
(* anyconst *) reg [LGFLEN:0] f_first_addr;
reg [LGFLEN:0] f_second_addr;
(* anyconst *) reg [BW-1:0] f_first_data, f_second_data;
always @(*)
f_second_addr = f_first_addr + 1;
reg f_first_addr_in_fifo, f_first_in_fifo;
reg f_second_addr_in_fifo, f_second_in_fifo;
reg [LGFLEN:0] f_distance_to_first, f_distance_to_second;
always @(*)
begin
f_distance_to_first = (f_first_addr - rd_addr);
f_first_addr_in_fifo = 0;
if ((f_fill != 0) && (f_distance_to_first < f_fill))
f_first_addr_in_fifo = 1;
else
f_first_addr_in_fifo = 0;
end
always @(*)
begin
f_distance_to_second = (f_second_addr - rd_addr);
if ((f_fill != 0) && (f_distance_to_second < f_fill))
f_second_addr_in_fifo = 1;
else
f_second_addr_in_fifo = 0;
end
reg [1:0] f_state;
initial f_state = 2'b0;
always @(posedge i_clk)
case(f_state)
2'h0: if (w_wr && (wr_addr == f_first_addr)
&& (i_data == f_first_data))
f_state <= 2'h1;
2'h1: if (w_rd && rd_addr == f_first_addr)
f_state <= 2'h0;
else if (w_wr)
f_state <= (i_data == f_second_data)
? 3'h2 : 2'h0;
2'h2: if (i_rd && rd_addr == f_first_addr)
f_state <= 2'h3;
2'h3: if (i_rd)
f_state <= 2'h0;
endcase
always @(*)
if (f_state == 2'b01)
begin
assert(f_first_addr_in_fifo);
assert(fifo_mem[f_first_addr]
== f_first_data);
assert(wr_addr == f_second_addr);
end
always @(*)
if (f_state == 2'b10)
begin
assert(f_first_addr_in_fifo);
assert(fifo_mem[f_first_addr]
== f_first_data);
//
assert(f_second_addr_in_fifo);
assert(fifo_mem[f_second_addr]
== f_second_data);
if (i_rd && rd_addr == f_first_addr)
assert(o_data == f_first_data);
end
always @(*)
if (f_state == 2'b11)
begin
assert(f_second_addr_in_fifo);
assert(fifo_mem[f_second_addr]
== f_second_data);
assert(o_data == f_second_data);
end
reg f_was_full;
initial f_was_full = 0;
always @(posedge i_clk)
if (o_full)
f_was_full <= 1;
always @(posedge i_clk)
cover($fell(f_empty));
always @(posedge i_clk)
cover($fell(o_empty));
always @(posedge i_clk)
cover(f_was_full && f_empty);
always @(posedge i_clk)
cover($past(o_full,2)&&(!$past(o_full))&&(o_full));
always @(posedge i_clk)
if (f_past_valid)
cover($past(o_empty,2)&&(!$past(o_empty))&& o_empty);
`endif
endmodule
Here is my testbench:
`timescale 1ns / 1ps
module FIFO;
reg i_clk;
reg [3:0] i_data;
reg i_rd;
reg i_wr;
wire [4:0] o_data;
wire i_empty;
wire o_full;
FIFO uut (
.i_clk(i_clk),
.i_data(i_data),
.i_rd(i_rd),
.i_wr(i_wr),
.o_data(o_data),
.i_empty(i_empty),
.o_empty(o_empty)
);
initial begin
// Initialize Inputs
i_clk = 1'b0;
i_data = 32'h0;
i_rd = 1'b0;
i_wr = 1'b0;
#20;
i_wr = 1'b1;
i_data = 32'h0;
#20;
i_data = 32'h1;
#20;
i_data = 32'h2;
#20;
i_data = 32'h3;
#20;
i_data = 32'h4;
#20;
i_wr = 1'b0;
i_rd = 1'b1;
end
always #10 i_clk = ~i_clk;
endmodule
When I run simulations, I get nothing output so I am wondering where I am going wrong in my code or simualtion?
Link to comment
Share on other sites
0 answers to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now