使用fifo 原语进行读写测试,利用modelsim软件进行仿真

本文详细描述了一种在Verilog中使用fifo原语进行读写测试的方法,通过a_tb_FifoSim.v文件中的colorbar模块、generate_test_data模块和fifo_module模块协同工作,以及在Modelsim中进行的仿真过程,展示了如何生成并验证递增数据的正确读写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用fifo 原语进行读写测试,利用modelsim软件进行仿真

a_tb_FifoSim.v文件,文件中例化了colorbar 模块,generate_test_data 模块,fifo_module模块。三个模块的作用为:

  1. colorbar 模块用来产生图像时序;
  2. generate_test_data用来根据图像时序生成测试的递增数据;
  3. fifo_module用来封装一个原语fifo,并将参数接口引出来,方便以后使用;
    下面将给出a_tb_FifoSim.v文件、generate_test_data 、fifo_module的verilig程序。colorbar 模块请参考上一篇博客“verilog实现colorbar”。

a_tb_FifoSim.v文件

`timescale  1ps/1ps
module a_tb_FifoSim();

reg                                     clk_50m                    ;
reg                                     clk_100m                   ;
reg                                     clk_200m                   ;
reg                                     clk_400m                   ;
reg                                     clk_800m                   ;
reg                                     clk_74p25m                 ;
reg                                     clk_148p5m                 ;
reg                                     rst_n                      ;

initial begin
    clk_50m     = 0;
    clk_100m    = 0;
    clk_200m    = 0;
    clk_400m    = 0;
    clk_800m    = 0;
    clk_74p25m  = 0;
    clk_148p5m  = 0;
    rst_n       = 0;
    #200000
    rst_n       = 1;
end

always  #10000 clk_50m      = ~clk_50m;
always  #5000  clk_100m     = ~clk_100m;
always  #2500  clk_200m     = ~clk_200m;
always  #1250  clk_400m     = ~clk_400m;
always  #625   clk_800m     = ~clk_800m;
always  #6734  clk_74p25m   = ~clk_74p25m;  
always  #3367  clk_148p5m   = ~clk_148p5m;

glbl glbl();
wire                                    colorbar_vde                      ;
wire                                    colorbar_vs                       ;
wire                                    colorbar_hs                       ;
wire                   [  23:0]         colorbar_dat                      ;
colorbar colorbar (
    .pclk                              (clk_100m                  ),//时钟
    .rst_n                             (rst_n                     ),//复位,低电平有效
    .frame_size                        (32'd128072050             ),
    .o_vde                             (colorbar_vde              ),//数据使能信号
    .o_hs                              (colorbar_hs               ),//行同步信号
    .o_vs                              (colorbar_vs               ),//场同步信号
    .o_dat                             (colorbar_dat              ) //RGB888颜色数据
);

wire                                    test_vde                   ;
wire                                    test_vs                    ;
wire                   [  15:0]         test_dat                   ;
generate_test_data generate_test_data(
    .pclk                              (clk_100m                  ),
    .rst_n                             (rst_n                     ),

    .i_vs                              (colorbar_vs               ),
    .i_vde                             (colorbar_vde              ),

    .o_vde                             (test_vde                  ),
    .o_vs                              (test_vs                   ),
    .o_dat                             (test_dat                  ) 
);




wire                                    rd_en                      ;
wire                                    fifo_rst                   ;
wire                   [16-1:0]         dout                       ;

assign fifo_rst = ~rst_n;
fifo_module#(
    .WRITE_DATA_WIDTH                  (16                        ),
    .READ_DATA_WIDTH                   (16                        ),
    .FIFO_DEPTH                        (4096                      ),
    .EMPTY_PROG                        (1280 - 1                  ) 
)fifo_module_u1(
    .fifo_rst                          (~rst_n                    ),
    .rd_clk                            (clk_100m                  ),
    .wr_clk                            (clk_100m                  ),
    .wr_en                             (test_vde                  ),
    .din                               (test_dat                  ),
    .o_rd_en                           (rd_en                     ), 
    .o_dout                            (dout                      ) 
);

endmodule
/*-----在modelsim中添加vivoda的仿真库文件-----*/
// vsim -gui work.a_tb_FifoSim -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/secureip -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/simprims_ver -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unifast -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unifast_ver -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unimacro -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unimacro_ver -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unisim -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/unisims_ver -L D:/modelsim_dlx64_10.6c/win64pe/vivado_2018.3_sim_lib/xpm

fifo_module.v

该模块例化了一个xpm_fifo_async原语fifo。

module fifo_module#(
    parameter                           WRITE_DATA_WIDTH = 16      ,
    parameter                           READ_DATA_WIDTH  = 16      ,
    parameter                           FIFO_DEPTH = 4096          ,
    parameter                           EMPTY_PROG = 1280 - 1            
)
(
    input                               fifo_rst                   ,
    input                               rd_clk                     ,
    input                               wr_clk                     ,
    input                               wr_en                      ,
    input       [WRITE_DATA_WIDTH-1:0]  din                        ,
    output                              o_rd_en                      ,
    output       [READ_DATA_WIDTH-1:0]  o_dout                        
);
wire                                    empty                      ;
wire                                    full                       ;
wire                                    prog_empty                 ;
wire                                    prog_full                  ;
wire            [READ_DATA_WIDTH-1:0]   dout                       ;
reg                                     rd_en                      ;
reg                    [  15:0]         read_count                 ;
xpm_fifo_async #(
    .CDC_SYNC_STAGES                   (2                         ),// DECIMAL
    .DOUT_RESET_VALUE                  ("0"                       ),// String
    .ECC_MODE                          ("no_ecc"                  ),// String
    .FIFO_MEMORY_TYPE                  ("auto"                    ),// String
    .FIFO_READ_LATENCY                 (1                         ),// DECIMAL
    .FIFO_WRITE_DEPTH                  (FIFO_DEPTH                ),// DECIMAL
    .FULL_RESET_VALUE                  (0                         ),// DECIMAL
    .PROG_EMPTY_THRESH                 (EMPTY_PROG                ),// DECIMAL
    .PROG_FULL_THRESH                  (10                        ),// DECIMAL
    .RD_DATA_COUNT_WIDTH               (1                         ),// DECIMAL
    .READ_DATA_WIDTH                   (READ_DATA_WIDTH                        ),// DECIMAL
    .READ_MODE                         ("fwft"                    ),// String
    .RELATED_CLOCKS                    (0                         ),// DECIMAL
    .USE_ADV_FEATURES                  ("0707"                    ),// String
    .WAKEUP_TIME                       (0                         ),// DECIMAL
    .WRITE_DATA_WIDTH                  (WRITE_DATA_WIDTH                        ),// DECIMAL
    .WR_DATA_COUNT_WIDTH               (1                         ) // DECIMAL
)xpm_fifo_async_inst (
    .almost_empty                      (                          ),// 1-bit output: Almost Empty : When asserted, this signal indicates that only one more read can be performed before the FIFO goes to empty.
    .almost_full                       (                          ),// 1-bit output: Almost Full: When asserted, this signal indicates that only one more write can be performed before the FIFO is full.
    .data_valid                        (                          ),// 1-bit output: Read Data Valid: When asserted, this signal indicates that valid data is available on the output bus (dout).
    .dbiterr                           (                          ),// 1-bit output: Double Bit Error: Indicates that the ECC decoder detected a double-bit error and data in the FIFO core is corrupted.
    .dout                              (dout                      ),// READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven when reading the FIFO.
    .empty                             (empty                     ),// 1-bit output: Empty Flag: When asserted, this signal indicates that the FIFO is empty. Read requests are ignored when the FIFO is empty, initiating a read while empty is not destructive to the FIFO.
    .full                              (full                      ),// 1-bit output: Full Flag: When asserted, this signal indicates that the FIFO is full. Write requests are ignored when the FIFO is full, initiating a write when the FIFO is full is not destructive to the contents of the FIFO.
    .overflow                          (                          ),// 1-bit output: Overflow: This signal indicates that a write request (wren) during the prior clock cycle was rejected, because the FIFO is full. Overflowing the FIFO is not destructive to the contents of the FIFO.
    .prog_empty                        (prog_empty                ),// 1-bit output: Programmable Empty: This signal is asserted when the number of words in the FIFO is less than or equal to the programmable empty threshold value. It is de-asserted when the number of words in the FIFO exceeds the programmable empty threshold value.
    .prog_full                         (prog_full                 ),// 1-bit output: Programmable Full: This signal is asserted when the number of words in the FIFO is greater than or equal to the programmable full threshold value. It is de-asserted when the number of words in the FIFO is less than the programmable full threshold value.
    .rd_data_count                     (                          ),// RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the number of words read from the FIFO.
    .rd_rst_busy                       (                          ),// 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read domain is currently in a reset state. 1-bit output: Single Bit Error: Indicates that the ECC decoder detected and fixed a single-bit error.
    .underflow                         (                          ),// 1-bit output: Underflow: Indicates that the read request (rd_en) during the previous clock cycle was rejected because the FIFO is empty. Under flowing the FIFO is not destructive to the FIFO.
    .wr_ack                            (                          ),// 1-bit output: Write Acknowledge: This signal indicates that a write request (wr_en) during the prior clock cycle is succeeded.
    .wr_data_count                     (                          ),// WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates the number of words written into the FIFO.
    .wr_rst_busy                       (                          ),// 1-bit output: Write Reset Busy: Active-High indicator that the FIFO write domain is currently in a reset state.
    .din                               (din                       ),// WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when writing the FIFO.
    .injectdbiterr                     (                          ),// 1-bit input: Double Bit Error Injection: Injects a double bit error if the ECC feature is used on block RAMs or UltraRAM macros.
    .injectsbiterr                     (                          ),// 1-bit input: Single Bit Error Injection: Injects a single bit error if the ECC feature is used on block RAMs or UltraRAM macros.
    .rd_clk                            (rd_clk                    ),// 1-bit input: Read clock: Used for read operation. rd_clk must be a free running clock.
    .rd_en                             (rd_en                     ),// 1-bit input: Read Enable: If the FIFO is not empty, asserting this signal causes data (on dout) to be read from the FIFO. Must be held active-low when rd_rst_busy is active high.
    .rst                               (fifo_rst                  ),// 1-bit input: Reset: Must be synchronous to wr_clk. The clock(s) can be unstable at the time of applying reset, but reset must be released only after the clock(s) is/are stable.
    .sleep                             (1'b0                      ),// 1-bit input: Dynamic power saving: If sleep is High, the memory/fifo block is in power saving mode.
    .wr_clk                            (wr_clk                    ),// 1-bit input: Write clock: Used for write operation. wr_clk must be a free running clock.
    .wr_en                             (wr_en                     ) // 1-bit input: Write Enable: If the FIFO is not full, asserting this signal causes data (on din) to be written to the FIFO. Must be held active-low when rst or wr_rst_busy is active high.
);

always @(posedge rd_clk) begin
    if(fifo_rst)
        rd_en <= 1'b0;
    else if(read_count == EMPTY_PROG)
        rd_en <= 1'b0;
    else if(~prog_empty)
        rd_en <= 1'b1;
    else
        rd_en <= rd_en;
end

always @(posedge rd_clk) begin
    if(fifo_rst)
        read_count <= 'd0;
    else if(rd_en)
        read_count <= read_count + 1'b1;
    else
        read_count <= 'd0;
end

assign o_rd_en = rd_en;
assign o_dout = dout;

endmodule

generate_test_data .v

产生测试的递增数,通过递增数可以很容易判断fifo读写是否正确。

module generate_test_data(
    input                               pclk                       ,
    input                               rst_n                      ,

    input                               i_vs                       ,
    input                               i_vde                      ,

    output                              o_vde                      ,
    output                              o_vs                       ,
    output             [  15:0]         o_dat                       
);

reg                                     i_vde_dly                  ;
reg                                     i_vs_dly                   ;
always @(posedge pclk) begin
    i_vde_dly <= i_vde;
    i_vs_dly <= i_vs;
end

reg [15:0] test_dat;
always @(posedge pclk or negedge rst_n) begin
    if(~rst_n)
        test_dat <= 'd0;
    else if(i_vde)
        test_dat <= test_dat + 1'b1;
    else
        test_dat <= 'd0;
end

assign o_vde = i_vde_dly;
assign o_vs  = i_vs_dly;
assign o_dat = test_dat;

endmodule

modelsim仿真结果

图1:数据写入到fifo,数据由1、2、3、…递增,然后写入到fifo中
数据的写入在这里插入图片描述
图2:递增数据依次从fifo中读出
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值