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

深入理解 Verilog 赋值语句:类型、语法与最佳实践

将值赋给网络和变量称为赋值。Verilog 中有三种基本形式:

合法的左值(LHS)

赋值语句包含右侧表达式(RHS)和左侧目标(LHS),中间用等号(=)或非阻塞赋值符号(<=)连接。

赋值类型左侧允许的对象
过程赋值
  • 变量(向量/标量)
  • 向量 reg、integer 或 time 变量的位选或部分选
  • 存储单元
  • 上述任意项的拼接
连续赋值
  • 网络(向量/标量)
  • 向量网络的位选或部分选
  • 位选和部分选的拼接
过程连续赋值
  • 网络或变量(向量/标量)
  • 向量网络的位选或部分选

RHS 可以是任意求值表达式,LHS 指明接收该值的网络或变量。

module tb;
  reg clk;
  wire a, b, c, d, e, f;
  reg z, y;
  // clk 在 LHS,~clk 构成 RHS
  always #10 clk = ~clk;
  // y 是 LHS,常量 1 是 RHS
  assign y = 1;
  // f 是 LHS,a,b,d,e 的表达式构成 RHS
  assign f = (a | b) ^ (d & e);
  always @ (posedge clk) begin
    // z 是 LHS,a,b,c,d 的表达式构成 RHS
    z <= a + b + c + d;
  end
  initial begin
    // 变量名在左侧形成 LHS,0 是 RHS
    a <= 0; b <= 0; c <= 0; d <= 0; e <= 0; clk <= 0;
  end
endmodule

过程赋值

过程赋值出现在 always、initial、task 和 function 等过程块中,用于给变量赋值。变量将保持该值,直到下一次对同一变量赋值。

赋值在仿真执行到该语句时发生,可通过 if-else、case 语句及循环机制等控制流语句灵活控制。

reg [7:0] data;
integer count;
real period;
initial begin
  data = 8'h3e;
  period = 4.23;
  count = 0;
end
always @ (posedge clk)
  count++;

变量声明赋值

可在变量声明时给出初始值。该赋值无持续时间,保持值直到下一次赋值。注意:不允许对数组进行声明赋值。

module my_block;
  reg [31:0] data = 32'hdead_cafe;
  initial begin
    #20 data = 32'h1234_5678;
    // data 从时刻 0 到 20 保持 dead_cafe
    // 20 时刻更新为 12345678
  end
endmodule
reg [3:0] a = 4'b4; // 等价于
reg [3:0] a;
initial a = 4'b4;

若变量在声明时初始化,且在 initial 块中于时刻 0 再次赋值,求值顺序不确定,可能得到 8'h05 或 8'hee。

module my_block;
  reg [7:0] addr = 8'h05;
  initial addr = 8'hee;
endmodule
reg [3:0] array [3:0] = 0; // 非法
integer i = 0, j; // 声明 i,j 并赋 i=0
real r2 = 4.5, r3 = 8; // 声明 r2,r3 并分别赋 4.5, 8
time startTime = 40; // 声明 time 变量初值 40

过程块与赋值将在后续章节详述。

连续赋值

点击查看分步仿真示例!

用于给标量和向量网络赋值,每当 RHS 发生变化即重新求值并更新 LHS。它提供了一种无需指定门级互连即可建模组合逻辑的方法,便于用逻辑表达式驱动网络。

// 与门建模示例
wire a, b, c;
assign a = b & c;

当 b 或 c 变化时,RHS 表达式重新求值,a 更新为新值。

网络声明赋值

可在声明网络的同一语句中进行连续赋值。因网络只能声明一次,故每个网络仅允许一次声明赋值。

wire penable = 1;

过程连续赋值

这类过程语句允许表达式持续赋给网络或变量,分两种:

assign / deassign

覆盖对变量的所有过程赋值,用 deassign 解除。变量值保持不变,直到通过过程或过程连续赋值获得新值。assign 的 LHS 不能是位选、部分选或数组引用,但可以是变量或变量拼接。

reg q;
initial begin
  assign q = 0;
  #10 deassign q;
end

force / release

类似 assign - deassign,但也可用于网络和变量。LHS 可以是网络的位选、部分选、变量或网络,但不能是数组引用和变量的位/部分选。force 覆盖该变量的所有其他赋值,直到用 release 释放。

reg o, a, b;
initial begin
  force o = a & b;
  ...
  release o;
end

Verilog

  1. C 语言变量详解:类型、命名规则、定义声明与内存管理
  2. Verilog 入门:数字电路设计完整教程
  3. 掌握 Verilog 拼接操作:实用指南
  4. Verilog阻塞与非阻塞赋值:关键区别详解
  5. 掌握Verilog函数:高效RTL设计的复用利器
  6. 理解Verilog任务:函数vs任务、语法与用法全解析
  7. Verilog 时钟发生器设计与实现指南
  8. 掌握 Verilog 数学函数:高效硬件设计的利器
  9. 掌握 Verilog $timeformat:精度控制与显示格式化
  10. 理解与打印 Verilog 任意作用域下的 Timescale
  11. 掌握 Verilog 文件 I/O:打开、读取、写入和关闭
  12. Verilog 入门指南:Hello World 示例