Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verilog signed vs unsigned samples and first

Assuming I have a register reg [15:0] my_reg, which contains a 16-bit signed sample:

How do I convert the sample from signed to unsigned? I have read this Wikipedia article, and am aware of the 2-bit complement for signed numbers, but how do I perform this conversion in Verilog efficiently? (I don't know if my_reg is positive or negatve, and it changes in every clock cycle = I receive a new sample on every positive clock edge).

The ultimate goal (to add a little bit of context) is to implement a digital FPGA built-in automatic gain control (AGC).

EDIT: as suggested I have split the two questions in two different posts. See the other one here

like image 604
titus.andronicus Avatar asked Jun 11 '14 11:06

titus.andronicus


People also ask

What is the difference between signed and unsigned in Verilog?

Signed numbers. By default, 'reg' and 'wire' data type are 'unsigned number, whereas 'integer' is signed number. Signed number can be defined for 'reg' and 'wire' by using 'signed' keywords i.e. 'reg signed' and 'wire signed' respectively as shown in Table 3.2.

Is logic in Verilog signed or unsigned?

logic, bit, reg, and packed arrays of those types are all unsigned by default.

What does $Signed do in Verilog?

Referring to SV LRM 1800-2012 : "... the $signed and $unsigned system functions are available for casting the signedness of expressions.". So, if we have logic signed [7:0] myreg; and myreg=$signed(4'b1100) , then the MSB is considered as signed bit and myreg=-4 .

Is $Signed synthesizable in Verilog?

Yes it is synthesizable. But it builds combinatorial logic (slow).


1 Answers

In Verilog a reg contains binary data, signed unsigned are just a matter of interpretation. The bit values stay the same, subtraction and addition are always performed using two's complement.

For example, we can look at a 4 bit value and see how the numbers can be interpreted:

  Binary Unsigned  signed  
  1000          8      -8
  1110         14      -2
  1111         15      -1    
  0001          1       1
  0010          2       2
  0111          7       7

I think you want to calibrate these numbers on to a positive scale, -8 becomes 0, 0 becomes 8, 7 becomes 15. This would be done by adding 1 in to the MSB position. In our 4 bit example:

  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

There are some closely related questions:
1. Verilog: how to take the absolute value.
2. Verilog Construction of Two's Complement Comparator.

If your register really does contain signed information then semantically you should define it as :

reg signed [15:0] my_reg;

To absolute the value:

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

If you do not need to absolute it but just want to use that number to drive some thing it is valid to just connect signed to an unsigned, ie:

always @* begin
  my_reg_unsigned = my_reg ;
end

This will copy the bit values, my_reg_unsigned can be interpreted as signed using $signed(my_reg_unsigned)

like image 168
Morgan Avatar answered Oct 16 '22 17:10

Morgan