mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-29 18:52:30 +00:00 
			
		
		
		
	Keep strings as strings in const ternary and concat
This commit is contained in:
		
							parent
							
								
									e935bb6eda
								
							
						
					
					
						commit
						891e4b5b0d
					
				
					 3 changed files with 25 additions and 5 deletions
				
			
		|  | @ -171,6 +171,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2) | |||
| 	is_output = false; | ||||
| 	is_reg = false; | ||||
| 	is_signed = false; | ||||
| 	is_string = false; | ||||
| 	range_valid = false; | ||||
| 	port_id = 0; | ||||
| 	range_left = -1; | ||||
|  | @ -591,6 +592,8 @@ bool AstNode::operator==(const AstNode &other) const | |||
| 		return false; | ||||
| 	if (is_signed != other.is_signed) | ||||
| 		return false; | ||||
| 	if (is_string != other.is_string) | ||||
| 		return false; | ||||
| 	if (range_valid != other.range_valid) | ||||
| 		return false; | ||||
| 	if (port_id != other.port_id) | ||||
|  | @ -658,6 +661,14 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe | |||
| 	return node; | ||||
| } | ||||
| 
 | ||||
| // create an AST node for a constant (using a string in bit vector form as value)
 | ||||
| AstNode *AstNode::mkconst_str(const std::vector<RTLIL::State> &v) | ||||
| { | ||||
| 	AstNode *node = mkconst_str(RTLIL::Const(v).decode_string()); | ||||
| 	log_assert(node->bits == v); | ||||
| 	return node; | ||||
| } | ||||
| 
 | ||||
| // create an AST node for a constant (using a string as value)
 | ||||
| AstNode *AstNode::mkconst_str(const std::string &str) | ||||
| { | ||||
|  | @ -671,6 +682,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) | |||
| 		} | ||||
| 	} | ||||
| 	AstNode *node = AstNode::mkconst_bits(data, false); | ||||
| 	node->is_string = true; | ||||
| 	node->str = str; | ||||
| 	return node; | ||||
| } | ||||
|  | @ -702,7 +714,7 @@ RTLIL::Const AstNode::asAttrConst() | |||
| 	RTLIL::Const val; | ||||
| 	val.bits = bits; | ||||
| 
 | ||||
| 	if (!str.empty()) { | ||||
| 	if (is_string) { | ||||
| 		val.flags |= RTLIL::CONST_FLAG_STRING; | ||||
| 		log_assert(val.decode_string() == str); | ||||
| 	} | ||||
|  |  | |||
|  | @ -143,7 +143,7 @@ namespace AST | |||
| 		// node content - most of it is unused in most node types
 | ||||
| 		std::string str; | ||||
| 		std::vector<RTLIL::State> bits; | ||||
| 		bool is_input, is_output, is_reg, is_signed, range_valid; | ||||
| 		bool is_input, is_output, is_reg, is_signed, is_string, range_valid; | ||||
| 		int port_id, range_left, range_right; | ||||
| 		uint32_t integer; | ||||
| 
 | ||||
|  | @ -213,6 +213,7 @@ namespace AST | |||
| 		// helper functions for creating AST nodes for constants
 | ||||
| 		static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32); | ||||
| 		static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed); | ||||
| 		static AstNode *mkconst_str(const std::vector<RTLIL::State> &v); | ||||
| 		static AstNode *mkconst_str(const std::string &str); | ||||
| 
 | ||||
| 		// helper function for creating sign-extended const objects
 | ||||
|  |  | |||
|  | @ -1176,6 +1176,7 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 	// perform const folding when activated
 | ||||
| 	if (const_fold && newNode == NULL) | ||||
| 	{ | ||||
| 		bool string_op; | ||||
| 		std::vector<RTLIL::State> tmp_bits; | ||||
| 		RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int); | ||||
| 		RTLIL::Const dummy_arg; | ||||
|  | @ -1306,6 +1307,9 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 					choice = children[2]; | ||||
| 				if (choice != NULL && choice->type == AST_CONSTANT) { | ||||
| 					RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); | ||||
| 					if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) | ||||
| 						newNode = mkconst_str(y.bits); | ||||
| 					else | ||||
| 						newNode = mkconst_bits(y.bits, sign_hint); | ||||
| 				} else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) { | ||||
| 					RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint); | ||||
|  | @ -1319,19 +1323,22 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 			} | ||||
| 			break; | ||||
| 		case AST_CONCAT: | ||||
| 			string_op = !children.empty(); | ||||
| 			for (auto it = children.begin(); it != children.end(); it++) { | ||||
| 				if ((*it)->type != AST_CONSTANT) | ||||
| 					goto not_const; | ||||
| 				if (!(*it)->is_string) | ||||
| 					string_op = false; | ||||
| 				tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end()); | ||||
| 			} | ||||
| 			newNode = mkconst_bits(tmp_bits, false); | ||||
| 			newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false); | ||||
| 			break; | ||||
| 		case AST_REPLICATE: | ||||
| 			if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT) | ||||
| 				goto not_const; | ||||
| 			for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++) | ||||
| 				tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end()); | ||||
| 			newNode = mkconst_bits(tmp_bits, false); | ||||
| 			newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false); | ||||
| 			break; | ||||
| 		default: | ||||
| 		not_const: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue