View previous topic :: View next topic 
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*(2B*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.
thanks in advance 

Back to top 


quark Site Admin
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/learningbluespec/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;
}



Back to top 


quark Site Admin
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;



Back to top 


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 XY the two numbers should have the same number of bits is not that right ? 

Back to top 


quark Site Admin
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*(2e) = 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 forloop with a recursive function.
There are still a couple ways to write it that preserve the forloop:
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 forloop 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. 

Back to top 


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 0s does it add to X?
does it add 0s to the left of X?
for example :
X=10101 >extend(X)>00010101
thanks. 

Back to top 


quark Site Admin
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/referenceguide.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 } ;



Back to top 


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! 

Back to top 


hadar_agam
Joined: 10 May 2007 Posts: 38

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


Note that you can precalculate 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. 

Back to top 


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] 

Back to top 


