Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

verilog - how can I apply fixed fraction to the integer

I'd like to multiply to integer with modified fraction as following

(Multiplication by power series summation with negative terms)

I have done what to find the method the fraction convert to CSD form. But I want to know how can I apply to multiply to integer.

For example, I got this

0.46194 = 2^-1 - 2^-5 - 2^-7 + 2^-10.

then I can get like this as verilog rtl expression :

y= (x>>1) - (x>>5) - (x>>7) + (x>>10);

But the problem is that what if I got the input value is 3, then how can I calculate above code?

y= (3>>1) - (3>>5) - (3>>7) + (3>>10);

But As i know, It does impossible calculate. because 3>>1 is 1, (3>>5) is 0, (3>>7) is 0, (3>>10) is 0;

So I can't get the normal result. Also the reason of finding the modified fraction expression has gone away. Then this posting's question point is "how can I apply the modified fraction to the integer".

UPDATE : This should be like this. y= ((3<<1024)>>1) - ((3<<1024)>>5) - ((3<<1024)>>7) + ((3<<1024)>>10);

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...