问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

FPGA通过移位相加实现有符号乘法器(参数化,封装成IP可直接调用)

创作时间:
作者:
@小白创作中心

FPGA通过移位相加实现有符号乘法器(参数化,封装成IP可直接调用)

引用
CSDN
1.
https://blog.csdn.net/xxqlover/article/details/139611543

FPGA(现场可编程门阵列)是一种可编程逻辑器件,广泛应用于数字信号处理、通信系统、图像处理等领域。在FPGA中实现有符号乘法器是一个常见的需求,本文将介绍如何通过移位相加的方法实现这一功能,并将其封装成可复用的IP核。

在上一篇博客中,我们实现了无符号移位相加乘法器。有符号乘法器和无符号乘法器的原理基本相同,只是需要额外处理符号位。本文将详细介绍如何在FPGA中实现有符号乘法器,并将其封装成可复用的IP核。

原理

对于有符号数乘法,一种常见的处理方法是先将两个数进行符号位扩展,然后按照无符号数的计算方式进行计算。例如,计算(-3)×(-6)时,首先将-3和-6转换为8位补码形式:

  • (-3)的补码是1101,符号位扩展后变为11111101
  • (-6)的补码是1010,符号位扩展后变为11111010

然后按照无符号数的计算步骤进行计算。

然而,本文提出了一种不同的思路:不进行符号位扩展,而是先抛开符号位,将负数的补码转换为原码,然后以无符号数乘法的计算方式进行计算。最后再来处理符号位,即"同号为正,异号为负"。

实现

下面展示了基于上述思路设计的有符号移位相加乘法器的Verilog代码实现。该实现是并行计算的,只需要一个周期就能出结果,并且进行了参数化。

module sign_Mult
    #(parameter WIDTH_A = 8,
                WIDTH_B = 8)
(
    input 				clk						 ,
    input 	signed		[WIDTH_A-1:0] 			a,
    input 	signed		[WIDTH_B-1:0] 			b,
    output 	reg	signed	[WIDTH_A+WIDTH_B:0]	  out

    );
    integer 			i							 ;
    reg 	signed		[WIDTH_A+WIDTH_B:0] 	out_r;//考虑结果会有溢出
    wire 	signed		[WIDTH_A:0] 			a_r	 ;
    wire	signed		[WIDTH_B:0] 			b_r	 ;	
always @(a or b) begin
    out_r = 0;
    for(i=0; i<(WIDTH_B); i=i+1)
        if(b_r[i])
            out_r = out_r + (a_r << i);
end
assign a_r = a[WIDTH_A-1] ? {1'b0,~a + 1'b1} : {1'b0,a};//负数取反加一转化为补码
assign b_r = b[WIDTH_B-1] ? {1'b0,~b + 1'b1} : {1'b0,b};//正数保持不变
always @(posedge clk)
    if(a[WIDTH_A-1] == b[WIDTH_B-1])
        out <= out_r;
    else
        out <= ~out_r + 1'b1;
endmodule

测试激励代码

为了验证上述设计的正确性,我们编写了以下测试激励代码:

`timescale 1ns / 1ps
module sign_Mult_tb;
reg 	signed	[11:0] 		a	;
reg		signed	[15:0] 		b	;
wire 	signed	[28:0]		out	;
reg							clk	;
sign_Mult
#(.WIDTH_A(12),
.WIDTH_B(16))
u1(
    .clk(clk),
    .a	(a)	 ,
    .b	(b)	 ,
    .out(out)
 );
 always #10 clk = ~clk;
 initial begin
    clk = 1'b0;
    a = -12'd2;
    b = -16'd3;//计算结果应为6
    #200
    a = -12'd2048;//12bit最小值-2048
    b =  16'd32767;//16bit有符号数最大值//计算结果应为-67_106_816
    #200
    a =  12'd2;
    b = -16'd3;//计算结果应为-6
    #200
    a =  12'd2047;//12bit最大值2047
    b = -16'd32768;//16bit最小值-32768//计算结果应为-67_076_096
 end
endmodule

注意事项

  1. 无论是有符号数相乘还是无符号数相乘,其乘积的位宽必定位a+b;
  2. 如果被乘数和乘数均为有符号数,那么相乘之前首先要进行符号位扩展,将被乘数和乘数均扩展位a+b位。
  3. 有符号数乘法的最终结果也是补码形式。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号