Verilog 入门(八)(验证)

news2025/1/23 13:44:47

文章目录

  • 编写测试验证程序
  • 波形产生
    • 值序列
    • 重复模式
  • 测试验证程序实例
  • 从文本文件中读取向量
  • 实例:时序检测器

测试验证程序用于测试和验证设计方法的正确性。Verilog 提供强有力的结构来说明测试验证程序。

编写测试验证程序

测试验证程序有三个主要目的:

  1. 产生模拟激励(波形);
  2. 将输入激励加入到测试模块并收集其输出响应;
  3. 将响应输出与期望值进行比较。

典型的测试验证程序形式如下:

module test_bench;
  // 通常测试验证程序没有输入和输出端口
  Local_reg_and_net_declarations
  Generate_waveforms_using_initial_&_always_statements
  Instantiate_module_under_test
  Monitor_output_and_compare_with_expected_values
endmodule

测试中,通过在测试验证程序中进行实例化,激励自动加载于测试模块。

波形产生

有两种产生激励值的主要方法:

  1. 产生波形,并在确定的离散时间间隔加载激励;
  2. 根据模块状态产生激励,即根据模块的输出响应产生激励。

通常需要两类波形。一类是具有重复模式的波形,例如时钟波形,另一类是一组指定的值确定的波形。

值序列

产生值序列的最佳方法是使用 initial 语句。例如:

initial
  begin
    Reset = 0;
    #100 Reset = 1;
    #80 Reset = 0;
    #30 Reset = 1;
  end

生成的波形如下图所示:

在这里插入图片描述
如果使用非阻塞性过程赋值产生如上所示的波形,则写法如下:

initial
  begin
    Reset <= 0;
    Reset <= #100 1;
    Reset <= #180 0;
    Reset <= #210 1;
  end

重复模式

重复模式的生成通过使用如下形式的连续赋值形式加以简化:

assign #(PERIOD/2) Clock = ~ Clock;

但是这种做法并不完全正确。问题在于 Clock 是一个线网(只有线网能够在连续赋值中被赋值),它的初始值是 z,并且,z 等于 x,~ x 等于 x。因此 Clock 的值永远固定为值 x。

下面是一个完整的时钟产生器模块:

module Gen_Clk_A(Clk_A);
  output Clk_A;
  reg Clk_A;
  parameter tPERIOD = 10;

  initial
    Clk_A = 0;

  always #(tPERIOD/2) Clk_A = ~ Clk_A;

测试验证程序实例

下面是 2-4 解码器和它的测试验证程序:

`timescale 1ns/1ns
module Dec2x4(A, B, Enable, Z);
  input A, B, Enable;
  output[0:3] Z;
  wire Abar, Bbar;

  not #(1, 2)
    V0(Abar, A);
    V1(Bbar, B);

  nand #(4, 3)
    N0(Z[0], Enable, Abar, Bbar);
    N0(Z[1], Enable, Abar, B);
    N0(Z[2], Enable, A, Bbar);
    N0(Z[3], Enable, A, B);
endmodule

module Dec_Test;
  reg Da, Db, Dena;
  wire[0:3] Dz;

  Dec2x4 D1(Da, Db, Dena, Dz);

  initial
    begin
      Dena = 0;
      Da = 0;
      Db = 0;
      #10 Dena = 1;
      #10 Da = 1;
      #10 Db = 1;
      #10 Da = 0;
      #10 Db = 0;
      #10 $stop;
    end

  always@(Dena or Da or Db or Dz)
    $display("At time %t, input is %b%b%b, output is %b", $time, Da, Db, Dena, Dz);
endmodule

从文本文件中读取向量

可用 $readmemb 系统任务从文本文件中读取向量(可能包含输入激励和输出期望值)。下面为测试 3 位全加器电路的例子。假定文件 "test.vec" 包含如下两个向量:

在这里插入图片描述
向量的前三位对应于输入 A,接下来的三位对应于输入 B,再接下来的位是进位,八到十位是期望的求和结果,最后一位是期望进位值的输出结果。下面是全加器模块和相应的测试验证程序:

module Adder1Bit(A, B, Cin, Sum, Cout);
  input A, B, Cin;
  output Sum, Cout;

  assign Sum = (A ^ B) ^ Cin;
  assign Cout = (A ^ B) | (A & Cin) | (B & Cin);
endmodule

module Adder3Bit(First, Second, Carry_In, Sum_Out, Carry_Out);
  input[0:2] First, Second;
  input Carry_In;
  output[0:2] Sum_Out;
  output Carry_Out;
  wire[0:1] Car;

  Adder1Bit
    A1(First[2], Second[2], Carry_In, Sum_Out[2], Car[1]),
    A1(First[1], Second[1], Car[1], Sum_Out[1], Car[0]),
    A1(First[0], Second[0], Car[0], Sum_Out[0], Carry_Out);
endmodule

module TestBench;
  parameter BITS = 11, WORDS = 2;
  reg[1:BITS] Vmem[1:WORDS];
  reg[0:2] A, B, Sum_Ex;
  reg Cin, Cout_Ex;
  integer J;
  wire[0:2] Sum;
  wire Cout;

  Adder3Bit F1(A, B, Cin, Sum, Cout);

  initial
    begin
      $readmemb("test.vec", Vmem);

      for(J=1, J<=WORDS; J=J+1)
        begin
          {A, B, Cin, Sum_Ex, Cout_Ex} = Vmem[J]
          #5;

          if((Sum !== Sum_Ex) || (Cout !== Cout_Ex))
            $display("****Mismatch on vector %b ****", Vmem[J]);
          else
            $display("No mismatch on vector %b", Vmem[J]);
        end
    end
endmodule

测试模块中首先定义存储器 Vmem,字长对应于每个向量的位数,存储器字数对应于文件中的向量数。

实例:时序检测器

检测数据线上连续三个 1 的序列。在时钟的每个下沿检查数据,状态图如下:

在这里插入图片描述

module Count3_1s(Data, Clock, Detect3_1s);
  input Data, Clock;
  output Detect3_1s;
  integer Count;
  reg Detect3_1s;

  initial begin
    Count = 0;
    Detect3_1s = 0;
  end

  always@(negedge Clock) begin
    if(Data == 1)
      Count = Count + 1;
    else
      Count = 0;
    if(Count >= 3)
      Detect3_1s = 1;
    else:
      Detect3_1s = 0;
  end
endmodule

module Top;
  reg Data, Clock;
  wire Detect;
  integer Out_File;
  Count3_1s F1(Data, Clock, Detect);

  initial begin
    Clock = 0;
    forever
      #5 Clock = ~ Clock;
  end

  initial begin
    Data = 0;
    #5 Data = 1;
    #40 Data = 0;
    #10 Data = 1;
    #40 Data = 0;
    #20 $stop;
  end

  initial begin
    Out_File = $fopen("results.vectors");
    $montitor(Out_File, "Clock = %b, Data = %b, Detect = %b", Clock, Data, Detect);
  end
endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1279532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 表达式引擎

企业的需求往往是多样化且复杂的&#xff0c;对接不同企业时会有不同的定制化的业务模型和流程。我们在业务系统中使用表达式引擎&#xff0c;集中配置管理业务规则&#xff0c;并实现实时决策和计算&#xff0c;可以提高系统的灵活性和响应能力。 引入规则引擎似乎就能解决这个…

UE学习C++(1)创建actor

创建新C类 在 虚幻编辑器 中&#xff0c;点击 文件&#xff08;File&#xff09; 下拉菜单&#xff0c;然后选择 新建C类...&#xff08;New C Class...&#xff09; 命令&#xff1a; 此时将显示 选择父类&#xff08;Choose Parent Class&#xff09; 菜单。可以选择要扩展的…

你知道MySQL 中的 order by 是怎么工作的吗?

欢迎大家到我的博客浏览。order by是怎么工作的&#xff1f; | YinKais Blog今天我们来看一下 MySQL 中 “ order by ” 是怎么工作的。 我们以一个实际的例子&#xff0c;来探讨这个问题&#xff1a; 假设我们的表是这样定义的&#xff1a; CREATE TABLE t (id int(11) NOT…

数据结构和算法-树与二叉树的存储结构以及树和二叉树和森林的遍历

文章目录 二叉树的存储结构二叉树的顺序存储二叉树的链式存储小结 二叉树的先中后序遍历例题小结 二叉树的层次遍历小结 由遍历序列构造二叉树一个遍历序列即使给定了前中后序&#xff0c;也不能确定该二叉树的形态可以确定的序列组合前序中序后序中序层序中序 小结若前序&…

LeetCode的几道题

一、捡石头 292 思路就是&#xff1a; 谁面对4块石头的时候&#xff0c;谁就输&#xff08;因为每次就是1-3块石头&#xff0c;如果剩下4块石头&#xff0c;你怎么拿&#xff0c;我都能把剩下的拿走&#xff0c;所以你就要想尽办法让对面面对4块石头的倍数&#xff0c; 比如有…

如何使用手机制作证件照

1、打开vx搜索小&#x1f34a;x名称&#xff1a;标准证件照免冠照 2、选择你需要的证件照尺寸类型 3&#xff0e;选择手机照片生活照或者点击开始拍摄&#xff08;建议纯色的墙面好换底色&#xff09; 4&#xff0e;选择背景颜色&#xff0c;红底&#xff0c;蓝底奉背景颜色随你…

LeetCode力扣每日一题(Java):1、两数之和

一、题目 二、解题思路 方法一&#xff1a;暴力枚举 这是最容易想到的一种方法&#xff0c;本质就是二重循环遍历数组&#xff0c;话不多说直接上代码 public int[] twoSum(int[] nums, int target) {for (int i 0; i < nums.length - 1; i) {for (int j i 1; j < …

纯js实现录屏并保存视频到本地的尝试

前言&#xff1a;先了解下&#xff1a;navigator.mediaDevices&#xff0c;mediaDevices 是 Navigator 只读属性&#xff0c;返回一个 MediaDevices 对象&#xff0c;该对象可提供对相机和麦克风等媒体输入设备的连接访问&#xff0c;也包括屏幕共享。 const media navigator…

【动态规划】LeetCode-931.下降路径最小和

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…

Selenium page object模式Python

目录 概述 优点 示例 项目结构&#xff1a; 基础页面类BasePage 业务页面类BaiduHomePage 测试类test_baidu&#xff1a; 文件工具类file_util 运行日志&#xff1a; 测试结果&#xff1a; 概述 在web应用程序的UI中&#xff0c;有一些区域可以与测试交互。页面对象…

神经网络模型预训练

根据神经网络各个层的计算逻辑用程序实现相关的计算&#xff0c;主要是&#xff1a;前向传播计算、反向传播计算、损失计算、精确度计算等&#xff0c;并提供保存超参数到文件中。 # coding: utf-8 import sys, os sys.path.append(os.pardir) # 为了导入父目录的文件而进行的…

2023年12月4日支付宝蚂蚁庄园小课堂小鸡宝宝考考你今日正确答案是什么?

问题&#xff1a;你知道电杆上安装的“小风车”有什么用途吗&#xff1f; 答案&#xff1a;防止鸟类筑巢 解析&#xff1a;小风车一般做成橙色&#xff0c;因为橙色是一种可令野鸟产生恐慌感的颜色&#xff1b;小风车在转动时&#xff0c;会发出令野鸟害怕的噪声&#xff1b;…

【iOS】数据持久化(三)之SQLite3及其使用

目录 数据库简介什么是SQLite&#xff1f;在Xcode引入SQLite APISQL语句的种类存储字段类型 SQLite的使用创建数据库创建表和删表数据表操作增&#xff08;插入数据INSERT&#xff09;删&#xff08;删除数据DELETE&#xff09;改&#xff08;更新数据UPDATE&#xff09;查&…

softmax实现

import matplotlib.pyplot as plt import torch from IPython import display from d2l import torch as d2lbatch_size 256 train_iter,test_iter d2l.load_data_fashion_mnist(batch_size) test_iter.num_workers 0 train_iter.num_workers 0 num_inputs 784 # 将图片…

【msg_msg】corCTF2021-msgmsg 套题

前言 该套题共两题&#xff0c;一道简单模式 fire_of_salvation&#xff0c;一道困难模式 wall_of_perdition&#xff0c;都是关于 msg_msg 的利用的。这题跟之前的 TPCTF2023 core 的很像&#xff08;应该是 TPCTF2023 core 跟他很像&#xff0c;bushi&#xff09;。 其中 f…

ISP算法简述-BLC

Black Level Calibration, 黑电平矫正 现象 1)在纯黑条件下拍张图&#xff0c;你会发现像素值不为0 2)或者你发现图像整体偏色 这些问题可能是黑电平导致的。 原因 存在黑电平的原因有2个&#xff1a; 1)sensor的电路本身存在暗电流。暗电流主要产生在光电信号转换过程中&#…

人工智能 - 人脸识别:发展历史、技术全解与实战

目录 一、人脸识别技术的发展历程早期探索&#xff1a;20世纪60至80年代技术价值点&#xff1a; 自动化与算法化&#xff1a;20世纪90年代技术价值点&#xff1a; 深度学习的革命&#xff1a;21世纪初至今技术价值点&#xff1a; 二、几何特征方法详解与实战几何特征方法的原理…

【C语言】深入理解指针(1)

前言 C语言是一种直接操作内存的编程语言&#xff0c;我们可以直接访问和操作计算机内存中的地址空间。 而C语言中存在的指针类型&#xff0c;指针指向的就是内存中的地址。我们可以通过指针来访问和修改内存中存储的数据。 因此&#xff0c;深入理解指针&#xff0c;并且理解内…

基于SSH的员工管理系统(一)——包结构

基于SSH的员工管理系统&#xff08;一&#xff09;——包结构 包结构 1、整体包结构 2、action包 3、domain实体包 4、service层 5、dao层 6、util工具包 7、页面层