Code Search for Developers
 
 
  

gs_config.h from GreenSocs at Krugle


Show gs_config.h syntax highlighted

#ifndef __gs_config_h__
#define __gs_config_h__

#include "systemc.h"
#include "protocol/generic.h"
#include "router_fabric.h"


#define TRACENAME "GS_CONFIG"


/**
 * \file gs_config.h A simple config file parser for GreenBus models.
 * (C) 2007 Wolfgang Klingauf @ TU Braunschweig, E.I.S.
 */

namespace tlm {

enum gs_config_parse_result {
  IGNORE = 0,
  MODULE,
  PARAM,
  BUS,
  CONNECT
};

#define BUFSIZE 1024
static char line[BUFSIZE];
static char token[BUFSIZE];


typedef pair<vector<string>, gs_config_parse_result> parseresult;


/**
 * Strip heading and trailing white spaces and tabs from a string.
 */
static void strip(string& str)
{
   if(str.empty()) return;

   int startIndex = str.find_first_not_of(" \t");
   int endIndex = str.find_last_not_of(" \t");
   string tmp = str;
   str.erase();
   str = tmp.substr(startIndex, (endIndex-startIndex+ 1) );
}


/**
 * Classify a token.
 * @param A token.
 * @return A classification of the given token.
 */
static parseresult parse(const string &token_) {
  string::size_type idx;
  vector<string> tokenlist;
  string token(token_);
  
  // test for empty token --> ignore
  if (token == "")
    return parseresult(tokenlist, IGNORE);

  // test for comment --> remove 
  idx = token.find("#"); 
  if (idx != string::npos)
    token = token.substr(0, idx);
   
  // test for tabs and spaces and create token list
  while((idx = token.find_first_of(" \t")) != string::npos) {
    if (idx > 0) { // is a word
      tokenlist.push_back(token.substr(0,idx));
    }    
    token = token.substr(idx+1);
  }
  
  if (token.size() > 0) {
    tokenlist.push_back(token);
  }  

  if (tokenlist.empty())
    return make_pair(tokenlist, IGNORE);

  if (tokenlist.size() == 1) 
    return make_pair(tokenlist, MODULE);
  else 
    return make_pair(tokenlist, PARAM);

}


static sc_object* getSCObject(const string &obj) {
  char ch[256];
  sc_simcontext *sim; // deprecated with SystemC-2.2
  // TODO: enable the following line for SystemC-2.2
  //const std::vector<sc_object *> &objs = sc_get_top_level_objects();
  sim = sc_get_curr_simcontext(); // deprecated with SystemC-2.2
  const vector<sc_object *> &objs = sim->get_child_objects();

  // walk through module hierarchy
  const vector<sc_object *> *childs = &objs;
  string a = "", z = obj;
  string::size_type idx;

  while (1) {
    if ((idx = z.find(".")) != string::npos) { // extract parent
      a = z.substr(0,idx); // parent name without path
      z = z.substr(idx+1); // reminding path to child
    }
    else
      a = z;
    bool found = false;
    for (unsigned i=0; i<childs->size() && !found; i++) {
      sc_object *o = (*childs)[i];
      string oname(o->name());
      oname = oname.substr(oname.rfind(".")+1);
      if (oname == a) {
        if (idx!=string::npos) { // parent found
          found = true;
          sc_module *m = dynamic_cast<sc_module*>(o);
          childs = &(m->get_child_objects());
        }
        else { // obj found
          return o;
        }
      }
    }

    if (!found) {
      sprintf(ch, "Cannot find module [%s] in simulation context.", obj.c_str());
      SC_REPORT_WARNING(TRACENAME, ch);
      return NULL;
    }
  }   
}


static sc_time_unit parse_time_unit(const string &s) {
  
  if (s == "SC_FS") return SC_FS;
  if (s == "SC_PS") return SC_PS;
  if (s == "SC_NS") return SC_NS;
  if (s == "SC_US") return SC_US;
  if (s == "SC_MS") return SC_MS;
  if (s == "SC_SEC") return SC_SEC;
  
  return static_cast<sc_time_unit>(-1);
}



/**
 * Create a bus from a vector of BUS command parameters.
 * @param v: Vector{bus, clock_period, time_base}
 */
static bool gs_create_bus(busmap *m, vector<string> &v) {
  char ch[256];

  sc_time_unit tu = parse_time_unit(v[3]);
  if (tu == -1) {
    sprintf(ch, "Unknown time_unit given in BUS command!");
    SC_REPORT_WARNING(TRACENAME, ch);
    return false;
  }
  sc_time t(atoi(v[2].c_str()), tu);
  
  // find create bus function in busmap
  busmap::iterator pos = m->find(v[1]);
  if (pos == m->end()) {
    sprintf(ch, "Unknown bus type specified in BUS command. See router/gsrouter.h for available busses.");
    SC_REPORT_WARNING(TRACENAME, ch);
    return false;
  }

  // create the bus
  sc_module_name busname(v[0].c_str());
  pos->second(busname, t);

  cout << "GS_CONFIG: Creating bus [" << v[0] << "] with type " << v[1] << " and clock period " << t << endl;

  return true;
}



/**
 * Bind greenbus ports from a vector of CONNECT command parameters.
 */
static bool gs_connect(vector<string> &v) {
  unsigned p=0;
  char ch[256];

  while (p<v.size()) {
    sc_object *iport = getSCObject(v[p++]);
    sc_object *tport = getSCObject(v[p++]);
    if (!iport || !tport) {
      sprintf(ch, "Port binding failed. One of the specified ports does not exist.");
      SC_REPORT_WARNING(TRACENAME, ch);
      return false;
    }

    if (v.size() == 2) { // point-to-point binding
      GenericMasterPort &out = *(dynamic_cast<GenericMasterPort*>(iport));
      GenericTargetPort &in  = *(dynamic_cast<GenericTargetPort*>(tport));
      if(iport && tport) {      
        cout << "GS_CONFIG: Binding initiator to target: " << iport->name() << "(" << tport->name() << ")" << endl;
        out(in);
      }
      else {
        sprintf(ch, "Initiator-target port binding failed. One of the specified ports is not an tlm_port.");
        SC_REPORT_WARNING(TRACENAME, ch);
        return false;
      }
    }

    else { // initiator-routers-target binding
      if (p == 2) { // initiator(router)
        GenericMasterPort &out = *(dynamic_cast<GenericMasterPort*>(iport));
        GenericRouterTargetPort &in = *(dynamic_cast<GenericRouterTargetPort*>(tport));
        if(iport && tport) {      
          cout << "GS_CONFIG: Binding initiator to router: " << iport->name() << "(" << tport->name() << ")" << endl;
          out(in);
        }
        else {
          sprintf(ch, "Initiator-router port binding failed. Initiator port is not tlm_port, or target port is not tlm_multi_port.");
          SC_REPORT_WARNING(TRACENAME, ch);
          return false;
        }
      }
      else if (p==v.size()) { // router(target)
        GenericRouterInitiatorPort &out = *(dynamic_cast<GenericRouterInitiatorPort*>(iport));
        GenericTargetPort &in = *(dynamic_cast<GenericTargetPort*>(tport));
        if (iport && tport) {
          cout << "GS_CONFIG: Binding router to target: " << iport->name() << "(" << tport->name() << ")" << endl;
          out(in);
        }
        else {
          sprintf(ch, "Router-target port binding failed. Router port is not tlm_multi_port, or target port is not tlm_port.");
          SC_REPORT_WARNING(TRACENAME, ch);
          return false;
        }          
      }
      else { // router(router)
        GenericRouterInitiatorPort &out = *(dynamic_cast<GenericRouterInitiatorPort*>(iport));
        GenericRouterTargetPort &in = *(dynamic_cast<GenericRouterTargetPort*>(tport));
        if (iport && tport) {
          cout << "GS_CONFIG: Binding router to router: " << iport->name() << "(" << tport->name() << ")" << endl;
          out(in);
        }
        else {
          sprintf(ch, "Router-router port binding failed. One or both ports are not tlm_multi_port.");
          SC_REPORT_WARNING(TRACENAME, ch);
          return false;
        }                    
      }
    }
  }
  return true;
}



static void executeCommand(parseresult &p) {
  char ch[256];

  switch (p.second) {
  case CONNECT:
    {
      cout << "GS_CONFIG: Executing command CONNECT(";
      for (unsigned i=0; i<p.first.size(); i++)
        cout<<p.first[i]<<",";
      cout<<")"<<endl;
      
      if (p.first.size()%2 != 0) {
        sprintf(ch, "CONNECT command must have even number of parameters.");
        SC_REPORT_WARNING(TRACENAME, ch);
        return;
      }
      
      gs_connect(p.first);
    }
    break;
    
  case BUS:
    {
      cout << "GS_CONFIG: Executing command BUS(";
      for (unsigned i=0; i<p.first.size(); i++)
        cout<<p.first[i]<<",";
      cout<<")"<<endl;
      
      // create busmap (see router/gsrouter.h)
      static busmap *m_busmap = NULL;
      if (m_busmap == NULL)
        m_busmap = create_busmap();
      
      if (p.first.size() != 4) {
        sprintf(ch, "BUS command must have four parameters: BUS(module_name, bus_type, clock_period, time_base)");
        SC_REPORT_WARNING(TRACENAME, ch);
        return;
      }
      
      gs_create_bus(m_busmap, p.first);
    }
    break;
    
  default:
    SC_REPORT_WARNING(TRACENAME, "Command not implemented");
  }
}


 

/**
 * Configure module parameters and create communication architecture
 * from a config file.
 */
void gs_config(const char *filename) {
  unsigned ln = 0;
  sc_module *current_module = NULL;
  char ch[256];

  ifstream is(filename);
  if (!is) {
    SC_REPORT_ERROR("GS_CONFIG", "Cannot open config file");
    return;
  }
  
  cout << endl << "GS_CONFIG: Reading configuration from file " << filename << endl;

  // get simulation context 
  sc_simcontext *sim; // deprecated with SystemC-2.2
  sim = sc_get_curr_simcontext(); // deprecated with SystemC-2.2
  const vector<sc_object *> &objs = sim->get_child_objects();
  
  // TODO: enable the following line for SystemC-2.2
  //const std::vector<sc_object *> &objs = sc_get_top_level_objects();
  
  
  // TODO: HACK warning --- the following code is quick and dirty. 
  //       There should be better ways to implement the config file parser.

  while(is) {
    is.getline(line, BUFSIZE, '\n');
    ln++;
    string::size_type lidx;
    string lstr(line);
    if ((lidx = lstr.find("#")) != string::npos)  // remove comment
      lstr = lstr.substr(0, lidx);
    stringstream s(lstr);
    current_module = NULL; // reset

    // command?
    parseresult p;
    p.second = IGNORE;

    if (lstr.find("CONNECT") != string::npos) p.second = CONNECT;
    else if (lstr.find("BUS") != string::npos) p.second = BUS;
    if (p.second != IGNORE) { // command found
      if ((lidx = lstr.find("(")) == string::npos || lstr.find(")") == string::npos) {
        sprintf(ch, "In config file line %d: '(' or ')' missing in command", ln);
        SC_REPORT_WARNING(TRACENAME, ch);
      }
      else { // get parameters
        lstr = lstr.substr(lidx+1);
        while ((lidx = lstr.find_first_of(" \t,)")) != string::npos) {
          if (lidx>0 && lstr[0]!=' ' && lstr[0]!='\t') {
            p.first.push_back(lstr.substr(0,lidx));            
            //cout << "found command parameter " << lstr.substr(0,lidx) << endl;
          }
          lstr = lstr.substr(lidx+1);
        }
        if (p.first.size() < 2) {
          sprintf(ch, "In config file line %d: Too few arguments to command", ln);
          SC_REPORT_WARNING(TRACENAME, ch);
        }
        else 
          executeCommand(p);
      }
    }


    else {

      // param
      while(s) {
        s.getline(token, BUFSIZE, '.');
        if (token != "") {
          parseresult p = parse(token);
          
          switch(p.second) {
          case PARAM: // set param value
            if (current_module) {
              cout << "GS_CONFIG: Configuring value of param [" << p.first[0] << "] in module [" << current_module->name() << "] to [" << p.first[1] << "]" << endl;
              gs_configurable *gsc = dynamic_cast<gs_configurable*>(current_module);
              if (gsc)
                gsc->setParam(p.first[0], p.first[1]);
              else {
                sprintf(ch, "In config file line %d: Module [%s] is not of type gs_configurable!", ln, current_module->name());
                SC_REPORT_WARNING(TRACENAME, ch);
              }
            }
            else {
              sprintf(ch, "In config file line %d: No module specified for param [%s].", ln, p.first[0].c_str());
              SC_REPORT_WARNING(TRACENAME, ch);
            }
            break;
            
          case MODULE: // step down in module hierarchy
            {
              const vector<sc_object *> *childs;
              if (current_module)
                childs = &(current_module->get_child_objects());
              else 
                childs = &objs;
              
              sc_object *o;
              bool found = false;
              for (unsigned int i=0; i<childs->size() && !found; i++) {
                o = (*childs)[i];
                string s(o->name());
                s = s.substr(s.rfind(".")+1);
                if (s == p.first[0]) {
                  /*
                    if (current_module) 
                    cout << "GS_CONFIG: Found matching child of [" << current_module->name() << "] with name [" << p.first[0] << "]" << endl;
                    else
                    cout << "GS_CONFIG: Found matching root module with name [" << p.first[0] << "]" << endl;
                  */
                  current_module = dynamic_cast<sc_module*>(o);
                  found = true;
                }
              }
              
              if (!found) {
                sprintf(ch, "In config file line %d: Module %s not found in module hierarchy.", ln, p.first[0].c_str());
                SC_REPORT_WARNING(TRACENAME, ch);
              }
            }
            break;
            
          case IGNORE: 
            break;
            
          default:
            sprintf(ch, "In config file line %d: Unknown token [%s]\n", ln, token);
            SC_REPORT_WARNING(TRACENAME, ch);
          }
        }
      }
    }    
  }
}


} // namespace tlm

#endif




See more files for this project here

GreenSocs

To develop SystemC infrustructure, basic IP, patches and add on library code for eventual standerdization.\r\nThe GreenSocs project is made up of a number of contributions (sub projects). Please visit www.greensocs.com for more information.

Project homepage: http://sourceforge.net/projects/greensocs
Programming language(s): C,C++,Java,Perl,XML
License: other

  class_wrapper.h
  description.h
  dust.h
  dust_model.h
  dust_model_and_introspection.h
  dust_model_and_transactions.h
  gs_config.h
  gs_config_parser.h
  gs_configurable.h
  gs_datatypes.h
  gs_dust_port.h
  gs_param.h
  gs_param_root.h
  gs_trace.h
  memoryutils.h
  payload_event_queue-new_buggy.h
  payload_event_queue.h
  phase_trace.h
  ref_count.h
  router_fabric.h