概况
Verilog为硬件编程语言,整体框架遵循非线性流程。每一个器件被包装成一个函数,并被相互引用,和python的函数库有些类似。
在仿真中,文件被分为模型文件和激励文件,模型文件是关于器件的代码,激励文件用于控制仿真测试和结果显示。
工具:Verilog编写使用的是加装拓展的神器VScode,仿真用的是Vivado
模型文件与基本语法
基础语句
- 和C类似,有
;
结尾,对排版没有硬性要求。 - 等号分为两种,
=
和<=
,前者为阻塞赋值,一般用在状态机,执行完后才会执行下一条;后者为非阻塞赋值,一般用在时序机,会和后面的代码一起执行。
如后文所提到的,等号左边不能是wire类型,一般是reg类型。
- 有基本的
+-*/
,也有基本的&|!
(只用一个就可以) - C中的大括号{}由
begin
和end
替换。 - 存在二进制数组,用
[7:0] name
表示位数和名称。 - 常量的表示:8’hff:表示8位的一个以十六进制(h可得)表示为ff的数字。
h表示十六进制,b表示二进制,d表示十进制
#10
代表时延,常用于制造信号和初始化
模型包装(相当于函数定义):
功能:定义模型名字,输入输出等
有两种写法:
1 | module bcd_decoder(s,o); |
以及:
1 | module heater ( |
注意:一般来说,程序会默认定义的input和output都是wire类型,但赋值的时候只能给reg类型赋值,所以在代码的第一行总是再次定义output的类型为reg:
1 reg led1,led2;
判断句
功能:基本判断,确定条件
代码为:
1 | if (条件)begin |
同时,支持if else
,else
语句。
触发模块
功能:作为核心模块,会一直监控,当条件满足时触发
代码为:
1 | always @(条件) begin |
当条件中直接填入变量时,当变量发生变动,代码就会被执行。
若条件为:posedge clk
则会在clk上跳沿时触发代码。
单次触发
功能:只被执行一次的代码
代码为:
1 | initial begin |
一般用于激励文件和初始化。
循环
和C极其类似,代码为:
1 | for (i=0; i< 16; i=i+1) |
注意,这里的i
需要提前声明: integer i;
激励文件
激励文件只是特殊的模型文件,大部分代码逻辑和上板块类似
首先同样需要定义一个模型和相关参数:
1 | module test( ); |
这里同样需要定义输入输出(对于模型文件而言),但由于在仿真的时候,输出由模型文件定义,输入由仿真文件定义,所以输出可以是wire型的,但输入是reg型的。
从另一个层面上说,仿真文件相当于模拟了模型文件的环境,它自己是没有输入输出的。
然后设定连接端口:
1 | ABC (.s0(sw[0]),.s1(sw[1]),.s2(sw[2]),.s3(sw[3]),.LD(ld)); |
ABC为模型文件的模型名字,后面的括号中,以逗号分隔,每一个板块为.模型文件变量(仿真文件变量)
,整体代码相当于调用了模型ABC并赋值。
之后跟一个单次触发的板块,用于对输入赋值即可,根据模型和测试要求,仿真的赋值各有不同,在这里不再赘述。