为什么内联Verilog算术移位会将其转换为逻辑移位?
我读过关于如何在Verilog中实现算术移位的文章。所有人都建议使用为什么内联Verilog算术移位会将其转换为逻辑移位?,verilog,bit-shift,Verilog,Bit Shift,我读过关于如何在Verilog中实现算术移位的文章。所有人都建议使用$signed(…)>>… 当直接将结果指定给导线或寄存器时,此功能有效,但当将其用作更大表达式的一部分时,则不起作用。即: reg[2:0]a=$signed(3'b100)>>1生成3'b110 reg[2:0]a=1'b1$签署(3'b100)>>>1:3'b000产生3'b010 解决方案似乎是将计算包装成$unsigned: reg[2:0]a=$unsigned($signed(3'b100)>>1)生成3'b
$signed(…)>>…
当直接将结果指定给导线或寄存器时,此功能有效,但当将其用作更大表达式的一部分时,则不起作用。即:
reg[2:0]a=$signed(3'b100)>>1代码>生成
3'b110
reg[2:0]a=1'b1$签署(3'b100)>>>1:3'b000代码>产生
3'b010
$unsigned
:
reg[2:0]a=$unsigned($signed(3'b100)>>1)代码>生成
3'b110
reg[2:0]a=1'b1$未签名($signed(3'b100)>>>1):3'b000代码>生成
3'b110
$unsigned
可以解决问题?
下面是一个简单的工作示例:
module puzzle();
reg [2:0] a_u = 3'b100 >>> 1; // 3'b010
reg [2:0] a_s = $signed(3'b100) >>> 1; // 3'b110
reg [2:0] a_mux = 1'b1 ? $signed(3'b100) >>> 1 : 3'b000; // 3'b010
reg [2:0] b_u = $unsigned(3'b100 >>> 1); // 3'b010
reg [2:0] b_s = $unsigned($signed(3'b100) >>> 1); // 3'b110
reg [2:0] b_mux = 1'b1 ? $unsigned($signed(3'b100) >>> 1) : 3'b000; // 3'b110
initial begin
$display("a_u = 3'b%3b", a_u);
$display("a_s = 3'b%3b", a_s);
$display("a_mux = 3'b%3b", a_mux);
$display("b_u = 3'b%3b", b_u);
$display("b_s = 3'b%3b", b_s);
$display("b_mux = 3'b%3b", b_mux);
end
endmodule
输出:
a_u = 3'b010
a_s = 3'b110
a_mux = 3'b010
b_u = 3'b010
b_s = 3'b110
b_mux = 3'b110
我不知道原因,但将
3'b000
转换为3'sb000
似乎也能解决您的问题
reg [2:0] a_mux = 1'b1 ? $signed(3'b100) >>> 1 : 3'sb000;
此外,使用$signed()
代替$unsigned()
也可以:
reg [2:0] b_mux = 1'b1 ? $signed($signed(3'b100) >>> 1) : 3'b000;
这里有两条Verilog表达式规则:
- 语境决定的与自我决定的表达
- 在上下文中,混合使用有符号和无符号操作数会导致所有操作数都无符号
C ? A : B
操作数A
和B
相互关联。每个操作数的大小都将调整为最大操作数,并且两个操作数都必须经过签名才能保持有符号。这发生在编译期间应用运算符之前S
是自定的,任何C
之外的内容都不会对其大小或签名产生任何影响。而且,C
对A
和B
类似地,当你有表达式
A >>> S
A
是上下文确定的,S
是自确定的
现在,如果我们将这两个表达式合并为一个:
C ? A >>> S : B
由于
A
和B
在相同的上下文中,并且B
是无符号的,A
被转换为无符号的。只要在函数调用中包装A>>>S
(任何类型的函数调用都是一样的),函数的每个输入参数都有自己的上下文,独立于它所属的表达式的其余部分。返回值将与表达式的其余部分一起在上下文中处理 太棒了,谢谢!有没有一种更干净的方法可以让表达式在自己的上下文中使用,而不是使用$unsigned
?我不认为它是干净的,但是使用串联可以减少字符数<代码>1'b1?{3'sb100)>>>1}:3'b000。串联中的所有操作数都是自定的。