mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Added support for "upto" wires to Verilog front- and back-end
This commit is contained in:
		
							parent
							
								
									3c45277ee0
								
							
						
					
					
						commit
						27a872d1e7
					
				
					 6 changed files with 96 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -181,6 +181,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2)
 | 
			
		|||
	is_signed = false;
 | 
			
		||||
	is_string = false;
 | 
			
		||||
	range_valid = false;
 | 
			
		||||
	range_swapped = false;
 | 
			
		||||
	port_id = 0;
 | 
			
		||||
	range_left = -1;
 | 
			
		||||
	range_right = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +277,7 @@ void AstNode::dumpAst(FILE *f, std::string indent)
 | 
			
		|||
	if (port_id > 0)
 | 
			
		||||
		fprintf(f, " port=%d", port_id);
 | 
			
		||||
	if (range_valid || range_left != -1 || range_right != 0)
 | 
			
		||||
		fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!");
 | 
			
		||||
		fprintf(f, " %srange=[%d:%d]%s", range_swapped ? "swapped_" : "", range_left, range_right, range_valid ? "" : "!");
 | 
			
		||||
	if (integer != 0)
 | 
			
		||||
		fprintf(f, " int=%u", (int)integer);
 | 
			
		||||
	if (realvalue != 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -620,6 +621,8 @@ bool AstNode::operator==(const AstNode &other) const
 | 
			
		|||
		return false;
 | 
			
		||||
	if (range_valid != other.range_valid)
 | 
			
		||||
		return false;
 | 
			
		||||
	if (range_swapped != other.range_swapped)
 | 
			
		||||
		return false;
 | 
			
		||||
	if (port_id != other.port_id)
 | 
			
		||||
		return false;
 | 
			
		||||
	if (range_left != other.range_left)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,7 +151,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, is_string, range_valid;
 | 
			
		||||
		bool is_input, is_output, is_reg, is_signed, is_string, range_valid, range_swapped;
 | 
			
		||||
		int port_id, range_left, range_right;
 | 
			
		||||
		uint32_t integer;
 | 
			
		||||
		double realvalue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -786,13 +786,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
			
		|||
				log_error("Signal `%s' with non-constant width at %s:%d!\n",
 | 
			
		||||
						str.c_str(), filename.c_str(), linenum);
 | 
			
		||||
 | 
			
		||||
			bool wire_upto = false;
 | 
			
		||||
			if (range_left < range_right && (range_left != -1 || range_right != 0)) {
 | 
			
		||||
				int tmp = range_left;
 | 
			
		||||
				range_left = range_right;
 | 
			
		||||
				range_right = tmp;
 | 
			
		||||
				wire_upto = true;
 | 
			
		||||
			}
 | 
			
		||||
			log_assert(range_left >= range_right || (range_left == -1 && range_right == 0));
 | 
			
		||||
 | 
			
		||||
			RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
 | 
			
		||||
			wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
 | 
			
		||||
| 
						 | 
				
			
			@ -800,7 +794,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
			
		|||
			wire->port_id = port_id;
 | 
			
		||||
			wire->port_input = is_input;
 | 
			
		||||
			wire->port_output = is_output;
 | 
			
		||||
			wire->upto = wire_upto;
 | 
			
		||||
			wire->upto = range_swapped;
 | 
			
		||||
 | 
			
		||||
			for (auto &attr : attributes) {
 | 
			
		||||
				if (attr.second->type != AST_CONSTANT)
 | 
			
		||||
| 
						 | 
				
			
			@ -918,17 +912,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
			
		|||
							children[0]->children[1]->clone() : children[0]->children[0]->clone());
 | 
			
		||||
					fake_ast->children[0]->delete_children();
 | 
			
		||||
					RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width,
 | 
			
		||||
							fake_ast->children[0]->genRTLIL(), fake_ast->children[1]->genRTLIL());
 | 
			
		||||
							fake_ast->children[0]->genRTLIL(), !wire->upto ? fake_ast->children[1]->genRTLIL() :
 | 
			
		||||
							current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL()));
 | 
			
		||||
					delete left_at_zero_ast;
 | 
			
		||||
					delete right_at_zero_ast;
 | 
			
		||||
					delete fake_ast;
 | 
			
		||||
					return sig;
 | 
			
		||||
				} else {
 | 
			
		||||
					chunk.offset = children[0]->range_right - id2ast->range_right;
 | 
			
		||||
					chunk.width = children[0]->range_left - children[0]->range_right + 1;
 | 
			
		||||
					if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right)
 | 
			
		||||
						log_error("Range select out of bounds on signal `%s' at %s:%d!\n",
 | 
			
		||||
								str.c_str(), filename.c_str(), linenum);
 | 
			
		||||
					chunk.width = children[0]->range_left - children[0]->range_right + 1;
 | 
			
		||||
					chunk.offset = children[0]->range_right - id2ast->range_right;
 | 
			
		||||
					if (wire->upto)
 | 
			
		||||
						chunk.offset = wire->width - (chunk.offset + chunk.width);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -504,6 +504,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
	if (type == AST_RANGE) {
 | 
			
		||||
		bool old_range_valid = range_valid;
 | 
			
		||||
		range_valid = false;
 | 
			
		||||
		range_swapped = false;
 | 
			
		||||
		range_left = -1;
 | 
			
		||||
		range_right = 0;
 | 
			
		||||
		log_assert(children.size() >= 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -525,6 +526,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
			int tmp = range_right;
 | 
			
		||||
			range_right = range_left;
 | 
			
		||||
			range_left = tmp;
 | 
			
		||||
			range_swapped = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -535,6 +537,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
				if (!range_valid)
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				range_valid = true;
 | 
			
		||||
				range_swapped = children[0]->range_swapped;
 | 
			
		||||
				range_left = children[0]->range_left;
 | 
			
		||||
				range_right = children[0]->range_right;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -542,6 +545,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
			
		|||
			if (!range_valid)
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			range_valid = true;
 | 
			
		||||
			range_swapped = false;
 | 
			
		||||
			range_left = 0;
 | 
			
		||||
			range_right = 0;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue