(原创)system verilog——同步fifo
本例代码都已给出,可以在MODELSIM6.3F中直接运行,大家通过下面仿真波形可以看到,有六个断言成功,0个断言失败,
成功的断言分别是:三个写入数据时,status的前后状态变化的断言;三个读出数据时,status的前后状态变化的断言。

代码如下:
1
`timescale 1ns/10ps 2
module syn_fifo(clk,3
rst,4
wr_cs,5
wr_en,6
din,7
rd_cs,8
rd_en,9
dout,10
empty,11
full12
);13
parameter DATA_WIDTH=8;14
parameter ADDR_WIDTH=8;15
parameter DEPT_WIDTH=(1<<ADDR_WIDTH);16
parameter fifo_sva=1'b1;17
input clk;18
input rst;19
input wr_cs;20
input rd_cs;21
input [DATA_WIDTH-1:0] din;22
input rd_en;23
input wr_en;24
output [DATA_WIDTH-1:0] dout;25
output empty;26
output full;27

28
logic [ADDR_WIDTH-1:0] wptr;29
logic [ADDR_WIDTH-1:0] rptr;30
logic [ADDR_WIDTH-1:0] status;31
assign empty=(status==0);32
assign full=(status==DEPT_WIDTH);33
// write data into fifo34
always@(posedge clk or posedge rst)35
begin36
if(rst)begin37
wptr=0;38
end39
else if(wr_en&&wr_cs&&!full)begin40
wptr=wptr+1;41
end42
end43
//read data from fifo44
always@(posedge clk or posedge rst)45
begin46
if(rst)begin47
rptr=0;48
end49
else if(rd_en&&rd_cs&&!empty)begin50
rptr=rptr+1;51
end52
end53
//count fifo status54
always@(posedge clk or posedge rst)55
begin56
if(rst)begin57
status=0;58
end59
else if((wr_en&&wr_cs)&&!(rd_en&&rd_cs)&&!full)begin60
status=status+1;61
end62
else if(!(wr_en&&wr_cs)&&(rd_en&&rd_cs)&&!empty)begin63
status=status-1;64
end65
else begin66
status=status;67
end68
end 69
asyn_dp_ram#(DATA_WIDTH,ADDR_WIDTH,DEPT_WIDTH)70
u(.din(din),71
.wptr(wptr),72
.wr_en(wr_en),73
.wr_cs(wr_cs),74
.dout(dout),75
.rptr(rptr),76
.rd_en(rd_en),77
.rd_cs(rd_cs)78
);79
//sva property description80
property p_write_not_read; 81
@(posedge clk)82
(wr_cs&&wr_en&&!rd_cs&&!rd_en&&!full)|=>(status==$past(status)+1); 83
endproperty84
property p_read_not_write; 85
@(posedge clk)86
(!wr_cs&&!wr_en&&rd_cs&&rd_en&&!empty)|=>(status==$past(status)-1); 87
endproperty88
property p_write_and_read; 89
@(posedge clk)90
(wr_cs&&wr_en&&rd_cs&&rd_en)|=>(status==$past(status)); 91
endproperty92

93
//sva check94
always@(posedge clk)95
if(fifo_sva)96
begin97
a_write_not_read:assert property(p_write_not_read) 98
else $display("write error at %d !",$time);99
a_read_not_write:assert property(p_read_not_write)100
else $display("read error at %d !",$time);101
a_write_and_read:assert property(p_write_and_read)102
else $display("write and read error at %d !",$time);103
104
c_write_not_read:cover property(p_write_not_read);105
c_read_not_write:cover property(p_read_not_write);106
c_write_and_read:cover property(p_write_and_read);107
end108
endmodule109

110
111

112
`timescale 1ns/10ps 113
module asyn_dp_ram(din,wptr,wr_en,wr_cs,dout,rptr,rd_en,rd_cs);114
parameter DATA_WIDTH=8;115
parameter ADDR_WIDTH=8;116
parameter DEPT_WIDTH=(1<<ADDR_WIDTH);117
input [DATA_WIDTH-1:0] din;118
input [ADDR_WIDTH-1:0] wptr;119
input [ADDR_WIDTH-1:0] rptr;120
input wr_en;121
input wr_cs;122
input rd_en;123
input rd_cs;124
output [DATA_WIDTH-1:0] dout;125

126
logic [DATA_WIDTH-1:0] dout;127
logic [DATA_WIDTH-1:0] mem [DEPT_WIDTH-1:0];128
//write data port129
always@(din or wptr or wr_en or wr_cs)130
begin131
if(wr_en&&wr_cs)132
mem[wptr]=din;133
end134
//read data port135
always@(rptr or rd_en or rd_cs)136
begin137
if(rd_en&&rd_cs)138
dout=mem[rptr];139
end140

141
endmodule 142

143

144
145

146
`timescale 1ns/10ps 147
module syn_fifo_testbench;148
logic clk;149
logic rst;150
logic wr_cs;151
logic rd_cs;152
logic [7:0] din;153
logic rd_en;154
logic wr_en;155
wire [7:0] dout;156
wire empty;157
wire full;158
syn_fifo #(8,4,256,1)159
u1(.clk(clk),160
.rst(rst),161
.wr_cs(wr_cs),162
.wr_en(wr_en),163
.din(din),164
.rd_cs(rd_cs),165
.rd_en(rd_en),166
.dout(dout),167
.empty(empty),168
.full(full)169
);170
parameter p=10;171
initial172
begin173
wr_cs=0;174
wr_en=0;175
rd_cs=0;176
rd_en=0;177
clk=0;178
rst=1;179
#p rst=0;180
#p wr_cs=1;181
wr_en=1;182
din=8'b10101010;183
#p din=8'b11001100;184
#p din=8'b11111111;185
#p wr_cs=0;186
#p wr_en=0; 187
#p rd_cs=1;188
#p rd_en=1;189
#p ;190
#p ;191
#p rd_cs=0;192
#p rd_en=0;193
#1000 $finish;194
end195
initial196
begin197
$monitor("the din is %b ,out is %b at %d",din,dout,$time);198
//$monitor("the dout is %b at %d",dout,$time);199
end200
always #5 clk=~clk;201
endmodule202

203

完整代码:

浙公网安备 33010602011771号