Files
BlogPosts/文章/学习之路/vivado_ip.md
2025-10-31 15:08:40 +08:00

113 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Vivado使用乘法器、除法器IP核实现乘除取余仿真
### 环境
Vivado 20.2
## 添加并配置IP核
1. 打开vivado找到对应IP核如下图
![](./vivado_ip_img/IPCore01.png)
2. 先双击除法器IP核进入配置页面如下图
![](./vivado_ip_img/IPCore02.png)
![](./vivado_ip_img/IPCore03.png)
除法器配置默认即可点击OK后弹出界面点击Generate
如下图即配置完成
![](./vivado_ip_img/IPCore04.png)
3. 配置乘法器IP核
![](./vivado_ip_img/IPCore05.png)
上图使用十六位有符号数与十六位无符号数进行运算
![](./vivado_ip_img/IPCore06.png)
上图输出32位间隔一个周期得到结果电脑性能不佳可适当增加
4. 如下图即配置完成
![](./vivado_ip_img/IPCore07.png)
## 添加并编写仿真代码文件
1. 选择一个文件夹创建例如ipcore_test.v文件
2. 添加文件到vivado
![](./vivado_ip_img/IPCore08.png)
![](./vivado_ip_img/IPCore09.png)
找到自己创建的.v文件路径并添加
3. 完成如下图
![](./vivado_ip_img/IPCore10.png)
4. 复制示例代码
![](./vivado_ip_img/IPCore11.png)
双击打开.veo 示例代码文件
![](./vivado_ip_img/IPCore12.png)
复制上图红框中的代码到自己的仿真文件,如下图我这是外部编辑器vivado自带编辑器同理
![](./vivado_ip_img/IPCore13.png)
上图的module与endmodule需要自己添加
如下图可以看到除法器IP核在你自己的代码文件之下表示被正确调用
![](./vivado_ip_img/IPCore14.png)
乘法器同理,打开.veo文件复制代码
![](./vivado_ip_img/IPCore15.png)
![](./vivado_ip_img/IPCore16.png)
示例代码复制完成后如下图这里我更改了实例名称u_ 开头,不改没影响)
![](./vivado_ip_img/IPCore17.png)
5. 最后自己补全仿真代码,我这里这样写
```verilog
`timescale 1ns / 1ps
module tb_ipcore_test();
reg clk; //时钟变量
reg signed [15:0] A; //有符号因数数据
reg unsigned [15:0] B; //无符号因数数据
wire signed [31:0] P; //乘法器结果
reg dividend_tvalid; //被除数有效使能,高为有效,低为无效
reg signed [15:0] dividend_tdata; //被除数数据
reg divisor_tvalid; //除数有效使能,高为有效,低为无效
reg signed [15:0] divisor_tdata; //除数数据
wire dout_tvalid; //输出电平,高为正确输出,低为错误输出
wire [31:0] dout_tdata; //除法器结果
wire signed [15:0] quotient; //商
wire signed [15:0] remainder; //余数
mult_gen_0 u_mult_gen_0 (
.CLK(clk), // input wire CLK
.A(A), // input wire [15 : 0] A
.B(B), // input wire [15 : 0] B
.P(P) // output wire [31 : 0] P
);
div_gen_0 u_div_gen_0 (
.aclk(clk), // input wire aclk
.s_axis_divisor_tvalid(divisor_tvalid), // input wire s_axis_divisor_tvalid
.s_axis_divisor_tdata(divisor_tdata), // input wire [15 : 0] s_axis_divisor_tdata
.s_axis_dividend_tvalid(dividend_tvalid), // input wire s_axis_dividend_tvalid
.s_axis_dividend_tdata(dividend_tdata), // input wire [15 : 0] s_axis_dividend_tdata
.m_axis_dout_tvalid(dout_tvalid), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata(dout_tdata) // output wire [31 : 0] m_axis_dout_tdata
);
assign quotient = dout_tdata[31:16]; //除法器16位余数模式高16位是商低十六位是余数
assign remainder = dout_tdata[15:0];
always #5 clk = ~clk; //10ns周期时钟
initial begin
clk = 0;
A = 16'h7FFF;
B = 16'hFFFF;
dividend_tvalid = 1;
dividend_tdata = 16'h7FFF;
divisor_tvalid = 1;
divisor_tdata = 16'hFFFF;
#300;
A = 16'h8001;
B = 16'h0001;
dividend_tvalid = 1;
dividend_tdata = 16'h8001;
divisor_tvalid = 1;
divisor_tdata = 16'hFFFF;
#300;
$finish;
end
endmodule
```
6. 结果分析
选中除B之外的所有变量调整为有符号的十进制B调整为无符号的十进制数
![](./vivado_ip_img/IPCore19.png)
下图可以看到,乘法器得到数据(一开始),在第一个周期得到结果,除法器得到数据,在第二十个周期得到结果
![](./vivado_ip_img/IPCore18.png)