
bluespec.com Bluespec Forums

View previous topic :: View next topic 
Author 
Message 
flashdisk
Joined: 29 May 2012 Posts: 56

Posted: Sun Nov 11, 2012 3:44 pm Post subject: bsv floating point processor 


hey, I am working on building floating point processor in bsv ,but I have some troubles that I could not solve so please I need your help to fix them here is my code:
testbench:
Code: 
(* synthesize *)
module mkTbPmult3();
Ifc_Pmult3 ifc_pmult3 < mkPmult3;
Ifc_Pdiv3 ifc_pdiv3 < mkPdiv3;
Reg#(Bit#(16)) state < mkReg(0);
rule step0(state == 0);
Bit#(10) x = 'b10000;
Bit#(10) y = 'b11000;
ifc_pmult3.mult1(x,y);
//
ifc_pdiv3.div1(x,y);
//
state <= 1;
endrule
rule step1(state == 1);
Bit#(4) exp1= 'b10;
Bit#(4) exp2= 'b10;
$display("Result is %b", ifc_pmult3.mult2);
$display("The final exp is %b", ifc_pmult3.exp(exp1, exp2));
//////////
$display("Result is %b", ifc_pdiv3.div2);
/////////////
$finish;
endrule
endmodule

the first problem: I need to get 2 numbers
Code: 
Bit#(10) x = 'b10000;
Bit#(10) y = 'b11000;

but I get them as Bits but I need the function that takes to save them as registers not as Bits as in the interface method Code:  ifc_pdiv3.div1(x,y);  here is the code of the interfaces that I had defined:
Code: 
interface Ifc_Pdiv3;
method Action div1(Bit#(10) x, Bit#(10) y);
method Bit#(70) div2();
method Bit#(4) exp(Bit#(4) exp1, Bit#(4) exp2);
endinterface
(* synthesize *)
module mkPdiv3(Ifc_Pdiv3);
Reg#(Bit#(70)) result<mkReg(0);
////////////////////////////////////////////////////////////
method Action div1(Bit#(10) x, Bit#(10) y);
Bit#(70) mi='b10000;
Bit#(70) cons='b100;
for(int i=1;i<7;i=i+1)
begin
Bit#(70) y_mi=(extend(y)<<4*(i1))*((mi));
Bit#(70) y_mi_2=(y_mi>>(3+(i1)*4))>>1;
cons= cons<<4;
Bit#(70) y_mi_mi=(cons)  y_mi_2;
Bit#(70) y_mi_mi_2=y_mi_mi*(mi<<4);
Bit#(70) new_mi=y_mi_mi_2>>(5+(i1)*4);
mi=new_mi;
end
Bit#(70) x_2=extend(x)<<24;
result<= (mi*x_2);
endmethod
////////////////////////////////////////////////////////////
method Bit#(70) div2();
return result;
endmethod
////////////////////////////////////////////////////////////

as you see above the method of the interface takes them as Bits I need it to take them as rigesters but in the testbench I create the 2 numbers as Bits
the second problem:
in the method Code:  method Action div1(Bit#(10) x, Bit#(10) y); 
here I have used an algorithm to calculate the mantissa of the answer of x/y but how can I implement the method by rules instead the way it is implemented above.
the third problem:
if I want to sensitize the code I will get 6 or 7 multiplication units instead of one it means that after every iteration of the loop
Code:  for(int i=1;i<7;i=i+1)  I will get variable called mi as it appears above, Code:  Bit#(70) mi='b10000;  (this is the first value in it),and the variable value I need to send back to the method to continue the next iteration using the value calculated in the previous and so on until the finish of the loop to get the final mi in the way that I have done the mi variable each iteration is taken to another multiplication unit and after that to another one until we finish the loop above but this way of implementation is too expensive!
thanks for any helper 

Back to top 


flashdisk
Joined: 29 May 2012 Posts: 56

Posted: Mon Nov 12, 2012 11:25 am Post subject: 


please anybody I need help to do this please! 

Back to top 


hadar_agam
Joined: 10 May 2007 Posts: 38

Posted: Mon Nov 12, 2012 2:32 pm Post subject: 


Hi flashdisk,
I'm not sure I fully understand your questions, but here is an attempt at some answers:
1. Are you trying to register the two inputs to mkPdiv3 (x and y) inside the module?
If so  you should instantiate two registers, and have the method div1 just register the values. The calculation of the "result" register will then be done in a rule context (and not an action method). Something like this:
Code:  module mkPdiv3(Ifc_Pdiv3);
Reg#(Bit#(70)) result<mkReg(0);
Reg#(Bit#(10)) rX < mkReg(0);
Reg#(Bit#(10)) rY < mkReg(0);
////////////////////////////////////////////////////////////
rule calc_result;
Bit#(70) mi='b10000;
Bit#(70) cons='b100;
for(int i=1;i<7;i=i+1)
begin
Bit#(70) y_mi=(extend(rY)<<4*(i1))*((mi));
Bit#(70) y_mi_2=(y_mi>>(3+(i1)*4))>>1;
cons= cons<<4;
Bit#(70) y_mi_mi=(cons)  y_mi_2;
Bit#(70) y_mi_mi_2=y_mi_mi*(mi<<4);
Bit#(70) new_mi=y_mi_mi_2>>(5+(i1)*4);
mi=new_mi;
end
Bit#(70) x_2=extend(rX)<<24;
result<= (mi*x_2);
endrule
////////////////////////////////////////////////////////////
method Bit#(70) div2();
return result;
endmethod
method Action div1(Bit#(10) x, Bit#(10) y);
rX <= x;
rY <= y;
endmethod

2. see answer for (1)  the action method only registers the two inputs; the internal behavior is described by a rule.
3. Basically, when you write such an expression in a for loop, you are only describing a combinational circuit. X and Y are simple variables and not registers; the bsv compiler does not assume or instantiate any state for you (such as flipflops, registers, fifos or any other submodules), so you get one big cloud of logic in your case.
I suggest you browse through the BSV By Example book (available for download in the product documentation part of this forum: http://www.bluespec.com/forum/viewtopic.php?t=2). If you look at section 4.2 you will find a good example of elaborating a combinational circuit.
If you want to do it differently  you can instantiate several registers for the intermediate mi values, and have a rule calculate the different values.
You might want to consider a vector of registers:
Vector#(7, Reg#(Bit#(70))) m < replicateM(mkReg(0));
This will create a static pipeline for you, and it will take several clock cycles to view a valid result in the result register.
You might want to consider a dynamic pipeline, where you have fifos holding the intermediate values of mi, and seperate rules to calculate each stage of the pipeline. There is a good discussion of static pipelines vs. dynamic pipelines in the pipeline lab which we offer:
http://www.bluespec.com/forum/viewtopic.php?t=6&highlight=pipeline
And your choice would depend on your design needs.
Hopefully this helps  good luck! 

Back to top 


flashdisk
Joined: 29 May 2012 Posts: 56

Posted: Mon Nov 12, 2012 6:24 pm Post subject: 


first of all let me say thank you very much hadar_agam for your answer, it was excellent but I have some uncleared answers:
you said to consider a vector of registers to the intermediate values of the mivariable in this way of implementation do I guarantee that the combinational circuit that I have made will use only one multiplication unit that means that the combinational logic is connected to a register and after a clock cycle the intermediate value of mi in the register will be sent back to the combinational logic and so on untill the completion of the for loop.
secondly, if I am using a vector register to save the intermediate values the I need to separate the rule to more rules because the value in the register will not be available untill the next clock cycle to use it to the next state of computation,moreover if I do that and separate the rule to more rules will it make the combinational circuit between each 2 registers small and make the clock cycle time shorter?
I have another question when is the rule you had defined is called to do the calculations,what you have done is to get the values of x and y and to register them but after that I can not see when the main rule is called to do the math.
thansk for your collaboration 

Back to top 


flashdisk
Joined: 29 May 2012 Posts: 56

Posted: Wed Nov 14, 2012 4:34 am Post subject: 


please I need answers to those questions! 

Back to top 




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 You can download files in this forum

Powered by phpBB © 2001, 2005 phpBB Group
