This section mainly provides a brief summary of signed numbers in decimal and binary representations, as well as some numeric conversions.
Define data dbin in two's complement format with width DW, and the signed decimal number it represents is ddec.
reg [DW-1:0] dbin ;
1. Converting Signed Decimal Numbers to Two's Complement
The two's complement of a positive number is its original code.
If the decimal number ddec is negative, there are mainly two methods to compute its corresponding two's complement:
Rewrite the sign bit (highest bit) of ddec to 1, then invert and add 1 to the remaining magnitude bits.
For example, the magnitude part of the 4-bit number -6 is 4'b0110; after inverting and adding 1, it becomes 4'b0010; after rewriting the high bit, it becomes 4'b1010.
dbin = {1'b1, ~3'b110 + 3'b1} ; //4'b1010
Add the negative number ddec directly to the maximum numerical range number it represents (some call it the modulus).
For example, the sum of the 4-bit number -6 and 16 (2 to the 4th power) is 10, which corresponds to 4'b1010.
dbin = ddec + (1<<4) ; //4'b1010
2. Converting Two's Complement to Signed Decimal Numbers
When the highest bit of dbin is 0, its magnitude is the positive decimal number it represents.
When the highest bit of dbin is 1, there are mainly two methods to calculate the signed decimal number it represents:
Invert dbin, add 1, and add a sign bit.
For example, the two's complement of the 4-bit number -6 is 4'b1010; after inverting and adding 1, it becomes 4'b0110; after adding a sign bit, it is -6.
ddec = -(~4'b1010 + 1'b1) ; //-6
Directly subtract the maximum numerical range number it represents from the unsigned value represented by dbin.
For example, the two's complement of the 4-bit number -6 is 4'b1010, i.e., the unsigned value is 10; subtracting 16 from 10 gives -6.
ddec = dbin - (1<<4) ; //-6
3. Absolute Value
The logic for finding the absolute value of dbin is as follows:
dbin_abs = (dbin[DW-1]? ~dbin : dbin) + 1'b1 ;
For example, the two's complement of the 4-bit number -6 is 4'b1010; after inverting and adding 1, the value is 4'b0110 (6), which is the absolute value of -6.
But if dbin is positive, the value after adding 1 is 1 greater than its actual absolute value. This step is only to make the number of positive absolute values consistent with that of negative numbers, because at a given bit width, due to the existence of 0, the number of negative numbers representable by signed numbers is one more than the number of positive numbers.
4. Converting Signed Numbers to Unsigned Numbers
The logic for converting a signed number to an unsigned number is as follows:
dbin_unsigned = {!dbin[DW-1], dbin[DW-2:0]) ;
For example:
4'b1010 (-6) -> 4'b0010 (2),4'b0010 (2) -> 4'b1010 (10)
Actually, the conversion principle is to shift the numerical range represented by the data to be above 0. After converting signed numbers to unsigned numbers, the relative differences between data do not change.
5. Extending the Sign Bit
During calculations, the bit width of signed numbers is sometimes extended as needed. Assuming the bit width increment is W, the extension logic is as follows:
dbin_extend = {{(W){dbin[DW-1]}}, dbin} ;
The extension principle is to fill the extended high-order data bits with the highest bit representing the sign bit of the signal.
For example, 4'b1010 (-6) extended to 8 bits is 8'b11111010; the corresponding negative number calculated is still -6.