verilog程序设计及SystemVerilog验证

server/2025/2/23 1:24:00/

1.Verilog测试程序设计基础
1.1Testbench及其结构
在仿真的时候Testbench用来产生测试激励给待验证设计( Design Under Verification, DUV),或者称为待测设计(Design UnderTest, DUT) 。

测试程序的一般结构:

Testbench是一个测试平台,信号集成在模块内部,没有输入输出。在Testbench模块内,例化待测设计的顶层模块,并把测试行为的代码封装在内,直接对待测系统提供测试激励。

例:T触发器测试程序

module TFF_tb;
reg clk, rst_n, T;
wire data_out;
TFF U1(.data_out(data_out), .T(T), .clk(clk), .rst_n(rst_n)); //对被测模块实例化
    always
        #5 clk = ~clk;
    Initial 
        begin
            clk = 0;
            #3 rst_n = 0;
            #5 rst_n = 1;
            T = 1;
            #30 T = 0;
            #20 T = 1;
        end
    Initial
        begin
            $monitor($time,"T=%b, clk=%b,rst_n=%b,data_out=%b", T, clk, rst_n,data_out);
        end
endmodule


T触发器的波形仿真和文本输出:

从下图可以清晰地看出Testbench的主要功能:
(1)为DUT提供激励信号0。
(2)正确实例化DUT。
(3)将仿真数据显示在终端或者存为文件,也可以显示在波形窗口中以供分析检查。
(4)复杂设计可以使用EDA工具,或者通过用户接口自动比较仿真结果与理想值,实现结果的自动检查。


在编写Testbench时需要注意的问题:
(1)testbench代码不需要可综合
Testbench代码只是硬件行为描述不是硬件设计。
(2)行为级描述效率高
Verilog HDL语言具备5个描述层次,分别为开关级、门级、RTL级、算法级和系统级。
(3)掌握结构化、程式化的描述方式
结构化的描述有利于设计维护,可通过initial、always以及assign语句将不同的测试激励划分开来。
一般不要将所有的测试都放在一个语句块中

2.2测试平台举例
测试平台需要产生时钟信号、复位信号和一系列的仿真向量,观察DUT的响应,确认仿真结果。

(1)组合逻辑电路仿真环境搭建
全加器真值表:


module adder1 (a, b, ci, so, co); 
input a, b, ci ; 
output so, co ; 
assign { co , so } = a + b + ci ; 
endmodule

根据全加器的真值表编写的全加器测试程序如下:

module adder1_tb ;
 wire so, co;
 reg a, b, ci; 
 adder1 U1(a, b, ci, so, co); //模块例化
 initial //测试信号产生 
     begin
          a = 0; b = 0; ci = 0; 
          #20 a = 0; b = 0; ci = 1; 
          #20 a = 0; b = 1; ci = 0; 
          #20 a = 0; b = 1; ci = 1; 
          #20 a = 1; b = 0; ci = 0;
          #20 a = 1; b = 0; ci = 1; 
          #20 a = 1; b = 1; ci = 0; 
          #20 a = 1; b = 1; ci = 1; 
          #200 $finish; 
    end 
endmodule


全加器的输入a、b和ci定义为reg型变量,把输出so和co定义为wire型变量;用模块例化语句
"adder1 U1(a,b,ci,so,co);"把全加器设计电路例化到测试仿真环境中;用initial块语句改变输入的变化并生成测试条件,输入的变化语句完全根据全加器的真值表编写

(2)时序逻辑电路仿真环境的搭建
在于时序逻辑电路仿真环境中,需要考虑时序、定时信息和全局复位、置位等信号,并定义这些信号。

Verilog编写的十进制加法计数器:

module cnt10(cIk ,rst, ena, q, cout); 
input clk,rst,ena; 
output [3:0] q;
output cout; 
reg [3:0] q;
always@(posedge clk or posedge rst) 
    begin
        if(rst)q=4’b0000;
            else if(ena)
                begin
                    if(q<9)
                        q=q+1;
                    else 
                        q=0;
                end
    end
assign cout=q[3]&q[0];
endmodule


测试程序代码:

module cnt10_tb; 
reg clk, rst, ena; 
wire [3:0] q;
wire cout;
cnt10 U1(clk ,rst, ena, q, cout); 
always #50 clk = ~clk; 
initial 
    begin
        clk=0;rst=0;ena=1; 
        #1200 rst=1;
        #120 rst=0;
        #2000 ena=0;
        #200 ena=1;
        #20000 $finish; 
    end
endmodule


实例化语句"cnt10 U1(clk,rst,ena,q,cout);“把十进制计数模块例化到仿真环境中;
在always中用语句”#50 clk=~clk;"产生周期为100(标准时间单位)的时钟方波;
用initial块生成复位信号rst和使能控制信号ena的测试条件。
测试结果如图:

2.3Verilog仿真结果确认
(1)直接观察波形
通过直接观察各信号波形的输出,比较测试值和期望值的大小,来确定仿真结果的正确性。


(2)打印文本输出法

module adder1_tb; 
wire so,co; 
reg a,b,ci; 
adderl U1(a,b,ci,so,co);
initial
    begin
        a=0;b=0;ci=0;
        #20 a=0;b=0;ci=1;
        #20 a=0;b=1 ;ci=0;
        #20 a=0;b=1 ;ci=1;
        #20 a=1 ;b=0;ci=0;
        #20 a=1 ;b=0;ci=1;
        #20 a=1 ;b=1 ;ci=0;
        #20 a=1;b=1;ci=1;
        #200 $finish; 
    end
    $monitor($time, "%b %b %b -> %b %b”,a, b, ci, so, co);
endmodule


输出结果:

0 0 0 0 -> 0 0
20 0 0 1 -> 1 0
40 0 1 0 -> 1 0
60 0 1 1 -> 0 1
80 1 0 0-> 1 0

系统任务打印任务:
$display:直接输出到标准输出设备;
$monitor:监控参数变化;
$fdisplay:输出到文件等。

(3)自动检查仿真结果
自动检查仿真结果是通过在设计代码中的关键节点添加断言监控器,形成对电路逻辑综合的注释或是对设计特点的说明,以提高设计模块的观察性。

(4)使用VCD文件
Verilog提供一系列系统任务用于记录信号值变化保存到标准的VCD(Value Change Dump)格式数据库中。VCD文件是一种标准格式的波形记录文件,只记录发生变化的波形。

2.4Verilog仿真效率
因为要通过串行软件代码完成并行语义的转化,Verilog行为级仿真代码的执行时间比较长。

提高Verilog HDL代码的仿真代码执行时间:
(1)减小层次结构
仿真代码的层次越少,执行时间就越短。
(2) 减少门级代码的使用
由于门级建模属于结构级建模,建议仿真代码尽量使用行为级语句,建模层次越抽象,执行时间就越短。
(3) 仿真精度越高,效率越低
计时单位值与计时精度值的差距越大,则模拟时间越长。`timescale仿真时间标度。
(4) 进程越少,效率越高
代码中的语句块越少仿真越快,这是因为仿真器在不同进程之间进行切换也需要时间。
(5) 减少仿真器的输出显小
Verilog语言包含一些系统任务,可以在仿真器的控制台显示窗口输出一些提示信息,但会降低仿真器的执行效率。
 


http://www.ppmy.cn/server/169432.html

相关文章

人工智障的软件开发-自动流水线CI/CD篇-docker+jenkins部署之道

指令接收&#xff1a;「需要自动构建系统」 系统检测&#xff1a;目标开发一个软件已完成代码仓库-轻盈的gitea&#xff0c;开始添加自动流水线 启动应急冷却协议&#xff1a;准备承受Java系应用的资源冲击 核心组件锁定&#xff1a;构建老将军Jenkins&#xff08;虽然年迈但依…

Vue.js 配置 Babel、Webpack 和 ESLint

Vue.js 配置 Babel、Webpack 和 ESLint 今天我们来聊聊如何配置 Babel、Webpack 和 ESLint&#xff0c;这三个工具在现代前端开发中扮演着重要角色。它们分别负责代码转译、模块打包和代码质量检测&#xff0c;合理配置它们能大大提高项目的开发效率和质量。下面我将详细介绍它…

装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法

问题描述 我们在u盘安装原版win10 iso镜像时&#xff0c;发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”&#xff0c;直接导致了无法继续安装下去。出现这种情况要怎么解决呢&#xff1f; 原因分析&#xff1a; 当您在安装Windows操作系统…

群联AI云防护——针对四层与七层协议的精细化安全防护方案

在网络攻击日益复杂化的今天&#xff0c;服务器的安全防护需要针对不同协议层的特点采取差异化的策略。四层&#xff08;传输层&#xff09;和七层&#xff08;应用层&#xff09;协议分别对应不同的网络通信层次&#xff0c;其攻击方式和防护需求也各不相同。本文将深入探讨群…

在nodejs中使用RabbitMQ(七)实现生产者确认

生产者&#xff1a;批量发送消息&#xff08;每批10条&#xff09;&#xff0c;每条消息附带唯一 correlationId&#xff0c;并监听确认队列&#xff08;ackQueue&#xff09;。 消费者&#xff1a;处理消息后&#xff0c;通过 ackQueue 返回确认消息&#xff08;携带原 corre…

SpringBean生命周期的执行流程

Spring Bean 的生命周期&#xff0c;就是一个 Bean 对象从诞生到消亡所经历的一系列过程&#xff0c;咱们可以把它想象成一个人从出生到去世的一生&#xff0c;下面详细给你讲讲&#xff1a; 1. 出生&#xff08;实例化&#xff09; 这就好比一个新生命呱呱坠地。Spring 容器就…

ib网络状态探测

在 InfiniBand 网络中&#xff0c;Host Channel Adapter&#xff08;HCA&#xff09;是关键组件&#xff0c;了解其状态和配置对于网络管理和故障排查至关重要。以下是一些常用的命令&#xff0c;用于查询和管理 HCA 的状态和配置。 常用命令 ibstat 功能&#xff1a;显示 HCA…

webpack和vite打包原理及比较

Webpack 和 Vite 是前端领域两种主流的构建工具&#xff0c;它们在设计理念、打包机制和适用场景上有显著差异。以下是它们的详细原理及对比分析&#xff1a; 一、Webpack 的打包原理 1. 核心机制 模块化与依赖解析 Webpack 将所有文件&#xff08;JS、CSS、图片等&#xff0…