Bluepsec Examples
Divider Server
Example of a simple iterative divider wrapped in a Server interface (i.e. a Put to start the divide and a Get to consume the result.)
package DividerServer;
import FIFO::*;
import SpecialFIFOs::*;
import GetPut::*;
import ClientServer::*;
typedef struct {
UInt#(width) numerator;
UInt#(width) denominator;
} DivOperandsT#(numeric type width) deriving(Bits);
// define type for the DividerServer interface, specialising the Server interface
typedef Server#(DivOperandsT#(width),Maybe#(UInt#(width)))
DividerServerT#(numeric type width);
module mkDividerServer(DividerServerT#(width))
provisos(Add#(width,width,doublewidth));
Reg#(Int#(doublewidth)) n <- mkRegU; // numerator
Reg#(Int#(doublewidth)) d <- mkRegU; // denominator
Reg#(UInt#(width)) r <- mkRegU; // result
Reg#(UInt#(TAdd#(TLog#(width),1))) ctr <- mkReg(0); // loop counter
FIFO#(Maybe#(UInt#(width))) result_fifo <- mkBypassFIFO; // output fifo
let active = (ctr!=0); // N.B. "active" works a bit like a Verilog wire
rule run(active);
let sub = n-d;
d <= d>>1;
ctr <= ctr-1;
UInt#(width) nextr;
if(sub>=0)
begin
nextr = (r<<1) | 1;
n <= sub;
end
else
nextr = r<<1;
r <= nextr;
if(ctr==1) result_fifo.enq(tagged Valid nextr);
endrule
interface Put request;
method Action put(op) if (!active);
if(op.denominator==0)
result_fifo.enq(Invalid);
else
begin
n <= zeroExtend(unpack(pack(op.numerator)));
d <= zeroExtend(unpack(pack(op.denominator)))<<(valueOf(width)-1);
r <= 0;
ctr <= fromInteger(valueOf(width));
end
endmethod
endinterface
interface response = toGet(result_fifo);
endmodule
endpackage
Link to the DividerServer.bsv source
