bool isNumeric(const string& p) { return pnum.matches(p); }
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; }
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; }