Bluepsec Examples
Server Farm
Introduction
This is generic package replicates any Server as many times as you like. For example, we could take the FibServer example (or a DividerServer, left as an exercise to the reader) and replicate it twice as illustrated below. This will route the requests to in an alternating (round-robin) manner the two internal FibServer. If the FibServer is iterative, it will take several cycles, so the ServerFarm version with two FibServers will have twice the bandwidth.

Example of ServerFarm instantiating two FibServers
So if the original FibServer was instantiated vis:
FibServerT#(`width) divServ <- mkFibServer;
then the new version with two FibServers is simply:
FibServerT#(`width) fasterDivServ <- mkServerFarm(2,mkFibServer);
This, for me, is an excellent example of how Bluespec allows you to do rapid design exploration.
Notes
- The Server to be replicated is passed in as a higher-order type called mkServer. A vector of mkServers is created using replicateM (monadic replicate).
- The incoming request is enqueued into a BypassFIFO. Exactly one of put_requests rules (generated using a for-loop) will be enabled and can forward the request to corresponding server.
The code
/***************************************************************************** ServerFarm ========== Simon Moore, Oct 2009 Substantial improvements by Matthew Naylor in 2013 Generic module which multiplexes N servers to one server interface. Useful if the base server is quite slow and you want several copies of it. *****************************************************************************/ package ServerFarm; import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import ClientServer::*; import Connectable::*; import List::*; import Assert::*; module mkServerFarm#(Integer numServers, module#(Server#(requestT,responseT)) mkServer) (Server#(requestT,responseT)) provisos(Bits#(requestT,requestTwidth), Bits#(responseT,responseTwidth)); staticAssert(numServers > 1, "ServerFarm: number of servers must be > 1."); staticAssert(numServers < 65, "ServerFarm: number of servers must be < 65."); List#(Server#(requestT,responseT)) servers <- replicateM(numServers, mkServer); Reg#(UInt#(6)) write_server <- mkReg(0); Reg#(UInt#(6)) read_server <- mkReg(0); FIFOF#(requestT) request_fifo <- mkBypassFIFOF; FIFOF#(responseT) response_fifo <- mkBypassFIFOF; function Integer nextServer(Integer n); let next = n+1; return (next>=numServers) ? 0 : next; endfunction for(Integer j=0; j<numServers; j=j+1) begin rule put_requests (write_server == fromInteger(j)); let r = request_fifo.first; request_fifo.deq; servers[j].request.put(r); write_server <= fromInteger(nextServer(j)); endrule rule gather_results (read_server == fromInteger(j)); let result <- servers[j].response.get; response_fifo.enq(result); read_server <= fromInteger(nextServer(j)); endrule end interface Put request = toPut(request_fifo); interface Get response = toGet(response_fifo); endmodule endpackage
Link to the ServerFarm.bsv source