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