Пример #1
0
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;
}
Пример #2
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);*/
}
Пример #3
0
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;
}
Пример #4
0
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);
}