bool isNumeric(const string& p)
{
    return pnum.matches(p);
}
Exemple #2
0
inline void make_pattern(pattern& rt, Match type)
{
  rt.add_match(type);
}
  bool create_simulation_pattern( const pattern& p, const circuit& circ, std::vector<boost::dynamic_bitset<> >& sim, std::map<std::string, boost::dynamic_bitset<> >& init, std::string* error )
  {
    // Initialzustand speichern
    const bus_collection::map& circStates = circ.statesignals().buses();
    for ( const auto& pa : p.initializers() )
    {
      // is there a bus, we need it for the bitwidth
      bus_collection::map::const_iterator stateIt = circStates.find( pa.first );
      if ( stateIt != circStates.end() )
      {
        int busSize = stateIt->second.size();
        boost::dynamic_bitset<> initBits( busSize, pa.second );

        init.insert( std::make_pair( pa.first, initBits ) );
      }
    }

    // Set init value to 0 for all remaining state signals
    for ( const auto& pa : circStates )
    {
      const std::string& statesignal = pa.first;
      std::map<std::string, boost::dynamic_bitset<> >::const_iterator stateIt = init.find( statesignal );
      if ( stateIt == init.end() )
      {
        init.insert( std::make_pair( statesignal, boost::dynamic_bitset<>( pa.second.size() ) ) );
      }
    }

    std::map<std::string, std::vector<unsigned> > varPlace;
    std::map<std::string, std::vector<unsigned> > varPlaceIC;
    std::list<unsigned> usedLines;
    unsigned numBits = 0;
    std::vector<std::string> vars;

    for ( const auto& input_name : p.inputs() )
    {
      // Search in input busses
      bus_collection::map::const_iterator busIt = circ.inputbuses().buses().find( input_name );
      if( busIt != circ.inputbuses().buses().end() )
      {
        const std::vector<unsigned>& busLines = busIt->second;
        varPlaceIC[input_name] = busLines;
        for ( unsigned line : busLines )
        {
          usedLines += line;
          ++numBits;
        }
        vars += input_name;
      }
      // Search in regular inputs
      else
      {
        std::vector<std::string>::const_iterator itOtherInput = std::find( circ.inputs().begin(), circ.inputs().end(), input_name );

        if ( itOtherInput != circ.inputs().end() )
        {
          unsigned line = std::distance( circ.inputs().begin(), itOtherInput );
          varPlaceIC[input_name] = std::vector<unsigned>( 1, line );
          usedLines.push_back( line );
          ++numBits;
          vars.push_back( input_name );
        }
        // ignore if not found
      }
    }

    // check for multiple defined inputs
    usedLines.sort();
    std::list<unsigned> ul = usedLines;
    usedLines.unique();
    if ( usedLines.size() < ul.size() )
    {
      if( error )
      {
        *error = "At least one primary input is specified multiple times in .inputs.";
      }
      return false;
    }

    // check, whether all primary inputs are covered and nothing else
    std::list<unsigned> primaryInputs;
    boost::push_back( primaryInputs, boost::irange( 0u, circ.lines() ) );

    // remove constant lines
    for ( std::vector<constant>::const_iterator it = circ.constants().begin(); it != circ.constants().end(); ++it )
    {
      if ( *it )
      {
        primaryInputs.remove( std::distance( circ.constants().begin(), it ) );
      }
    }

    // remove statesignals
    for ( const auto& pa : circStates )
    {

      for ( unsigned line : pa.second )
      {
        primaryInputs.remove( line );
      }
    }

    // check
    if ( primaryInputs != usedLines )
    {
      if ( error )
      {
        *error = "Specified inputs don't match primary inputs of the circuit.";
      }
      return false;
    }

    for ( const auto& varName : vars )
    {
      std::vector<unsigned> vp;
      for ( unsigned line : varPlaceIC[varName] )
      {
        vp += std::distance( usedLines.begin(), boost::find( usedLines, line ) );
      }
      varPlace.insert( std::make_pair( varName, vp ) );
    }

    for ( pattern::pattern_vec::const_iterator step = p.patterns().begin(); step != p.patterns().end(); ++step )
    {
      boost::dynamic_bitset<> stepBits(numBits);
      for( std::vector<unsigned>::const_iterator it2 = step->begin(); it2 != step->end(); ++it2 )
      {
        unsigned input = *it2;
        const std::vector<unsigned>& lines = varPlace[vars.at( std::distance( step->begin(), it2 ) )];
        if ( input >= ( 1u << lines.size() ) )
        {
          if ( error )
          {
            *error = boost::str( boost::format( "In step %d: Input %s has not enough bits to represent the given value." )
                                 % ( std::distance( p.patterns().begin(), step ) + 1u )
                                 % vars.at( std::distance( step->begin(), it2 ) ) );
          }
          return false;
        }

        boost::dynamic_bitset<> inputVal( lines.size(), input );
        unsigned j = 0u;
        for ( unsigned line : lines )
        {
          stepBits[line] = inputVal[j++];
        }
      }
      sim += stepBits;
    }

    return true;
  }
Exemple #4
0
  bool read_pattern( pattern& p, const std::string& filename, std::string* error )
  {
    std::string line;
    std::ifstream patternfile( filename.c_str() );
    if ( patternfile.is_open() == false )
    {
      if ( error )
      {
        *error = "Couldn't open patternfile.";
      }
      return false;
    }

    while ( patternfile.good() && getline( patternfile, line ) )
    {
      boost::algorithm::trim( line );

      /* Skip empty lines */
      if ( !line.size() )
      {
        continue;
      }

      std::vector<std::string> params;
      boost::algorithm::split( params, line, boost::algorithm::is_any_of( " " ) );

      /* It is possible that there are empty elements in params,
         e.g. when line contains two spaces between identifiers instead of one.
         These should be removed. */
      std::vector<std::string>::iterator newEnd = std::remove( params.begin(), params.end(), "" );
      params.erase( newEnd, params.end() );

      /* By means of the first element we can determine the command */
      std::string command = params.front();
      params.erase( params.begin() );

      if ( command == ".version" )
      {
        // Do nothing right now
      }

      else if ( command == ".init" )
      {
        if ( params.size() != 2u )
        {
          if ( error )
          {
            *error = "Too many arguments for .init command";
          }
          return false;
        }

        p.add_initializer( params.at( 0u ), boost::lexical_cast<unsigned>( params.at( 1u ) ) );
      }

      else if (command == ".inputs")
      {
        for ( unsigned i = 0u; i < params.size(); ++i )
        {
          // input is quoted?
          if ( params.at( i ).at( 0u ) == '"' )
          {
            std::string temp = params.at( i );
            // search next input with quote and concatenate
            for ( unsigned j = i + 1u; j < params.size(); ++j )
            {
              temp += " " + params.at( j );
              if ( params.at( j ).at( params.at( j ).size() - 1u ) == '"' )
              {
                i = j;
                break;
              }
            }

            // erase quotes
            temp.erase( 0u, 1u );
            temp.erase( temp.length() - 1u, temp.length() );

            p.add_input( temp );
          }

          // input without quote
          else
          {
            p.add_input( params.at( i ) );
          }
        }
      }

      else if ( command == ".begin" )
      {
        while ( true )
        {
          /* Get next line */
          std::vector<std::string> tact;
          getline(patternfile, line);
          boost::algorithm::split(tact, line, boost::algorithm::is_any_of( " " ) );

          /* Abort? */
          if ( tact.at( 0u ) == ".end" )
          {
            break;
          }

          /* Correct number of pattern? */
          if ( tact.size() != p.inputs().size() )
          {
            if ( error )
            {
              *error = "Wrong number of simulation pattern";
            }
            return false;
          }

          /* Make array */
          using boost::adaptors::transformed;

          std::vector<unsigned> tmp( tact.size() );
          std::transform( tact.begin(), tact.end(), tmp.begin(), []( const std::string& s ) { return boost::lexical_cast<unsigned>( s ); } );

          /* Push array */
          p.add_pattern( tmp );
        }
      }
    }
    return true;
  }