FPGA基础 -- Verilog 数据流建模
一、数据流建模概念简介(初级)
1. 什么是数据流建模?
数据流建模是一种 使用并行赋值语句(assign)来表达布尔逻辑或组合逻辑行为 的建模方式。它强调 信号之间的逻辑数据依赖关系,而不明确指定信号何时更新(不使用时钟)。
特点:
- 面向组合逻辑,不依赖时钟;
- 高度抽象,更关注表达式而非行为顺序;
- 使用
assign
语句进行建模。
2. 基础语法
assign y = a & b;
assign z = (a | b) & c;
上面两个 assign
就是数据流建模风格 —— 描述信号之间的数据关系。
3. 与其他建模方式对比
建模方式 | 应用场景 | 语法关键字 | 侧重点 |
---|---|---|---|
数据流建模 | 组合逻辑 | assign | 表达逻辑关系 |
行为建模 | 时序逻辑或控制流程 | always , if , case | 行为过程控制 |
结构建模 | 结构层次化系统 | instantiation | 模块连接构建 |
二、常用数据流表达方式(中级)
1. 组合逻辑表达式
assign out = (~a & b) | (a & ~b); // XOR
2. 优化常用逻辑结构
优先编码器(4选1)
assign out = d[3] ? 2'b11 :d[2] ? 2'b10 :d[1] ? 2'b01 :d[0] ? 2'b00 : 2'bxx;
译码器(2 to 4 decoder)
assign y = (sel == 2'b00) ? 4'b0001 :(sel == 2'b01) ? 4'b0010 :(sel == 2'b10) ? 4'b0100 :(sel == 2'b11) ? 4'b1000 : 4'b0000;
加法器(1 位加法器)
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (cin & (a ^ b));
3. 运用 generate 优化可扩展结构(适合中级)
genvar i;
generatefor(i=0; i<8; i=i+1) begin : gen_xorassign out[i] = in1[i] ^ in2[i];end
endgenerate
这是在结构上批量生成 assign
,配合数据流建模更有可扩展性。
三、深入工程级建模技巧(高级)
1. 使用数据流实现条件控制
assign y = sel ? a : b; // 相当于 mux
注意:该写法等效于:
always @(*) beginif (sel)y = a;elsey = b;
end
但数据流更为精炼、高效,适用于简单逻辑条件分支。
2. 与综合工具的协同
数据流描述方式更容易让综合工具(如 Vivado、Quartus)进行 逻辑优化与资源折叠,特别在:
- 减少 LUT 使用;
- 加快组合路径;
- 自动组合约束分析。
3. 常见坑位与陷阱
问题类型 | 示例 | 分析 |
---|---|---|
赋值环路 | assign a = b; assign b = a; | 会形成非法环路,综合失败 |
多驱动冲突 | 多个 assign 同时驱动一个 wire | 不可综合 |
表达式过复杂 | 一行表达多个条件判断和算术 | 时序路径太长,影响时序收敛 |
条件优先级不清晰 | 三目表达式嵌套过深 | 建议改写为多个分支或行为建模方式 |
四、配套仿真验证建议
建议:
- 使用
Testbench
对assign
逻辑输出进行覆盖率测试; - 利用
assert
与monitor
验证边界条件; - 搭配
GTKWave
查看组合输出稳定时间。
五、实践项目建议(进阶应用)
- 实现一个 8 位加减法器(带符号)
- 实现一个带优先级的多路选择器(Mux)
- 构建组合滤波模块(如中值滤波)
- 结合 Vivado Schematic View 观察 assign 合成后的门级结构