如何写一个仿真文件——testbench

2024-05-31 20:48
文章标签 仿真 testbench

本文主要是介绍如何写一个仿真文件——testbench,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欲观原文,请君移步微信

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提供一组用于访问外部数据文件的函数和任务。文件可以通过 f o p e n 和 fopen和 fopenfclose函数来打开和关闭。$fopen的语法为:

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

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

这篇关于如何写一个仿真文件——testbench的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1019012

相关文章

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

perl的学习记录——仿真regression

1 记录的背景 之前只知道有这个强大语言的存在,但一直侥幸自己应该不会用到它,所以一直没有开始学习。然而人生这么长,怎就确定自己不会用到呢? 这次要搭建一个可以自动跑完所有case并且打印每个case的pass信息到指定的文件中。从而减轻手动跑仿真,手动查看log信息的重复无效低质量的操作。下面简单记录下自己的思路并贴出自己的代码,方便自己以后使用和修正。 2 思路整理 作为一个IC d

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

Matlab simulink建模与仿真 第十章(模型扩展功能库)

参考视频:simulink1.1simulink简介_哔哩哔哩_bilibili 一、模型扩展功能库中的模块概览         注:下面不会对Block Support Table模块进行介绍。 二、基于触发的和基于时间的线性化模块 1、Trigger-Based Linearization基于触发的线性化模块 (1)每次当模块受到触发时,都会调用linmod或者dlinmod函数

AMEsim和Simulink联合仿真生成新的.mexw64液压模型文件

AMEsim和Simulink进行联合仿真非常重要的就是AMEsim经过第四阶段Simulation会在相同文件下面生成一个与AMEsim液压模型相同名字的.mexw64文件,在Simulink进行联合仿真的S-Function需要找的也就是这个文件,只不过输入的时候除了液压模型名字之外,后面有一个短下划线。 简而言之: AMEsim和Simulink联合仿真, 首先是需要AMEsim软

【自动驾驶】控制算法(八)横向控制Ⅱ | Carsim 与 Matlab 联合仿真基本操作

写在前面: 🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝 个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。 🔍 本文系 清流君 原创之作,荣幸在CSDN首发🐒 若您觉得内容有价值,还请评论告知一声,以便更多人受益。 转载请注明出处,尊重原创,从我做起。 👍 点赞、评论、收藏,三连走一波,让我们一起养成好习惯😜 在这里,您将

Matlab/Simulink和AMEsim联合仿真(以PSO-PID算法为例)

目录 安装软件和配置环境变量 Matlab/Simulink和AMEsim联合仿真详细流程 非常重要的一点 Simulink模型和AMEsim模型用S-Function建立连接 从AMEsim软件打开Matlab Matlab里的设置 Matlab的.m文件修改(对于PSO-PID算法) 运行程序 我印象中好像做过Matlab/Simulink和AMEsim联合仿真的分享似的

基于SA模拟退火算法的多车辆TSP问题求解matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述        基于SA模拟退火算法的多车辆TSP问题求解matlab仿真,三个车辆分别搜索其对应的最短路径,仿真后得到路线规划图和SA收敛曲线。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 (完整程序运行后无水印)

modelsim仿真流程

modelsim仿真流程 1、建立工程 project new "../prj" test.mpf 2、添加rtl文件 project addfile "../test.v" verilog 3、建立仿真库 vlib work 4、编译rtl到仿真库中 vlog -sv -sv09compat +define+T133 +incdir+"../rtl" test.v -wo

Matlab simulink建模与仿真 第八章(数学运算库)【下】

参考视频:simulink1.1simulink简介_哔哩哔哩_bilibili 六、圆整函数及最值函数模块 1、Rounding Function圆整函数模块 圆整函数模块的功能是将小数转换为整数,它提供了四种取整方式: ①floor:向下取整,输出距离输入小数在负无穷方向上最近的整数。 ②ceil:向上取整,输出距离输入小数在正无穷方向上最近的整数。 ③round:四舍五入,输出距