Verilog与无签名样本签署并首先签署

tit*_*cus 6 verilog bit-manipulation hdl

假设我有一个reg [15:0] my_reg包含16位带符号样本的寄存器:

如何将样本从签名转换为未签名?我已经阅读了这篇维基百科的文章,并且知道签名数字的2位补码,但是如何有效地在Verilog中执行这种转换呢?(我不知道它my_reg是正还是负,并且它在每个时钟周期都会发生变化=我在每个正时钟边沿都会收到一个新的样本).

最终目标(增加一点上下文)是实现数字FPGA内置自动增益控制(AGC).

编辑:正如所建议的那样,我将两个问题分成了两个不同的帖子.在这里看到另一个

Mor*_*gan 7

在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)

  • @Tobia +, - 所有工作都自然地在未签名和签名的数字上工作.一元〜执行一个有点明智的反转(一个补码),即不关心符号.一元 - 执行二进制补码反转+1,它不关心输入的符号.想到的唯一函数是comparaisons >> = <= <乘法和除法 (2认同)