一:系统调用函数
1:必须在procedure中执行,always,initial,task,function
2:$display,$write,$monitor,$strobe
(1)$display("..",arg2,arg3,...) 在active区
(2)$write("..", arg2,arg3,...)类似于display,但$write在输出字符串里不添加换行符
(3)$monitor("..",arg2,arg3,...)类似于display,在monitor events区,但打印参数改变的每一个值?这个观点有点奇怪,
输出:
并没有输出每一个HalfWordRegister的值
(4)$strobe("..", arg2,arg3,...)类似于display,在monitor event区。但$strobe被调用的时刻所有活动都完成了,$strobe才打印文本(打印最后稳定的数值),例如
输出
这包括所有的阻塞与非阻塞。写仿真结果时,请尽量使用strobe,以保证选通线网和寄存器被写的稳定。
但如果打印前有延时,则按照顺序打印,例如
输出:
3:$stop,$finish
$stop;暂停仿真
$finish;停止仿真
4:$fopen("filename");
打开文件,返回文件句柄;可以使用$diaplay(fd,"..",arg2,arg3,..) 或者$monitor(fd,"..",arg2,arg3,..)将内容写入文件里
5:$fclose(fd);
6:$random(seed);
产生无符号32位整型数据
7:$readmemh("path")/$readmemb("path");将文件内容读入memory里。
8:格式打印
9:$time:返回系统仿真时间
10:
二:编译选项
1:`include "filename"
2:`define <text1> <text2>
eg:`define BUS reg [31:0] ;声明:`BUS data;
3:`timescale <time unit>/<precision>
时间单位/时间精度
eg:`timescale 10ns/1ns later: #5 a = b; //这里#5是50ns
三:parameter参数化设计
1:定义
(1)parameter WIDTH = 4;
(2)module adder #(parameter MSB=31,LSB=0) (output reg[MSB:LSB] sum,....)
2:顶层模块使用带有parameter的子模块(instB)时
(1)若参数相同,则可直接使用
(2)若参数改变,使用defparam
defparam instB .WIDTH=2;
3:在verilog2001里,parameter可有size
parameter[2:0] WIDTH;
四:testbench
1:无输入输出,out设为wire
例化里的输出也为wire类型,例如:
2:DUT/DUV,例化
3:产生时钟模块
4:写testcase
5:例子:
五:时序电路基础概念
FF/FSM
1:FF(触发器)
异步电路与同步电路,一般使用同步电路,异步电路会造成亚稳态等
(1)锁存器latch
一般设计中很少希望出现latch,en有效时,起锁存作用,无效时,输出端随着输入端变化而变化;一般电平触发,没有时钟端
(2)触发器
与事件相关的特殊存储过程,构成时序逻辑电路的基本单元。
2:同步复位与异步复位
异步复位,同步释放;详情看资料
3:FSM
一般采用三段式
第一段:状态跳转,第二段:跳转的判断与跳转,第三段:当前状态的输出
(1)mealy:与当前状态与输入有关
(2)moore:与当前状态有关
4:阻塞赋值与非阻塞赋值
阻塞赋值(=),非阻塞赋值(<=)
一般来说,非阻塞赋值形成移位寄存器;
但现在综合工具现已智能化,阻塞赋值在某些工具中也有可能被综合成移位寄存器形式。
六:task and function
能否综合取决于内部语句是否可以综合
1:task
(1)可有0到n个参数,参数可以是输入,输出,或者inout
(2)不返回值
(3)里面可以有时间,delay,如#10;当存在delay时,不可综合
(4) 常用于testcase中。
2:function
(1)只能有输入
(2)不可有时间(delay),不可有@
(3)用于设计中,类似于c语言中的函数
3:区别
最重要的是function里面不能包含delay,task里面可以包含delay;因此task可以调用function,而function不能调用task。
七:其他:
1:wc -l filename.v 可得到代码的总行数