系列文章
数值(整数,实数,字符串)与数据类型(wire、reg、mem、parameter)
运算符
数据流建模
定义
行为描述常常用于复杂数字逻辑系统的顶层设计中,也就是通过行为建模把一个复杂的系统分解成可操作的若干个模块,每个模块之间的逻辑关系通过行为模块的仿真加以验证。这样就能把一个大的系统合理地分解为若干个较小的子系统,然后再将每个子系统用可综合风格的Verilog HDL模块(门级结构或RTL级、算法级、系统级的模块)加以描述。同时行为建模也可以用来生成仿真测试信号,对已设计的模块进行检测。
过程语句
Verilog HDL中过程块是由过程语句所组成的。过程语句有两种,分别是initial 过程语句和always过程语句。
initial过程语句
initial 过程块在进行仿真时从模拟0时刻开始执行,它在仿真过程中只执行一次 ,在执行完一次后该initial过程块就被挂起,不再执行。如果一个模块中存在多个initial过程块,则每个initial过程块都是同时从0时刻开始并行执行的。initial过程块内的多条行为语句可以是顺序执行的,也可以是并行执行的。
Initial过程语句通常用于仿真模块中对激励向量的描述,或用于给寄存器变量赋初值。
示例:用initial过程语句对变量A、B、C进行赋值:
verilog
module initial_tb1;
reg A,B,C;
initial
begin
A=0;B=1;C=0;
#100 A=1;B=0;
#100 A=0;C=1;
#100 B=1;
#100 B=0;C=0;
end
endmodule
always过程语句
从语法描述角度而言,相对于initial过程语句,always过程语句的触发状态是一直存在的,只要满足always后面的敏感事件列表,就执行语句块。其语法格式是:
verilog
always@(<敏感事件列表>) 语句块;
其中,敏感事件列表就是触发条件,只有当触发条件满足时,其后的语句块才能被执行。即当该列表中变量的值改变时,就会引发块内语句的执行。因此,敏感信号列表中应列出影响块内取值的所有信号。若有两个或两个以上信号,则它们之间可以用"or"连接,也可以用逗号","连接。
示例:
verilog
@(a) //当信号a的值发生改变时
(a or b) //当信号a或信号b的值发生改变时
(posedge clock) //当clock的上升沿到来时
(negedge clock) //当clock的下降沿到来时
(posedge clk or negedge reset) //当clk的上升到来或reset信号的下降沿到来时
过程语句使用中的注意事项
无论是对时序逻辑电路还是对组合逻辑电路进行描述,Verilog HDL要求在过程语句(initial和always)中,被赋值信号必须定义为"reg"类型。
采用过程语句对组合电路 进行描述时,需要把全部的输入信号列入敏感信号列表。
采用过程语句对时序电路进行描述时,需要把时间信号和部分输入信号列入敏感信号列表。
示例:
verilog
//用always语句描述4选1数据选择器
module mux4_1(out,in0,in1,in2,in3,sel);
output reg out;
input in0,in1,in2,in3;
input[1:0] sel;//选择信号
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
过程赋值语句
过程块中的赋值语句称为过程赋值语句。过程性赋值是在initial语句或always语句 内的赋值,它只能对寄存器数据类型的变量赋值。
过程赋值语句有阻塞赋值 语句和非阻塞赋值语句两种。
-
阻塞赋值语句的操作符号为"=",其语法格式是:变量 = 表达式;例如:b = a;
当一个语句块中有多条阻塞赋值语句时,如果前面的赋值语句没有完成,则后面的语句就不能被执行,仿佛被阻塞了一样,因此称为阻塞赋值方式。
-
非阻塞赋值语句的操作符号为"<=",其语法格式是:变量 <= 表达式;例如:b <= a;
如果在一个语句块中有多条非阻塞赋值语句,则后面语句的执行不会受到前面语句的限制,因此称为非阻塞赋值方式。
连续赋值语句
连续赋值是过程性赋值的一种方式,可以在always和initial过程语句中对连线型和寄存器型变量类型进行赋值操作。
赋值语句用的关键字是"assign"
条件分支语句
Verilog HDL的条件分支语句有两种:if条件分支语句和case条件分支语句。
-
if条件分支语句:
条件语句只能在initial和always语句引导的语句块(begin-end)中使用,模块的其它部分都不能使用。
verilog形式2: 形式1: if(条件表达式)语句块; 形式2: if(条件表达式) 语句块1; else 语句块2;
-
case条件分支语句:
相对于if语句只有两个分支而言,case语句是一种可实现多路分支选择控制的语句,比if-else条件语句更为方便和直观。一般的,case语句多用于多条件译码电路设计,如描述译码器、数据选择器、状态机及微处理器的指令译码等。
verilogcase(控制表达式) 值1:语句块1 值2:语句块2 ... 值n:语句块n default:语句块n+1 endcase
循环语句
Verilog HDL中规定了四种循环语句,分别是forever、repeat、while和for循环语句。与条件分支语句一样,循环语句也是一种高级程序语句,多用于测试仿真程序设计。
-
关键字"forever"所引导的循环语句表示永久循环。在永久循环中不包含任何条件表达式,只执行无限循环,直至遇到系统任务$finish。如果需要从forever循环中退出,则可以使用disable语句。
-
关键字"repeat"所引导的循环语句表示执行固定次数的循环,其语法格式是:
verilogrepeat(循环次数表达式) 语句或语句块(循环体);
-
关键字"while"所引导的循环语句表示的是一种"条件循环"。while语句根据条件表达式的真假来确定循环体的执行,当指定的条件表达式取值为真时才会重复执行循环体,否则就不执行循环体。
-
关键字"for"所引导的循环语句也表示一种"条件循环",只有在指定的条件表达式成立时才进行循环。其语法格式是:
for(循环变量赋初值;循环结束条件;循环变量增值) 语句块;
示例:
verilog
//设计一个8位移位寄存器
module shift_regist1(Q,D,rst,clk);
output reg [7:0]Q;
input D,rst,clk;
always @(posedge clk)
if (!rst)
Q<=8'b000000;
else
Q<={Q[6:0],D};
endmodule