mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Set results of out-of-bounds static bit/part select to undef
This commit is contained in:
		
							parent
							
								
									55521c085a
								
							
						
					
					
						commit
						a03297a7df
					
				
					 1 changed files with 31 additions and 5 deletions
				
			
		| 
						 | 
					@ -866,6 +866,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
				
			||||||
			RTLIL::Wire *wire = NULL;
 | 
								RTLIL::Wire *wire = NULL;
 | 
				
			||||||
			RTLIL::SigChunk chunk;
 | 
								RTLIL::SigChunk chunk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int add_undef_bits_msb = 0;
 | 
				
			||||||
 | 
								int add_undef_bits_lsb = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) {
 | 
								if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) {
 | 
				
			||||||
				RTLIL::Wire *wire = current_module->addWire(str);
 | 
									RTLIL::Wire *wire = current_module->addWire(str);
 | 
				
			||||||
				wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
 | 
									wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
 | 
				
			||||||
| 
						 | 
					@ -919,17 +922,40 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
				
			||||||
					delete fake_ast;
 | 
										delete fake_ast;
 | 
				
			||||||
					return sig;
 | 
										return sig;
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right)
 | 
										int source_width = id2ast->range_left - id2ast->range_right + 1;
 | 
				
			||||||
						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.width = children[0]->range_left - children[0]->range_right + 1;
 | 
				
			||||||
					chunk.offset = children[0]->range_right - id2ast->range_right;
 | 
										chunk.offset = children[0]->range_right - id2ast->range_right;
 | 
				
			||||||
					if (id2ast->range_swapped)
 | 
										if (id2ast->range_swapped)
 | 
				
			||||||
						chunk.offset = wire->width - (chunk.offset + chunk.width);
 | 
											chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width);
 | 
				
			||||||
 | 
										if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) {
 | 
				
			||||||
 | 
											if (chunk.width == 1)
 | 
				
			||||||
 | 
												log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n",
 | 
				
			||||||
 | 
														str.c_str(), filename.c_str(), linenum);
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
												log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n",
 | 
				
			||||||
 | 
														str.c_str(), filename.c_str(), linenum, chunk.width);
 | 
				
			||||||
 | 
											chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											if (chunk.width + chunk.offset > source_width) {
 | 
				
			||||||
 | 
												add_undef_bits_msb = (chunk.width + chunk.offset) - source_width;
 | 
				
			||||||
 | 
												chunk.width -= add_undef_bits_msb;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (chunk.offset < 0) {
 | 
				
			||||||
 | 
												add_undef_bits_lsb = -chunk.offset;
 | 
				
			||||||
 | 
												chunk.width -= add_undef_bits_lsb;
 | 
				
			||||||
 | 
												chunk.offset += add_undef_bits_lsb;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (add_undef_bits_lsb)
 | 
				
			||||||
 | 
												log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n",
 | 
				
			||||||
 | 
														str.c_str(), filename.c_str(), linenum, add_undef_bits_lsb);
 | 
				
			||||||
 | 
											if (add_undef_bits_msb)
 | 
				
			||||||
 | 
												log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n",
 | 
				
			||||||
 | 
														str.c_str(), filename.c_str(), linenum, add_undef_bits_msb);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			RTLIL::SigSpec sig(chunk);
 | 
								RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (genRTLIL_subst_from && genRTLIL_subst_to)
 | 
								if (genRTLIL_subst_from && genRTLIL_subst_to)
 | 
				
			||||||
				sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to);
 | 
									sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue