Monday 30 September 2013

Parser for converting IBM Power Grid Benchmarks into SPICE netlist

The following program written in c++ converts IBM Power Grid Benchmarks into SPICE netlist. The IBM Power Grid Benchmarks are available for download from here.

Header File
 /* Name - Nahit Pawar 
  * MTech - Electronic Systems - IITB  
  *  
  * Description - parser_PG.hpp 
  */ 
 class parser_PG 
 { 
 public: 
  string edgeType; 
  string sourceSymbol; 
  string sinkSymbol; 
  double branchValue; 
   
  parser_PG() : edgeType(""), sourceSymbol(""), sinkSymbol(""), branchValue(0) 
  { } 
 };   

Main File
 /*  Name: Nahit Pawar  
  *  MTech - Electronic Systems - IIT Bombay   
  *    
  *  Description - main.cpp  
  */  
 #include <iostream>  
 #include <fstream>  
 #include <sstream>  
 #include <vector>  
 #include <set>  
 #include <map>  
 #include <utility>  
   
 #include <cstdlib>  
    
 using namespace std;  
   
   
 #include "parser_PG.hpp"  
   
 typedef map<string,int>::value_type entry;  
   
 int main(int argc, char* argv[])  
 {  
  if(argc != 3)  
  {  
   cout<<"Error: circuit file not found"<<endl;  
   exit(1);  
  }  
     
  ifstream in_file(argv[1]);  
  ofstream out_file(argv[2]);   
  ofstream out_map("map_ibm_test_ckt");  
    
  if(!in_file.is_open() || !out_file.is_open())  
  {  
   cout<<"Error: Can't open input file"<<endl;  
   exit(1);  
  }  
    
  stringstream SS;  
    
  parser_PG parPG;  
  vector<parser_PG> EdgeList;  
    
  string temp;  
  temp.reserve(100);  
    
  const string delim("*");  
  string::size_type begIdx, endIdx;  
    
  uint NumOfEdges=0;  
  uint NumOfNodes=0;  
  uint NumOfCurrentSors=0;  
  uint NumOfVoltageSors=0;  
  uint NumOfResistance=0;  
    
  while(!in_file.eof())  
  {  
   getline(in_file, temp);  
     
   if(!temp.compare(".op")) break;  
     
   begIdx = temp.find_first_of(delim);  
   if(begIdx != string::npos) continue;  
     
   NumOfEdges++;    
  }  
    
  in_file.close();   
  in_file.open(argv[1]);  
    
  EdgeList.reserve(NumOfEdges);  
    
  while(!in_file.eof())  
  {  
   getline(in_file, temp);  
     
   if(!temp.compare(".op")) break;  
     
   begIdx = temp.find_first_of(delim);  
   if(begIdx != string::npos) continue;  
       
   SS.clear();  
   SS.str("");  
     
   SS.str(temp);  
     
   SS >> parPG.edgeType >> parPG.sourceSymbol >> parPG.sinkSymbol >> parPG.branchValue;  
     
   EdgeList.push_back(parPG);  
     
  }  
   
  set<string> source_sink;  
  pair< set<string>::iterator, bool > check;  
    
  map<string,int> symToNum;  
  map<string,int>::iterator sourceNum;  
  map<string,int>::iterator sinkNum;  
  pair< map<string,int>::iterator, bool > status;  
     
  set<string>::iterator setIter;  
    
  status = symToNum.insert(entry("0",NumOfNodes));  
  if(status.second == true) NumOfNodes++;  
    
  for(int i=0; i<EdgeList.size(); i++)  
  {  
   status = symToNum.insert(entry(EdgeList[i].sourceSymbol,NumOfNodes));  
   if(status.second == true) NumOfNodes++;  
   status = symToNum.insert(entry(EdgeList[i].sinkSymbol,NumOfNodes));  
   if(status.second == true) NumOfNodes++;  
  }  
   
    
  string elements("riVvR");  
  string edgeType;  
   
  for(int i=0; i<EdgeList.size(); i++)  
  {  
   sourceNum = symToNum.find(EdgeList[i].sourceSymbol);  
   sinkNum = symToNum.find(EdgeList[i].sinkSymbol);  
     
   begIdx = (EdgeList[i].edgeType).find_first_of(elements);  
   if(begIdx != string::npos)  
   {  
    endIdx = (EdgeList[i].edgeType).find_first_not_of(elements, begIdx);  
    edgeType = (EdgeList[i].edgeType).substr(begIdx, endIdx);  
      
    if(edgeType == "rr")  
    {  
      EdgeList[i].edgeType = "R";  
      NumOfResistance++;  
    }  
    else if(edgeType == "v")  
    {  
      EdgeList[i].edgeType = "V";  
      NumOfVoltageSors++;  
    }  
    else if(edgeType == "V")  
    {  
      EdgeList[i].edgeType = "R";  
      NumOfResistance++;  
    }  
    else if(edgeType == "i")  
    {  
      EdgeList[i].edgeType = "I";  
      NumOfCurrentSors++;  
    }  
    else if(edgeType == "R")  
    {  
      EdgeList[i].edgeType = "R";  
      NumOfResistance++;  
    }  
      
   }  
     
   out_file << EdgeList[i].edgeType <<i+1<< " " << (*sourceNum).second << " " << (*sinkNum).second << " " << EdgeList[i].branchValue << endl;  
  }  
    
  out_file << ".end";  
    
  cout << "Total Number of Edges = " << NumOfEdges << endl;  
  cout << "Total Number of Nodes = " << NumOfNodes << endl;  
  cout << "Total Number of Current sources = " << NumOfCurrentSors << endl;  
  cout << "Total Number of Voltage sources(including shorts) = " << NumOfVoltageSors << endl;  
  cout << "Total Number of Resistance(including shorts) = " << NumOfResistance << endl;  
    
  return 0;  
 }