Testbench¶
仿真过程¶
读/写时钟域复位并释放
设计两串读/写使能序列,作为DUT的rd_en_i和wr_en_i输入,其值在相应时钟的上升沿发生变化
设计待写入数据序列从4’b0000开始递增,作为DUT的wr_dat_i输入,其值在写时钟的上升沿发生变化
完成复位释放后,同步给入使能信号和待写入数据,并观察相应输出信号的变化
备注¶
为了分别验证慢时钟域(写)到快时钟域(读)和快时钟域(写)到慢时钟域(读),设置了两组激励,可根据实际需要选用
已完成慢时钟域到快时钟域以及快时钟域到慢时钟域模式下的仿真验证,FIFO工作正常
仿真代码¶
tb_fifo.v¶
1// testbench of fifo (top module)
2`timescale 1ns/1ps
3// `define HALF_CLK_PERIOD_RD 5
4`define HALF_CLK_PERIOD_RD 18
5// `define HALF_CLK_PERIOD_WR 18
6`define HALF_CLK_PERIOD_WR 5
7
8module tb_fifo;
9
10 parameter FIFO_DEPTH = 8 ;
11 parameter FIFO_DAT_WD = 4 ;
12 parameter FIFO_ADDR_WD = 3 ;
13
14
15 reg wr_clk ;
16 reg wr_rstn ;
17 reg [FIFO_DAT_WD -1:0] wr_dat_i ;
18 wire wr_en_i ;
19 reg rd_clk ;
20 reg rd_rstn ;
21 wire [FIFO_DAT_WD -1:0] rd_dat_o ;
22 wire rd_en_i ;
23
24 fifo #(.FIFO_DEPTH(FIFO_DEPTH), .FIFO_DAT_WD(FIFO_DAT_WD), .FIFO_ADDR_WD(FIFO_ADDR_WD)) fifo(
25 .wr_clk ( wr_clk ),
26 .wr_rstn ( wr_rstn ),
27 .wr_dat_i ( wr_dat_i ),
28 .wr_en_i ( wr_en_i ),
29 .rd_clk ( rd_clk ),
30 .rd_rstn ( rd_rstn ),
31 .rd_dat_o ( rd_dat_o ),
32 .rd_en_i ( rd_en_i )
33 );
34
35 // reg [64 -1:0] rd_en_i_array = 64'b0100000000000000000000000000000001010101010101010101010101010101;
36 reg [64 -1:0] rd_en_i_array = 64'b0101010101010101010101010101010101010101010101010101010101010101;
37 // reg [64 -1:0] wr_en_i_array = 64'b0000001010101010101010101010101010101010101010101010101010101010;
38 reg [64 -1:0] wr_en_i_array = 64'b0000101010101010101010101010101000000000000000000000000000000000;
39
40 assign rd_en_i = rd_en_i_array [64 -1] ;
41 assign wr_en_i = wr_en_i_array [64 -1] ;
42
43 initial begin
44 rd_clk = 1'b0;
45 wr_clk = 1'b0;
46 end
47
48 always #(`HALF_CLK_PERIOD_RD) rd_clk = ~rd_clk;
49 always #(`HALF_CLK_PERIOD_WR) wr_clk = ~wr_clk;
50
51 initial begin
52 rd_rstn = 1'b0;
53 wr_rstn = 1'b0;
54 #21;
55 rd_rstn = 1'b1;
56 wr_rstn = 1'b1;
57 end
58
59 always@(posedge rd_clk) begin
60 if(rd_rstn) begin
61 rd_en_i_array = rd_en_i_array << 1;
62 end
63 end
64
65 always@(posedge wr_clk) begin
66 if(wr_rstn) begin
67 wr_en_i_array = wr_en_i_array << 1;
68 end
69 end
70
71 always @(posedge wr_clk or negedge wr_rstn) begin
72 if(~wr_rstn) begin
73 wr_dat_i = 0;
74 end
75 else begin
76 wr_dat_i = wr_dat_i + 1'b1;
77 end
78 end
79
80endmodule