FPGA基础知识关键点摘要
一.组合逻辑和时序逻辑的区别:
组合逻辑与输入直接实时相关,时序逻辑还必须在时钟上升沿出发后输出新值,有没有时钟输入是他们最大的区别!
组合时序容易出现竞争冒险现象出现亚稳态,时序逻辑不会出现,且更容易达到时序收敛
所以必须很好的掌握时序逻辑
设置不使用的 IO 为 为 in-tri 状态
RTL,Register Transfer Level,直译为寄存器转换级,顾名思义,也就是在这个级别下,要描述各级寄存器(时序逻辑中的寄存器),以及寄存器之间的信号的是如何转换的(时序逻辑中的组合逻辑)。
RTL 级代码
︴
综合 逻辑电路
︴
布局布线
︴
电路
可综合的语法就是那些可以在电路上实现的语法…
行为级语法就是不能够实现在电路里面,却可以作为仿真验证的高层次语法!
reg型和wire型信号有什么本质的区别?
此问题较大,需常百度查查!
二.阻塞和非阻塞赋值:
=,<=
区别与联系?
在输入输出GPIO口电路中,用到assign,它的详细用法如下:
1.被assign赋值的信号定义为wire型,被always@(*)结构块下的信号定义为reg型,值得注意的是,这里的reg并不是一个真正的触发器,只有敏感列表为上升沿触发的写法才会综合为触发器,在仿真时才具有触发器的特性。
2.另外一个区别则是更细微的差别:举个例子,
wirea;
regb;
assigna = 1'b0;
always@(*)
b= 1'b0;
在这种情况下,做仿真时a将会正常为0,但是b却是不定态。这是为什么?verilog规定,always@(*)中的*是指该always块内的所有输入信号的变化为敏感列表,也就是仿真时只有当always@(*)块内的输入信号产生变化,该块内描述的信号才会产生变化,而像always@(*)b = 1'b0;
这种写法由于1'b0一直没有变化,所以b的信号状态一直没有改变,由于b是组合逻辑输出,所以复位时没有明确的值(不定态),而又因为always@(*)块内没有敏感信号变化,因此b的信号状态一直保持为不定态。事实上该语句的综合结果有可能跟assign一样(本人没有去尝试),但是在功能仿真时就差之千里了。
3.always@(*)描述组合逻辑时,begin和end之间是串行,一条一条语句执行;
而用assign则是并行,相当于描述的是连线
fifo.数据缓存!很重要!
时间单位:
1s=1000ms=1000000微秒=1000000000纳秒=1000000000000皮秒=10^15飞秒=10^18啊秒=10^21仄秒=10^24幺秒
波形窗口的时间单位是软件的设置项 和仿真时间单位没有关系
可以通过波形窗口菜单tools/windows preferences/grid & timeline中的time units进行修改
三.testbench的输入输出数据类型正好与被测模块相反??原因如下:
1、被测module中,输入为wire,输出为reg
输入信号是由模块外部决定的,输入数据的状态是变化的,与外部模块是通过线连接,所以用wire,不用reg
2、testbench中,输入为reg,输出为wire
所谓寄存器类型就是暂存一个数据,保持数据不变。
在testbenchb里定义的A,B输出给被测模块
因此对于testbench来说,A,B是输出,数据需要存储才能输出给被测module,用reg型
在testbenchb里定义的result用来接收从被测模块中输入的数据
因此对于testbenchb来说,result是输入,用导线与被测模块连接,用wire型
也就是说,tb的输出对应着被测模块的输入;tb的输入对应着被测模块的输出
注意:只要是always块内部的变量输出,都用reg型
四:寄存器打拍:
“打一拍”的目的很简单,就是为了FPGA中时序的正确性!!!!(了保证FPGA输入输出接口的时序,一般会要求将输入管脚首先打一拍再使用,输出接口也要打一拍再输出FPGA。将信号打一拍的方法是将信号通过一次寄存器,而且必须在IOB里面的寄存器中打一拍。因为,从FPGA的PAD到IOB里面的寄存器是有专用布线资源的,而到内部其他寄存器没有专用的布线资源。使用IOB里面的寄存器可以保证每次实现的结果都一样,使用内部其他寄存器就无法保证每次用的都是同一个寄存器且采用同样的布线。同时,为了使用输入输出延迟功能(Input / Output delay),也必须要求信号使用IOB里面的寄存器。)
“打一拍”具体是怎么通过FPGA实现的呢?如下
always @ (posedge Clk) //对输入信号打三拍
begin
inputs_reg1 <= inputs;
inputs_reg2 <= inputs_reg1;
inputs_reg3 <= inputs_reg2;
if (inputs_reg2 == 1'b1 && inputs_reg3 == 1'b0)
begin
...
end