数字IC设计 FPGA——再谈乘法器设计(使用Verilog 原语 LUT 进行四位乘法器设计)

数字IC设计 FPGA——再谈乘法器设计(使用Verilog 原语 LUT 进行四位乘法器设计)

乘法器同加法器一样,在数字信号的各种算法中被频繁的使用,并且对于整个系统的速度的影响是很大的。那么如何实现快速高效的乘法器关系着整个系统的运算速度和资源效率最大化的利用。

乘法操作分为有符号操作和无符号操作两大类,无符号操作相对于有符号乘法操作相对简单,但也只需要简单的变换就能有符号乘法器变换为无符号乘法器。

本次主要是基于Verilog 原语LUT 进行乘法器的设计。
相关的乘法器知识可以参考之前的博文:

数字电路基础知识——组合逻辑电路之乘法器的设计(一)—— 并行、移位相加、加法树、查找表乘法器
数字电路基础知识——乘法器的设计(二)( 串行、流水线、有符号数八位乘法器)

一、乘法器架构
  1. 乘法器
    由于乘数和被乘数都是二进制,所以利用人工计算来分析,所以利用乘数从最后一位到第第一位每一位依次与被乘数相乘,从第二位开始每一位都要依次左移一位,形成一个阵列的式。而由于两个一位二进制数相乘,实际上是做与运算,所以就将乘法操作简化为了与运算、移位操作以及加法操作。比如 1011与 1101相 乘,如图,实际上可看作 1011+00000+101100+1011000四个数相加。
    在这里插入图片描述
  2. 乘法器结构
    乘法运算是由与、或、非等基本逻辑组合而成的,如下图所示是乘法器内部结构图
    在这里插入图片描述
二、乘法器的 Verilog 原语设计
  1. 设计思路
    使乘法器的输入分别为A[3:0]和B[3:0],设计思路先计算出相与的结果,将相与的结果一次移位相加得到最后的结果。移位相加所使用的全加器是之前在下面这篇博客中以LUT3设计的一位全加器。
    数字IC设计 FPGA——再谈加法器设计(使用Verilog 原语 进行四位加法器设计)
    并设置中间变量:
    t0,t1,t2,t3:第一行至第四行相与的结果
    ts0,ts1,ts2,ts3:第一行至第四行的结果输出
    tc0,tc1,tc2,tc3:第一行至第四行的进位输出
  2. Verilog代码
module addr_4bit(
A,B,Y
    );

input [3:0] A,B;
output [7:0] Y;

wire [3:0] t0,t1,t2,t3; //每一行相与结果
wire [3:0] ts0,ts1,ts2,ts3; //每一行的相加的结果输出
wire [3:0] tc0,tc1,tc2,tc3; //每一行的进位输出

genvar i;
generate
   for (i=0;i<4;i=i+1)
   begin: label1  
        assign t0[i] = A[i] & B[0];
        assign t1[i] = A[i] & B[1];
        assign t2[i] = A[i] & B[2];
        assign t3[i] = A[i] & B[3];
   end  
endgenerate

genvar j;
generate
    for (j=0;j<4;j=j+1)
    begin:label2
        assign ts0[j]= t0[j];
        assign tc0[j] = 1'b0;
    end
endgenerate

genvar m;
generate
   for (m=0;m<3;m=m+1)
   begin: label3
        addr_bit u1(
        .A(t1[m]),
        .B(ts0[m+1]),
        .S(ts1[m]),
        .Cout(tc1[m]),
        .Cin(tc0[m])
        ); 
   end  

   for (m=0;m<3;m=m+1)
   begin: label4
        addr_bit u2(
        .A(t2[m]),
        .B(ts1[m+1]),
        .S(ts2[m]),
        .Cout(tc2[m]),
        .Cin(tc1[m])
        ); 
   end  

   for (m=0;m<3;m=m+1)
   begin: label5
        addr_bit u3(
        .A(t3[m]),
        .B(ts2[m+1]),
        .S(ts3[m]),
        .Cout(tc3[m]),
        .Cin(tc2[m])
        ); 
   end  
endgenerate


assign ts1[3]=t1[3];
assign ts2[3]=t2[3];
assign ts3[3]=t3[3];

wire [3:0] rac,ras;

assign rac[0]= 1'b0;

genvar n;
generate
    for (n=0;n<3;n=n+1)
    begin :label6
        addr_bit u4(
        .A(rac[n]),
        .B(ts3[n+1]),
        .S(ras[n]),
        .Cin(tc3[n]),
        .Cout(rac[n+1])
        );
    end
endgenerate

assign Y[0]=ts0[0];
assign Y[1]=ts1[0];
assign Y[2]=ts2[0];
assign Y[3]=ts3[0];


genvar p;
generate
    for (p=4;p<7;p=p+1)
    begin:label7
        assign Y[p]=ras[p-4];
    end
endgenerate

assign Y[7]=rac[3];
endmodule

rac和ras是高四位的进位输出和结果输出相与的结果。必须要想加才能得到正确的结果。

  1. RTL结构图
    在这里插入图片描述
  2. 仿真结果如下:
    可以看到有正确的输出结果和进位输出
    在这里插入图片描述
  3. 综合之后资源的利用在这里插入图片描述
    40LUT包括24个LUT3和16个LUT2(与门)
三、总结
  1. 使用该乘法器能够拓展为其他新的位宽的乘法器。该乘法器可能不是最好的乘法器架构。
  2. 如果再不采用原语进行设计的情况下,直接编写加法器Verilog代码,综合工具会根据自己的算法给出一个比较合理的电路,可能会比我们采用后一种方法设计的要更好,这需要依赖EDA综合工具。
  3. 但是通过了解CLB的不同的基本配置方式以及内部资源分布,对于更好理解软件综合过程和设计具有更好的指导意义
  4. 如果能再关键的位置手动配置硬件资源,可能会改善局部性能,这对于高性能计算硬件有重要意义,尤其是底层的硬件加法等部件。
  • 9
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
16位乘法器芯片verilog设计实验Quartus9.1工程源码+设计说明文件,可以做为的学习实验设计参考。 module mux16( clk,rst_n, start,ain,bin,yout,done ); input clk; //芯片的时钟信号。 input rst_n; //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。 input start; //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得乘数和被乘数,并将乘积复位清零。 input[15:0] ain; //输入a(被乘数),其数据位宽为16bit. input[15:0] bin; //输入b(乘数),其数据位宽为16bit. output[31:0] yout; //乘积输出,其数据位宽为32bit. output done; //芯片输出标志信号。定义为1表示乘法运算完成. reg[15:0] areg; //乘数a寄存器 reg[15:0] breg; //乘数b寄存器 reg[31:0] yout_r; //乘积寄存器 reg done_r; reg[4:0] i; //移位次数寄存器 always@(posedge clk) begin if(!rst_n) begin areg <= 16'h0000; breg <= 16'h0000; done_r <= 1'b0; yout_r <= 32'h00000000; i <= 5'd0; end else if(start) //启动运算 begin if(i < 5'd21) i <= i+1'b1; if(i == 5'd0) begin //锁存乘数、被乘数 areg <= ain; breg <= bin; end else if(i > 5'd0 && i < 5'd16) begin if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]}; //累加并移位 else yout_r <= yout_r>>1; //移位不累加 end else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg; //累加不移位 else if(i == 5'd18) done_r <= 1'b1; //乘完成标志位置位 else if(i == 5'd20) done_r <= 1'b0; //乘完成标志位清除 end else i <= 5'd0; end assign done = done_r; assign yout = yout_r;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆渡沧桑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值