mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Now only use value from "initial" when no matching "always" block is found
This commit is contained in:
		
							parent
							
								
									161565be10
								
							
						
					
					
						commit
						f1a2fd966f
					
				
					 5 changed files with 32 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -51,6 +51,7 @@ namespace AST_INTERNAL {
 | 
			
		|||
	std::map<std::string, AstNode*> current_scope;
 | 
			
		||||
	RTLIL::SigSpec *genRTLIL_subst_from = NULL;
 | 
			
		||||
	RTLIL::SigSpec *genRTLIL_subst_to = NULL;
 | 
			
		||||
	RTLIL::SigSpec ignoreThisSignalsInInitial;
 | 
			
		||||
	AstNode *current_top_block, *current_block, *current_block_child;
 | 
			
		||||
	AstModule *current_module;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -704,6 +705,9 @@ static AstModule* process_module(AstNode *ast)
 | 
			
		|||
	current_module->ast = NULL;
 | 
			
		||||
	current_module->name = ast->str;
 | 
			
		||||
	current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
 | 
			
		||||
 | 
			
		||||
	ignoreThisSignalsInInitial = RTLIL::SigSpec();
 | 
			
		||||
 | 
			
		||||
	for (auto &attr : ast->attributes) {
 | 
			
		||||
		if (attr.second->type != AST_CONSTANT)
 | 
			
		||||
			log_error("Attribute `%s' with non-constant value at %s:%d!\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -718,10 +722,20 @@ static AstModule* process_module(AstNode *ast)
 | 
			
		|||
	}
 | 
			
		||||
	for (size_t i = 0; i < ast->children.size(); i++) {
 | 
			
		||||
		AstNode *node = ast->children[i];
 | 
			
		||||
		if (node->type != AST_WIRE && node->type != AST_MEMORY)
 | 
			
		||||
		if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL)
 | 
			
		||||
			node->genRTLIL();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ignoreThisSignalsInInitial.sort_and_unify();
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < ast->children.size(); i++) {
 | 
			
		||||
		AstNode *node = ast->children[i];
 | 
			
		||||
		if (node->type == AST_INITIAL)
 | 
			
		||||
			node->genRTLIL();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ignoreThisSignalsInInitial = RTLIL::SigSpec();
 | 
			
		||||
 | 
			
		||||
	current_module->ast = ast_before_simplify;
 | 
			
		||||
	current_module->nolatches = flag_nolatches;
 | 
			
		||||
	current_module->nomem2reg = flag_nomem2reg;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -221,7 +221,7 @@ namespace AST_INTERNAL
 | 
			
		|||
	extern bool flag_dump_ast, flag_dump_ast_diff, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib;
 | 
			
		||||
	extern AST::AstNode *current_ast, *current_ast_mod;
 | 
			
		||||
	extern std::map<std::string, AST::AstNode*> current_scope;
 | 
			
		||||
	extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to;
 | 
			
		||||
	extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial;
 | 
			
		||||
	extern AST::AstNode *current_top_block, *current_block, *current_block_child;
 | 
			
		||||
	extern AST::AstModule *current_module;
 | 
			
		||||
	struct ProcessGenerator;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,7 +183,9 @@ struct AST_INTERNAL::ProcessGenerator
 | 
			
		|||
{
 | 
			
		||||
	// input and output structures
 | 
			
		||||
	AstNode *always;
 | 
			
		||||
	RTLIL::SigSpec skipSyncSignals;
 | 
			
		||||
	RTLIL::Process *proc;
 | 
			
		||||
	const RTLIL::SigSpec &outputSignals;
 | 
			
		||||
 | 
			
		||||
	// This always points to the RTLIL::CaseRule beeing filled at the moment
 | 
			
		||||
	RTLIL::CaseRule *current_case;
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +207,7 @@ struct AST_INTERNAL::ProcessGenerator
 | 
			
		|||
	// map helps generating nice numbered names for all this temporary signals.
 | 
			
		||||
	std::map<RTLIL::Wire*, int> new_temp_count;
 | 
			
		||||
 | 
			
		||||
	ProcessGenerator(AstNode *always) : always(always)
 | 
			
		||||
	ProcessGenerator(AstNode *always, RTLIL::SigSpec skipSyncSignalsArg = RTLIL::SigSpec()) : always(always), skipSyncSignals(skipSyncSignalsArg), outputSignals(subst_lvalue_from)
 | 
			
		||||
	{
 | 
			
		||||
		// generate process and simple root case
 | 
			
		||||
		proc = new RTLIL::Process;
 | 
			
		||||
| 
						 | 
				
			
			@ -351,8 +353,10 @@ struct AST_INTERNAL::ProcessGenerator
 | 
			
		|||
 | 
			
		||||
	// add an assignment (aka "action") but split it up in chunks. this way huge assignments
 | 
			
		||||
	// are avoided and the generated $mux cells have a more "natural" size.
 | 
			
		||||
	void addChunkActions(std::vector<RTLIL::SigSig> &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool noSyncToUndef = false)
 | 
			
		||||
	void addChunkActions(std::vector<RTLIL::SigSig> &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false)
 | 
			
		||||
	{
 | 
			
		||||
		if (inSyncRule)
 | 
			
		||||
			lvalue.remove2(skipSyncSignals, &rvalue);
 | 
			
		||||
		assert(lvalue.width == rvalue.width);
 | 
			
		||||
		lvalue.optimize();
 | 
			
		||||
		rvalue.optimize();
 | 
			
		||||
| 
						 | 
				
			
			@ -361,7 +365,7 @@ struct AST_INTERNAL::ProcessGenerator
 | 
			
		|||
		for (size_t i = 0; i < lvalue.chunks.size(); i++) {
 | 
			
		||||
			RTLIL::SigSpec lhs = lvalue.chunks[i];
 | 
			
		||||
			RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks[i].width);
 | 
			
		||||
			if (noSyncToUndef && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync"))
 | 
			
		||||
			if (inSyncRule && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync"))
 | 
			
		||||
				rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.width);
 | 
			
		||||
			actions.push_back(RTLIL::SigSig(lhs, rhs));
 | 
			
		||||
			offset += lhs.width;
 | 
			
		||||
| 
						 | 
				
			
			@ -1014,10 +1018,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint)
 | 
			
		|||
		break;
 | 
			
		||||
 | 
			
		||||
	// use ProcessGenerator for always blocks
 | 
			
		||||
	case AST_ALWAYS:
 | 
			
		||||
	case AST_INITIAL: {
 | 
			
		||||
	case AST_ALWAYS: {
 | 
			
		||||
			AstNode *always = this->clone();
 | 
			
		||||
			ProcessGenerator generator(always);
 | 
			
		||||
			ignoreThisSignalsInInitial.append(generator.outputSignals);
 | 
			
		||||
			delete always;
 | 
			
		||||
		} break;
 | 
			
		||||
 | 
			
		||||
	case AST_INITIAL: {
 | 
			
		||||
			AstNode *always = this->clone();
 | 
			
		||||
			ProcessGenerator generator(always, ignoreThisSignalsInInitial);
 | 
			
		||||
			delete always;
 | 
			
		||||
		} break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue