If we have reg [3:0]
we can consider that it can hold integer values 0 to 15.
Now we want to have fractional information, we have to perceptually add fractional bits, but to verilog the number is still an integer.
We still have 4 bits, but we change the binary weighting, instead of 8 4 2 1
to 2 1 0.5 0.25
. but verilog does not know this it is all about how we interpret the bit pattern.
In the question the right hand side of >>
just represents the fractional bit. Also using T
to represent a -1 in the CSD term
2^-1 - 2^-5 - 2^-7 + 2^-10.
Decimal 0.5 - 0.03125 - 0.0078125 + 0.0009765625
Binary 0.1000T0T001
As you have noted shifting a number will result in truncating to an integer. The trick is to add fractional bits to the number before doing this.
For instance to add 10 fractional bits to an incoming integer:
input [9:0] a,
wire [19:0] a_frac = { a, 10'b0};
Remember Verilog thinks this is an integer but we have have to interpret the number differently.
wire [19:0] y = (a_frac>>1) - (a_frac>>5) - (a_frac>>7) + (a_frac>>10);
y
Should now contain something, as you left room for those shifted values. The output will have 10 Integer bits and 10 fractional bits.
To display the number you could scale a real:
$display("%d * 0.46194 = %f", a, y * 2.0**-10);
NB: I would avoid x
as a variable in verilog as x
has a special meaning in verilog, either do not care or an unknown value on a wire.
A quick example on EDA Playground.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…