tit*_*cus 6 verilog bit-manipulation hdl
假设我有一个reg [15:0] my_reg包含16位带符号样本的寄存器:
如何将样本从签名转换为未签名?我已经阅读了这篇维基百科的文章,并且知道签名数字的2位补码,但是如何有效地在Verilog中执行这种转换呢?(我不知道它my_reg是正还是负,并且它在每个时钟周期都会发生变化=我在每个正时钟边沿都会收到一个新的样本).
最终目标(增加一点上下文)是实现数字FPGA内置自动增益控制(AGC).
编辑:正如所建议的那样,我将两个问题分成了两个不同的帖子.在这里看到另一个
在Verilog中,reg包含二进制数据,无符号签名只是解释的问题.位值保持不变,减法和加法总是使用二进制补码执行.
例如,我们可以查看4位值,看看如何解释数字:
Binary Unsigned signed
1000 8 -8
1110 14 -2
1111 15 -1
0001 1 1
0010 2 2
0111 7 7
Run Code Online (Sandbox Code Playgroud)
我想你想要将这些数字校准为正数,-8变为0,0变为8,7变为15.这可以通过向MSB位置加1来完成.在我们的4位示例中:
Binary Signed Addition Unsigned result
1000 -8 +1000 0000 0
1110 -2 +1000 0110 6
1111 -1 +1000 0111 7
0001 1 +1000 1001 9
0010 2 +1000 1010 10
0111 7 +1000 1111 15
Run Code Online (Sandbox Code Playgroud)
有一些密切相关的问题:
1,Verilog的:如何取绝对值.
2. 两个补码比较器的Verilog构造.
如果您的注册确实包含签名信息,那么在语义上您应该将其定义为:
reg signed [15:0] my_reg;
Run Code Online (Sandbox Code Playgroud)
绝对值:
reg signed [15:0] my_reg;
reg [15:0] my_reg_unsigned;
always @* begin
if (my_reg < 16'd0) begin
my_reg_unsigned = -my_reg ;
end
else begin
my_reg_unsigned = my_reg ;
end
end
Run Code Online (Sandbox Code Playgroud)
如果您不需要绝对但只是想使用该数字来驱动某些东西,那么将signed连接到unsigned是有效的,即:
always @* begin
my_reg_unsigned = my_reg ;
end
Run Code Online (Sandbox Code Playgroud)
这将复制位值,my_reg_unsigned可以解释为使用签名$signed(my_reg_unsigned)