当前位置: 首页 > news >正文

FPGA基础 -- Verilog函数

Verilog 函数(function)

目标:让具备一般 RTL 经验的工程师,系统掌握 Verilog 函数的语法、约束、可综合写法以及在实际项目中的高效用法,为后续 SystemVerilog 及 HLS 设计奠定基础。


1 为什么要用函数?

设计痛点函数带来的价值
重复逻辑:CRC、Parity、优先编码等往往在多个模块出现将共用运算封装为函数,避免复制粘贴,减少 Bug 概率
可读性差:长表达式嵌套写在连线或 always 块中抽象为函数名,表达意图清晰
调试困难:一段组合逻辑难以单独仿真函数可在 Testbench 中独立调用并加断言

2 语法与基本规则

function [宽度-1:0] fname;input [m-1:0] a, b;   // 只能是 input 端口reg   [宽度-1:0] tmp; // 必须声明内部寄存器
begintmp      = a ^ b;fname    = tmp;       // 赋值给同名变量或用 return
end
endfunction

要点

  1. 单返回值:函数名本身是返回寄存器;SystemVerilog 可用 return

  2. 无时序控制:禁止 # 延时、@ 事件,否则综合器会报错(仅仿真可用)。

  3. 端口方向:只能 input,无 output/inout

  4. 侧 射(Side Effect)禁止:函数内部不能写模块外部信号。

  5. 调用环境

    • 连续赋值:assign y = myfunc(a,b);
    • 过程块:always @* begin result = myfunc(a,b); end
    • 参数化:parameter W=8; function [W-1:0] …

3 与 task 的区别

维度functiontask
返回值必须且只有一个可无返回,用端口输出
端口方向仅 inputinput/out/inout 均可
时序控制禁止 #、@、wait允许
并行执行无 fork/join可包含
适用场景纯组合运算时序操作、仿真刺激

4 自动(automatic)与静态(static)

  • 默认 static:所有调用共享同一套局部变量,递归或并发调用会冲突。

  • automatic function可重入/递归,每次调用独立栈帧。

    某些综合工具对递归支持有限,实际项目常用“尾递归 + 显式栈”改写。


5 SystemVerilog 扩展亮点

特性价值
完整数据类型logic, bit, enum, struct, union写法更接近 C/C++,可编译时静态检查
默认自动:省去 static 纠结;支持 return 语句代码可读性更佳
package 作用域:跨模块复用无需 include大型项目库化管理
内建 dpi_c/dpi_importC-function 与 RTL 交互

6 可综合函数设计模式

6.1 组合运算模板

function automatic [7:0] parity8;input [7:0] data;
beginparity8 = ^data;  // XOR 归约
end
endfunction

合成结果:1-级 XOR 逻辑;工具可再平衡以满足时序。

6.2 参数化优先编码器

function automatic [N-1:0] prio_enc;input [M-1:0] req;               // M 为参数integer i;
beginprio_enc = '0;for (i=M-1; i>=0; i=i-1)if (req[i]) prio_enc = i[N-1:0];
end
endfunction
  • for 循环被展开成优先链;结合流水线可提升频率。
  • N = $clog2(M); 使用 SystemVerilog 的 $clog2 系统函数。

6.3 带符号定点乘法(避免乘法器爆发)

用函数统一封装小位宽 signed 乘加,可让综合器推断 DSP Slice。


7 调试与验证技巧

  1. 函数级仿真:在 TB 中直接 #0 $display("crc=%h", crc16(pkt));
  2. 覆盖率:UVM 中可为函数添加 covergroup 监测输入分布。
  3. ILA 观测:将函数输出打一拍寄存后接 ILA,确认硬件值。
  4. 断言assert (func_out == golden_model(in)); 在线比对。

8 常见综合 Pitfall Checklist

问题规避方案
在函数内写外部 reg仅返回值,再在调用处赋外部 reg
引入 #1 做仿真 delayifdef SYNTH 宏分离仿真逻辑
使用 $display$random同上,或包在 synthesis off/on 区段
递归深度不定改写成 for 循环 + 寄存器/堆栈

9 练习与进阶读物

  1. 练习

    • 实现 CRC-32、Gray 编码转换、位反转函数,并用 QuestSim 仿真。
    • 将一个 3×3 Sobel 算子的卷积核写成函数,约束综合后查看 LUT 利用率。
  2. 推荐书籍

    书名章节
    Digital Design & Verilog HDL (Charles Roth)Ch5 Functions & Tasks
    SystemVerilog for Design (Suthar, Simpson)3.10 Functional Constructs
    FPGA Prototyping by Verilog Examples (Pong P. Chu)Labs 4-7

10 培训路线图(6 小时工作坊示例)

时间模块目标
1 h函数 vs Task,语法规则能写出合法函数
1 h可综合写法、示例讲解明确 prohibit 特性
1.5 hSystemVerilog 扩展掌握 package/return/logic
0.5 h工具演示 (Vivado & ModelSim)从编辑到时序报告
1 h实战 Lab:优先编码器/CRC独立编码 + 波形分析
1 hQ&A + 代码 Review固化最佳实践

结语

Verilog 函数看似简单,却是构建 可重用、易维护、高性能 RTL 库 的基础。掌握语法约束只是第一步,更重要的是在 抽象层次、综合友好度与可验证性 之间找到平衡。通过系统化训练与大量实战,你将能将函数运用到参数化 IP、算法流水线、甚至高层 HLS 模型中,显著提升 FPGA 开发效率与设计质量。

相关文章:

  • 在真实环境中对 LLM 代理进行安全评估的综合基准
  • Spring Boot(九十三):Springboot 整合cfx实现webservice接口
  • 【Computer】计算机原理大纲
  • uni-app项目实战笔记16--实现头部导航栏效果
  • 苍穹外卖--WebSocket、来单提醒、客户催单
  • 设计案例分享 | 临床生物样本大数据中心网站设计
  • springboot的后端处理HTML的页面请求
  • openssl 自签证书生成步骤
  • 查询docker-compose 部署的milvus 请求日志
  • 解决 Docker 里 DrissionPage 无法连接浏览器的问题,内含直接可用的Docker镜像(DrissionPage 浏览器链接失败 怎么办?)
  • Dockerfile的学习与实践
  • candence17.4仿真高通滤波与电容隔离电路
  • 坤驰科技QTS4200战鹰(Battle Eagle)系列实时频谱分析记录回放系统
  • 基于大模型的急性结石性胆囊炎全流程预测与诊疗方案研究
  • 【单片机】51单片机学习笔记
  • 使用Charles抓包工具提升API调试与性能优化效率
  • 【数字人开发】Unity+百度智能云平台实现短语音文本识别功能
  • DOM型XSS深度渗透实战
  • DL00215-基于YOLOv11的太阳能电池红外异常检测含数据集
  • 不同AI架构如何选择?单Agent+MCP“与“多Agent“架构对比分析!
  • 新疆交通厅建设局网站/百度免费发布信息网站
  • 网站建设流程知乎/seo排名优化软件免费
  • 凡科建站加盟靠谱吗/湘潭seo公司
  • 织梦做网站利于优化/怎么免费建个人网站
  • 广西平台网站建设设计/chrome浏览器
  • 网站图片滚动咋么做/seo关键词排名优化销售