Course pages 2013–14
Advanced Computer Design
Example FibServer
/***************************************************************************** Examples of Fibonnaci servers for lecture 2 Copyright (c) Simon Moore, January 2010 *****************************************************************************/ import FIFO::*; import GetPut::*; import ClientServer::*; import Vector::*; /*****************************************************************************/ // specialisation of Server interface for Fib typedef Server#(UInt#(width), UInt#(TMul#(width,4))) FibServerT#(numeric type width); module mkFibServer(FibServerT#(width)) provisos (Add#(width,TMul#(width,3),TMul#(width,4))); Reg#(UInt#(TMul#(width,4))) a <- mkRegU; Reg#(UInt#(TMul#(width,4))) b <- mkRegU; Reg#(UInt#(TMul#(width,4))) j <- mkRegU; Reg#(Bool) active <- mkReg(False); FIFO#(UInt#(TMul#(width,4))) result_fifo <- mkLFIFO; rule loop (active && (j>1)); a <= a+b; b <= a; j <= j-1; endrule rule the_end (active && (j==1)); result_fifo.enq(a); active <= False; endrule rule n_is_zero (active && (j==0)); result_fifo.enq(0); active <= False; endrule // new interfaces interface Put request; method Action put(n) if (!active); j <= extend(n); a <= 1; b <= 0; active <= True; endmethod endinterface interface response = toGet(result_fifo); endmodule module mkTestFibServer(Empty); FibServerT#(8) fib <- mkFibServer; Reg#(UInt#(8)) n <- mkReg(0); FIFO#(UInt#(8)) inputs <- mkSizedFIFO(4); rule loop (n<10); n <= n+1; fib.request.put(n); inputs.enq(n); endrule rule display_results; let r <- fib.response.get(); inputs.deq; $display("%05t: result of fib(%1d)=%d", $time, inputs.first, r); endrule endmodule /*****************************************************************************/ function Integer fib_func(Integer n); if(n<2) return n; else return fib_func(n-1)+fib_func(n-2); endfunction module mkTestFibFunc(Empty); rule do_fib; $display("Output fib results on one cycle"); for(Integer n=0; n<10; n=n+1) begin Integer f = fib_func(n); $display("%05t: result of fib(%1d)=%d", $time, n, fromInteger(f)); end $finish(); endrule endmodule /*****************************************************************************/ module mkFibServerROM(FibServerT#(width)) provisos (Add#(width,TMul#(width,3),TMul#(width,4))); Vector#(TExp#(width), Wire#(UInt#(TMul#(width,4)))) rom <- replicateM(mkBypassWire); FIFO#(UInt#(TMul#(width,4))) result_fifo <- mkLFIFO; UInt#(width) index=0; rule init_rom; for(Integer n=0; inLiteralRange(index,n); n=n+1) rom[fromInteger(n)] <= fromInteger(fib_func(n)); endrule interface Put request; method Action put(n); result_fifo.enq(rom[n]); endmethod endinterface interface response = toGet(result_fifo); endmodule module mkTestFibServerROM(Empty); FibServerT#(4) fib <- mkFibServerROM; Reg#(UInt#(4)) n <- mkReg(1); FIFO#(UInt#(4)) inputs <- mkSizedFIFO(4); rule loop (n!=0); n <= n+1; fib.request.put(n); inputs.enq(n); endrule rule display_results; let r <- fib.response.get(); inputs.deq; $display("%05t: result of fib(%2d)=%d", $time, inputs.first, r); endrule endmodule // a synthesizable version if you want to have a look at the Verilog produced (* synthesize *) module mkFibServerROM4(FibServerT#(4)); FibServerT#(4) fibserver <- mkFibServerROM; interface request = fibserver.request; interface response = fibserver.response; endmodule