mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	rtlil: Disallow 0-width chunks in SigSpec.
Among other problems, this also fixes equality comparisons between SigSpec by enforcing a canonical form. Also fix another minor issue with possible non-canonical SigSpec. Fixes #2623.
This commit is contained in:
		
							parent
							
								
									e178d0367a
								
							
						
					
					
						commit
						f965b3fa54
					
				
					 2 changed files with 63 additions and 18 deletions
				
			
		| 
						 | 
					@ -3276,8 +3276,12 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.const");
 | 
						cover("kernel.rtlil.sigspec.init.const");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (GetSize(value) != 0) {
 | 
				
			||||||
		chunks_.emplace_back(value);
 | 
							chunks_.emplace_back(value);
 | 
				
			||||||
		width_ = chunks_.back().width;
 | 
							width_ = chunks_.back().width;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width_ = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3286,8 +3290,12 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.chunk");
 | 
						cover("kernel.rtlil.sigspec.init.chunk");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (chunk.width != 0) {
 | 
				
			||||||
		chunks_.emplace_back(chunk);
 | 
							chunks_.emplace_back(chunk);
 | 
				
			||||||
		width_ = chunks_.back().width;
 | 
							width_ = chunks_.back().width;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width_ = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3296,8 +3304,12 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.wire");
 | 
						cover("kernel.rtlil.sigspec.init.wire");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wire->width != 0) {
 | 
				
			||||||
		chunks_.emplace_back(wire);
 | 
							chunks_.emplace_back(wire);
 | 
				
			||||||
		width_ = chunks_.back().width;
 | 
							width_ = chunks_.back().width;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width_ = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3306,8 +3318,12 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.wire_part");
 | 
						cover("kernel.rtlil.sigspec.init.wire_part");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (width != 0) {
 | 
				
			||||||
		chunks_.emplace_back(wire, offset, width);
 | 
							chunks_.emplace_back(wire, offset, width);
 | 
				
			||||||
		width_ = chunks_.back().width;
 | 
							width_ = chunks_.back().width;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width_ = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3316,8 +3332,12 @@ RTLIL::SigSpec::SigSpec(const std::string &str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.str");
 | 
						cover("kernel.rtlil.sigspec.init.str");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (str.size() != 0) {
 | 
				
			||||||
		chunks_.emplace_back(str);
 | 
							chunks_.emplace_back(str);
 | 
				
			||||||
		width_ = chunks_.back().width;
 | 
							width_ = chunks_.back().width;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width_ = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3326,6 +3346,7 @@ RTLIL::SigSpec::SigSpec(int val, int width)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.int");
 | 
						cover("kernel.rtlil.sigspec.init.int");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (width != 0)
 | 
				
			||||||
		chunks_.emplace_back(val, width);
 | 
							chunks_.emplace_back(val, width);
 | 
				
			||||||
	width_ = width;
 | 
						width_ = width;
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
| 
						 | 
					@ -3336,6 +3357,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.state");
 | 
						cover("kernel.rtlil.sigspec.init.state");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (width != 0)
 | 
				
			||||||
		chunks_.emplace_back(bit, width);
 | 
							chunks_.emplace_back(bit, width);
 | 
				
			||||||
	width_ = width;
 | 
						width_ = width;
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
| 
						 | 
					@ -3346,11 +3368,13 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cover("kernel.rtlil.sigspec.init.bit");
 | 
						cover("kernel.rtlil.sigspec.init.bit");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (width != 0) {
 | 
				
			||||||
		if (bit.wire == NULL)
 | 
							if (bit.wire == NULL)
 | 
				
			||||||
			chunks_.emplace_back(bit.data, width);
 | 
								chunks_.emplace_back(bit.data, width);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			for (int i = 0; i < width; i++)
 | 
								for (int i = 0; i < width; i++)
 | 
				
			||||||
				chunks_.push_back(bit);
 | 
									chunks_.push_back(bit);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	width_ = width;
 | 
						width_ = width;
 | 
				
			||||||
	hash_ = 0;
 | 
						hash_ = 0;
 | 
				
			||||||
	check();
 | 
						check();
 | 
				
			||||||
| 
						 | 
					@ -3795,7 +3819,13 @@ void RTLIL::SigSpec::remove_const()
 | 
				
			||||||
		width_ = 0;
 | 
							width_ = 0;
 | 
				
			||||||
		for (auto &chunk : chunks_)
 | 
							for (auto &chunk : chunks_)
 | 
				
			||||||
			if (chunk.wire != NULL) {
 | 
								if (chunk.wire != NULL) {
 | 
				
			||||||
 | 
									if (!new_chunks.empty() &&
 | 
				
			||||||
 | 
										new_chunks.back().wire == chunk.wire &&
 | 
				
			||||||
 | 
										new_chunks.back().offset + new_chunks.back().width == chunk.offset) {
 | 
				
			||||||
 | 
										new_chunks.back().width += chunk.width;
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
					new_chunks.push_back(chunk);
 | 
										new_chunks.push_back(chunk);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				width_ += chunk.width;
 | 
									width_ += chunk.width;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3955,6 +3985,7 @@ void RTLIL::SigSpec::check() const
 | 
				
			||||||
		int w = 0;
 | 
							int w = 0;
 | 
				
			||||||
		for (size_t i = 0; i < chunks_.size(); i++) {
 | 
							for (size_t i = 0; i < chunks_.size(); i++) {
 | 
				
			||||||
			const RTLIL::SigChunk &chunk = chunks_[i];
 | 
								const RTLIL::SigChunk &chunk = chunks_[i];
 | 
				
			||||||
 | 
								log_assert(chunk.width != 0);
 | 
				
			||||||
			if (chunk.wire == NULL) {
 | 
								if (chunk.wire == NULL) {
 | 
				
			||||||
				if (i > 0)
 | 
									if (i > 0)
 | 
				
			||||||
					log_assert(chunks_[i-1].wire != NULL);
 | 
										log_assert(chunks_[i-1].wire != NULL);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								tests/opt/bug2623.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tests/opt/bug2623.ys
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					read_rtlil << EOT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module \top
 | 
				
			||||||
 | 
					  wire output 1 \a
 | 
				
			||||||
 | 
					  wire width 0 $dummy
 | 
				
			||||||
 | 
					  cell \abc \abc
 | 
				
			||||||
 | 
					    connect \a \a
 | 
				
			||||||
 | 
					    connect \b $dummy
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EOT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					opt_clean
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue