第三章 Verilog-HDL中的语句
1.基本语句
1.1赋值语句
赋值语句分为连续赋值语句和过程赋值语句。 1.1.1连续赋值语句
1.连续赋值语句用于把值赋给wire型变量(不能为reg型变量赋值)。 语句形式为:assign A = B & C;
a.只要在右端表达式的操作数上有事件(事件为值的变化)发生时,表达式即被计算; b.如果计算的结果值有变化,新结果就赋给左边的线网。 2.连续赋值的目标类型 ? 标量线网 wire a;
? 向量线网 wire [7:0] a;
? 向量线网的常数型位选择 a[1] ? 向量线网的常数型部分选择 a[3:1]
? 上述类型的任意的拼接运算结果 {3a[2],a[2:1]} 注:多条assign语句可以合并到一起。 3.线网说明赋值
? 连续赋值可作为线网说明本身的一部分。这样的赋值被称为线网说明赋值。如:
wire Clear = 'b1; 等价于 wire clear;
assign clear=‘b1; 1.1.2 过程赋值语句 1.
a.过程性赋值是仅仅在initial语句或always语句内的赋值
b.它只能对reg型的变量赋值。表达式的右端可以是任何表达式。 c.过程性赋值分两类:阻塞性过程赋值 = 非阻塞性过程赋值<= 2.语句内部时延与句间时延
a.在赋值语句中表达式右端出现的时延是语句内部时延。
Done = #5 1'b1;
b.通过语句内部时延表达式,右端的值在赋给左端目标前被延迟。即右端表达式在语句内部时延之前计算,随后进入时延等待,再对左端目标赋值。 c.对比以下语句间的时延 begin
Temp = 1'b1;
#5 Done = Temp; //语句间时延控制 end
3.阻塞性过程赋值
a.赋值运算符是“=”的过程赋值是阻塞性过程赋值。
b.阻塞性过程赋值在在下一语句执行前,执行该赋值语句。
例:
initial begin
Clr = #5 0; Clr = #4 1; Clr = #10 0; end
4.非阻塞性过程赋值
a.在非阻塞性过程赋值中,使用赋值符号“ <=”。对目标的赋值是非阻塞的,但可预定在将来某个时间步发生。
b.当非阻塞性过程赋值被执行时,计算右端表达式,右端值被赋于左端目标,并继续执行下一条语句。
c.在当前时间步结束或任意输出被调度时,即完成对左端目标赋值。 例如: initial begin
Clr <= #5 1; Clr <= #4 0; Clr <= #10 0; end
注:在编写可综合的时序逻辑模块时,这是最常用的赋值方法。 5.阻塞性赋值与非阻塞型赋值比较 a.非阻塞性赋值: bSETSETacQDQD
CLRQCLRQ
clk
always @(posedge clk) begin
b <= a; c <= b; end
b.阻塞性赋值: abSETQD
c
clkCLRQ
always@(posedge clk) begin
b = a; c = b; end
6.过程赋值与连续赋值的比较
7.使用过程赋值八原则
? 规则1: 建立时序逻辑模型时,采用非阻塞赋值语句。 ? 规则2: 建立latch模型时,采用非阻塞赋值语句。
? 规则3: 在always块中建立组合逻辑模型时,采用阻塞赋值语句。
? 规则4: 在一个always块中同时有组合和时序逻辑时时, 采用非阻塞赋值语句。 ? 规则5: 不要在一个always块中同时采用阻塞和非阻塞赋值语句。 ? 规则6: 同一个变量不要在多个always块中赋值。
? 规则7: 调用$strobe系统函数显示用非阻塞赋值语句赋值。 ? 规则8: 不要使用#0延时赋值。
1.2 条件语句 1.2.1 if语句
1.2.2 case语句
case语句是多路条件分支形式,其语法如下: case(case_expr)
case_item_expr:procedural_statement; ... ...
default:procedural_statement; endcase
? case语句首先对条件表达式case_expr求值,然后依次对各分支项求值并进行比较。 ? 第一个与条件表达式值相匹配的分支中的语句被执行。 ? 可以在1个分支中定义多个分支项;这些值不需要互斥。
? 缺省分支(default)覆盖所有没有被分支表达式覆盖的其他分支。 ? 如果case表达式和分支项表达式的长度不同情况下,在进行任何比较前所有的case
表达式都统一为这些表达式的最长长度。 ? 在casez语句中,出现在case表达式和任意分支项表达式中的值z被认为是无关值,
即那个位被忽略(不比较)。
? 在casex语句中,值x和z都被认为是无关位。 casex( Mask )
4'b1??? : Dbus[4] = 0; 4'b01?? : Dbus[3] = 0; 4'b001? : Dbus[2] = 0; 4'b0001 : Dbus[1] = 0; defalut : Dbus=4’hf;
endcase
1.2.3 条件语句的优先级
? case语句和if?else嵌套描述结构有很大的区别。在Verilog语法中,if?else
语句是有优先级的
? 一般来说第一个if的优先级最高,最后一个else的优先级最低。
? case语句是“平行”的结构,所有的case的条件和执行都没有“优先级”。 ? 建立优先级结构会消耗大量的组合逻辑,所以如果能够使用case语句的地方,尽量
用case替换if...else结构。
1.3 循环语句 1.3.1 for语句
? 一个for循环语句按照指定的次数重复执行过程赋值语句若干次。 ? for 循环语句的形式如下:
for(initial_assignment ; condition ; step_assign)
procedural_statement
? 初始赋值initial_assignment给出循环变量的初始值。condition条件表达式指定
循环条件;step_assign给出要修改的赋值,通常为增加或减少循环变量计数。
例:
integer K;
for(K=0 ; K<7 ; K=K+1) begin
if(Abus[K]==0) Abus[K]=1;
else if(Abus[k]==1) Abus[K]=0; else
$display(\end
1.3.2 while语句
? while语句连续执行过程赋值语句,直到不满足指定的条件。 ? while 循环语句语法如下:
while(condition)
procedural _statement;
? 如果表达式在开始时为假,那么过程语句便永远不会执行。如果条件表达式为x或
z,它也同样按0(假)处理。例如: while (BY > 0 ) begin
Acc = Acc << 1; BY = BY - 1; end
1.3.3 forever语句
? forever循环语句连续执行语句,常用在“initial” 语句中生成周期性的输入波
形。
initial begin
Clock = 0; # 5; forever
#10 Clock = ~Clock; end
1.3.4 repeat语句
? repeat执行指定循环次数的过程语句。 ? repeat 循环语句形式如下:
repeat(loop_count)
procedural_statement;
? 如果循环计数表达式的值不确定,即为x或z时,那么循环次数按0处理。 repeat(Count) Sum=Sum+10; repeat(ShiftBy) P_Reg=P_Reg<<1;
1.4 结构说明语句
Verilog-HDL中任何语句模块都从属于以下四种结构的说明语句: 1.initial语句 2. always语句 3. task语句 4. function语句
1.4.1 initial语句
? initial 语句主要用于仿真初始化,并且在仿真开始时便执行,而且只执行一次 ? initial 语句的语法如下:
initial
begin