FPGA知识点小总结(1)
----------------------------------------------分割线------------------------------------------------------
其实鲁迅在年轻的时候从事过FPGA的工作,他又说了,知识点一点点的去总结,积累下来,的确很重要。
后来师从鲁迅以后,天天都在想师傅说的每一句话,学东西一定得细,细到不能自拔。
----------------------------------------------分割线------------------------------------------------------
有小伙伴问我,如何写这个test bench 文件,这个问题挺好,是基础问题,但是却是实践当中随时随地都在用的问题。这里做一个小总结,如何写自己需要的test bench。
编写test bench 的目的:
在我们利用VHDL或者verilog等硬件描述语言去描述完电路以后,会想知道这个电路具体工作性能,但是如果我们写的电路过于庞大,我们不便于直接综合布线
上板验证,并且如果我们只是关心逻辑正确性,并不考虑实际的电路延迟等影响,对于我们最方便的应该是编写仿真文件。
这就是我们编写仿真文件的目的,那么仿真文件如何写呢?写代码和写作文一样,我们先列一个大纲。
1. 'timescale 单位/精度
2. module test_bench()
3. 定义需要的变量;
4. initial语句给定初始化;
5. always语句时序块;
6. 把要用仿真的模块例化进来;
7. endmodule
这就是仿真文件,需要的完全步骤,根据这几个步骤来梳理。
----------------------------------------------分割线------------------------------------------------------
全流程解析,如果你使用的是vivado,那么请按照这个步骤来创建自己的testbench。
文件如下,命名之后保存在本地工程文件下面就可以了。
接下来打开这个test_bench就可以了,请注意这里使用的是verilog语言。
1. 'timescale 单位/精度
顶上第一句语句就是第一步,确定仿真时间的规格,首先是单位,1ns这个单位表示是,你所执行仿真的时候的单位值。1ps表示精度值,就是
你在描述后续时序的时候,最小操作单位。#20表示延迟20个单位,即20纳秒,可以延迟#20.001因为精度是ps。
请注意以下,这一句语句结尾没有分号!
2. module test_bench()
紧跟其后的是testbench的模块声明,由于verilog当中模块是最基本的单元,所以仿真模块同样需要这样申明,只不过仿真模块不需要有输入
输出,我们需要模拟的仿真时钟,输入源都按照模块内部变量的方法赋值。
3.定义需要的变量或常量
如果接下来定义的变量或者常量,则按照一下规则进行:
有人喜欢先定义reg,有人喜欢先定义wire,不太有影响。
这里说明一下,常量是内部不变量,wire指线网,一根线,仅仅是接入后续模块当中的一根线,reg是寄存器变量,描述的是仿真模块当中需要
利用initial和always块去描述时序特性。
简单总结一下,通常申明信号和变量的关键字一般都是reg和wire。reg类型是在initial和always语句中使用的变量,在assign语句和用于例化连接
的信号用wire定义。
4.initial语句给定初始化;
初始化之前申明的所有内部reg变量用如上表达式,记得begin 和 end。
5. always语句时序块;
表示每过20ns,clk翻转一次。可以算算这是多少频率的时钟。
这里分析一下,20ns转一次,则每一个电平保持20ns,所以周期是40ns。
占空比也就是百分之50。
6. 把要用仿真的模块例化进来;
这里要仿真的模块是example,所以就例化上去,注意看这个例化的模块输入时clk所以把testbench内部变量写进去,就算是模拟的输入。
同样需要一个wire线来接到example的输出。
好了最后加上endmodule就可以了。
----------------------------------------------分割线------------------------------------------------------
完整模板放下面,供忘记的时候给自己复习看看,请注意就是test_bench内部变量个数定义,取决于要去仿真的模块(即被例化的模块)