我有一个具体问题,需要更一般的指导。
我的问题是,在SystemVerilog中将带符号的数字乘以无符号的数字最干净的方法是什么?
下面是一些说明问题的测试代码。 “ a”是无符号数字。 “ b”是签名号。为了产生正确的带符号结果,SystemVerilog似乎要求对乘法的两个操作数进行签名。为了在这里工作,我必须在无符号数字的前面添加一个额外的“ 0”以使其成为有效的带符号数字。我在想必须有一种更清洁的方法。
更一般而言,我才刚刚开始在SystemVerilog中进行定点数学运算。在VHDL中,有非常具体的语法,甚至是一个标准的程序包,都支持有符号和无符号定点数学运算以及舍入等。在SystemVerilog世界中是否有类似的东西?
谢谢
module testbench ();
localparam int Wa = 8;
localparam int Wb = 8;
logic [Wa-1:0] a; // unsigned
logic [Wa:0] a_signed; // signed word with extra bit to hold unsigned number.
logic [Wb-1:0] b; // signed
logic [Wa+Wb-1:0] c; // result
localparam clk_period = 10;
assign a_signed = {1'b0, a};
assign c = $signed(a_signed)*$signed(b);
initial begin
a = +5;
b = +10;
#(clk_period*1);
$display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
a = +5;
b = -10;
#(clk_period*1);
$display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
a = +255;
b = +10;
#(clk_period*1);
$display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
a = +255;
b = -10;
#(clk_period*1);
$display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
$stop;
end
endmodule
答案 0 :(得分:0)
系统Verilog规则说
如果任何操作数是无符号的,则结果是无符号的,而不管运算符是什么
将表达式(或自定义子表达式)的类型和大小传播回表达式的上下文确定操作数
当传播达到11.5中定义的简单操作数时,则应将该操作数转换为传播的类型和大小。
因此,换句话说,当您使用带符号的数字和无符号的数字时,表达式类型将确定为unsigned
。这将被传播回操作数,所有带符号的也将被视为无符号。
因此,您的结果将等于两个无符号数字相乘的结果。因此,如果需要带符号的结果,最干净的方法是将所有操作数转换为带符号的数字。
您还需要在操作数中加一个位,以放置符号位。否则,在8位符号转换中将255视为-1
。