Verilog阻塞与非阻塞赋值详解及RTL设计实践

1. 阻塞与非阻塞赋值的本质区别

在Verilog硬件描述语言中,赋值语句的阻塞(Blocking)与非阻塞(Non-blocking)特性直接影响电路的综合结果和仿真行为。这两种赋值方式看似简单,却是许多初学者在RTL设计时最容易混淆的概念之一。

阻塞赋值使用"="操作符,其执行过程类似于软件编程中的顺序执行。当仿真器遇到阻塞赋值时,会立即计算右侧表达式并更新左侧变量,然后才会继续执行下一条语句。这种特性使得多条阻塞赋值语句具有明确的先后顺序关系。

verilog复制// 阻塞赋值示例
always @(posedge clk) begin
    a = b;  // 语句1
    b = a;  // 语句2
end

非阻塞赋值使用"<="操作符,其行为更接近真实的硬件寄存器传输。所有非阻塞赋值的右侧表达式会同时计算,但左侧变量的更新会推迟到整个always块结束时才统一进行。这种并行特性使得非阻塞赋值特别适合描述时序逻辑电路。

verilog复制// 非阻塞赋值示例
always @(posedge clk) begin
    a <= b;  // 语句1
    b <= a;  // 语句2
end

关键经验:在同一个always块中混合使用阻塞和非阻塞赋值是严格禁止的,这会导致不可预测的综合结果和仿真行为差异。

1.1 硬件行为映射

阻塞赋值通常用于组合逻辑建模,其顺序执行特性可以准确描述信号通过组合逻辑的传播路径。例如在ALU设计中:

verilog复制always @(*) begin
    temp = a + b;       // 语句1
    result = temp << 1; // 语句2
end

非阻塞赋值则完美对应时序元件的行为。考虑一个典型的寄存器组:

verilog复制always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        reg1 <= 8'h00;
        reg2 <= 8'h00;
    end else begin
        reg1 <= next_reg1;
        reg2 <= reg1;  // 实现寄

内容推荐

已经到底了哦
已经到底了哦