Verilog中的定点符号乘法

时间:2018-03-02 13:58:15

标签: verilog multiplication fixed-point

我正在设计一个签名的verilog乘数,我打算在另一个模块中多次使用。

我的两个输入将始终是s4.27格式。 1位有符号,4位整数和27位分数。我的输出也必须是s4.27格式,我必须得到最准确的结果。

在C中,以下不那么完美的代码片段完成了这项工作。

int32_t mul(int32_t x, int32_t y)
{
 int64_t mul = x;
 mul *= y;
 mul >>= 27;
 return (int32_t) mul;
}

在verilog中,我的简单版本的代码如下所示,

`timescale 1ns/1ps

module multiplier (
i_multiplicand,
i_multiplier,
o_result,
clk
);

input clk;
input signed [31:0] i_multiplicand;
input signed [31:0] i_multiplier;
output signed [31:0] o_result;
wire signed [63:0] out;

assign out = i_multiplicand*i_multiplier;
assign o_result = out;
endmodule

上面提到的代码存在我知道的错误,因为我根本没有得到预期的结果。

所以我的问题是,

(1)作为这一行"指定o_result = out;"对我来说似乎至关重要,如何对我的最终输出进行分配,以便获得正确且最准确的s4.27格式输出?请注意,此输出将被输入到加法器,加法器输出将再次作为乘法器的输入。

上面提到的问题,我也尝试对两个输入的符号位进行xor-ing并将[57:27]位分配给最终输出。不适合我并导致溢出,而​​在C相同的输入没有给出任何溢出错误。

(2)使用C我在定点乘法中没有任何问题,而在verilog我想我正在努力,因为我是一个新手。有什么建议在处理有符号的乘法/加法时要记住什么?

以下是测试平台代码

`timescale 1ns / 1ps
module tb_mul;
// Inputs
reg clk;
reg [31:0] a;
reg [31:0] b;

// Outputs
wire [31:0] c;

multiplier mul_i  (
.clk(clk),
.i_multiplicand(a),
.i_multiplier(b),
.o_result(c)
);

initial begin

$dumpfile("test_mul.vcd");
$dumpvars(1);

$monitor ("a=%h,\tb=%h,\tc=%h",a,b,c);

  a = 32'h10000000;
  b = 32'h10000000;

  $finish();

end
endmodule

提前谢谢你。

1 个答案:

答案 0 :(得分:0)

您的乘法器无法像您想象的那样工作。 Verilog将假定您的乘法将是无符号的,并将以此进行计算。您可能需要执行以下操作:

wire [61:0] temp_out;
assign temp_out = i_multiplicand[30:0] * i_multiplier[30:0];
assign sign = i_multiplicand[31] ^ i_multiplier[31];
assign out = {sign, temp_out[57:37]};