11. 过程块
过程块是行为模型的基础。
过程块有两种:
initial 块,只能执行一次
always 块,循环执行
过程块中有下列部件:
过程赋值语句:在描述过程块中的数据流
高级结构(循环,条件语句):描述块的功能
时序控制:控制块的执行及块中的语句。
initial 语句与 always 语句和 begin_end 与 fork_join 是一种高频搭配:
1.initial 语句
initial 语句的格式如下:
initial
begin
语句 1;
语句 2;
......
语句 n;
end
举例说明:
[例 1]:
initial
begin
areg=0; //初始化寄存器 areg
for(index=0;index<size;index=index+1)
memory[index]=0; //初始化一个 memory
end
在这个例子中用 initial 语句在仿真开始时对各变量进行初始化。
[例 2]:
initial
begin
inputs = 'b000000; //初始时刻为 0
#10 inputs = 'b011001;
#10 inputs = 'b011011;
#10 inputs = 'b011000;
#10 inputs = 'b001000;
end
从这个例子中,我们可以看到 initial 语句的另一用途,即用 initial 语句来生成激励波形作为电路的测试仿真信号。一个模块中可以有多个 initial 块,它们都是并行运行的。
initial 块常用于测试文件和虚拟模块的编写,用来产生仿真测试信号和设置信号记录等仿真环境。
2.always 语句
always 语句在仿真过程中是不断重复执行的。
其声明格式如下:
always <时序控制> <语句>
always 语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。如果一个 always 语句没有时序控制,则这个 always 语句将会成为一个仿真死锁。见下例:
[例 1]:
always areg = ~areg;
这个 always 语句将会生成一个 0 延迟的无限循环跳变过程,这时会发生仿真死锁。如果加上时序控制,则这个 always 语句将变为一条非常有用的描述语句。见下例:
[例 2]:
always #10 areg = ~areg;
这个例子生成了一个周期为 20 的无限延续的信号波形,常用这种方法来描述时钟信号,作为激励信号来测试所设计的电路。
[例 3]:
reg[7:0] counter;
reg tick;
always @(posedge areg)
begin
tick = ~tick;
counter = counter + 1;
end
这个例子中,每当 areg 信号的上升沿出现时把 tick 信号反相,并且把 counter 增加 1。这种时间控制是 always 语句最常用的。
always 的时间控制可以是沿触发也可以是电平触发的,可以单个信号也可以多个信号,中间需要用关键字 or 连接,如:
always @(posedge clock or posedge reset) //由两个沿触发的 always 块
begin
……
end
always @( a or b or c ) //由多个电平触发的 always 块
begin
……
end