编写Testbench的目的是把RTL代码在Modsim中进行仿真验证,通过查看仿真波形和打印信息验证代码逻辑是否正确。下面以3-8译码器说明Testbench代码结构。

Testbench代码的本质是通过模拟输入信号的变化来观察输出信号是否符合设计要求!因此,Testbench的核心在于如何模拟输入信号,并把模拟的输入信号输入到功能模块中产生输出信号,如上图所示。解决方案为:
Testbench代码可自定义,也可自动生成!
module decoder3_8(
input wire [2:0] in,
output reg [7:0] out
);
// always/initial 模块中只能用 reg型变量
always @(*) begin
case(in)
3'h0: out = 8'h01;
3'h1: out = 8'h02;
3'h2: out = 8'h04;
3'h3: out = 8'h08;
3'h4: out = 8'h10;
3'h5: out = 8'h20;
3'h6: out = 8'h40;
3'h7: out = 8'h80;
// 避免lanth
default: out = 8'h00;
endcase
end
endmodule
`timescale 1ns/1ns // 时间单位及=精度设置
module tb_decoder3_8();
reg [2:0] in;
wire [7:0] out;
// 初始化
initial begin
in <= 3'h0;
end
// 实现输入信号电平自动变化
always #10 in <= {$random} % 8;
initial begin
$timeformat(-9, 0, "ns", 6);
$monitor("time:%t in:%b out:%b",$time,in,out);
end
// 通过实例化模块把模拟输入信号传入功能模块中
decoder3_8 decoder3_8_inist(
.in(in),
.out(out)
);
endmodule
(1) 时间单位:时间尺度预编译指令 时间单位 / 时间精度
(2) 延时:#数字
(3) 测试模块的命名:tb_<功能模块名>
(4) 需要定义模拟的输入/输出信号:
(5) 输入信号初始化
(6) 用always 语句实现信号在仿真过程中的电平变化
(7) 通过实例化模块把模拟输入信号传入功能模块中
(8) 通过 $monitor实现变量实时监测
testbench文件中编写的系统函数要在initial语句块中!
使用格式:
$timeformat(time_unit, decimal_number, suffix_string, minimum_field_wdith);
$display //打印信息,自动换行
$write //打印信息
$strobe //打印信息,自动换行,最后执行
$monitor //监测变量
$stop //暂停仿真
$finish //结束仿真
$time //时间函数
$random //随机函数
$readmemb //读文件函数
用法:
$<系统函数名>("格式控制语句", 变量1, 变量2, 变量3....);
相应的格式控制符有:
(1) 常用转义字符
| 转义字符 | 含义 |
| \n | 换行符 |
| \t | 横向制表符 |
| \v | 纵向制表符 |
| \\ | 反斜杠 / |
| \'' | 引号 '' |
| \a | 响铃 |
| %% | 百分号 % |
(2) 常用数据格式
| 格式 | 说明 |
| %b / %B | 二进制 |
| %d / %D | 十进制 |
| %o / %O | 八进制 |
| %h / %H | 十六进制 |
| %e / %E | 科学计数法显示十进制数 |
| %c / %C | ASCII码 |
| %t / %T | 时间 |
| %s / %S | 字符串 |
| %v / %V | 线网型信号强度 |
| %m / %M | 层次名 |
更多打印格式参考:
System_Verilog打印格式_我不是悍跳狼丶的博客-CSDN博客_verilog格式化输出
用法:
$display("Add:%b+%b=%d",a, b, c); //格式“%b+%b=%d” 格式控制,未指定时默认十进制
Quartus可自动生成Testbench的基本框架,其中包含仿真所需参数的定义及rtl模块的实例化,生成后自己根据仿真需求对相应的变量进行初始化,或对输入信号进行模拟即可!可减少代码量,避免不必要的错误!
按下图依次点击即可:
Processing -> Start -> Start Test Bench Template Witer

在下方会显示生成的testbench文件路径:

注意:此时生成的文件为.vt文件,需要在生成的文件夹中改成.v文件,再根据需要进行改写即可!
基本语法:实例化的模块名.变量名
如:在RTL代码中定义了变量 state
module rtl_module(
port
);
// 定义状态寄存器
reg [2:0]state;
endmodule
在testbench中访问的方式为:
`timescale 1 ns/ 1 ps
module tb_rtl_module(
port
);
// 获取rtl代码中的变量
wire [2:0] state = rtl_module_int1.state;
// 实例化的模块
rtl_module rtl_module_int1 (
.port(port)
)
endmodule
注意:testbench中接收的变量要定义为wire型!
如:在RTL代码中定义的输入信号in
module rtl_module(
input wire in
);
//
endmodule
在testbench中对输入信号进行模拟的方式为:
`timescale 1 ns/ 1 ps
module tb_rtl_module();
reg in;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(sys_rst_n == 1'b0)
in<= 1'b0;
else
in<= {$random} % 2;
end
rtl_module rtl_module_int1 (
.in(in)
)
endmodule
注意事项:有严格时序要求时不能采用直接复制的方式,否则仿真图中会出现逻辑混乱的问题!
错误演示:
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
push_money <= 1'b0;
#30
sys_rst_n <= 1'b1;
#28
push_money <= 1'b1;
#43
push_money <= 1'b0;
#59
push_money <= 1'b1;
#68
push_money <= 1'b0;
end
在实际仿真中,我们没有必要按照实际的计数器值进行仿真,这将给仿真调试带来不便,此时我们只需改仿真参数为较小的数,能方便的看出输入输出的关系即可:
即在仿真文件的顶层模块中给每个参数传入新的值!如下所示:
rom_ip
#(
.CNT_200MS_MAX (199) ,
.CNT_256_MAX (9) ,
.CNT_KEYFILTER_MAX (9) ,
.CUNT_SCAN_MAX (99) ,
.CNT_SHIFT_MAX (21)
)
rom_ip_inst (
port
);
这种写法要求参数要从最顶层模块传到最底层模块,每一级都需写参数列表,当参数过多时会造成不便!
用defparam命令重定义每个子模块中的仿真参数,这样比较直观,且可以对任意子模块的参数进行设置,较为方便。
// 重定义仿真参数的方法
defparam rom_ip_inst.rom_rader_inst.CNT_200MS_MAX = 199;
defparam rom_ip_inst.rom_rader_inst.CNT_256_MAX = 9;
defparam rom_ip_inst.key1_filter_inst1.COUNTER_MAX = 9;
defparam rom_ip_inst.key1_filter_inst2.COUNTER_MAX = 9;
defparam rom_ip_inst.dynamic_seg_main_inst1.CUNT_SCAN_MAX = 99;
defparam rom_ip_inst.dynamic_seg_main_inst1.CNT_SHIFT_MAX = 99;
语法:
defparam 顶层模块实例化名.子模块1实例化名.子模块1的子模块实例化名 = 值;
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona
我正在尝试用Ruby(Rails)编写一个正则表达式,以便用户名的字符仅包含数字和字母(也没有空格)。我有这个正则表达式,/^[a-zA-Z0-9]+$/,但它似乎没有用,我在Rails中收到一个错误,说“The如果正则表达式使用多行anchor(^或$),这可能会带来安全风险。您是要使用\A和\z,还是忘记添加:multiline=>true选项?"我的user.rb模型中此实现的完整代码是:classUser我做错了什么以及如何修复此正则表达式,使其仅对数字和字母有效而不对空格有效?谢谢。 最佳答案 简短回答:使用/\A[a-z
为了减少我的小Rails应用程序中的代码重复,我一直致力于将我的模型之间的通用代码放入它自己的单独模块中,到目前为止一切顺利。模型的东西相当简单,我只需要在开头包含模块,例如:classIso这工作正常,但是现在,我将有一些Controller和View代码,这些代码也将在这些模型之间通用,到目前为止,我有这个用于我的可发送内容:#Thisisamodulethatisusedforpages/formsthatarecanbe"sent"#eitherviafax,email,orprinted.moduleSendablemoduleModeldefself.included(kl
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。Ruby是一种美丽的语言,但有一个我讨厌写很多次的关键词“结束”。有什么方法可以写出简洁的代码而不用每次都写“end”吗?