bluespec.com
Bluespec Forums

Author Message
flashdisk

Joined: 29 May 2012
Posts: 56

Posted: Mon Aug 13, 2012 5:15 am    Post subject: building bsv function

hello,

I need to build a function in bsv that does the following :
 Code: for(i=0;i<6;i++) { A = A*(2-B*A*0.5); }

A and B are Bits type and each one is 5 bits so the multiplication needs to be 10 Bits ,in addition how can I do the subtraction, plus I need to save 2 bits after each multiplication lets say A*B is 10 bits so we save 5+2=7 bits after the first multiplication after that the result *(0.5) no need to save here!
after that we do 2-(the result)
the last thing to do is to multiply OLD A with the result we got and save to A and to do the loop again up to 6 iterations.
quark

Joined: 02 Nov 2007
Posts: 500

Posted: Mon Aug 13, 2012 1:08 pm    Post subject: Re: building bsv function

It might help to look at some of the Bluespec training material, available online: https://sites.google.com/a/bluespec.com/learning-bluespec/Home
There are a lot of links, and they're not in any order of usefulness, so let me point you specifically to the document "BSV By Example", which is under the "BSV Documentation" link at the bottom: http://www.bluespec.com/forum/download.php?id=161
The document is divided by concepts, so even if you don't have time to read it through, you can search for specific things that you need examples for.

In this example, you'd write it like you might in Verilog. Here's an example where I explicitly keep track of most sizes, to make it clearer:
 Code: for(i=0;i<6;i++) {   Bit#(7) b_a = truncate(B * A);   Bit#(9) b_a_a = truncate(b_a * A);   Bit#(8) half_b_a_a = b_a_a >> 1;   Bit#(8) two_A = A << 1;   Bit#(5) new_a = truncate(two_a - half_b_a_a);   A = new_a; }
quark

Joined: 02 Nov 2007
Posts: 500

Posted: Mon Aug 13, 2012 1:29 pm    Post subject: Re: building bsv function

I apologize, there were a couple mistakes in that last post. Some vectors needed to be extended to appropriate sizes. Some are necessary because I'm using the default multiply operator, where I could have used "unsignedMul" as mentioned in a previous forum post.
 Code: for(i=0;i<6;i++) {   Bit#(7) b_a = extend(B) * extend(A);   Bit#(9) b_a_a = extend(b_a) * extend(A);   Bit#(8) half_b_a_a = truncate(b_a_a >> 1);   Bit#(8) two_a = extend(A) << 1;   Bit#(5) new_a = truncate(two_a - half_b_a_a);   A = new_a; }

Also note that the extending and truncating only matters if you want specific sizes at each step. If you extend A and B to the maximum number of bits, then you can do all arithmetic at that size and truncate at the end:
 Code: Bit#(9) b_a = extend(B) * extend(A);   Bit#(9) b_a_a = b_a * extend(A);   Bit#(9) half_b_a_a = b_a_a >> 1;   Bit#(9) two_a = extend(A) << 1;   Bit#(5) new_a = truncate(two_a - half_b_a_a);

which could be written as:
 Code: Bit#(9) eA = extend(a);   Bit#(9) eB = extend(b);   A = truncate((eA << 1) - ((eB * eA * eA) >> 1));

Also, I don't know if my choice of implementation was correct. You might want to save the multiplication by 0.5 for last:
 Code: Bit#(9) sub_res = (eA << 2) - (eB * eA * eA); Bit#(9) final_res = sub_res >> 1;
flashdisk

Joined: 29 May 2012
Posts: 56

 Posted: Mon Aug 13, 2012 1:35 pm    Post subject: thanks a lot,but I did not understand how did you do the "2-" the subtraction and the number of bits I save in every loop is not constant what you have done is working for the first loop when i=0 but when i=1 for example the first line which is A*B should save different size not #Bits(7) how can I do that? plus when I do the "2-" the number two must have the same bits size as of A*B*0.5 otherwise it would not work because when you do X-Y the two numbers should have the same number of bits is not that right ?
quark

Joined: 02 Nov 2007
Posts: 500

 Posted: Mon Aug 13, 2012 2:31 pm    Post subject: I handled the subtraction by rewriting the expression with an equivalent expression: A*(2-e) = A*2 - A*e. If I understand correctly now, the important issue is that the size of the result increases on each iteration of the loop? That is indeed a tricky topic. It was recently discussed in another forum thread, so have a look at the answers there: http://bluespec.com/forum/viewtopic.php?t=336 Although the advice in that thread might be more applicable if you replace the for-loop with a recursive function. There are still a couple ways to write it that preserve the for-loop: One option is to extend the inputs to the maximum size and do all operations in all loops at that size; the synthesis tools later on might remove the unnecessary bits. Another option is to have a vector of return results, all of the maximum size, but each iteration of the for-loop extracts only the size it needs, and writes the result to the vector (padding it as necessary). The Vector will contain the max size during compilation, but the resulting RTL should only refer to the bits that are actually used.
flashdisk

Joined: 29 May 2012
Posts: 56

 Posted: Mon Aug 13, 2012 3:10 pm    Post subject: I think that extending the inputs to the maximum size and do all operations in all loops at that size is a better and easier solution do you think so? moreover what does extend(X) do? how many 0-s does it add to X? does it add 0-s to the left of X? for example : X=10101 ->extend(X)->00010101 thanks.
quark

Joined: 02 Nov 2007
Posts: 500

Posted: Mon Aug 13, 2012 3:25 pm    Post subject:

The answers to these questions are found in the BSV Reference Guide, which should be available at \${BLUESPECDIR}/../doc/BSV/reference-guide.pdf
If you search for "extend" or look it up in the index, you'll see that it's defined in section B.1.11.

You can also check the behavior of any code by writing a small example and seeing what RTL is generated. For instance, this example:
 Code: (* synthesize *) module mkTest();    Reg#(Bit#(5)) rg1 <- mkRegU;    Reg#(Bit#(10)) rg2 <- mkRegU;    rule r;       rg2 <= extend(rg1);    endrule endmodule

Will generate Verilog containing this statement:
 Code: assign rg2\$D_IN = { 5'd0, rg1 } ;
flashdisk

Joined: 29 May 2012
Posts: 56

Posted: Mon Aug 13, 2012 4:00 pm    Post subject:

I still have a problem ! in the code you gave me lets say that the maximum number of bits I need is 20 and A and B are 5 bits at the beginning so the code would be:
 Code: for(i=0;i<6;i++) {   Bit#(20) b_a = extend(B) * extend(A);   Bit#(20) b_a_a = b_a * extend(A);   Bit#(20) half_b_a_a = b_a_a >> 1;   Bit#(20) two_a = extend(A) << 1;   Bit#(5) new_a = truncate(two_a - half_b_a_a); }

when the first line is done the result would be consisting of maximum 10 bits
but I need 2 bits to save after each multiplication that means 7 and I do not need the precise answer which is 10 bits ,so in the second line I multiply the 10 bits I got from above by A which is also 5 bits and after the multiplication I save 9 bits not the maximum 15 bits at the last line I save the bits I got in A and start over in the loop but this time I multiply B which is 5 bits always with A we have got from the last iteration which is 9 bits and now we can get answer with maximum 5+9=14 bits but we save 11 bits and so on until we finish 6 iterations does the code you have provided me supports that? I think it save the number after multiplication!

Joined: 10 May 2007
Posts: 38

Posted: Tue Aug 14, 2012 12:23 pm    Post subject:

Note that you can pre-calculate the maximum size for your bit vector, and always just select the desired bits to be assigned to it. Something like this:

 Code: for(i=0;i<6;i++) {   Bit#(20) b_a = extend(B) * extend(A);   Bit#(20) b_a_a = b_a * extend(A);   Bit#(20) half_b_a_a = b_a_a >> 1;   Bit#(20) two_a = extend(A) << 1;   Bit#(MAX_SIZE) new_a = (two_a - half_b_a_a)[2*i+6:0]; }

Is this what you are trying to achieve?

Otherwise - it might be helpful to get some context.
flashdisk

Joined: 29 May 2012
Posts: 56

 Posted: Tue Aug 14, 2012 5:32 pm    Post subject: I think what you did is good,but I need to do this after each multiplication strating from the first line after the for statement that means : after the first multiplication I need to save 2 bits for example a=11111 ->5 bits b=11111 ->5 bits c=a*b=1111111111 ->10 bits but, I save only 2 bits not the whole 10 bits which means: c=a*b=0001111111 ->only 7 bits saved now, I do c multiply another number but not saving the whole number instead of that I save now 9 bits . that means every multiply operation the saved bits are BASE+2*i where i is representing the multiplication counter for example: BASE=5 after the first multiplication we save 5+2 after the second multiplication we save 5+2+2 after the third multiplication we save 5+2+2 and all of them happens in iteration and continuing to the next iteration until we finish the 6 iterations.[/u]
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 4 Hours Page 1 of 1

 Jump to: Select a forum Announcements----------------Announcements Downloads----------------Bluespec SystemVerilog (BSV) Documents, Examples and Technical White PapersSoftware Releases Bluespec SystemVerilog----------------Designing with BSV's Rules, Interfaces, ...Tools: BSC (Bluespec Compiler)Tools: BluesimTools: OtherContributed tidbits General----------------Non-technical discussions and questions
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum