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; }
void write_realization( const circuit& circ, std::ostream& os, const write_realization_settings& settings ) { unsigned oldsize = 0; if ( !settings.header.empty() ) { std::string header = settings.header; boost::algorithm::replace_all( header, "\n", "\n# " ); os << "# " << header << std::endl; } if ( !settings.version.empty() ) { os << ".version " << settings.version << std::endl; } os << ".numvars " << circ.lines() << std::endl; std::vector<std::string> variables( circ.lines() ); for ( unsigned i = 0u; i < circ.lines(); ++i ) { variables[i] = boost::str( boost::format( "x%d" ) % i ); } std::vector<std::string> _inputs( circ.inputs().begin(), circ.inputs().end() ); oldsize = _inputs.size(); _inputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _inputs[i] = boost::str( boost::format( "i%d" ) % i ); } std::vector<std::string> _outputs( circ.outputs().begin(), circ.outputs().end() ); oldsize = _outputs.size(); _outputs.resize( circ.lines() ); for ( unsigned i = oldsize; i < circ.lines(); ++i ) { _outputs[i] = boost::str( boost::format( "o%d" ) % i ); } os << ".variables " << boost::algorithm::join( variables, " " ) << std::endl; namespace karma = boost::spirit::karma; namespace ascii = boost::spirit::ascii; os << ".inputs"; //std::ostream_iterator<char> outit( os ); //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _inputs ); for ( const auto& _input : _inputs ) { std::string quote = ( _input.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _input % quote; } os << std::endl; os << ".outputs"; //karma::generate_delimited( outit, *( karma::no_delimit['"' << karma::string] << '"' ), ascii::space, _outputs ); for ( const auto& _output : _outputs ) { std::string quote = ( _output.find( " " ) != std::string::npos ) ? "\"" : ""; os << boost::format( " %s%s%s" ) % quote % _output % quote; } os << std::endl; std::string _constants( circ.lines(), '-' ); std::transform( circ.constants().begin(), circ.constants().end(), _constants.begin(), constant_to_char() ); std::string _garbage( circ.lines(), '-' ); std::transform( circ.garbage().begin(), circ.garbage().end(), _garbage.begin(), garbage_to_char() ); os << ".constants " << _constants << std::endl << ".garbage " << _garbage << std::endl; for ( const auto& bus : circ.inputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".inputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.outputbuses().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".outputbus " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& bus : circ.statesignals().buses() ) { std::vector<std::string> lines; std::transform( bus.second.begin(), bus.second.end(), std::back_inserter( lines ), line_to_variable() ); os << ".state " << bus.first << " " << boost::algorithm::join( lines, " " ) << std::endl; } for ( const auto& module : circ.modules() ) { os << ".module " << module.first << std::endl; write_realization_settings module_settings; module_settings.version.clear(); module_settings.header.clear(); write_realization( *module.second, os, module_settings ); } os << ".begin" << std::endl; std::string cmd; for ( const auto& g : circ ) { cmd = settings.type_label( g ); std::vector<std::string> lines; // Peres is special boost::transform( g.controls(), std::back_inserter( lines ), line_to_variable() ); boost::transform( g.targets(), std::back_inserter( lines ), line_to_variable() ); os << cmd << " " << boost::algorithm::join( lines, " " ); boost::optional<const std::map<std::string, std::string>&> annotations = circ.annotations( g ); if ( annotations ) { std::string sannotations; for ( const auto& p : *annotations ) { sannotations += boost::str( boost::format( " %s=\"%s\"" ) % p.first % p.second ); } os << " #@" << sannotations; } os << std::endl; } os << ".end" << std::endl; }