赞
踩
一、数据类型
1.首先记住,verilog中有符号数的运算全都是补码的方式。数据的存储也以补码形式
常量如1默认为有符号数。而1‘b1为无符号数。
2.只有当右值全为signed,计算才会按signed完成;否则,右值又要存在unsigned数,就按unsigned处理;
3.不论是对signed还是unsigned数进行截位,截位后的数据都是unsigned;
4.当右值位数不等时进行运算,小位宽数会先扩位到大位宽再参与运算;扩位按最高位进行扩,所以要尤其注意正负
5.如果在signed和unsigned计算中不想过分考虑扩位截位等逻辑,可以用$signed()函数来简化。
6.另外,有符号数1000 0000表示的-128(比较特殊,不能用原码补码概念来理解,记住就好),所以8位寄存器表示的数据范围是-128-0-127,共256个数。无符号8位表示的数据范围是0-255,也是256个数。
参考:尤老师公开课FPGA入门到实战,verilog语法第三讲,cnt_7为累加器加1的输出
二、case语句
1.case语句只能在always块下
2.always下比如else后加begin end 这么做是为了如果不止赋值一个信号,加了不会出错,否则最好两个信号分两个always块来写,加了begin end可以放在一个always块中
3.fpga是并行,上面可综合模块里面的begin end里面的语句也是并行触发。
4.verilog代码要在脑海里映射出硬件电路,区分软件思维。
5.不同功能的寄存器分always块来写,这样代码的可维护性更好。
6.同样的,在case里面的某一种情况里面,如果是多条赋值,在这一种情况里面加beginend,这多条语句都是这一种情况触发,所以可以写到一块。这几条赋值在always中赋值了,那么就得在这个always块中把对它的复位加上。要不然复位会接到寄存器的使能端。
7.if else相比case语句,级数更多,延时更多,而case只要一级,类似译码器
case实际是组合逻辑,LUT查找表实现,实际就是一个表,把真值表等转化为查找表,触发条件就类似地址
8.case一定要写defaule,未知的情况为default。
9.always块中都会综合为寄存器,但是还是要写非阻塞赋值。
10.下为时序逻辑,与sclk有关。
11.注意组合逻辑怎么写,组合逻辑是可以实时变化,
12.一定要消除锁存器,always中敏感列表要写全,锁存器延时时间不固定,电平触发,路径无法参与时序分析,布线出现问题,功能出现不稳定。
13.case情况中,赋值语句的右边的变量也要加到always敏感列表里面。
14.所有条件分支写全,加default。
15.产生锁存器的modelsim仿真时warning如下
16.always块同样可以描述组合逻辑,组合逻辑通过查找表生成,时序逻辑通过寄存器
17.时钟线是金线,数据线是铜线 所以always块中的边沿检测都用时钟线。
18.integer 32位整形 testbench才有
19.仿真里面是顺序执行 task里面
20.tb里面某一个输入没有附初始值,仿真刚开始即为红线。
注意task主要任务区必须加begin end也就是integer以后
tb模块里面的task,用于给tb模块的i_addr和i_data赋值。二者例化时为输入。
21.modelsim中启动仿真时右键选不带优化。
22.下面看时序理解,cnt_7也在另一个always块中同步加法器加1,所以第一个上升沿,cnt_7从0变为1,但是o_dv等变化用来判断的cnt_7这时还是用0来判别,因为同一时刻cnt_7在变还没变完。
或者说sclk上升沿前面低电平时候寄存器cnt_7数值是多少,那么上升沿到来时候就按照这个数来变化输出,低电平数据加载到D端,上升沿到来的时候加载到Q端,寄存器输出变化。
23.上文task中的@(posedge…) 下面是i_addr…,beginend里面两句有先后顺序但是延时为0ns
24.或者对i_addr和i_data其赋值初始值,并重新编译modelsim中文件,并重新复位运行波形即可不用关闭modelsim。对比仿真图可以看出变量就不是刚开始是红线了。
25.task对tb里面的所有reg变量都可以赋值。
26.乘除不可以直接用,要用ip核。
27.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。