initial、always、task、function模块均称为过程结构。initial模块和always模块都是同时并行执行的,initial模块只执行一次,而always模块则是不断重复地运行,具体使用方法如下。
1. initial模块
在进行仿真时,一个initial模块从模拟0开始执行,且在仿真过程中只执行一次,在执行一次后,该initial就被挂起,不再执行。如果仿真种有两个initial模块,则同时从0时刻开始并行执行。
initial模块是面向仿真的,是不可综合的,其格式如下:
initial
begin
快内变量说明
时序控制1 行为语句1;
........
时序控制n 行为语句n;
end
当块内只有一条语句且不需要定义局部变量时,begin...end可以省略。
例:initial模块的使用实例
initial begin
//初始化输入向量
clk = 0;
ar = 0;
ai = 0;
br = 0;
bi = 0;
//等待100ns,全局reset信号有效
#100;
ar = 20;
ai = 10;
br = 10;
bi = 10;
end
2. always模块
always模块时一直重复执行的且可综合。其格式为:
always@(敏感事件列表)
begin
块内变量说明
时序控制1 行为语句1;
........
时序控制n 行为语句n;
end
敏感事件列表:由一个或多个事件表达式构成,只要表达式所代表的多个触发条件种的一个成立,就启动块内语句的执行。
module test1(
input wire i_a,
input wire i_b,
input wire i_c,
output reg o_d,
);
always @(i_a or i_b)
begin
o_d = i_a & i_b & i_c;
end
endmodule
上例中,当i_a和i_b发生变化时,o_d的值随之变化。且由于i_c不在敏感列表中,故i_c的变化不会影响输出结果。上例中的触发方式又被称为电平触发,即只要敏感事件列表内信号的电平有变化,输出结果会随之变化。
always块的另一种常用的触发方式为边沿触发,指利用敏感事件列表内信号的边沿的跳变控制块内逻辑执行。上升沿用posedge关键字描述,下降沿用negedge关键字描述,实例如下:
例:边沿触发事件计数器
reg [5:0] d_cnt;
always @(posed clk)
begin
if(rst)
d_cnt <= 0;
else
d_cnt <= d_cnt + 1;
end
上例中,只要时钟clk信号有上升沿,计数器d_cnt信号加一,实现计数功能。
参考:《无线通信FPGA设计》 田耕 徐文波 张延伟等.