磕磕碰碰 发表于 2022-5-4 22:59:35

【智多晶FPGA-039】【开发流程】IP调用之DSP,乘/除法器

1、DSP模块实现的乘法器
创建一个DSP测试工程“DSP_test”,进入IP管理,选择“DSP_Mult”。进入乘法器IP设置界面,设置相应的输入和输出位宽,有无符号数。



创建好IP后建立测试“DSP_test_tb”文件

`timescale 1ns/1ps
`define CLK_PERIOD 40

module DSP_test_tb;

    xsGSR xsGSR_INST(.GSR(1'b1));
    xsPWR xsPWR_INST(.PUR(1'b1));

      reg clk;
      reg Reset0;
      reg ClkEn0;
      reg ClkEn1;
      
      wire Product;
      
      initial clk = 1;
    always #(`CLK_PERIOD/2) clk = ~clk;
      
      
      //乘法器
      DSP_MULT DSP_MULT(
                .Clock0(clk),
                .ClkEn0(ClkEn0),
                .Reset0(Reset0),
                .A(8),
                .B(16),
                .Product(Product)
      );
      
      
      initial begin
                Reset0 = 1'b1;
                ClkEn0 = 1'b0;
                ClkEn1 = 1'b0;
                //ClkEn2 = 1'b0;
                #202;
                Reset0 = 1'b0;
                #200;
                ClkEn0 = 1'b1;
                ClkEn1 = 1'b1;
                //ClkEn2 = 1'b1;

                #2000;
                $stop;
      end
      
endmodule





如图乘法的最大延迟为3,计算结果为h10*h08=h80

2、DSP模块实现的乘\加\减功能IP
DSP_MULTADDSUB可实现乘加、乘减运算,运算方式可以在配置栏选:加、减或动态。



数据输出位宽一定要等于A端位宽 + B端位宽 + 1,否则计算结果就出错。
在我们的tb文件的initial前加上DSP_MULTADDSUB的调用代码

wire Sum;
      
      DSP_MULTADDSUB DSP_MULTADDSUB(
                .Clock0(clk),
                .ClkEn0(ClkEn1),
                .Reset0(Reset0),
                .ADDNSUB(0),
                .A0(10),
                .A1(2),
                .B0(3),
                .B1(4),
                .Sum(Sum)
      );
      


!!注意
这里的出现的ADDNSUB端口,以及后文中出现的ADDNSUB1和ADDNSUB3。
都是在将运算方式改为dynamic(动态模式)的前提下引入的端口 如下图




我们切换运算方式的办法通常有两种
1.直接在ip设置界面修改以切换




2.!!(推荐使用)!!将运算模式修改为dynamic模式(动态模式)
动态模式下我们可以在tb文件中通过直接给这个端口赋值的方式改变运算的方式


.ADDNSUB(0),表示设置为add模式
进行乘加运算:A0*B0+A1*B1得h26即38




.ADDNSUB(1),表示设置为sub模式
进行乘减运算:A0*B0-A1*B1得h16即22



需要另外注意的是不管是直接通过修改ip设置中的运算模式以更新ip,还是通过及工程,进行运算。



3、乘\加\减\求和
DSP_MULTADDSUBSUM可实现乘加求和、乘减求和、乘加与乘减求和运算,运算方式可以在配置栏选择。




运算方式同样可以选:加、减或动态。注意数据输出位宽一定要等于A端位宽 + B端位宽 + 2
同样我们需要在tb文件中加入新ip的调用,此时还需要把initial begin中注释掉的两句关于ClkEn2的语句恢复。(是因为之前没有定义这个端口也用不到,防止仿真报错所以注释掉)

reg ClkEn2;
      DSP_MULTADDSUBSUM DSP_MULTADDSUBSUM
      (
                .Clock0(clk),
                .ClkEn0(ClkEn2),
                .Reset0(Reset0),
                .ADDNSUB1(0),
                .ADDNSUB3(1),
                .A0(1),
                .A1(2),
                .A2(3),
                .A3(4),
                .B0(1),
                .B1(2),
                .B2(3),
                .B3(4),
                .Sum()
      );




通过分配我们的ADDNSUB1和ADDNSUB3, 易得我们此处有四种分配方式,(++、+ -、- +、- -)
进行乘加求和运算:(A0*B0 + A1*B1)+(A2*B2 + A3*B3)得数为d30即h1e



进行乘减求和运算:(A0*B0 - A1*B1)+(A2*B2 - A3*B3) 得数是d'-10这里取了补码就变成了ffff6,取反后是1001,+1变成10



另外进行先乘减后乘加(A0*B0 - A1*B1)+(A2*B2 + A3*B3)得h16



进行先乘加后乘减(A0*B0 + A1*B1)+(A2*B2 - A3*B3)得ffffe,取反b‘0001,加一为b’2


3、DIVIDER除法器
添加“Divider”IP到测试工程,在IP管理页点击打开“Divider”,设置并添加。



例化并设置参数。

wire Quotient;
      wire Remainder;
      wire result_vld;
      
      
      xsIP_DIVIDER xsIP_DIVIDER(
      .rst(Reset0),
    .clk(clk),
    .divider_en(1),
    .din_vld(9),
    .dividend(16),
    .divisor(5),
    .result_vld(),
    .quotient(),
    .remainder()
      );
      

设置Modelsim仿真,添加并加载仿真,观察仿真发现,数据延时9个时钟周期输出。




(2.14版)工程源码

更多智多晶FPGA相关资料,请查看下述汇总贴
【智多晶FPGA-001】小梅哥智多晶FPGA产品使用自助服务手册




页: [1]
查看完整版本: 【智多晶FPGA-039】【开发流程】IP调用之DSP,乘/除法器