6.1.1 显式连续赋值语句
语法:
Assign #
两条语句:第一条语句是对连线型变量进行类型说明的语句;第二条语句是对连线型变量进行连续赋值的赋值语句,赋值语句由assign引导,用来驱动连线型变量,且只能对连线型变量赋值,主要用于对wire型变量的赋值。
6.1.2 隐式连续赋值语句
net_declaration:除了trireg类型外的任何一种连线型数据类型
range:指明变量数据类型的宽度,缺省时为1位
drive_strength:驱动强度
delay:延迟量
举例:
6.2.1 概念
行为级建模是从一个层次很高的抽象角度表示电路,其目的不是对电路的具体硬件结构说明,他是为了综合以及仿真的目的而进行的。在这个层次上设计数字电路更类似于使用一些高级语言(C)进行编程。通过把复杂的系统分解为可操作的若干模块,每个模块之间的逻辑关系通过行为模块的仿真加以验证。
6.2.2 图示
6.2.3 Verilog HDL行为描述语句及其可综合性
6.2.4 过程语句
(1)initial 语句
过程语句有两种,分别是initial与always,用来对寄存器赋值。Initial块在仿真时只执行一次,initial中多条行为语句可以是顺序执行也可以是并序执行的。Initial过程语句通常用于仿真模块中对激励向量的描述,或用于给寄存器变量赋值。
语法:
(2)always语句
相比于initial语句,always过程语句的触发状态一直存在,只要满足always后面的敏感时间列表,就会执行always语句块。
语法:
always@(敏感事件)
语句块
敏感时间列表应该列出影响块内取值的所有信号,若有两个以上的信号,则可以用or连接或者“ ,”连接。敏感信号分为两种类型,一种为边沿敏感型,一种为电平敏感型。对于时序电路,事件通常由时钟边沿触发。
例如:
注意事项:
举例:
6.2.5 语句块
语句块相当于对块中的一组行为描述语句进行打包,包括串行语句块(begin ----end)和并行语句块(fork---join)
采用begin_end模式,其中语句按串行方式顺序执行,可以用于可综合电路程序和仿真测试中。
其语法结构为:
Begin :块名
块内声明语句;
语句1;
语句2;
End
特点:
串行语句的每条语句依据快中的排列次序逐条执行,块中每条语句给出的延迟时间都是相对于前一条语句执行结束的相对时间。
串行语句块的起始执行时间就是串行语句块中第一条语句开始执行的时间,串行语句块的结束时间就是快中最后一条语句的结束时间。
并行结构的关键字“fork……join”,其中的语句按并行的方式执行,只能用于仿真测试,不可综合,其语法为:
Fork:块名
块内声明语句;
语句1;
语句2;
Join
串、并语句的对比
语句块 |
串行语句 |
并行语句 |
执行顺序 |
按照语句的执行顺序执行 |
所有语句在同一时刻执行 |
语句前面延迟时间的意义 |
相对于前一条语句结束的时间 |
相对于并行语句启动的时间 |
起始时间 |
首句开始执行的时间 |
转入并行语句块的时间 |
结束时间 |
最后一条语句的结束时间 |
执行时间最长的那条语句的结束时间 |
行为描述的意义 |
电路中的数据在时钟及控制信号的作用下,沿数据通道中各级寄存器之间传送的过程 |
电路上电之后,各电路模块同时开始工作 |
6.2.6 过程赋值语句
(1)阻塞赋值语句
阻塞赋值的操作符为“ = ”
语法格式:
B = a;
特点:在串行语句块中,各条阻塞赋值语句将按照排列顺序依次进行,并在并行语句块中的各条阻塞赋值语句同时进行,没有先后之分。
执行阻塞赋值语句的顺序是,先计算等号右端表达式的值,然后立即将计算的值赋给左边的变量,与仿真时间无关。
(2)非阻塞赋值
非阻塞赋值的操作符为“ <=”
语法格式:
A <=b
特点:
在串行语句块中,各条非阻塞赋值语句没有先后之分,排在前面的语句不会影响到后面的语句执行,各条语句并行执行;
执行非阻塞赋值语句的顺序是,先计算右端表达式的值,然后等待延迟时间的结束,再将计算的值赋给左边的变量。
例如:
1、赋值语句与重新赋值语句
赋值语句和重新赋值语句采用的关键字是“assign”与“deassign”,语法格式分别是
Assign<寄存器型变量> = <赋值表达式>
Design<寄存器型变量>
赋值语句只对寄存器型变量赋值,不可用于对连线型变量赋值,重新赋值语句用于释放assign对寄存器型变量的连续赋值,使用assign给寄存器型变量赋值后,该值将一直保持在寄存器上,直到遇到deassign
2、强制语句和释放语句
强制语句和释放语句采用的关键字是“force”和“release”,可以对连线型和寄存器型变量进行赋值操作,force语句的优先级高于assgin语句,语法格式:
Force<寄存器型、连线型变量> = <赋值表达式>
Release<寄存器或连线型变量>
使用force语句对寄存器型变量赋值时,变量的当前值被force覆盖,因而限制了驱动。遇到release,才能被释放。
3、条件分支语句
1)条件分支语句只能在initial和always语句引导的语句块(begin - end)中使用。
2)case语句
使用case,必须包含全部状态,若不能包含,则需要写出缺省项,否则产生锁存器。
特殊情况
4、循环语句
多用于仿真程序设计
1、forever语句
关键字:forever引导永久循环语句,在永久循环中不包含条件表达式,只执行无限循环,由 $finish引导结束。
语法格式:forever 语句或语句块
注意:不能写在程序中,一般用在initial过程语句中,没有时延控制。
(2) repeat语句
关键字“repeat”所引导的循环表示执行固定次数的循环,语法结构:
Repeat(循环次数)
循环体;
执行过程:先计算循环次数表达式的值,并将它作为循环次数保存起来,接着执行后面语句块,语句块执行结束之后,将重复执行次数减一,执行下一次操作,直至循环执行次数被减为0
(3) while语句
While(条件表达式) 语句或语句块:
其中,条件表达式表示循环体得以继续重复执行时必须满足的条件,常常是一个逻辑表达式。其过程可以表示为:先判断条件表达式是否为真,如果是,则执行后面的语句,直至某一次执行完语句后,判断出条件表达式的值为非真时,结束循环。
(4)for语句
只有在指定条件下表达式成立才进行循环,语法是:
For(循环变量赋初值;循环结束条件;循环变量增值) 语句块;
执行过程:先给循环变量赋初值,然后判断循环结束条件,若为真,则执行for语句中指定的语句块,然后进行“循环变量增值”操作,直到循环条件满足时,for语句结束。
循环语句可以用于可综合电路的设计,当采用循环语句进行计算和赋值描述时,可以得到可综合逻辑电路。
6.3 结构化建模
结构描述方式是将硬件电路描述成一个分级子模块系统,通过逐层调用这些子模块构成功能复杂的数字逻辑电路和系统。主要分为:模块级建模、门级建模、开关级建模
6.3.1 模块级建模
概念
通过由用户设计生成的低级子模块来对硬件电路结构进行说明,这种情况下的模块由低级模块的实例构成。
调用方式
基本语法:
模块名<参数列表>实例名(端口列表)
例如:
“模块名”就是被调用的模块,“参数值列表”是可选项,“实例名”代表生成的模块实例,实例名必须各不相同,“端口列表指明了模块实例与外部信号的连接。”
当需要对同一个模块进行多次调用时,可以采用阵列调用的方式对模块进行调用。
语法格式:
<被调用的模块名><实例阵列名>[阵列左边界:阵列右边界](<端口列表>)
模块端口对应方式
端口位置对应方式:
语法:
模块名<参数值列表>实例名(<信号1,信号2,信号3……>)
端口名列表中的信号与实例名中的信号一次连接,如果某一项缺省,则表示悬空,需要空出来
例如:
端口名对应方式
语法:
模块名<参数值列表>实例名(.端口名1<信号名1>,……)
调用实例:
不同端口的匹配
6.3.2 模块参数值
当一个模块在另一个模块的内部被实例引用时,较高层次的模块能够通过调用较低层次的模块来改变低层次模块的值。
修改的途径主要有两种:
使用带有参数的模块实例语句修改参数值
语法格式:
模块名<参数值列表>调用名(端口名列表);
调用实例:
使用参数重定义语句defparam修改参数
语法格式:
Defparam 参数名1 = 参数值1;
参数名2 = 参数值2;
实例: