2.4 语句
过程语句 initial
、always
在一个模块中,使用
initial
和always
语句的次数是不受限制的;initial
语句常用于仿真中的初始化,过程块中的语句仅执行一次;always
块内的语句则是不断重复执行的。always
语句格式:
always @ (<event_expression>) begin <......> end
always
过程语句通常是带有触发条件的,触发条件写在敏感信号表达式中,只有当触发条件满足时,其后的begin-end
块语句才能被执行。敏感信号表达式又称事件表达式或敏感信号列表,即当该表达式中变量的值改变时,就会引发块内语句的执行。其中应列出影响块内取值的所有信号,若有两个或两个以上信号时,它们之间用
or
连接。举例:@(a) // 当信号a的值发生改变 @(a or b) // 当信号a或信号b的值发生改变 @(posedge clock) // 当clock的上升沿到来时 @(negedge clock) // 当clock的下降沿到来时 @(posedge clk or negedge reset) // 当clk的上升沿或reset信号的下降沿到来
posedge
和negedge
关键字:对于时序电路,事件通常是由时钟边沿触发的,为表达边沿概念,Verilog提供了这两个关键字来描述。例:4选1数据选择器
module mux4_1 (out, in0, in1, in2, in3, sel); output out; input in0, in1, in2, in3; input [1:0] sel; reg out; always @ (in0 or in1 or in2 or in3 or sel) case(sel) 2'b00: out=in0; 2'b01: out=in1; 2'b10: out=in2; 2'b11: out=in3; default: out=2'bx; endcase endmodule
例:同步置数、同步清零的计数器
module count(out, data, load, reset, clk); output [7:0] out; input [7:0] data; input load, clk, reset; reg [7:0] out; always @ (posedge clk) begin if(!reset) out=8'h00; // 同步清0,低电平有效 else if(load) out=data; // 同步预置 else out=out+1; // 计数 end endmodule
块语句 begin-end
块语句是由块标志符
begin-end
的一组语句,当块语句只包含一条语句时,块标志符可以缺省。begin-end
串行块中的语句按串行方式顺序执行。比如:begin regb=rega; regc=regb; end
由于begin-end
块内的语句顺序执行,在最后,将regb
、regc
的值都更新为rega
的值,该begin-end
块执行完后,regb
、regc
的值是相同的。
赋值语句 assign
、=
、<=
1. 连续赋值语句
assign
为持续赋值语句,主要用于对wire
型变量的赋值。如:
wire a, b, c;
assign c = a & b;
在上面的赋值中,a
、b
、c
三个变量皆为wire
型变量,a
和b
信号的任何变化都将随时反映到c
上来。
2. 过程赋值语句 nonblocking
、blocking
过程赋值语句多用于对reg
型变量进行赋值。
非阻塞(nonblocking)赋值:符号
<=
;例如:b<=a;
在整个过程块结束时才完成赋值操作,即b
的值并不是立刻就改变的。阻塞(blocking)赋值:符号
=
;例如:b=a;
阻塞赋值在该语句结束时就立即完成赋值操作,即b
的值在该条语句结束后立刻改变。如果在一个块语句中,有多条阻塞赋值语句,那么在前面的赋值语句没有完成之前,后面的语句就不能被执行,仿佛被阻塞了一样,因此称为阻塞赋值方式。
3. 顺序与并发
两个或更多个always
过程块、assign
持续赋值语句、实例元件调用等操作都是同时执行的。在always
模块内部,其语句如果是非阻塞赋值,也是并发执行的;而如果是阻塞赋值,则语句是按照指定的顺序执行的,语句的书写顺序对程序的执行结果有着直接的影响。
条件语句 if-else
、case
、casez
、casex
1. if-else
语句
if <expression> <statement>;
if <expression> <statement1>;
else <statement2>;
if <expression1> <statement1>;
else if <expression2> <statement2>;
else if <expression3> <statement3>;
......
else if <expression_n> <statement_n>;
else <statement_n+1>;
2. case
语句
case
:全等比较,即控制表达式和分支项表达式的值各对应位必须全等case (<expression>) key1: <statement1>; key2: <statement2>; ...... key_n: <statement_n>; default: <statement_n+1>; endcase
casez
:如果表达式的值的某些位是z,那么对这些位的比较就不予考虑,只对非z位进行比较。casex
:如果表达式的值的某些位是x或z,那么对这些位的比较就不予考虑,只对非x或非z位进行比较。
循环语句 for
、forever
、repeat
、while
forever
:连续地执行语句;多用在initial块中, 以生成时钟等周期性波形repeat
:连续执行一条语句n次initial begin repeat(5) out = out + 1; end
while
:执行一条语句直到某个条件不满足initial begin i = 0; while(i < 10) i = i + 1; end
for
:有条件的循环语句initial begin for(i = 0; i < 4; i = i + 1) out = out + 1; end