内容纲要

用于验证的Verilog语法

DUT (Design Under Test, 被测电路)

initial语句

对变量初始化,只执行一次

系统任务

$finish

仿真结束

$stop

停止仿真,但不退出,输入.后可以继续进行

$display

打印信息到屏幕,如调试信息,错误或者异常等,可以在testbench中使用“.”支出信号在DUT中的路径信号来判断输出打印信息。

$monitor

和display类似,但是仅在监视的信号数值发生变化才输出打印信息。

`timescale

`timescale 仿真时间单位/时间精度 
//单位和精度的数字只能是1、10、100

$time

任务返回仿真器当前仿真时间。在testbench中需要使用`timescale指出仿真时间单位(通常为1ns)。当前仿真时间是一个64位整数乘以timescale的单位后四舍五入取整的结果,不包含小数部分。

$realtime

以实数的方式返回当前仿真时间,包含小数部分。使用delay的方式会出现小数的时间精度。

$random

返回32为带符号的随机整数。将$random放入{}内,可得到非负整数。\$ramdom(seed)中的seed是一个正整数,可以设定随机数的取值范围。

$save

$save("file name")可以将仿真器当前仿真状态保存早指定文件中。后续可以加载继续仿真。

$readmemh/\$writememh

$readmemh从文本读取数据。

$fopen/\$fclose

    integer j, file;
    reg [31:0] mem_addr;
    initial begin
        mem_addr = 0;
        file = $fopen("results_file.dat");
        for (j = 0; j < 10; j++) begin
            $fdisplay(file, "the compute result is %d", mem_addr);
            mem_addr += 1;
        end
        $fclose(file);
    end

任务

与Verilog函数非常类似,可以将一段代码定义为一个任务,然后在不同的地方多次调用。

与函数的差异是:任务可以自定义输出输出端口,任务也可以进行定时控制,如@posedge clk、none-zerotimings和#10等时间控制语句。

任务是按顺序执行的,内部的定时控制语句,仿真器会等到条件满足才执行后续语句。任务既可以是可综合的也可以是不可综合的,一般用作testbench中。

储存器建模

在Verilog中可以通过定义二维寄存器数据的方式定义存储器,在综合的时候采用寄存器阵列加以实际实现。在实际芯片中通常通过定制设计的SRAM(Static Random Access Memory,静态随机存取储存器)来实现的,不是通过综合生成的。Verilog中定义的存储器模型主要用于验证。

其他Verilog语法结构

while循环

当括号内条件为真是循环,为假时退出。循环内部建议加入与定时控制有关的语句,如@posedge clk或#5,以避免形成定时环路,造成死循环。

for循环、repeat

for循环语句可以用于testbench或者可综合的RTL中。

force/release

force用于讲一个固定值(1,0)强制赋予一个reg或者wire类型的变量。在release命令被执行之前,不论reg或者wire类型的变量被怎样驱动,变量的只都不会发生改变。release命令被执行后,变量值由其具体驱动决定。

fork/join

fork/join内部的语句是并发执行的,当其内部的多条语句都执行完后,才继续执行其后面的其他语句。

在fork-join内部通常并发地的执行多个仿真任务,主要用于testbench中,用于模拟正式的电路工作情况。

    task memread;
        begin
            #100 $display("mem read task time", $time);
        end
    endtask

    task memcomp;
        begin
            #500 $display("mem comp task time", $time);
        end
    endtask

    initial begin
        fork
            begin
                memread();
                memread();
                memread();
            end
            begin
                memcomp();
                memcomp();
                memcomp();
            end
        join

        $display("time after memread, memcomp task executed", $time);
    end
最后修改日期: 2024年 1月 19日

作者