FPGA基础 -- Verilog 行为级建模之过程性结构

Verilog 中的"过程性结构(Procedural Constructs)"**,这是行为级建模的核心内容之一。


一、什么是过程性结构(Procedural Constructs)

过程性结构是 Verilog 中用来描述"按顺序执行"的语句块,通常出现在 always 或 initial 块中。与数据流建模(assign)的并行逻辑不同,过程性结构是一种顺序执行的行为描述方式,更贴近软件语言中的过程控制逻辑。


二、基本过程性结构分类

类型 关键字 用途
顺序结构 begin ... end 组织多个语句顺序执行
条件结构 if / if-else / case 条件分支
循环结构 for / while / repeat / forever 多次执行语句块
并发结构 fork ... join(仿真用) 并发执行(testbench 中)

注意:综合工具仅支持有限子集 ,如 for 和 if/case 的结构。while、repeat、forever、fork 一般只用于 testbench。


三、顺序结构:begin ... end

✅ 示例

verilog 复制代码
always @(posedge clk) begin
    a <= b;
    c <= d;
end
  • 多个语句按顺序执行;
  • 可嵌套使用。

四、条件结构详解

4.1 if / else

verilog 复制代码
always @(posedge clk) begin
    if (en)
        q <= d;
    else
        q <= 0;
end

4.2 多级嵌套 if-else if

verilog 复制代码
if (a == 2)
    y <= 1;
else if (a == 3)
    y <= 2;
else
    y <= 0;

⚠️ 注意:避免未完全覆盖条件会导致 latch 推断(不综合安全)


4.3 case 结构

verilog 复制代码
case (sel)
    2'b00: y = a;
    2'b01: y = b;
    default: y = c;
endcase
casex 和 casez
类型 支持通配符 示例 用途
casex x / z 都匹配 casex(sel) 适用于 don't care
casez 只 z 匹配 casez(sel) 保留 x 作为明确值
⚠️ 综合建议:
  • 尽量使用 case 或 casez;
  • 始终写 default 分支;
  • 否则容易推断不完整组合逻辑(=> latch)。

五、循环结构详解

5.1 for 循环(唯一综合安全的循环)

verilog 复制代码
integer i;
always @(posedge clk) begin
    for (i = 0; i < 4; i = i + 1)
        sum[i] <= sum[i] + data[i];
end
综合时的行为:

综合工具会将循环展开为多个并行语句 ,所以 for 的次数必须是常数。

5.2 while、repeat、forever

仅用于仿真(initial block / testbench):

verilog 复制代码
// while
while (a < 5) a = a + 1;

// repeat
repeat (10) @(posedge clk) $display("Tick");

// forever
forever begin
    clk = ~clk;
    #5;
end

六、组合逻辑中的过程性结构写法

组合逻辑 always 块写法建议:

verilog 复制代码
always @(*) begin
    case (op)
        2'b00: y = a + b;
        2'b01: y = a - b;
        default: y = 0;
    endcase
end

⚠️ 注意事项:

  • 输入变化全部列入 @(*);
  • 所有输出变量都要在所有路径中赋值;
  • 否则综合工具会推断 latch(存储器件),不符合组合逻辑预期。

七、阻塞与非阻塞赋值的过程性差异

7.1 阻塞赋值 =

  • 左右同步执行,常用于组合逻辑
  • 有"顺序"语义(会等待执行完当前语句才继续)
verilog 复制代码
a = b;
c = a; // 此处使用的是 b 的值

7.2 非阻塞赋值 <=

  • 同步赋值,常用于时序逻辑(寄存器更新)
  • 在时钟沿之后,所有赋值同时生效
verilog 复制代码
a <= b;
c <= a; // 下一时钟时刻才会看到上一个周期的 b 和 a
综合建议:
场景 建议赋值方式
时序逻辑(always @(posedge clk)) 非阻塞赋值 (<=)
组合逻辑(always @(*)) 阻塞赋值 (=)

八、综合常见错误总结

错误写法 问题 建议
if/case 不完整 推断 latch 加 default 分支或完整条件覆盖
混用 = 与 <= 时序混乱 按规则区分阻塞/非阻塞
@(*) 中漏信号 组合逻辑更新不全 保证包含所有输入变量
使用 while / repeat 不可综合 仅用于 testbench

九、Testbench 中的过程结构支持

在 testbench 中,过程结构提供仿真流程控制:

verilog 复制代码
initial begin
    rst_n = 0;
    #20 rst_n = 1;
end

always #5 clk = ~clk; // forever loop 替代

还可结合 fork ... join 实现并发仿真:

verilog 复制代码
initial fork
    begin #10 a = 1; end
    begin #15 b = 1; end
join

十、实战建议与进阶方向

  1. 实践推荐:

    • 先用组合逻辑练习 if / case;
    • 再通过寄存器实现 always @(posedge clk);
    • 理解 for 在综合后是硬件资源复制。
  2. 配合写 Testbench

    • 结合 initial 与 forever 模拟时钟;
    • 观察行为过程性赋值的执行顺序。
  3. 进阶探索:

    • SystemVerilog always_comb / always_ff 精准区分组合与时序;
    • 掌握行为模型的 task / function 拆解方式。
相关推荐
吉他英雄一里20 小时前
FPGA--RAM
fpga开发
szxinmai主板定制专家21 小时前
储能 EMS、微网控制器选型:RK3588、RK3576、RK3568+FPGA 怎么选?多网、多 CAN、EMC 设计权衡
人工智能·深度学习·机器学习·fpga开发·工业网关·rk3576·电力网关
XMAIPC_Robot1 天前
ARM+FPGA+AI船舶/工业自动化控制器EMC测试等级解析(IEC60533/IEC60945)
arm开发·人工智能·fpga开发·zynq·arm+fpga·rk3588+fpga
ALINX技术博客1 天前
ALINX 亮相 2026 工博会,聚焦 FPGA 行业应用场景
ai·fpga开发·射频工程
星夜离尘561 天前
FPGA 复位回归实验:双时钟停钟、释放中重入与消费端首拍自检
fpga开发
szxinmai主板定制专家1 天前
ZYNQ 数据采集方案踩坑总结:电力强电磁干扰、工业现场多协议适配优化
运维·人工智能·fpga开发·机器人·zynq
幻智星科技2 天前
一个开源的纯FPGA网口采集卡
网络协议·fpga开发·udp
bobuddy2 天前
硬件加速三件套:emulator-FPGA 原型-云仿真
fpga开发
szxinmai主板定制专家2 天前
软硬协同!ZYNQ 高速多通道同步采集,变电站 / 工厂设备状态监测方案详解
人工智能·深度学习·机器学习·fpga开发·zynq·rk3576
FPGA小徐2 天前
FPGA 8阶LFSR加扰/解扰器设计
fpga开发