1.过程语句
并发执行,时序条件或事件触发。每个模块中可以含任意个initial和always语句,块内部可顺序执行,块间的语句可以交叉执行。较适合的做法是在always语句中描述硬件行为,在年语句中模块初始化。
(a)initial:在仿真开始时,且该块仅执行一次,常用于测试和虚拟模块中,多个initial语句之间并行;可以是下列语句之一:
assign //阻塞或非阻塞过程赋值语句
continous //连续赋值语句
conditioal //条件语句
case //case语句
loop //循环
wait //等待
disable //终止
sequential //顺序执行块
parallel //并行执行块
task //任务使能语句
(b)always [@(timing_control)]:循环执行,触发条件由时序控制决定,可以电平触发也可边沿触发(negedge,posedge),还可以多个信号用or连接,满足条件才执行,否则阻塞并等待再次满足条件,所以输入的变化会影响输出;可用语句与initial类似;缺省条件则产生一个仿真死锁。
边沿触发常用于描述时序行为,如有限状态机等;电平触发常用来描述组合逻辑行为。
2.条件语句
(a)if() else if() else;
(b)条件操作符(?:)二选一;
3.case endcase语句
多分支枚举选择,表达式长度要统一。派生的casez和casex语句,在casex句中值x(未知)和z(高阻)都被认为是无关位,if句中表达式产生的x或z值将出错;在casez句中值z被认为是无关值。如casez(mask)4`b1???:Dbus[4]=0;表示第4位是1忽略其他位。
4.循环语句
(a)forever:连续执行,跳出语句disable可与过程语句同使用;
(b)repeat():执行固定次数,计数表达式值X或z不定是,按0处理;
(c)while():执行过程赋值语句直到指定的条件为假,如果表达式开始就假,则不执行;
(d)for:
(e)循环的异常退出:disable,可退出任何循环,能终止任何begin_end块的执行,块名可放在begin关键字后冒号后。
5.事件控制
在verilog2001新规范中@(a,b,c)和@(a or b or c)等价,
(a)边沿触发事件 @event :posedge和negedge表示上升沿转换的形式有:
0->x,0->z,0->1,x->1,z->1;
下降沿转换形式有:
1->z,1->x,1->0,x->0,z->0;
(b)电平触发事件 wait()
6.持续赋值
赋值给预先定义好的网线,在模拟期间只要且只有等式右边有变化,就赋值给左边,且连续、自动完成;若有指定赋值延迟,则在右边变化后过一定延迟时间再赋值给左边;用于数据流行为建模,常用在组合逻辑设计。
assign a=b;
7.过程赋值语句
用来更新寄存器型、整型、时间型和存储器型变量;与持续赋值的区别:
一,在过程控制流下控制更新寄存器变量;assign驱动线网,且在输入操作值变化时求解新值并更新变量;
二,在过程块内部;assign句在过程块外步;
三,通常用在initial和always块中,只能对寄存器型变量赋值;
·通常在always块中用阻塞性赋值来产生组合逻辑;
·通常在always块中用非阻塞性赋值来产生时序逻辑;
(a)verilogHDL的层次化事件模型:IEEE标准中四个独立层次化事件队列:
动态事件队列
停止运行的事件队列()顺序可变:
阻塞赋值,计算非阻塞赋值右边的表达式,持续赋值,执行$display命令,计算原语的输入和输出变化;
非阻塞事件队列:
#0延迟阻塞赋值;
监控事件队列:
更新非阻塞赋值语句左边变量的值;
其他指定的PLI命令队列:
执行$monitor命令,$strobe命令;
所有事件可以加入到任何一个事件队列中,但只能从活跃事件队列中移出。
8条可综合风格的VerilogHDL编码规则(尽量避免条件竞争):
·时序逻辑建模使用非阻塞赋值;
·锁存器建模使用非阻塞赋值;
·在always块中组合逻辑建模使用阻塞赋值;
·在同一个always块中对时序逻辑和组合逻辑同时建模使用非阻塞赋值;
·不要在同一个always块中混和使用阻塞和非阻塞赋值;
·不要在多个always块中对同一个变量赋值;
·使用$strobe命令显示对非阻塞语句进行的赋值;
·不要使用零延迟赋值语句。
(b)阻塞性过程赋值
必须在顺序块中后续语句执行前执行完毕,但不能阻止并行块中后续语句执行;如:
reg y1,y2;
y1=0;y2=1;
(c)非阻塞性过程赋值
在时钟拍开始时刻计算右边表达式的值,在时钟拍结束时刻赋值给左边表达式,即在计算结果和更新变量期间可以计算其他语句表达式的值并更新,就是非阻塞赋值语句不阻塞其他语句的执行。
那么各条非阻塞语句各自独立,并行执行,不会阻塞其他语句执行。"<="为非阻塞赋值符号,例:reg x1,x2;x1<=9;x2=5;
非阻塞赋值语句只能对寄存器操作,因此只能在过程块(initial和always)内部实现。如果时序逻辑和组合逻辑同时在一个always块中出现,常用非阻塞赋值,把这个always块当作时序逻辑来处理。
单独阻塞赋值表示的组合逻辑和单独非阻塞赋值表示的时序逻辑混合,例如:
module ex1(q,a,b,clk,rst_n);
output q;
input clk,rst_n,a,b;
reg q,y;
always @(a or b)
y=a^b;
always @(posedge clk or negedge rst_n)
if(!rst_n)
q<=1`b0;
else
q<=y;
endmodule
建议在所有的时序逻辑编码中使用非阻塞赋值。
文章评论(0条评论)
登录后参与讨论