亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Verilog

Verilog 总是阻塞

一个always 块是程序之一 Verilog 中的块。 always 块中的语句是按顺序执行的。

语法

  
  
always @ (event)
	[statement]
	
always @ (event) begin
	[multiple statements]
end

  

always 块在某些特定事件中执行。该事件由敏感度列表定义。

什么是敏感列表?

一个敏感性 list 是定义何时执行 always 块的表达式,在 @ 之后指定 括号内的运算符 ( ) .此列表可能包含一个或一组信号,其值更改将执行 always 块。

在如下所示的代码中,always 内的所有语句 只要信号 a 或 b 的值发生变化,就会执行块。

  
  
// Execute always block whenever value of "a" or "b" change
always @ (a or b) begin
	[statements]
end

  

always 块是做什么用的?

一个 always 块可用于实现组合或顺序元素。当提供时钟并复位时,触发器等时序元件将变为活动状态。类似地,组合块在其输入值之一改变时变为活动状态。这些硬件块都相互独立地同时工作。两者之间的联系决定了数据的流动。为了模拟这种行为,一个 always 块是一个连续的过程,当敏感度列表中的信号变为活动状态时,它会被触发并执行一些操作。

在以下示例中,always 块中的所有语句都会在信号 clk 的每个上升沿执行。

  
  
// Execute always block at positive edge of signal "clk"
always @ (posedge clk) begin
	[statements]
end

  

如果没有敏感度列表会怎样?

always 块在整个模拟过程中不断重复。敏感列表带来了一定的时间感,即每当敏感列表中的任何信号发生变化时,都会触发always块。如果always块中没有时序控制语句,仿真会因为零延迟无限循环而挂起!

示例

下面显示的示例是一个 always 块,它尝试反转信号 clk 的值。该语句在每 0 个时间单位后执行。因此,由于语句中没有延迟,它会永远执行。

  
  
// always block is started at time 0 units
// But when is it supposed to be repeated ?
// There is no time control, and hence it will stay and
// be repeated at 0 time units only. This continues
// in a loop and simulation will hang !
always clk = ~clk;

  

即使敏感列表是空的,也应该有其他形式的时间延迟。 always 中的延迟语句可以提前模拟时间 构造如下图。现在,每 10 个时间单位进行一次时钟倒转。

  
  
	always #10 clk = ~clk;

  

注意: 显式延迟不能合成到逻辑门中!

因此,真正的 Verilog 设计代码总是需要一个敏感度列表。

顺序元素设计示例

下面显示的代码定义了一个名为 tff 的模块,它接受数据输入、时钟和低电平有效复位。只要在时钟的上升沿发现 d 为 1,输出就会反转。这里,always 块在 clk 的上升沿或 rstn 的下降沿触发。

时钟上升沿会发生什么?

以下事件发生在时钟的上升沿,并在所有时钟上升沿重复。

  1. 第一个if 块检查低电平有效复位 rstn 的值
    1. 如果 rstn 为零,则输出 q 应重置为默认值 0
    2. 如果 rstn 为 1,则表示未应用重置,应遵循默认行为
  2. 如果上一步为假:
    1. 检查d的值,如果是1,则取反q的值
    2. 如果d为0,则保持q的值

  
  
module tff (input  		d,
						clk,
						rstn,
			output reg 	q);
			
	always @ (posedge clk or negedge rstn) begin
		if (!rstn)
			q <= 0;
		else
			if (d)
				q <= ~q;
			else
				q <= q;
	end
endmodule

  

在复位的下降沿会发生什么?

以下事件发生在 rstn 的下降沿,并在所有此类事件中发生。

  1. 第一个if 块检查低电平有效复位 rstn 的值。在信号的下降沿,其值为 0。
    1. 如果 rstn 的值为 0,则表示应用了复位,输出应复位为默认值 0
    2. 不考虑rstn值为1的情况,因为当前事件是负边缘 第一个

组合元素设计实例

一个 always 块也可用于组合块的设计。例如,下面的数字电路代表了三个不同逻辑门的组合,它们在信号 o 处提供一定的输出。

<无脚本> combinational-gates

下面显示的代码是一个module 具有四个输入端口和一个称为 o 的输出端口。 always 每当敏感度列表中的任何信号值发生变化时,都会触发块。输出信号被声明为类型 reg 在模块端口列表中,因为它在程序块中使用。程序块中使用的所有信号都应声明为类型 reg .

  
  
module combo (	input 	a,
      			input	b,
              	input	c,
              	input	d,
  	            output reg o);
  
  always @ (a or b or c or d) begin
    o <= ~((a & b) | (c^d));
  end
  
endmodule

  

看到只要 RHS 上的组合表达式为真,信号 o 就变为 1。同样,当 RHS 为 false 时,o 变为 0。

模拟输出

单击此处查看带有模拟示例的幻灯片!


Verilog

  1. Verilog 教程
  2. Verilog 连接
  3. Verilog - 简而言之
  4. Verilog 作业
  5. Verilog 阻塞和非阻塞
  6. Verilog 函数
  7. Verilog 任务
  8. Verilog 时钟发生器
  9. Verilog 数学函数
  10. Verilog 时间格式
  11. Verilog 时间刻度范围
  12. Verilog 文件 IO 操作