verilog testbench-产生时钟复位

最近在看vivado的官方例程,顺便总结一下比较常用且优雅的testbench代码。将这些代码封装一下,以后在仿真时直接调用,非常的方便。

产生单端时钟(tb_clockgen_single .v)

//-----------------------------------------------------------------------------
//  
//  Copyright (c) JoeJoe.
//
//  Project  : Common Testbench
//  Module   : tb_clockgen_single .v
//  Parent   : 
//  Children : none
//
//  Description: 
//    This is a general single clock generation module. It should be instantiated
//    and connected to both the DUT
//
//
//  Parameters:
//    None
//
//  Notes       : 
//
//  Multicycle and False Paths
//    None - this is a testbench file only, and is not intended for synthesis
//

`timescale 1ns/1ps

module tb_clockgen_single #
(
     parameter           PERIOD = 500 // 周期
)
(
     output reg      clk
);

//***************************************************************************
// Parameter definitions
//***************************************************************************

  
//***************************************************************************
// Register declarations
//***************************************************************************


//***************************************************************************
// Code
//***************************************************************************

    initial begin
        clk = 0;
        forever begin
            #(PERIOD/2.0)
            clk = ~clk;
        end // forever
    end // initial

endmodule

非常常见的时钟激励编写方式。时钟通过clk端口输出,周期通过参数传入。

产生差分时钟(tb_clockgen_diff.v)

//-----------------------------------------------------------------------------
//  
//  Copyright (c) JoeJoe.
//
//  Project  : Common Testbench
//  Module   : tb_clockgen_diff.v
//  Parent   : 
//  Children : none
//
//  Description: 
//    This is a general differential clock generation module. It should be instantiated
//    and connected to both the DUT
//
//
//  Parameters:
//    None
//
//  Notes       : 
//
//  Multicycle and False Paths
//    None - this is a testbench file only, and is not intended for synthesis
//

`timescale 1ns/1ps

module tb_clockgen_diff #
(
     parameter           PERIOD = 500 // 周期
)
(
     output reg      clk_p
    ,output reg      clk_n
);

//***************************************************************************
// Parameter definitions
//***************************************************************************

  
//***************************************************************************
// Register declarations
//***************************************************************************


//***************************************************************************
// Code
//***************************************************************************

    // Generate the clock
    initial begin
        clk_p = 0;
        clk_n = ~clk_p;
        forever begin
            #(PERIOD/2.0)
            clk_p = ~clk_p;
            clk_n = ~clk_p;
        end // forever
    end // initial

endmodule

和前一个没什么区别,只是用于产生差分时钟。时钟通过clk_p,clk_n端口输出,周期通过参数传入。

产生复位信号(tb_reset.v)

//-----------------------------------------------------------------------------
//  
//  Copyright (c) JoeJoe.
//
//  Project  : Common Testbench
//  Module   : tb_reset.v
//  Parent   : 
//  Children : none
//
//  Description: 
//    This is a general reset generation module. It should be instantiated
//    and connected to both the DUT
//
//
//  Parameters:
//    None
//
//  Notes       : 
//
//  Multicycle and False Paths
//    None - this is a testbench file only, and is not intended for synthesis
//

`timescale 1ns/1ps

module tb_resetgen #
(
     parameter           RESET_POL = 1 // 0: 复位低电平有效; 1: 复位高电平有效
)
(
     input      clk
    ,output reg reset
);

//***************************************************************************
// Parameter definitions
//***************************************************************************

  
//***************************************************************************
// Register declarations
//***************************************************************************


//***************************************************************************
// Code
//***************************************************************************

    initial begin
        reset = RESET_POL;
    end // initial

    task assert_reset (
        input [31:0] num_clk
    );
        begin
            $display("%t       Asserting reset for %d clocks",$realtime, num_clk);
            reset = RESET_POL;
            repeat (num_clk) @(posedge clk);
            $display("%t       Deasserting reset",$realtime);
            reset = ~RESET_POL;
        end
    endtask

endmodule

复位极性可通过参数配置,复位时长可配置。

顶层文件(tb_test.v)

`timescale 1ns / 1ps
//
// Company: 
// Engineer:  JoeJoe
// 
// Create Date: 2024/05/13 21:49:42
// Design Name: 
// Module Name: tb_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_test();

//***************************************************************************
// Parameter definitions
//***************************************************************************

    parameter SYS_PERIOD = 10; // 10ns
    parameter APB_PERIOD = 10; // 10ns
    
//***************************************************************************
// Register declarations
//***************************************************************************

    wire sys_clk_p;
    wire sys_clk_n;
    wire apb_clk;
    
    wire sys_rst;
    wire apb_rstn;
    
//***************************************************************************
// Tasks
//***************************************************************************

    task init(
    ); 
        begin
            fork
                // Assert the reset for 40 clocks
                U0_TB_RESETGEN.assert_reset(40);
                U1_TB_RESETGEN.assert_reset(40);
            join
            #100_000; // Wait for clocks to stabilize
        end
    endtask

//***************************************************************************
// Code
//***************************************************************************

    tb_clockgen_diff # (
         .PERIOD                                             ( SYS_PERIOD                    )
    )
    U_TB_CLOCKGEN_DIFF (
         .clk_p                                              ( sys_clk_p                     )
        ,.clk_n                                              ( sys_clk_n                     )
    );
    
    tb_clockgen_single # (
         .PERIOD                                             ( APB_PERIOD                    )
    ) 
    U_TB_CLOCKGEN_SINGLE (
         .clk                                                ( apb_clk                       )
    );
    
    tb_resetgen # (
         .RESET_POL                                          ( 1'b0                          )
    )
    U0_TB_RESETGEN (
         .clk                                                ( apb_clk                       )
        ,.reset                                              ( apb_rstn                      )
    );
    
    tb_resetgen # (
         .RESET_POL                                          ( 1'b1                          )
    )
    U1_TB_RESETGEN (
         .clk                                                ( sys_clk_p                     )
        ,.reset                                              ( sys_rst                       )
    );

    initial begin
        $timeformat(-9,2," ns",14);
        
        #10;
        $display("%t       Starting simulation",$realtime);
        
        init();
        
        $stop;
        $finish;
    end

endmodule

这里的顶层文件即是一个非常nice的testbench模板,每次在仿真时可以直接搬去用,非常优雅。

相关推荐
fei_sun12 小时前
【Verilog】第一章作业
fpga开发·verilog
深圳市雷龙发展有限公司longsto13 小时前
基于FPGA(现场可编程门阵列)的SD NAND图片显示系统是一个复杂的项目,它涉及硬件设计、FPGA编程、SD卡接口、NAND闪存控制以及图像显示等多个方面
fpga开发
9527华安18 小时前
FPGA实现PCIE3.0视频采集转10G万兆UDP网络输出,基于XDMA+GTH架构,提供工程源码和技术支持
网络·fpga开发·udp·音视频·xdma·pcie3.0·万兆网
able陈18 小时前
为什么verilog中递归函数需要定义为automatic?
fpga开发
fei_sun18 小时前
【Verilog】第二章作业
fpga开发·verilog
碎碎思19 小时前
如何使用 Vivado 从源码构建 Infinite-ISP FPGA 项目
fpga开发·接口隔离原则
江山如画,佳人北望21 小时前
fpga-状态机的设计及应用
fpga开发
晓晓暮雨潇潇1 天前
Xilinx IP核(3)XADC IP核
fpga开发·vivado·xadc·ip核
CWNULT1 天前
AMD(Xilinx) FPGA配置Flash大小选择
fpga开发
碎碎思1 天前
很能体现FPGA硬件思维的一道面试题
fpga开发