4.3 KiB
4.3 KiB
Vivado使用乘法器、除法器IP核实现乘除取余仿真
环境
Vivado 20.2
添加并配置IP核
- 打开vivado,找到对应IP核,如下图

- 先双击除法器IP核进入配置页面,如下图
除法器配置默认即可,点击OK;后弹出界面,点击Generate
如下图即配置完成

- 配置乘法器IP核
上图使用十六位有符号数与十六位无符号数进行运算
上图输出32位,间隔一个周期得到结果(电脑性能不佳可适当增加) - 如下图即配置完成

添加并编写仿真代码文件
- 选择一个文件夹,创建例如ipcore_test.v文件
- 添加文件到vivado
找到自己创建的.v文件路径并添加 - 完成如下图

- 复制示例代码
双击打开.veo 示例代码文件
复制上图红框中的代码到自己的仿真文件,如下图(我这是外部编辑器,vivado自带编辑器同理)
上图的module与endmodule需要自己添加
如下图,可以看到,除法器IP核在你自己的代码文件之下,表示被正确调用
乘法器同理,打开.veo文件复制代码
示例代码复制完成后如下图,这里我更改了实例名称(u_ 开头,不改没影响)

- 最后自己补全仿真代码,我这里这样写
`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

