// Example function that uses VerilogParser class to parse the given ISPD-13 verilog // file. The extracted data is simply printed out in this example. void test_verilog_parser (string filename,string format) { set<std::string> piset; // all the pis are added to this set set<std::string> poset;// all the pos are added to this set set<std::string> wireset;// all the wires are added to this set set<std::string>::iterator myit;// this is an iterator that iterates through the set can be used for piset,poset or wireset map<int,std::string> mymap;// a map where number is the key and value is the component either pi,po or the cell set<std::string> clkset;// added on 15th july to treat clocks screws up slack estimation map<std::string,int> mymap2;//a map where the component is the key and value is the number map<int,std::string>::iterator mapit;// an iterator that iterates through the map map<int,std::string>::iterator mapit2;// a second iterator that iterates through the map used for file writes map<int,vector<string> > cellinputmap;// if a wire ( not pi not po) is in the input of a cell it gets added to this map. map<int,vector<string> >celloutputmap;// if a wire (not pi not po) is in the output of a cell it gets added to this map. Both cellinput map and celloutputmap are useful for adding edges b/w cells typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS> Graph; // we intialize a graph ,for the time being it is bidirectional although making it uni-directional or a DAG will not make any difference because we are not adding any backward edges all the edges are forward (from PI->PO) VerilogParser vp (filename) ; int elementcount=0;// counts the pis and pos alone int totalcount=0;//counts total components pi+po+cells used as key for hash map mymap line no 1116 string moduleName ; bool valid = vp.read_module (moduleName) ; assert (valid) ; cout << "Module " << moduleName << endl << endl ; do { string primaryInput ; valid = vp.read_primary_input (primaryInput) ; if (valid) { cout << "Primary input: " << primaryInput << endl ; if(primaryInput=="ispd_clk") clkset.insert(primaryInput); else { piset.insert(primaryInput); // we add primary input to the set of PIS mymap[totalcount]=primaryInput;// add it to the hash map and increment elementcount and totalcount mymap2[primaryInput]=totalcount; elementcount++; totalcount++; } } } while (valid) ; cout << endl ; do { string primaryOutput ; valid = vp.read_primary_output (primaryOutput) ; if (valid) { cout << "Primary output: " << primaryOutput << endl ; poset.insert(primaryOutput);// we add the primary output to the set of POs mymap[totalcount]=primaryOutput;// add it to the hash map mymap and increment elementcount and totalcount mymap2[primaryOutput]=totalcount; elementcount++; totalcount++; } } while (valid) ; // elementcount--; cout << endl ; do { string net ; valid = vp.read_wire (net) ; if (valid) { cout << "Net: " << net << endl ; wireset.insert(net);//if the net is not a pi nor a po then it will be added to wireset which is a set of intermediated wires } } while (valid) ; Graph g; cout<<"total count"<<totalcount<<endl; int cellcount=0;// a variable that counts only the number of cells cout << endl ; cout << "Cell insts: " << std::endl ; // cellcount++; do { string cellType, cellInst ;// each cell comes with a celltype and cellInst we use cellType to index into the hashmap as it will be easy to get the cell details like power area and timing during library parsing vector<std::pair<string, string> > pinNetPairs ; vector<string> tempinvect; // a vector that stores all the intermediate wires that feed into the cell vector<string>tempoutvect; // a vector that stores all the intermediate wires that are the cell's output valid = vp.read_cell_inst (cellType, cellInst, pinNetPairs) ; int temp=0; if (valid) { cout << cellType << " " << elementcount+cellcount << " "<<totalcount<<" " ; mymap[totalcount]=cellType;// we add the cellType to the hashmap instead of the cellInst as cellType will be useful for getting cell details like power area and timing during library parsing. mymap2[cellType]=totalcount;//find out where are u using this again int sizecount=pinNetPairs.size(); for (int i=0; i < pinNetPairs.size(); ++i) { if(piset.find(pinNetPairs[i].second)!=piset.end()) // if the pin is the primary input set then { temp=mymap2[pinNetPairs[i].second]; cout<<"primary input "<<pinNetPairs[i].second<<" "<<temp<<" "; boost::add_edge(temp,totalcount,g); // we add an incoming edge from PI to the cell } else if(clkset.find(pinNetPairs[i].second)!=clkset.end()) { cout<<"clk "<<pinNetPairs[i].second<<" "; temp=mymap2[pinNetPairs[i].second]; // boost::add_edge(temp,totalcount,g); } else if(pinNetPairs[i].first=="o" && poset.find(pinNetPairs[i].second)!=poset.end()) // if the pin is the primary output set then { // mapit=mymap.begin(); temp=mymap2[pinNetPairs[i].second]; cout<<"primary output "<<pinNetPairs[i].second<<" "<<temp<<" "; boost::add_edge(totalcount,temp,g);// we add an from the cell to the PO } if(wireset.find(pinNetPairs[i].second)!=wireset.end())// if it is an intermediate wire { if(pinNetPairs[i].first=="o"){ // if it is a output of the cell tempoutvect.push_back(pinNetPairs[i].second); // we add it to the temporary outputvector cout<<"output wire "<<pinNetPairs[i].second<<" "; sizecount--; } else { cout<<"input wire "<<pinNetPairs[i].second<<" "; // else if it is an input of the cell tempinvect.push_back(pinNetPairs[i].second); // we add it to the temporary inputvector } } } cout << endl ; totalcount++; celloutputmap[elementcount+cellcount]=tempoutvect; // we map the temporary outputvector to the celloutputmap cellinputmap[elementcount+cellcount]=tempinvect;//we map the temporary inputvector the cellinputmap cellcount++; } } while (valid) ; //cellcount--; vector<string> invect;// a temporary inputvector vector<string> outvect;// a temporary output vector vector<string>::iterator it1;// we use two vector iterators to iterate over the input and output vectors vector<string>::iterator it2; string tempstring1,tempstring2; cout<<"doing vector"<<endl; for(int j=0;j<cellcount;j++) // iterate over all the cells { invect=cellinputmap[elementcount+j];// get the input vectors for the cell cout<<j<<"\t"; for(int k=0;k<cellcount;k++) { if(j!=k) { outvect=celloutputmap[elementcount+k];// get the output vectors for the cell for(it1=invect.begin();it1<invect.end();it1++) { tempstring1=*it1;//for each input in cell1 for(it2=outvect.begin();it2<outvect.end();it2++) { tempstring2=*it2;//for each output in cell2 if(tempstring1==tempstring2)//if input matches output { boost::add_edge(elementcount+k,elementcount+j,g);// add edge b/w cell1 and cell2 } } } } } } cout<<"writing to file"<<endl; if(format=="ispd")// we have two format options one is ispd and the other is hypergraph { string file=moduleName; string str2=file.append(".ispd"); ofstream myfile; myfile.open(str2.c_str()); /* * This is style 1 ispd benchmark format but multiple instances of same gate so have to use style 2*/ /* for(int i=0;i<elementcount+cellcount;i++) { myfile<<mymap[i]<<" s 1\n"; for(int j=0;j<elementcount+cellcount;j++) { if(boost::edge(i,j,g).second) { myfile<<mymap[j]<<"\n"; } } // myfile<<"\n"; }*/ //style 2 for(int i=0;i<elementcount+cellcount;i++) { if(poset.find(mymap[i])==poset.end()) myfile<<i<<" s 1\n";// if component is not PO for(int j=0;j<elementcount+cellcount;j++) { if(boost::edge(i,j,g).second) // if there exists an outgoing edge then write output to file { myfile<<j<<"\n"; } } // myfile<<"\n"; } myfile.close(); } else if(format=="hgr") // writes into hypergraph format { string file=moduleName; string str2=file.append(".hgr"); ofstream myfile; myfile.open(str2.c_str()); /* * This is style 1 ispd benchmark format but multiple instances of same gate so have to use style 2*/ /* for(int i=0;i<elementcount+cellcount;i++) { myfile<<mymap[i]<<" s 1\n"; for(int j=0;j<elementcount+cellcount;j++) { if(boost::edge(i,j,g).second) { myfile<<mymap[j]<<"\n"; } } // myfile<<"\n"; }*/ //style 2 myfile<<totalcount<<"\n"; for(int i=0;i<totalcount;i++) { for(int j=0;j<totalcount;j++) { if(boost::edge(i,j,g).second) { myfile<<j<<"\t"; } } myfile<<"\n"; } myfile.close(); ofstream myfile4; myfile4.open("debugcells.txt"); for(int i=0;i<totalcount;i++) { myfile4<<mymap[i]<<"\t"<<i<<"\t"; for(int j=0;j<totalcount;j++) { if(boost::edge(i,j,g).second) { myfile4<<mymap[j]<<"\t"<<j<<"\t"; } } myfile4<<"\n"; } } ofstream myfile3; myfile3.open("debug.txt"); for(int i=0;i<totalcount;i++) { myfile3<<i<<"\t"; for(int j=0;j<totalcount;j++) { if(boost::edge(j,i,g).second) { myfile3<<j<<"\t"; } } myfile3<<"\n"; } myfile3.close(); ofstream myfile2; string s3=moduleName.append(".type"); myfile2.open(s3.c_str()); cout<<"key values"<<endl; cout<<"the size is "<<mymap.size()<<endl; //for(int i=0;i<elementcount+cellcount;i++) mapit=mymap.begin();// we also create a type file which contains component,component TYPE,if it is a cell the cellType do { if(piset.find(mapit->second)!=piset.end()) myfile2<<"PI\n"; else if(clkset.find(mapit->second)!=clkset.end()) myfile2<<"CLK\n"; else if(poset.find(mapit->second)!=poset.end()) myfile2<<"PO\n"; else myfile2<<mapit->second<<"\n"; ++mapit; }while(mapit!=mymap.end()); myfile2.close(); //for(mapit=mymap.begin();mapit!=mymap.end();mapit++) //{ // if(poset.find(mapit->second)==poset.end()) // myfile<<mapit->second<<" s 1\n"; // for(mapit2=mymap.begin();mapit2!=mymap.end();mapit2++) // { // if(boost::edge(mapit->first,mapit2->second,g).second) // { // myfile<<mapit2->first<<"\n"; // } // } //} //myfile.close(); cout<<"Cellcount:"<<cellcount<<endl; }
// Example function that uses VerilogParser class to parse the given ISPD-13 verilog // file. The extracted data is simply printed out in this example. void test_verilog_parser (string filename) { VerilogParser vp (filename) ; string moduleName ; bool valid = vp.read_module (moduleName) ; assert (valid) ; cout << "Module " << moduleName << endl << endl ; do { string primaryInput ; valid = vp.read_primary_input (primaryInput) ; if (valid) cout << "Primary input: " << primaryInput << endl ; } while (valid) ; cout << endl ; do { string primaryOutput ; valid = vp.read_primary_output (primaryOutput) ; if (valid) cout << "Primary output: " << primaryOutput << endl ; } while (valid) ; cout << endl ; do { string net ; valid = vp.read_wire (net) ; if (valid) cout << "Net: " << net << endl ; } while (valid) ; cout << endl ; cout << "Cell insts: " << std::endl ; do { string cellType, cellInst ; vector<std::pair<string, string> > pinNetPairs ; valid = vp.read_cell_inst (cellType, cellInst, pinNetPairs) ; if (valid) { cout << cellType << " " << cellInst << " " ; for (int i=0; i < pinNetPairs.size(); ++i) { cout << "(" << pinNetPairs[i].first << " " << pinNetPairs[i].second << ") " ; } cout << endl ; } } while (valid) ; }