/***************************************************************************** Testbench for Divider Server ============================ Simon Moore, Oct 2009 *****************************************************************************/ import DividerServer::*; import FIFO::*; import GetPut::*; import ClientServer::*; import ServerFarm::*; `define width 8 `define debuglevel 0 `define maxtestdata 70000 module mkTestDividerServer(Empty); Reg#(DivOperandsT#(`width)) operands <- mkReg(unpack(0)); Reg#(Bool) passed <- mkReg(True); Reg#(Maybe#(Bit#(64))) lasttime <- mkReg(tagged Invalid); Reg#(Bit#(64)) result_rate <- mkReg(0); Reg#(Bit#(64)) result_latency <- mkReg(0); Reg#(Bit#(64)) result_max_latency <- mkReg(0); Reg#(Bit#(64)) result_number <- mkReg(0); Server#(DivOperandsT#(`width),Maybe#(UInt#(`width))) divServ <- mkServerFarm8(mkDividerServer); //mkDividerPureServer; FIFO#(Tuple3#(UInt#(`width),UInt#(`width),Bit#(64))) ndt_fifo <- mkSizedFIFO(16); // sized for max pipeline depth let finished = result_number > (256*255); rule push_test_data(!finished); let t <- $time; divServ.request.put(operands); ndt_fifo.enq(tuple3(operands.numerator,operands.denominator,t)); if(`debuglevel>0) $display("%05d: put %d/%d",t,operands.numerator,operands.denominator); DivOperandsT#(`width) next_operands = unpack(pack(operands)+1); if(next_operands.denominator==0) operands <= unpack(pack(next_operands)+1); else operands <= next_operands; endrule rule collect_results(!finished); let r <- divServ.response.get; let ndt = ndt_fifo.first; let n = tpl_1(ndt); let d = tpl_2(ndt); let request_time = tpl_3(ndt); ndt_fifo.deq; let check = n/((d==0) ? 1:d); let failed = ((d==0) ? isValid(r) : (fromMaybe(0,r)!=check)); let t <- $time; lasttime <= tagged Valid t; if(isValid(lasttime)) begin result_rate <= result_rate+(t-fromMaybe(0,lasttime)); let latency = (t-request_time); result_latency <= result_latency+latency; if(latency>result_max_latency) result_max_latency <= latency; result_number <= result_number+1; end if((`debuglevel>0) || failed) begin if(failed) $write("FAILED: "); if(isValid(r)) $display("%05d: result: %1d/%1d = %1d check = %1d", $time,n,d,fromMaybe(0,r),check); else $display("%05d: result: %1d/%1d = Error",$time,n,d); end passed <= passed && !failed; endrule rule the_end(finished); // calculate rate and latency (N.B. each clock cycle is 10 simulation ticks) let rate10 = (result_rate)/result_number; let latency10 = (result_latency)/result_number; $write("Finished (%1d tests) - ",result_number); if(passed) $display("Passed"); else $display("FAILED"); $display("cycles between results = %1d.%1d cycles latency between input and output = %1d.%1d cycles max = %1d",rate10/10,rate10%10,latency10/10,latency10%10,result_max_latency/10); $finish(); endrule endmodule