欲观原文,请君移步微信

testbench作用是什么?

testbench就是对写的FPGA文件进行测试的文件。任何设计都是有输入输出的,testbench的作用就是给这个设计输入,然后观察输出是否符合我们的预期,这就是testbench的功能。运行环境一般是ise或者vivado自带的仿真工具,或者如modelsim一样的第三方仿真工具。
如下图所示,仿真模型就好比是"一道菜"(Verilog design file),而输入是厨师给的"各种调料"(Stimulus),输出是这道菜的口味是否符合顾客的"预期口感"(Response)。

testbench是如何运行的?

首先要记住一点就是所有testbench本质上都是串行执行,因为在CPU环境下,所有的语句都是串行的。所有并行的语句,比如两个always模块,fork join语句块,都是软件模拟并行执行的。所以早先的编译器,信号定义要在initial语句前面,initial的信号要先有初始值后面的语句才能从给定初值开始执行。所以写testbench的时候,要注意最好先定义信号再写initial语句后面的语句交换顺序不影响,软件可以识别并按照IEEE标准的顺序去执行。
如果一个模块里面想用并行执行语句用fork join语句,顺序执行用begin end语句。initial语句可以写多个,都是并行执行的,当两个信号在initial冲突的时候,会先执行前面的initial的值。

常用testbench语法

1.精度问题
编译器指令用以控制编译和预处理verilog代码,他们通过重音符号[``]来指明。重音符号常位于键盘的左上角。与时间有关的指令是`timescale指令

`timescale [time_unit] / [time_precision]

time_unit指定计时和延时的测量单位,time_precision则是指定仿真器的精度。
比方说,指令

`timescale 1ns/10ps

则说明仿真单位为1ns,精度为10ps。
2.延迟问题
延时语句——#n; 代表延时n个时间轴单位。比如之前定义了timescale 1ns / 10ps;当指定如下代码中的延时,
#5 y = a & b;
表明实际上的延时为5ns(即5*1ns)。
3.initial
一般用 initial 块给信号赋初值,initial 块执行一次。inital 块里面是顺序执行的。如下

initial
begin
a=0;
#100;
a=1;
end。

4.always
always表示由事件激发反复执行。比如下面产生的语句:

always #5 clk= !clk;

5.forever
forever 表示由事件激发反复执行,,重复执行其主体直至仿真结束位置。循环体内常包括一定的时序控制结构,以致周期性推迟执行。比方说,我们换一种方式来描述时钟信号,该信号每10个时间单位翻转一次,且永远运行下去。

initial
begin
clk=1'b0;forever#10 clk=~clk;
end

6.repeat
repeat循环的简单语法如下,循环体内的语句被重复执行指定数次,该数可通过[number]来指定。

integer i;
...
repeat(16)
begin[procedural_statements;]
end

7.wait
wait语句用以等待指定条件。其简单语法如下

wait[boolean_expression]

直到[boolean_expression]被计算为真,后面语句才可跳过延迟,继续执行。比方说,

wait(state==READ && mem_ready==1'b1) [statement_to_get_data];

8.task
任务就是一段封装在“task-endtask”之间的程序。任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的。调用某个任务时可能需要它处理某些数据并返回操作结果,所以任务应当有接收数据的输入端和返回数据的输出端。另外,任务可以彼此调用,而且任务内还可以调用函数。?
任务定义的形式如下:

task task_id; [declaration] procedural_statement
endtask

其中,关键词 task 和 endtask 将它们之间的内容标志成一个任务定义,task 标志着一个任务的开始;task_id 是任务名;可选项declaration 是端口声明语句和变量声明语句,任务接收输入值和返回输出值就是通过此处声明的端口进行的;procedural_statement是一段用来完成这个任务操作的过程语句,如果过程语句多于一条,应将其放在语句块内;endtask 为任务定义结构体结束标志。下面给出一个的实例:

task task_demo;                //任务定义结构开头,命名为 task_demo input  [7:0] x,y;           //输入端口说明 output [7:0] tmp;           //输出端口说明  if(x>y)                  //给出任务定义的描述语句 tmp = x; else tmp = y;
endtask

虽然任务中不能出现 initial 语句和 always 语句语句, 但任务调用语句可以在 initial 语句
和 always 语句中使用,其语法形式如下:

task_id[(端口1,  端口 2, ........,  端口 N)];

9.function
函数定义是嵌入在关键字function和endfunction之间的,其中关键词function标志着一个函数定义结构的开端,endfunction标志着一个函数定义结构的结束。
定义函数的语法:

function <返回值的类型或范围> (函数名);
<端口说明语句>
<变量类型说明语句>begin
<语句>
........
end
endfunction

如下例:

function [7:0] getbyte;
input [15:0] address;
begin<说明语句> //从地址字中提取低字节的程序getbyte = result_expression; //把结果赋予函数的返回字节
end
endfunction

(1)函数只能与主模块共用同一个仿真时间单位,而任务可以定义自己的仿真时间单位。
(2)函数不能启动任务,而任务能启动其它任务和函数。
(3)函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量。
(4)函数返回一个值,而任务则不返回值
10.数据类型转换函数
$unsigned和$signed函数执行介于无符号数和有符号数类型之间的转换。
11.系统函数
Verilog有一组预定义的系统函数,以$打头,执行与系统相关的操作,如仿真控制、文件读取等。下面我们讲一下一些常用的函数和任务。
1.$finish和$stop。其中,$finish任务用于终止仿真并跳出仿真器;$stop任务则用于中止仿真。
2.在Modelsim中,仿真的结果可以以波形的形式显示,也可以以文本的形式显示。四种主要的显示任务有$display、$write、$strobe和$monitor,它们语法类似。在Modelsim中,文本是在控制面板显示的。$display的语法与C语言中的打印函数类似。其简单语法为:

$display([format_string], [argument], [argument], ...);

3.Veirlog提供一组用于访问外部数据文件的函数和任务。文件可以通过fopen和fopen和fopen和fclose函数来打开和关闭。$fopen的语法为:

[mcd_names] = `$`fopen("[file_name]");

至此,testbench文件的语法部分就告一段落,但是小编提醒:学verilog要知道verilog语句的执行顺序和机制,生成的对应时序,哪些语句可综合哪些不可综合。这是最基础的要求。

如何写一个仿真文件——testbench相关推荐

  1. cpp 一个文件分成两个文件写_为ORB-SLAM2写一个launch文件

    在ros下启动ORB-SLAM2的步骤比较繁琐,比如运行单目版本,首先需要启动相机,然后在新的命令窗口下打开ORB-SLAM2的相应节点,这个步骤需要输入配置好的路径等: # ros 启动orb-sl ...

  2. 用C语言写一个人员文件管理系统(一)

    题目如下: 1.输入三个人的信息(姓名,年龄.性别.家庭住址),并保存到txt文件中.再从文件中读取信息显示在屏幕上: 2.实现人员信息重复显示功能: 3.实现人员信息的添加. 过程如下: 首先建立一 ...

  3. 如何写一个不带BOM的UTF8文件

    大多数情况下,我们并不关心UTF8文件是否带BOF.可是今天突然要写一个UTF8文件,但不需要带BOF.实现方法如下: 在用StreamWriter构造的时候不要传系统默认的Encoding.UTF8 ...

  4. Xilinx Vivado的使用详细介绍(1):创建工程、编写代码、行为仿真、Testbench

    新建工程 打开Vivado软件,直接在欢迎界面点击Create New Project,或在开始菜单中选择File - New Project即可新建工程. 点击Next 输入工程名称和路径. 选择R ...

  5. discuz中写一个表单,数据存入到数据库中,再从数据库读出来显示在列表中

    2019独角兽企业重金招聘Python工程师标准>>> 要做到如下的一个效果: 创建的文件有: ./funds.php ./template/PHPChina/funds/funds ...

  6. 利用fputc函数写一个putw(w,fp)函数,将整数w写入fp所指文件中; 利用fgetc函数写一函数getw(fp)从所指文件读出一整数

    <程序设计基础-c语言>杨莉 刘鸿翔 ISBN-978-7-03-032903-5 p257 习题8 5.利用fputc函数写一个putw(w,fp)函数,将整数w写入fp所指文件中: 利 ...

  7. 教你写一个可以找到.m文件所有接口名的命令行工具

    项目github 出发点 今天工作中写了一个工具类,在.m中完成所有功能后,发觉把所有接口从.m中拷贝到.h中声明,好麻烦啊,所以就考虑写个命令行工具来做这些工作. 想要达到的结果 我们设计这个小工具 ...

  8. 多进程同时写一个文件会怎样?分别用write和fwrite去观察现象

    一.问题还原 在多进程的环境下,父子进程同时去写一个文件,例如父进程每次写入aaaaa,子进程每次写入bbbbb,问题是会不会出现写操作被打断的现象,比如出现aabbbaaabb这样交替的情况? 二. ...

  9. python文件分发_python 写一个文件分发小程序

    一.概述 该小程序实现从源端到目标端的文件一键拷贝,源端和目标段都在一台电脑上面,只是目录不同而已 二.参数文件说明 1. settings.txt的说明 a. 通过配置settings.txt,填源 ...

最新文章

  1. ASP .NET Core Web MVC系列教程二:添加控制器
  2. Java与Unicode
  3. 如何用计算机输入数学公式,使用Win7输入面板让数学公式输入更轻松
  4. Express中间件的应用-路由保护(登录限制)、网站维护、页面404
  5. 洛谷 P1983 车站分级
  6. c++ 添加按钮_使用 Visual Studio 2019 批量添加代码文件头
  7. centos网卡发送被占满了_CentOS 查看实时网络带宽占用情况方法
  8. 设计模式笔记之 - Composite
  9. TRACERT命令及用法
  10. 函数递归/二分法/列表,字典生成式/三元表达式/匿名函数/内置函数
  11. configure: error: cannot guess build type; you must specify one解决方法
  12. 鼠标移开事件(onmouseout)
  13. Java_基础(一)
  14. jQuery源码06-jQuery = function(){};给JQ对象,添加一些方法和属性,extend : JQ的继承方法,jQuery.extend()...
  15. music的matlab程序,MUSIC算法matlab程序
  16. 2023年前实现大型工业企业5G应用渗透率超35%!模组企业如何保驾护航?
  17. Android开发:基站定位
  18. 解决MERCURY弹出上网公告的窗口方法
  19. Qt例子学习笔记 - Examples/Qt-6.2.0/charts/callout
  20. Telegraf 简单使用介绍

热门文章

  1. maven pom.xml解析、命令说明、依赖传递、继承、聚合、properties、build、依赖范围、版本仲裁、profile
  2. 史上最全的C++/游戏开发面试问题总结(一)——C++基础
  3. 【Golang第6章:排序和查找】golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例
  4. doodoo.js发布1.1.0 -- 中文最佳实践Node.js Web快速开发框架,支持Koa.js, Express.js中间件。包含多项功能改进,及Bug修复。...
  5. system.setout_Java System类setOut()方法及示例
  6. 网站标题设计与搜索引擎
  7. 香港银行开户多少钱能开下来
  8. JAVA:实现求StandardDeviation标准差算法(附完整源码)
  9. openEuler 的安装及内核编译
  10. impala添加kerberos认证