mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Improved rewrite code for writing to bit slice (disabled for now)
This adds the new rewrite rule. But it's still missing a check that makes sure the new rewrite rule is actually a valid substitute in the always block being processed. Therefore the new rewrite rule is just disabled for now. Signed-off-by: Claire Wolf <claire@symbioticeda.com>
This commit is contained in:
		
							parent
							
								
									3c4758c60e
								
							
						
					
					
						commit
						4711fea6c0
					
				
					 1 changed files with 64 additions and 12 deletions
				
			
		|  | @ -1721,8 +1721,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	} | ||||
| 
 | ||||
| 	// replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
 | ||||
| 	// a big case block that selects the correct single-bit assignment.
 | ||||
| 	if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) { | ||||
| 	// either a big case block that selects the correct single-bit assignment, or mask and
 | ||||
| 	// shift operations.
 | ||||
| 	if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) | ||||
| 	{ | ||||
| 		if (children[0]->type != AST_IDENTIFIER || children[0]->children.size() == 0) | ||||
| 			goto skip_dynamic_range_lvalue_expansion; | ||||
| 		if (children[0]->children[0]->range_valid || did_something) | ||||
|  | @ -1731,10 +1733,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			goto skip_dynamic_range_lvalue_expansion; | ||||
| 		if (!children[0]->id2ast->range_valid) | ||||
| 			goto skip_dynamic_range_lvalue_expansion; | ||||
| 
 | ||||
| 		int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1; | ||||
| 		int result_width = 1; | ||||
| 
 | ||||
| 		AstNode *shift_expr = NULL; | ||||
| 		AstNode *range = children[0]->children[0]; | ||||
| 
 | ||||
| 		if (range->children.size() == 1) { | ||||
| 			shift_expr = range->children[0]->clone(); | ||||
| 		} else { | ||||
|  | @ -1747,19 +1752,66 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 				log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); | ||||
| 			result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; | ||||
| 		} | ||||
| 		did_something = true; | ||||
| 		newNode = new AstNode(AST_CASE, shift_expr); | ||||
| 		for (int i = 0; i < source_width; i++) { | ||||
| 			int start_bit = children[0]->id2ast->range_right + i; | ||||
| 			AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true)); | ||||
| 
 | ||||
| 		if (1) | ||||
| 		{ | ||||
| 			// big case block
 | ||||
| 
 | ||||
| 			did_something = true; | ||||
| 			newNode = new AstNode(AST_CASE, shift_expr); | ||||
| 			for (int i = 0; i < source_width; i++) { | ||||
| 				int start_bit = children[0]->id2ast->range_right + i; | ||||
| 				AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true)); | ||||
| 				AstNode *lvalue = children[0]->clone(); | ||||
| 				lvalue->delete_children(); | ||||
| 				int end_bit = std::min(start_bit+result_width,source_width) - 1; | ||||
| 				lvalue->children.push_back(new AstNode(AST_RANGE, | ||||
| 						mkconst_int(end_bit, true), mkconst_int(start_bit, true))); | ||||
| 				cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone()))); | ||||
| 				newNode->children.push_back(cond); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// mask and shift operations, disabled for now
 | ||||
| 
 | ||||
| 			AstNode *wire_mask = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true))); | ||||
| 			wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", filename.c_str(), location.first_line, autoidx++); | ||||
| 			wire_mask->attributes["\\nosync"] = AstNode::mkconst_int(1, false); | ||||
| 			wire_mask->is_logic = true; | ||||
| 			while (wire_mask->simplify(true, false, false, 1, -1, false, false)) { } | ||||
| 			current_ast_mod->children.push_back(wire_mask); | ||||
| 
 | ||||
| 			AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true))); | ||||
| 			wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", filename.c_str(), location.first_line, autoidx++); | ||||
| 			wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); | ||||
| 			wire_data->is_logic = true; | ||||
| 			while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } | ||||
| 			current_ast_mod->children.push_back(wire_data); | ||||
| 
 | ||||
| 			did_something = true; | ||||
| 			newNode = new AstNode(AST_BLOCK); | ||||
| 
 | ||||
| 			AstNode *lvalue = children[0]->clone(); | ||||
| 			lvalue->delete_children(); | ||||
| 			int end_bit = std::min(start_bit+result_width,source_width) - 1; | ||||
| 			lvalue->children.push_back(new AstNode(AST_RANGE, | ||||
| 					mkconst_int(end_bit, true), mkconst_int(start_bit, true))); | ||||
| 			cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone()))); | ||||
| 			newNode->children.push_back(cond); | ||||
| 
 | ||||
| 			AstNode *ref_mask = new AstNode(AST_IDENTIFIER); | ||||
| 			ref_mask->str = wire_mask->str; | ||||
| 			ref_mask->was_checked = true; | ||||
| 
 | ||||
| 			AstNode *ref_data = new AstNode(AST_IDENTIFIER); | ||||
| 			ref_data->str = wire_data->str; | ||||
| 			ref_data->was_checked = true; | ||||
| 
 | ||||
| 			AstNode *shamt = shift_expr; | ||||
| 
 | ||||
| 			newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, ref_mask->clone(), | ||||
| 					new AstNode(AST_SHIFT_LEFT, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), shamt->clone()))); | ||||
| 			newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, ref_data->clone(), | ||||
| 					new AstNode(AST_SHIFT_LEFT, new AstNode(AST_BIT_AND, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), children[1]->clone()), shamt))); | ||||
| 			newNode->children.push_back(new AstNode(type, lvalue, new AstNode(AST_BIT_OR, new AstNode(AST_BIT_AND, lvalue->clone(), new AstNode(AST_BIT_NOT, ref_mask)), ref_data))); | ||||
| 		} | ||||
| 
 | ||||
| 		goto apply_newNode; | ||||
| 	} | ||||
| skip_dynamic_range_lvalue_expansion:; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue