int main(int argc , char ** argv) { // set timer clock_t t1, t2; t1 = clock(); // check files if(argc < 4) { cout << "please input verlog, sdf and pat file" <<endl; return 0; } // ================================================================================ // cell manager contain nangate45 library information(pin name and cell type names) // ================================================================================ Library lib; LibraryParser libp(&lib); if(!libp.read(argv[1])) { cout << "**ERROR main(): LIB parser failed" <<endl; return 0; } // =============================================================================== // use circuit builder to build a circuit // =============================================================================== CircuitBuilder cb; // tell circuit builder to build the circuit using cells in cell manager cb.set(&lib); // tell circuit builder to build the levelized circuit whose clk is set to level 0 cb.set("CK"); // set flip flop functional pins cb.set("Q","QN","D","SI","SE","CK"); // read the circuit if(!cb.read(argv[2])) { cout << "read verlog file fail" <<endl; return 0; } // get the circuit Circuit cir = cb.getCircuit(); // =============================================================================== // use pattern set to read the pattern // =============================================================================== cout << "read pattern" <<endl; PatternSet ps; // tell pattern set to build ppi and pi order according to cell ID in the circuit ps.set(&cir); // read the pattern file if(!ps.setFile(argv[4])) { cout << "read pattern file fail" <<endl; return 0; } ps.readAll(); // =============================================================================== // use circuit simulator to simulate the circuit // =============================================================================== CircuitSimulator cs; // tell which circuit will be simulated cs.set(&cir); // set cell manager to get pin name when simulation cs.set(&lib); // set clk wave of the simulation Wave clkWave; clkWave.initialValue = Wave::L; // set rise transition of clk Transition riseTrans; riseTrans.value = Wave::H; riseTrans.time = 0.0; riseTrans.period = 0.002; riseTrans.prevTransition = NULL; clkWave.addTransition(Wave::H , riseTrans);//0.0 , 0.002, NULL, 0); // set fall transition of clk Transition fallTrans; fallTrans = riseTrans; fallTrans.value = Wave::L; fallTrans.time = 0.25; clkWave.addTransition(Wave::L , fallTrans);//0.25 , 0.002, NULL, 0); cs.set("CK", &clkWave , 1.0); // set pattern pi and ppi order cs.set(&ps.piOrder , &ps.poOrder , &ps.ppiOrder); // =============================================================================== // perform circuit simulation // =============================================================================== cout << "start!" << endl; for(unsigned i = 0 ; i < ps.patterns.size() ; ++i) { // system("clear"); Pattern pat = ps.patterns[i]; cs.initial(pat.pis[0] , pat.ppi); string ppo = cs.getPPO(); if(pat.cycle[0] == Pattern::CAPTURE) cout << "pattern " << i << "\t" <<ppo << endl; else cout << "pattern " << i << "\t" << pat.ppi << endl; } //} t2 = clock(); cout << "total cost: " << (t2-t1)/(double)(CLOCKS_PER_SEC)/12 << " second!" <<endl; ofstream fout; fout.open("time.txt",ios::app); fout << cir.getName() << "," << cir.getNets().size() << "," << ps.patterns.size()<< ","<< (t2-t1)/(double)(CLOCKS_PER_SEC)/12 << endl; return 0; }
void VerifyIdea::setPathMeasurement(bool ideal, SpMaker &sp , const Transition *trans, Circuit &cir) { sp.add("* Measurement"); const vector<Cell> &cells = cir.getCells(); const vector<Net> &nets = cir.getNets(); const Transition *t = trans; while(t) { // get the net of transition int netID = t->netID; // get the net of previous transition int prevNetID = -1; if(t->prevTransition) prevNetID = t->prevTransition->netID; else break;// there are no previous transition anymore // get the cell between above two transition int cellID = nets[netID].ipt_cell_id; string cellName = cells[cellID].name; // get pin name connected the cell and net vector<int>::const_iterator optPinIDIter;// = find(cells[cellID].opt_net_id.begin() , cells[cellID].opt_net_id.end() , netID); for(optPinIDIter = cells[cellID].opt_net_id.begin() ; optPinIDIter != cells[cellID].opt_net_id.end() ; optPinIDIter++) if(*optPinIDIter == netID) break; assert(optPinIDIter != cells[cellID].opt_net_id.end()); int optPinID = optPinIDIter - cells[cellID].opt_net_id.begin(); string optPinName = lib->getFanoutName(cells[cellID].type , optPinID); // get pin name connected the cell and previous net vector<int>::const_iterator iptPinIDIter;// = find(cells[cellID].ipt_net_id.begin() , cells[cellID].ipt_net_id.end() , prevNetID); for(iptPinIDIter = cells[cellID].ipt_net_id.begin() ; iptPinIDIter != cells[cellID].ipt_net_id.end() ; iptPinIDIter++) if(*iptPinIDIter == prevNetID) break; assert(iptPinIDIter != cells[cellID].ipt_net_id.end()); int iptPinID = iptPinIDIter - cells[cellID].ipt_net_id.begin(); string iptPinName = lib->getFaninName(cells[cellID].type , iptPinID); string nodeOptPin = cellName + "_" + optPinName; string nodeIptPin = cellName + "_" + iptPinName; bool optPinRise = t->value == Wave::H; bool iptPinRise = t->prevTransition->value == Wave::H; double averageV = 0.55; sp.setMeasure(nodeIptPin , averageV , iptPinRise , nodeOptPin , averageV , optPinRise , cellName + "_delay"); double vstart = (iptPinRise)?0.33:0.77; double vend = (iptPinRise)?0.77:0.33; sp.setMeasure(nodeIptPin , vstart , iptPinRise , nodeIptPin , vend , iptPinRise , cellName + "_transition"); vstart = (optPinRise)?0.33:0.77; vend = (optPinRise)?0.77:0.33; //.meas TRAN U11_transition TRIG v(U11_A1) VAL=0.77 fall=1 TARG v(U11_A1) VAL=0.33 fall=1 //os << ".meas TRAN " << cellName << "_vh TRIG v(" << nodeOptPin << ") VAL=" << vstart << " fall=" << optPinRise << " TRAG v(" << nodeOptPin << ") VAL=" << vend << " fall=" << optPinRise; //sp.add(os.str()); //sp.setMeasure(nodeOptPin , vstart , optPinRise , nodeOptPin , vend , optPinRise , cellName + "_vh"); t = t->prevTransition; } /*void setMeasure(const std::string &node1 ,double value1, bool rise1, const std::string &node2, double value2, bool rise2 , const std::string& measureName);*/ }
void VerifyIdea::printResult(SpMaker &sp , const Transition *trans, Circuit &cir, Wave *wave) { const vector<Cell> &cells = cir.getCells(); const vector<Net> &nets = cir.getNets(); const Transition *t = trans; cout << "=========================Critical Path=============================" << endl; cout << endl; double pathDelaySpiceIR(0); double extraPathDelayIdea(0); double pathDelaySpice(0); double pathDelayIdea(0); bool lastGate = true; while(t) { // get the net of transition int netID = t->netID; // get the net of previous transition int prevNetID = -1; if(t->prevTransition) prevNetID = t->prevTransition->netID; else break;// there are no previous transition anymore // get the cell between above two transition int cellID = nets[netID].ipt_cell_id; string cellName = cells[cellID].name; double cap = (t->value==Wave::H)?nets[netID].totalRiseCap:nets[netID].totalFallCap; vector<Measurement >measure = sp.getAlterMeasure(cellName + "_delay"); vector<Measurement >measuret = sp.getAlterMeasure(cellName + "_transition"); double spiceDelay = measure[0].gateDelay*1e9; double spiceDelay2 = measure[1].gateDelay*1e9; double gateDelay = t->time - t->prevTransition->time; int transitionID = idea->transitionIDs[t]; double extraGateDelay = idea->extraGateDelays[idea->extraGateDelays.size()/2][transitionID]; double vl = idea->vls[transitionID]; double vh = idea->vhs[transitionID]; cout << "----------------------------------" << endl; cout << "cell name : \t" << cellName << endl; cout << "cell type : \t" << cir.cell_types[cells[cellID].type] << endl; cout << "value : \t" << t->value << endl; cout << "time : \t" << t->time << endl; cout << "spice delay : \t" << measure[0].gateDelay*1e9 <<endl; cout << "spice extra delay: \t" << measure[1].gateDelay*1e9 - measure[0].gateDelay*1e9 <<endl; cout << "spice ir factor : \t" << (measure[1].gateDelay*1e9 - measure[0].gateDelay*1e9)/measure[0].gateDelay*1e-9<<endl; cout << "library delay : \t" << gateDelay << " " << gateDelay/spiceDelay << " " << gateDelay/spiceDelay2<< endl; cout << "idea extra delay : \t" << extraGateDelay << endl; cout << "idea ir factor : \t" << extraGateDelay/gateDelay << endl; cout << "vdd, gnd : \t" << vh << " " << vl << endl; cout << "real transition: : \t" << measuret[0].gateDelay*1e9 <<" " << measuret[1].gateDelay*1e9 << endl; cout << "idea ipt transition : \t" << t->prevTransition->period << endl; cout << "idea opt cap : \t" << cap << endl; if(lastGate){ pathDelaySpiceIR = measure[1].endTime; pathDelaySpice = measure[0].endTime; pathDelayIdea = t->time; lastGate = false; } extraPathDelayIdea += extraGateDelay; t = t->prevTransition; } cout << "path delay spice : " << pathDelaySpice << endl; cout << "path delay spice IR: " << pathDelaySpiceIR << endl; cout << "path delay idea : " << pathDelayIdea << endl; cout << "path delay idea IR : " << pathDelayIdea + extraPathDelayIdea << endl; cout << "error : " << (pathDelayIdea - pathDelaySpice*1e9)/pathDelaySpice<<endl; cout << "extra error: " << (extraPathDelayIdea - (pathDelaySpiceIR - pathDelaySpice)*1e9)/(pathDelaySpiceIR - pathDelaySpice)/1e9<<endl; cout << "portion : " << (pathDelaySpiceIR - pathDelaySpice) / pathDelaySpiceIR<<endl; }
void VerifyIdea::singleVerify(Circuit &cir, Wave *waves, pgNs::PowerGrid &pg, const Transition *trans, VERIFY_TYPE type) { std::string fileName = "../../spCombine/circuit/" + cir.getName() + ".sp"; std::ifstream fin(fileName.c_str()); if(!fin) { std::cout << "**ERROR VerifyIdea::verify: Can't find file " << fileName << std::endl; return; } string spFileName = "./verify/test.sp"; SpMaker sp(spFileName); std::string line; while(std::getline(fin , line)) { //cout << line << endl; sp.add( line ); if(line == "* INPUT") break; } /* V1 G0 0 PWL(0ns 0v 2ns 0v 2.001ns 1.1v 4ns 1.1v) V2 G1 0 PWL(0ns 0v 2ns 0v 2.001ns 1.1v 4ns 1.1v) V3 G2 0 PWL(0ns 1.1v 2ns 1.1v 2.001ns 0v 4ns 0v) V4 G3 0 PWL(0ns 1.1v 2ns 1.1v 2.001ns 0v 4ns 0v) V5 test_se 0 0v V6 test_si 0 1.1v*/ // setup voltage source for(unsigned i = 0 ; i < pg.vddNodes.size() ; ++i){ string nodeName(pg.getNodes()[pg.vddNodes[i]].getName()); size_t found = nodeName.find("."); assert(found != string::npos); nodeName[found] = '_'; sp.add("VDDSOURCE " + nodeName + " 0 1.1v"); } for(unsigned i = 0 ; i < pg.gndNodes.size() ; ++i){ string nodeName(pg.getNodes()[pg.gndNodes[i]].getName()); size_t found = nodeName.find("."); assert(found != string::npos); nodeName[found] = '_'; sp.add("VSSSOURCE " + nodeName + " 0 0v"); } // setup PPI const vector<Cell> &cells = cir.getCells(); const vector<Net> &nets = cir.getNets(); string ffstring = "* flip-flop switch"; sp.add( ffstring ); int qPin = lib->getFanoutIndex(cells[cir.ff[0]].type, "Q"); int qnPin = lib->getFanoutIndex(cells[cir.ff[0]].type, "QN"); for(unsigned i = 0 ; i < cir.ff.size() ; ++i) { int cellID = cir.ff[i]; // print Q int netQ = cells[cellID].opt_net_id[qPin]; if(netQ != -1){ // string line = printNet(cells[cellID].name + "_Q" ,waves[netQ]); string qNode = cells[cellID].name + "_Q"; double val = (waves[netQ].initialValue == Wave::H)?pg.getSupplyVoltage():0; stringstream ss; ss << val; sp.add(".ic v("+qNode+")="+ss.str()); if(val != 0){ sp.add(".ic v(X"+cells[cellID].name+"."+"N_8_M8_s"+")=1.1v"); sp.add(".ic v(X"+cells[cellID].name+"."+"n_5_m20_g"+")=1.1v"); }else { sp.add(".ic v(X"+cells[cellID].name+"."+"N_8_M8_s"+")=0v"); sp.add(".ic v(X"+cells[cellID].name+"."+"n_5_m20_g"+")=0v"); } } // print QN int netQN = cells[cellID].opt_net_id[qnPin]; if(netQN != -1){ //string line = printNet(cells[cellID].name + "_QN",waves[netQN]) ; //sp.add( line); string qNode = cells[cellID].name + "_QN"; double val = (waves[netQN].initialValue == Wave::H)?pg.getSupplyVoltage():0; stringstream ss; ss << val; sp.add(".ic v("+qNode+")="+ss.str()); } } sp.add("* PI switch"); // setup PI for(unsigned i = 0 ; i < cir.pi.size() ; ++i) { int netID = cir.pi[i]; string line = printNet(nets[netID].name,waves[netID]); sp.add( line ); } if(trans == NULL) { spicePathDelay.push_back(0); spicePathDelayIR.push_back(0); ideaPathDelay.push_back(0); ideaPathDelayIR.push_back(0); } // setup measurement setPathMeasurement(true, sp, trans, cir); while(std::getline(fin,line)) { if(line == ".END") setPathMeasurement(false, sp, trans, cir); sp.add( line ); } if(type == HSPICE) sp.spiceSim(); else sp.nanoSim(); printResult(sp, trans, cir, waves); }