Verilog支持设计者从算法的角度,即从电路的外部行为对其进行描述。
–
结构化过程语句:initial语句和always语句。
Verilog中的各个执行流程(进程)
并发
执行,每个initial语句和always语句代表一个独立的执行过程,每个执行过程从仿真时间零开始执行,两者不能嵌套使用。
-initial
语句:
从仿真0开始顺序执行,整个仿真过程中只执行一次。若含多个initial块则其并发执行,且每个块各自独立。块内多条语句需用
begin和end
来组合。
可以在变量声明同时进行初始化:
-always
语句:
从仿真0开始顺序执行,在执行完最后一条语句,再次开始执行第一条语句,循环直到仿真结束。两个或者更多的always块是同时(并行)执行的,而內部的块是顺序执行的。
–
时钟发生器:
–
过程赋值语句:
更新对象是寄存器、整数、实数、时间变量。在被赋值之后值保持不变,直到被其他过程赋值语句赋予新值。
左值可以是reg、整数、实数、时间寄存器变量、存储器单元;或上述类型的位选、域选、拼接。
–
阻塞赋值语句:
使用“=”作为赋值符。串行块语句中的阻塞赋值语句按顺序执行,不会阻塞其后并行块中语句的执行。如果在一个begin-end块中使用阻塞赋值语句,那么这个语句块表现得是串行行为。
–
非阻塞赋值语句:
使用“<=”作为赋值符。允许赋值调度,不会阻塞位于同一个顺序块中其后语句的执行。赋值与完成顺序无关。
非阻塞赋值语句可以避免竞争:
1、使用阻塞赋值会导致两者具有相同值,具体值与仿真器有关,使用阻塞赋值来交换两数则必须使用中间变量;
2、使用非阻塞赋值可以达到交换两者值的目的,赋值时仿真器读取每个操作数的值并计算表达式的值,保存在临时变量中,赋值时仿真器将这些值赋予左侧变量,
读与写是分开的
,这也将会带来
仿真速度下降和内存使用量增加
等问题。
–
时序控制:
指定过程赋值发生的时刻,进而控制仿真时间如何向前推进。
–
基于延迟的时序控制:
指定语句开始执行到执行完成之间的时间间隔。延迟值可以是数字、标识符、表达式。延迟前要有
关键字#
–
常规延迟控制:
位于赋值语句左边。推迟整个赋值语句的执行。
#10 y = 1;
–
内嵌赋值延迟控制:
位于赋值符右边。相当于将值存在临时变量中,然后使用常规延迟控制将这个值赋给左侧变量。
y = #5 x + z;
–
零延迟控制:
可以保证带零延迟控制的语句将在执行时刻相同的多条语句中最后执行,避免竞争。但如果存在多条带零延迟控制的语句,他们之间的执行顺序与不一定。
–
基于事件的时序控制:
事件是指某一个寄存器或线网变量的值发生变化。事件可以用来触发声明语句或块语句的执行。
–
常规事件控制:
事件控制使用
关键字@
,poseedge表示正向跳变,negedge表示负向跳变。
–
命名事件控制:
声明event类型变量,触发该变量并识别事件是否发生,不能保存任何值,事件触发用
->
表示,判断时间是否发生用
@
来识别。
-OR
事件控制:
由关键词“
or
”连接的多个事件名或者信号名组成的列表称为敏感列表(or也可用‘
,逗号
’替代)。
当输入变量很多,可以使用
@(*)
来表示对其后语句块中所有输入变量的变化都是敏感的。
–
电平敏感时序控制:
使用关键字waie来表示等待电平敏感的条件为真。
–
条件语句:
–
多路分支语句:
四选一多路选择器:
-casex
与casez:
casex
:
将条件表达式或候选表达式中的x作为无关值。
casez
:
将条件表达式或候选表达式中的z作为无关值,所有值为z的位也可以用”?”来代表。
–
循环语句:
-while
循环:
关键字while。
-for
循环:
关键字for。
1、初始条件;
2、检查终止条件是否为真;
3、改变控制变量的过程赋值语句;
-repeat
循环:
关键字repeat。执行固定次数的循环,循环次数必须是一个常量、变量、信号。变量及信号作为重复次数,则重复次数为循环开始时变量或信号的值。
-forever
循环:
关键字forever。表示永久循环,等价于while(1)。中途退出使用disable语句。
–
顺序块与并行块:
–
顺序块:关键字begin-end组成。
1、语句一条一条按顺序执行,前面语句执行结束后在执行下一条语句(含有内嵌延迟控制的非阻塞赋值语句除外)。
2、若语句包含延迟或事件控制,延迟总是基于上一条语句执行完成的仿真时间。
–
并行块:关键字fork-join组成。
1、并行块内语句并发执行。
2、语句执行顺序是由各自语句延迟或事件控制决定的。
3、语句中的延迟或事件控制是相对于块语句开始执行的时刻而言的。
–
块语句特点:
–
嵌套块:
块可以嵌套使用,顺序块可以和并行块混合使用。
–
命名块:
块可以命名。
1、命名块中可以声明局部变量。
2、命名块是设计层次的一部分,命名块中声明的变量可以通过层次名引用进行访问。
3、命名块可以被禁用。
–
命名块禁用:关键字disable。
类似于C语言中的break。用于从循环中退出、处理错误条件、根据控制信号来控制某些代码段是否被执行。
–
生成块:关键字generate-endgenerate。
1、生成实例可以是:模块、用户自定义原语、门级原语、连续赋值语句、initial和always块。
2、生成的声明和生成的实例能够在设计中被有条件地调用(实例引用)。在设计中可以多次调用(实例引用)生成的实例和生成的变量声明。生成的实例可以用层次命名规则引用。
3、允许在生成范围内声明的数据类型包含:net、reg、integer、real、time、realtime、event。任务和函数的声明也允许出现在生成范围中,但是不能出现在循环生成当中,可悲层次引用。
4、不允许出现在生成范围中的模块项声明包括:参数、局部参数、输入、输出、输入/输出声明、指定块。
5、生成方式:
–
循环生成语句:
–
条件生成语句:
类似于if-else-if的生成构造。
-case
生成语句: