mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	further improved const function support
This commit is contained in:
		
							parent
							
								
									5281562d0e
								
							
						
					
					
						commit
						7c8a7b2131
					
				
					 3 changed files with 22 additions and 17 deletions
				
			
		| 
						 | 
					@ -202,7 +202,7 @@ namespace AST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// additional functionality for evaluating constant functions
 | 
							// additional functionality for evaluating constant functions
 | 
				
			||||||
		struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
 | 
							struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
 | 
				
			||||||
		bool has_const_only_constructs();
 | 
							bool has_const_only_constructs(bool &recommend_const_eval);
 | 
				
			||||||
		void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
 | 
							void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
 | 
				
			||||||
		AstNode *eval_const_function(AstNode *fcall);
 | 
							AstNode *eval_const_function(AstNode *fcall);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -623,10 +623,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
 | 
				
			||||||
				if (id_ast->type == AST_AUTOWIRE)
 | 
									if (id_ast->type == AST_AUTOWIRE)
 | 
				
			||||||
					this_width = 1;
 | 
										this_width = 1;
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					// current_ast_mod->dumpAst(stdout, "");
 | 
										// current_ast_mod->dumpAst(NULL, "mod> ");
 | 
				
			||||||
					// printf("---\n");
 | 
										// log("---\n");
 | 
				
			||||||
					// dumpAst(stdout, "");
 | 
										// id_ast->dumpAst(NULL, "decl> ");
 | 
				
			||||||
					// fflush(stdout);
 | 
										// dumpAst(NULL, "ref> ");
 | 
				
			||||||
					log_error("Failed to detect with of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
 | 
										log_error("Failed to detect with of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
| 
						 | 
					@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AST_REPLICATE:
 | 
						case AST_REPLICATE:
 | 
				
			||||||
		while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { }
 | 
							while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
 | 
				
			||||||
		if (children[0]->type != AST_CONSTANT)
 | 
							if (children[0]->type != AST_CONSTANT)
 | 
				
			||||||
			log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum);
 | 
								log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum);
 | 
				
			||||||
		children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
 | 
							children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,12 +349,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (detect_width_simple && width_hint < 0) {
 | 
						if (detect_width_simple && width_hint < 0) {
 | 
				
			||||||
 | 
							if (type == AST_REPLICATE)
 | 
				
			||||||
 | 
								while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true)
 | 
				
			||||||
 | 
									did_something = true;
 | 
				
			||||||
		for (auto child : children)
 | 
							for (auto child : children)
 | 
				
			||||||
			while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
 | 
								while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
 | 
				
			||||||
				did_something = true;
 | 
									did_something = true;
 | 
				
			||||||
		if (type == AST_REPLICATE)
 | 
					 | 
				
			||||||
			while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true)
 | 
					 | 
				
			||||||
				did_something = true;
 | 
					 | 
				
			||||||
		detectSignWidth(width_hint, sign_hint);
 | 
							detectSignWidth(width_hint, sign_hint);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -376,8 +376,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
				
			||||||
			bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
 | 
								bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
 | 
				
			||||||
			int width_hint_here = width_hint;
 | 
								int width_hint_here = width_hint;
 | 
				
			||||||
			bool sign_hint_here = sign_hint;
 | 
								bool sign_hint_here = sign_hint;
 | 
				
			||||||
			if (i == 0 && type == AST_REPLICATE)
 | 
								bool in_param_here = in_param;
 | 
				
			||||||
				const_fold_here = true;
 | 
								if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE))
 | 
				
			||||||
 | 
									const_fold_here = true, in_param_here = true;
 | 
				
			||||||
			if (type == AST_PARAMETER || type == AST_LOCALPARAM)
 | 
								if (type == AST_PARAMETER || type == AST_LOCALPARAM)
 | 
				
			||||||
				const_fold_here = true;
 | 
									const_fold_here = true;
 | 
				
			||||||
			if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
 | 
								if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
 | 
				
			||||||
| 
						 | 
					@ -394,7 +395,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
				
			||||||
				width_hint_here = -1, sign_hint_here = false;
 | 
									width_hint_here = -1, sign_hint_here = false;
 | 
				
			||||||
			if (children_are_self_determined)
 | 
								if (children_are_self_determined)
 | 
				
			||||||
				width_hint_here = -1, sign_hint_here = false;
 | 
									width_hint_here = -1, sign_hint_here = false;
 | 
				
			||||||
			did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param);
 | 
								did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
 | 
				
			||||||
			if (did_something_here)
 | 
								if (did_something_here)
 | 
				
			||||||
				did_something = true;
 | 
									did_something = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1187,7 +1188,9 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
				log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
 | 
									log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (in_param || current_scope[str]->has_const_only_constructs())
 | 
							bool recommend_const_eval = false;
 | 
				
			||||||
 | 
							bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval);
 | 
				
			||||||
 | 
							if (in_param || recommend_const_eval || require_const_eval)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			bool all_args_const = true;
 | 
								bool all_args_const = true;
 | 
				
			||||||
			for (auto child : children) {
 | 
								for (auto child : children) {
 | 
				
			||||||
| 
						 | 
					@ -1205,7 +1208,7 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (in_param)
 | 
								if (in_param)
 | 
				
			||||||
				log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum);
 | 
									log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum);
 | 
				
			||||||
			else
 | 
								if (require_const_eval)
 | 
				
			||||||
				log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
 | 
									log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1828,15 +1831,17 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
 | 
				
			||||||
		addr_bits++;
 | 
							addr_bits++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool AstNode::has_const_only_constructs()
 | 
					bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (type == AST_FOR)
 | 
				
			||||||
 | 
							recommend_const_eval = true;
 | 
				
			||||||
	if (type == AST_WHILE || type == AST_REPEAT)
 | 
						if (type == AST_WHILE || type == AST_REPEAT)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	if (type == AST_FCALL && current_scope.count(str))
 | 
						if (type == AST_FCALL && current_scope.count(str))
 | 
				
			||||||
		if (current_scope[str]->has_const_only_constructs())
 | 
							if (current_scope[str]->has_const_only_constructs(recommend_const_eval))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
	for (auto child : children)
 | 
						for (auto child : children)
 | 
				
			||||||
		if (child->AstNode::has_const_only_constructs())
 | 
							if (child->AstNode::has_const_only_constructs(recommend_const_eval))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue