Verilog中的定点有符号乘法

Verilog中的定点有符号乘法,verilog,multiplication,fixed-point,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中,我的

我正在设计一个有符号的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 fixed_multiplier (
i_a,
i_b,
o_p,
clk
);

input clk;
input signed [31:0] i_a;
input signed [31:0] i_b;
output signed [31:0] o_p;
wire signed [63:0] out;

assign out = i_a*i_b;
assign o_p = out;
endmodule
我知道上面提到的代码有bug,因为我根本没有得到想要的结果

所以我的问题是

(1) 由于这一行“assign o_result=out;”对我来说至关重要,我应该如何对最终输出进行赋值,以便获得正确和最准确的s4.27格式输出?请注意,此输出将馈送至加法器,加法器输出将再次成为乘法器的输入

在提出上述问题时,我还尝试对两个输入的符号位进行异或运算,并将[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;

fixed_multiplier mul_i  (
.clk(clk),
.i_a(a),
.i_b(b),
.o_p(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

先谢谢你

你的乘数不像你想象的那样工作。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]};

它应该和你的“c”片段一样工作吗?如果是这样的话,
assign o_result=out>>27有什么问题
[57:27]
将是31位,比您需要的少一位<代码>分配o_结果=输出[58:27]
应该可以工作。@Greg
[57:27]
应该是31位,这是真的。另一位是来自两个输入的两个符号位的x或。所以总共32位。@Serge你的建议比我以前的任何解决方案都有效。非常感谢您。
x*y>>27
截断,
最准确的结果
可能意味着舍入。无论出于何种原因,当以-1输出5.179时,此方法似乎不会返回正确的结果。