|
看了一个关于同步fifio的设计,这个设计还是比较简单的:
`define DEL 1
module synfifo(clock,reset_n,data_in,read_n,write_n,data_out,full,empty);
input clock,reset_n,read_n,write_n;
input [0:7] data_in;
output [0:7] data_out;
output full,empty;
wire clock,reset_n,read_n,write_n;
wire [0:7] data_in;
reg [0:7] data_out;
wire full,empty;//?
reg[7:0] fifo_mem[14:0];
reg [3:0] counter;
reg[3:0] rd_pointer;
reg[3:0] wr_pointer;
assign #`DEL full=(counter==15)?1'b1:1'b0;
assign #`DEL empty=(counter==0)?1'b1:1'b0;
always @(reset_n)
if(~reset_n)
begin
#`DEL;
rd_pointer<=4'b0;
wr_pointer<=4'b0;
counter<=4'b0;
end
always @(posedge clock)
begin
if(~read_n)
begin
if(counter==0)
begin
$display("\nERROR at time %0t:",$time);
$display("\FIFO Underflow\n");
$stop;
end
if(write_n)
begin
counter<=counter-1;
end
data_out<=#`DEL fifo_mem[rd_pointer];
if(rd_pointer==14)
rd_pointer<= #`DEL 4'b0;
else
rd_pointer<=rd_pointer+1;
end
if(~write_n)
begin
if(counter==15)
begin
$display("\nERROR at time %0t:",$time);
$display("FIFO Overflow\n");
$stop;
end
if(read_n)
begin
counter<=#`DEL counter+1;
end
fifo_mem[wr_pointer]<=#`DEL data_in;
if(wr_pointer==14)
wr_pointer<=#`DEL 4'b0;
else
wr_pointer<=#`DEL wr_pointer+1;
end
end
endmodule
可是没想到testbench竟然写的这么好,打死我也写不出啊!
`define DEL 10
module syn_tb;
reg clock,reset_n,read_n,write_n;
reg [7:0] in_data;
wire [7:0] out_data;
wire full,empty;
integer fifo_count;
reg [7:0] exp_data;
reg fast_read,fast_write;
reg filled_flag;
reg cycle_count;
synfifo synfifo_tb(.clock(clock),.reset_n(reset_n),.data_in(in_data),.read_n(read_n),.write_n(write_n),.data_out(out_data),.full(full),.empty(empty));
initial
begin
in_data=0;
exp_data=0;
fifo_count=0;
read_n=1;
write_n=1;
filled_flag=0;
cycle_count=0;
clock=1;
fast_read=0;
fast_write=1;
reset_n=1;
#20 reset_n=0;
#20 reset_n=1;
if(empty!==1)
begin
$display("\nerror at time %0t:",$time);
$display("after reset,empty status not asserted\n");
$stop;
end
if(full!==0)
begin
$display("\nerror at time %0t:",$time);
$display("\nerror at time %0t:",$time);
$stop;
end
end
always #100 clock=~clock;
always @(posedge clock)
begin
if(~write_n && read_n)
fifo_count=fifo_count+1;
else if(write_n && ~read_n)
fifo_count=fifo_count-1;
end
always @(negedge clock)
begin
if(~read_n && (out_data!==exp_data))
begin
$display("\nerror at time %0t:",$time);
$display("expected data ut=%h",exp_data);
$display("actual data ut=%h\n",out_data);
$stop;
end
if((fast_write||(cycle_count&1'b1))&&~full)//?
begin
write_n=0;
in_data=in_data+1;
end
else
write_n=1;
if((fast_read||(cycle_count&1'b1))&&~empty)//?
begin
read_n=0;
exp_data=exp_data+1;
end
else
read_n=1;
if(full)
begin
fast_read=1;
fast_write=0;
filled_flag=1;
end
if(filled_flag&&empty)
begin
$display("\nsimulation complete -no errors\n");
$finish;
end
cycle_count=cycle_count+1;
end
always@(fifo_count)
begin
# `DEL;
# `DEL;
# `DEL;
case (fifo_count)
0:begin
if((empty!==1)||(full!==0))
begin
$display("\nerror at time %0t:",$time);
$display("fifo_count=%h",fifo_count);
$display("empty=%h\n",empty);
$display("full=%h\n",full);
$stop;
end
if(filled_flag==1)
begin
$display("\nsimulation complete -no error\n");
$finish;
end
end
15:begin
if((empty!==0)||(full!==1))
begin
$display("\nerror at time %0t:",$time);
$display("fifo_count=%h",fifo_count);
$display("empty=%h\n",empty);
$display("full=%h\n",full);
$stop;
end
filled_flag=1;
fast_write=0;
fast_read=1;
end
default:begin
if((empty!==0)||(full!==0))
begin
$display("\nerror at time %0t:",$time);
$display("fifo_count=%h",fifo_count);
$display("empty=%h\n",empty);
$display("full=%h\n",full);
$stop;
end
end
endcase
end
endmodule