always语句 always语句在仿真过程中是不断重复执行的。 其声明格式如下:
always语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。如果一个always语句没有时序控制,则这个always语句将会发成一个仿真死锁。见下例: [例1]:
这个always语句将会生成一个0延迟的无限循环跳变过程,这时会发生仿真死锁。如果加上时序控制,则这个always语句将变为一条非常有用的描述语句。见下例: [例2]:
这个例子生成了一个周期为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
沿触发的always块常常描述时序逻辑,如果符合可综合风格要求可用综合工具自动转换为表示时序逻辑的寄存器组和门级逻辑,而电平触发的always块常常用来描述组合逻辑和带锁存器的组合逻辑,如果符合可综合风格要求可转换为表示组合逻辑的门级逻辑或带锁存器的组合逻辑。一个模块中可以有多个always块,它们都是并行运行的。 always是一个极高频的语法,always@()用法总结如下① always@(信号名) • 信号名有变化就触发事件
② always@( posedge信号名) • 信号名有上升沿就触发事件 例:
always@( posedge clock)
a=b;
③ always@(negedge信号名) • 信号名有下降沿就触发事件 例:
always@( negedge clock)
a=b;
④ always@(敏感事件1or敏感事件2or…) • 敏感事件之一触发事件 • 没有其它组合触发 例:
always@(posedge reset or posedge clear)
reg_out=0;
⑤ always@(*) • 无敏感列表,描述组合逻辑,和assign语句是有区别的
assign赋值语句和always@(*)语句。两者之间的差别有: 1.被assign赋值的信号定义为wire型,被always@(*)结构块下的信号定义为reg型,值得注意的是,这里的reg并不是一个真正的触发器,只有敏感列表为上升沿触发的写法才会综合为触发器,在仿真时才具有触发器的特性。
|