第6章VerilogHDL设计进阶1第六章VerilogHDL设计进阶6.1过程语句中的赋值语句格式:目标变量名=驱动表达式;6.1.1过程中的阻塞式赋值“阻塞”是在当前的赋值语句完成前,阻塞或停止其它语句的执行。阻塞赋值的步骤:(1)计算出“驱动表达式”的值。(2)向“目标变量”进行赋值操作。(3)完成赋值,即实现目标变量的更新。对于阻塞赋值,这三条是并成一步完成的,即一旦执行,目标变量立即更新。在同一过程结构中,允许对同一变量多次赋值。类似于软件语言里面的顺序赋值特点。第6章VerilogHDL设计进阶26.1.2过程中的非阻塞式赋值格式:目标变量名=驱动表达式;在一个串行块中,一条非阻塞型赋值语句的执行,并不影响块中其它语句的执行。非阻塞赋值的步骤:①首先计算出“驱动表达式”的值。(立即完成的,不耗时的)。②进入步骤(2)的赋值阶段:等待其它所有的非阻塞语句。程序要执行到结尾才开始进入步骤(3)。③目标变量的更新。所有语句同时被更新。第6章VerilogHDL设计进阶3在begin-eng串行块语句中,各条非阻塞过程赋值语句对应的“赋值表达式”同时开始计算。在过程块结束时,才将结果赋值给各个“被赋值变量”。可理解为先同时采样,最后一起赋值。非阻塞赋值不允许用于连续赋值。非阻塞赋值操作只能用于对寄存器类型变量进行赋值,因此只能用在initial块和always块等过程块中。在同一过程结构中,允许对同一目标变量多次赋值。目标变量最终接受最接近过程结束的那个驱动源的数据。非阻塞赋值特点阻塞与非阻塞都不允许在作为并行语句的连续赋值语句assign中对同一变量赋值第6章VerilogHDL设计进阶4举例:例6-1中,对Q1的多次赋值是错误的。因为3条assign语句是并行执行的,Q1的值无法确定。例6-2中,对Q1的多次赋值是允许的,最终Q1获得表达式C∧A的值。第6章VerilogHDL设计进阶5说明:假设A与B在同一时刻从0变化到1。例6-3与例6-4都讲启动过程。例6-3中最终Q的值是1例6-4中,3条语句是同时赋值的,因此Q得到的值是M1与M2在A、B变动以前的值0。第6章VerilogHDL设计进阶66.1.3进一步了解阻塞和非阻塞式赋值的内在规律第6章VerilogHDL设计进阶7所有的阻塞与非阻塞赋值语句都必须在一个延时中完成。阻塞赋值在延时前就已经按照顺序方式完成所有的赋值更新。但是所有的非阻塞赋值这时刚进入并完成赋值的第一阶段,且必须在延时后同时完成赋值。可以换个角度来考虑。当过程一启动,到执行完过程中所有类型的语句没有耗费任何时间,时间是在过程结束时流逝的。即有两个过程,一个是全部是阻塞赋值语句组成的,另一个全部是非阻塞赋值语句组成的,它们的执行周期是一样的。第6章VerilogHDL设计进阶8变量b1得到值是比变量a1的到的值早一个时间。第6章VerilogHDL设计进阶9例6-9中,T在过程中出现了3次非阻塞赋值。对于对同一个目标变量T进行多次非阻塞赋值,只取最后一个语句中的值。最后一个语句又需要前面T的值,因为在前面两条语句没有给T赋值,因此T的值是个未知数。T成了一个不确定信号。例6-10中,虽然有不完整的if语句存在,但是T在前面已经赋值0,因此不会出现时序电路。第6章VerilogHDL设计进阶106.2过程语句归纳结构化过程语句1.initial语句2.always语句第6章VerilogHDL设计进阶11过程块的定义过程语句@(敏感信号列表)块语句开始标示符:块名块内局部变量说明一条或多条过程赋值或高级程序语句块语句结束标示符蓝色表示的是可以省略部分。过程语句是initial或者是always敏感信号列表只在always语句中出现,用于激活过程语句的执行。块语句标示符指begin-end(顺序块)与fork-join(并行块)组成块名与块内局部变量说明均为可选项。第6章VerilogHDL设计进阶12过程语句initial与always都是从模拟的0时刻开始运行的,但是initial过程中的语句只执行一次,而always语句是循环的执行后面的语句。initial过程语句不带触发敏感条件,因而必定从模拟的0时刻开始执行它后面的块语句;always语句通常带有触发条件,只有当触发条件被满足的时,其后的块语句才真正被执行。如果触发条件被缺省,则认为触发条件始终满足。一个模块中可以包含多个initial与always语句,代表多个过程块的存在,它们之间互相独立,并行运行。1.initial语句1.initial块从仿真0时刻开始执行,在整个仿真过程中只执行一次;2.initial块内部的语句是顺序执行的;3.如果一个模块里包含多个initial块,则这些initial块从仿真0时刻开始并发执行,且每个块的执行是各自独立的4.作用:一般用于初始化、信号监视、生成仿真波形等目的。5.initial是一条主要面向模拟仿真的过程语句,通常不被综合工具所接受。modulestimulusinitial;regx,y,a,b,m;initialbeginm=1'b0;$display($time,m=%b,m);endinitialbegin#5a=1'b1;$display($time,a=%b,a);#25b=1'b0;$display($time,b=%b,b);endinitialbegin#10x=1'b0;$display($time,x=%b,x);#25y=1'b1;$display($time,y=%b,y);endinitial#50$finish;endmodul#0m=0#5a=1#10x=0#30b=0#35y=1举例:2.always语句1.always语句为一无限循环语句过程只有两种工作状态:执行状态、等待状态2.过程中的顺序语句具有明显的顺序和并行双重性在一个always中,10条语句与100条语句的执行时间是一样的。3.过程语句本身是并行语句同一模块中,不同的过程结构是并行运行的。即两个或者多个always语句是并行的。4.一个过程中只允许描述对应于一个时钟信号的同步时序逻辑一个过程中只描述针对同一时钟的同步时序逻辑。举例4-19,需要两个always过程来描述两个时钟信号。不要在同一过程中混用阻塞与非阻塞赋值。5.注意不完整条件语句与时序电路的关系不完整的条件语句会产生时序电路完整的条件语句可能构成组合电路,也可能构成时序电路。在例4-1中删除最后两条语句,会在输出口含反馈线路第6章VerilogHDL设计进阶20注意:如果case语句的条件语句中未能“历数”所有条件时,即时使用了default语句也有可能在综合后的电路中依然出现锁存器。因为在default语句中未能将在case语句中出现过的所有赋值语句都在default语句中指明其操作。modulecase_test(x,y,m,p,q,j,A,B,C,D,S1,S0);inputx,y,m,p,q,j,S1,S0;outputA,B,C,D;regA,B,C,D;always@(x,y,m,p,q,j,S1,S0)begincase({S1,S0})2’B00:A=x&y;2’B01:B=m;2’B10:C=p|q;2’B11:D=~j;Default:A=0;endcaseendendmodule举例:6.always语句的作用:在测试模块中一般用于对时钟的描述,但更多的是用于对硬件功能模块的行为描述。功能模块的行为描述是由过程块构成的,但是每个过程块是由过程语句所引导的,因而每个功能模块的行为至少存在一个always过程语句。moduleclock_gen(outputregclock);initialclock=1'b0';always#10clock=~clock;//产生周期为20的脉冲initial#1000$finish;endmodule举例:第6章VerilogHDL设计进阶246.3移位寄存器之VerilogHDL设计1、移位指令分类普通移位指令:逻辑左移、逻辑右移算术左移、算术右移循环移位:不带进位位的循环带进位位的循环不带进位位的循环:循环左移、循环右移带进位位的循环:带进位位的循环左移、带进位位的循环右移第6章VerilogHDL设计进阶252、普通移位指令特点:逻辑左移、算术左移COPRD0逻辑右移:COPRD0算术右移:COPRD第6章VerilogHDL设计进阶263、不带进位位的循环移位特点:循环左移:COPRD循环右移:COPRD4、带进位位的循环移位特点:带进位位的循环左移:带进位位的循环右移:COPRDCOPRD第6章VerilogHDL设计进阶27Verilog中的移位左移An右移An移位运算时,移出的空位用‘0’来填补左移是先补后移,右移是先移后补。Verilog2001增加了有符号数的左移与右移。有符号数的右移,空出的位用符号位填补。有符号数的左移与无符号数的左移规律一样的。举例:4’b10012=6’1001004’b10011=5’b100104’b10011=4’b01004’b10014=4’b000016=32’b1000000第6章VerilogHDL设计进阶28试比较以下左右两段语句的操作结果:第6章VerilogHDL设计进阶296.3.1含同步并行预置功能的8位移位寄存器设计QBOPRD例6-14:同步并行预置功能的8位算术右移寄存器。CLK是时钟信号,DIN是8位并行预置数据端口,LOAD是并行数据预置使能信号,QB是串行输出口。工作过程:当CLK的上升沿到来时,过程被启动,如果LOAD是高电平,则把DIN端口的8位数据被同步并行置入寄存器里面。如果LOAD是低电平则执行。REG8[6:0]=REG8[7:1];原来的的最低位REG8[0]向QB输出.第6章VerilogHDL设计进阶30移位时要注意三点:移位的方向:是从高位向低位移还是从低位向高位移。移出去的位到哪里去了。此例中是一到移到QB里面去了。空出来的位谁来补。此例中没有说,也就是保持。第6章VerilogHDL设计进阶31(*synthesis,probe_port*)reg[7:0]REG8;(*synthesis,probe_port,keep*)reg[7:0]REG8;因为REG8是中间变量不是端口信号,因此没有仿真信号。为了也能看到REG8的变化过程。在其定义是前面加上(*synthesis,probe_port*)因为REG8信号有可能在综合是被优化掉。因此还需要加上keep来“保持属性:第6章VerilogHDL设计进阶326.3.2移位模式可控的8位移位寄存器设计(接下页)第6章VerilogHDL设计进阶33(接上页)第6章VerilogHDL设计进阶34第6章VerilogHDL设计进阶356.3.4使用循环语句设计乘法器循环语句分类:for语句repeat语句while语句forever语句第6章VerilogHDL设计进阶36for(循环初始值设置表达式;循环结束条件;循环变量增值表达式)begin循环体语句结构endfor语句for循环的3个步骤:(1)本次循环开始前根据“循环初始值设置表达式”计算获得循环次数初始值。(2)在本次循环开始前判断“循环结束”条件的真假,如果“循环控制条件表达式”为真,则继续执行“循环体语句结构”中的语句,否则即刻跳出循环。(3)在本次循环结束时,根据“循环控制变量增值表达式”计算出循环控制变量的数值,然后跳到以上步骤(2)。第6章VerilogHDL设计进阶37第6章VerilogHDL设计进阶38repeat(循环次数表达式)begin循环体语句结构endrepeat语句说明:repeat语句的循环次数在进入此语句之前就已经确定。循环次数可以是确定的值,也可以是定义