FPGA实战(11):基于Xilinx除法器IP核的有符号整数除法器设计(附源码)

张开发
2026/6/15 1:52:57 15 分钟阅读

分享文章

FPGA实战(11):基于Xilinx除法器IP核的有符号整数除法器设计(附源码)
1. 引言在实际FPGA开发中除法运算是一种常见但比较消耗资源尤其是LUT和乘法器资源的操作。为了兼顾开发效率与性能Xilinx Vivado提供了Divider Generator除法器生成器IP核支持有符号/无符号除法并可以配置为高吞吐率或低延迟模式。本文将介绍一个简单的有符号整数除法器模块——tops。它调用了Vivado生成的div_gen_0IP核完成16位有符号整数的除法同时输出商和余数并给出一个Testbench用于仿真验证。创新点在于巧妙利用32位输出数据的高16位和低16位分别输出商和余数接口简洁正确处理IP核的复位极性高有效转低有效提供完整的可仿真示例帮助初学者快速上手除法器IP核的使用。2. 功能点概述信号名方向位宽说明i_clkinput1时钟信号i_rstinput1高有效异步复位i_dividendinput16被除数有符号i_divisorinput16除数有符号o_C(Quotient)output16商有符号o_R(Remainder)output16余数有符号核心功能完成o_C i_dividend / i_divisor整数除法向零取整完成o_R i_dividend % i_divisor并满足i_dividend o_C * i_divisor o_R适用场景数字信号处理中的定点数除法预处理嵌入式软核与FPGA加速器接口的数据分割简单控制系统中需要求商和余数的场合3. 模块设计与代码分析3.1 顶层模块topstimescale 1ns / 1ps module tops ( input i_clk , input i_rst , input signed [15:0] i_dividend , input signed [15:0] i_divisor , output signed [15:0] o_C , output signed [15:0] o_R ); // // Wire declarations // wire [31:0] w_dout_tdata; // 除法器输出数据高16位商低16位余数 // // Assign statements // assign o_R w_dout_tdata[15:0] ; assign o_C w_dout_tdata[31:16] ; // // Module instantiations // div_gen_0 div_gen_0_u0 ( .aclk (i_clk ), .aresetn (i_rst ), // 复位极性转换高有效转低有效 .s_axis_divisor_tvalid (1b1 ), .s_axis_divisor_tdata (i_divisor ), .s_axis_dividend_tvalid (1b1 ), .s_axis_dividend_tdata (i_dividend ), .m_axis_dout_tvalid ( ), // 未使用 .m_axis_dout_tdata (w_dout_tdata ) ); endmodule代码解读IP核例化div_gen_0是Vivado生成的除法器IP核。aclk时钟。aresetn低有效异步复位。但模块端口i_rst是高有效因此直接将i_rst连接到aresetn上相当于实现了极性转换。s_axis_divisor_tvalid与s_axis_dividend_tvalid固定为1表示输入数据始终有效不考虑握手。m_axis_dout_tdata输出32位数据高16位是商quotient低16位是余数remainder。输出拆分直接使用assign将w_dout_tdata的高16位和低16位分别赋值给o_C和o_R接口一目了然。3.2 Testbench 测试模块test_topstimescale 1ns / 1ps module test_tops; reg i_clk; reg i_rst; reg signed[15:0] i_dividend; reg signed[15:0] i_divisor; wire signed[15:0] o_C; wire signed[15:0] o_R; tops tops_u ( .i_clk (i_clk), .i_rst (i_rst), .i_dividend (i_dividend), .i_divisor (i_divisor), .o_C (o_C), .o_R (o_R) ); initial begin i_clk 1b1; i_rst 1b0; #100 i_rst 1b1; end initial begin i_dividend 16d2040; i_divisor 16d100; end always #5 i_clk ~i_clk; endmodule测试说明复位后i_rst1输入被除数2040除数100。预期结果商20余数40。由于除法器IP核有一定延迟通常为几个时钟周期但Testbench未等待m_axis_dout_tvalid信号直接观察输出波形即可实际仿真时可添加$display或观察波形。4. 创新点与技巧总结巧妙复用32位总线IP核同时输出商和余数一次性读取并拆分为两个16位信号省去了多余的总线打包逻辑。极性无痛转换模块对外使用高有效复位与大多数用户设计习惯一致内部IP核需要低有效复位直接连线完成转换无需额外反相器。简化valid信号对于持续有效的除法需求直接将tvalid固定为1避免复杂握手逻辑适合流式数据。有符号除法的正确保留所有信号均声明为signed综合工具会正确实现有符号除法保证负数的商和余数符合Verilog标准向零取整。5. 仿真波形分析示例使用Vivado Simulator运行Testbench得到波形如下描述时间复位被除数除数输出商输出余数0~100ns02040100XX100ns后120401002040扩展测试负数输入i_dividend -2040,i_divisor 100→ 商-20余数-40。除数为0除法器IP核会产生溢出标志可通过增加m_axis_dout_tuser端口获取本设计中未处理。6. 如何生成和使用除法器IP核在Vivado中打开IP Catalog搜索“Divider Generator”。配置Algorithm TypeRadix-2默认或High Radix。Dividend Width16Divisor Width16。Signed勾选。Output商和余数都保留输出宽度32即高Half商低Half余数。将生成的div_gen_0.xci添加到工程中直接例化即可。7. 总结本文实现了一个非常简洁实用的有符号整数除法器模块通过调用Xilinx除法器IP核仅用几行代码就完成了商和余数的输出。适合FPGA初学者理解IP核的例化方法、复位极性处理以及总线数据拆分的常用技巧。读者可以在自己的工程中直接复制使用只需注意IP核的配置参数与顶层信号位宽保持一致。后续改进方向加入tvalid与tready握手信号实现背压控制。添加除数为零的保护和溢出标志输出。希望这篇博客能帮助您快速在FPGA中实现高效的除法运算。如有问题欢迎在评论区交流附完整代码文件my_tops.v与tb_TOPS.v已贴于文中复制保存到Vivado工程中添加对应IP核即可运行仿真。

更多文章