Stmt FSMMotivationTesting the IP Lookup DesignTesting IP LookupBut we usually want more counters, display, ...Writing a Testbench (Case 1)A more complicated Case: Initializing memoryInitialize a memory with a 2-D patternAn imperative viewFrom Action Lists to FSMsThe Stmt SublanguageTranslation Example: Seq to FSMParallel TasksStart ref and dut at the same timeWhat exactly is the translation?Base Case: Primitive Action: aSequential List - seqImplementation - parImplementation - ifImplementation - whileThe StmtFSM libraryFSM atomicityFSM AtomicityFSM summaryMarch 10, 2010L11-1http://csg.csail.mit.edu/6.375Stmt FSMArvind (with the help of Nirav Dave) Computer Science & Artificial Intelligence LabMassachusetts Institute of TechnologyMotivationSome common design patterns are tedious to express in BSVTestbenchsSequential machines (FSMs)especially sequential looping structuresThese are tedious to express in Verilog as well (but not in C)March 10, 2010L11-2http://csg.csail.mit.edu/6.375Testing the IP Lookup DesignInput: IP AddressOutput: Route ValueNeed to test many different input/output sequencesdone?done?RAMfifoenteroutQcbufyesnogetTokenMarch 10, 2010L11-3http://csg.csail.mit.edu/6.375Testing IP LookupCall many streams of requests responses from the device under test (DUT)Case 1dut.enter(17.23.12.225)dut.getResult()dut.enter(17.23.12.25)dut.getResult()Case 2dut.enter(128.30.90.124)dut.enter(128.30.90.126)dut.getResult()dut.getResult()Check correct with 1 request at a timeCheck correct with 2 concurrent requestsMarch 10, 2010L11-4http://csg.csail.mit.edu/6.375But we usually want morecounters, display, ...function Action makeReq(x); action reqCnt <= reqCnt + 1; dut.enter(x); $display(“[Req #: ”,fshow(reqCnt),“] = ”,fshow(x)); endactionendfunctionfunction Action getResp(); action resCnt <= resCnt + 1; let x <- dut.getResult(); $display(“[Rsp #:”,fshow(resCnt),“] = ”,fshow(x)); endactionendfunction March 10, 2010L11-5http://csg.csail.mit.edu/6.375Writing a Testbench (Case 1)rule step0(pos==0); makeReq(17.23.12.225); pos <= 1;endrulerule step1(pos==1); getResp(); pos <= 2;endrulerule step2(pos==2); makeReq(17.23.12.25); pos <= 3;endrulerule step3(pos==3); getResp(); pos <= 4;endrulerule finish(pos==4); $finish;endruleA lot of text!Wait until response is readyHow should we do it for a sequence of 100 actions?March 10, 2010L11-6http://csg.csail.mit.edu/6.375A more complicated Case: Initializing memoryf(i)nIiaddr0int i; Addr addr=addr0;bool done = False;for(i=0; i<nI; i++){ mem.write(addr++,f(i));}done = True;CNeed an FSM in HW as memory can only do one write per cycleReg#(int) i <-mkReg(0);Reg#(Addr) addr <-mkReg(addr0);Reg#(Bool) done <-mkReg(False);rule initialize (i < nI); mem.write (addr, f(i)); addr <= addr + 1; i <= i + 1; if (i+1 == nI) done<=True;endruleBSVMarch 10, 2010L11-7http://csg.csail.mit.edu/6.375Initialize a memory with a 2-D patternReg#(int) i <-mkReg(0);Reg#(int) j <-mkReg(0);Reg#(Addr) addr <-mkReg(addr0);Reg#(Bool) done <-mkReg(False);rule loop ((i < nI) && (j < nJ)); mem.write (addr, f(i,j)); addr <= addr + 1; if (j < nJ-1) j <= j + 1; else begin j <= 0; if (i < nI-1) i <= i + 1; else done <= True; endendrulef(i,j)nJnIijaddr0Bluespec code gets messier as compared to C even with small changes in C, e.g.,initialization based on old memory valuesinitialization has to be done more than onceShall we do triply-nested loops?March 10, 2010L11-8http://csg.csail.mit.edu/6.375An imperative viewvoid doTest(){ makeReq(17.23.12.225); getResp(); makeReq(17.23.12.25); getResp(); exit(0);}seq makeReq(17.23.12.225); getResp(); makeReq(17.23.12.25); getResp(); $finish();endseq; It is easy to write a sequence in C Writing this in rules is tedious:Can we just write the actions and have the compiler make the rules?March 10, 2010L11-9http://csg.csail.mit.edu/6.375From Action Lists to FSMsFSM interfaceCreating an FSMinterface FSM; method Action start(); method Bool done();endinterfacemodule mkFSM#(Stmt s)(FSM);donestartMarch 10, 2010L11-10http://csg.csail.mit.edu/6.375The Stmt SublanguageStmt = <Bluespec Action>| seq s1..sN endseq | par s1..sN endpar| if-then / if-then-else| for-, while-, repeat(n)-(w/ break and continues)BSV ActionSequence of StmtList of Parallel StmtsConditional StmtsLoop StmtsMarch 10, 2010L11-11http://csg.csail.mit.edu/6.375Translation Example: Seq to FSMStmt s = seq makeReq(17.23.12.225); getResp(); makeReq(17.23.12.25); getResp(); $finish();endseq;FSM f <- mkFSM(s);module mkFSM_s(FSM) Reg#(Bit#(3)) pos <- mkReg(0); rule step1(pos==1); makeReq(17.23.12.225); pos <= 2; endrule rule step2(pos==2); getResp(); pos <= 3; endrule rule step3(pos==3); makeReq(17.23.12.25); pos <= 4; endrule rule step4(pos==4); getResp(); pos <= 5; endrule rule step5(pos==5); $finish; pos <= 0; endrule method Action start() if(pos==0); pos <= 1; endmethod method Bool done() return (pos == 0); endmethodendmoduleMarch 10, 2010L11-12http://csg.csail.mit.edu/6.375Parallel Tasksseq refReq(x); refRes(rReg); dutReq(x); dutRes(dReg); checkMatch(rReg,dReg);endseqWe want to check dut and ref have same result Do each, then check resultsBut it doesn’t matter that ref finishes before dut starts…March 10, 2010L11-13http://csg.csail.mit.edu/6.375Start ref and dut at the same timeSeq. for each implementationStart togetherBoth run at own rate Wait until both are doneseq par seq refReq(x); refRes(refv);endseq seq dutReq(x);dutRes(dutv); endseq endpar checkMatch(refv,dutv);endseqMarch 10, 2010L11-14http://csg.csail.mit.edu/6.375What exactly is the translation?The Stmt sublanguage is clearer for the designer; but, what FSM do we get?Let’s examine each Stmt Construction case and see how it can be implementedMarch 10, 2010L11-15http://csg.csail.mit.edu/6.375Base Case: Primitive Action: aReg#(Bool) doneR <- mkReg(True);rule dowork(!doneR); a; doneR <= True;endrulemethod Action start() if (doneR); doneR <= False;endmethodmethod Bool done(); return doneR; endmethodMarch 10, 2010L11-16http://csg.csail.mit.edu/6.375Sequential List - seq seq s1...sN endseq: sequential compositionReg#(int) s <-mkReg(0);FSM s1 <- mkFSM (s1); … ; FSM sN <- mkFSM (sN); Bool flag = rule one (s==1); s1.start(); s <= 2; endrulerule two (s==2&& s1.done()); s2.start(); s <= 3; endrule…rule n (s==n && sN-1.done()); sN.start(); s <= 0; endrulemethod Action
View Full Document