mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	sigspec: more hell
This commit is contained in:
		
							parent
							
								
									5beba35600
								
							
						
					
					
						commit
						b8e363bf9a
					
				
					 2 changed files with 275 additions and 199 deletions
				
			
		
							
								
								
									
										178
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
							
						
						
									
										178
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
YOSYS_NAMESPACE_BEGIN
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2423,6 +2424,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth
 | 
			
		|||
RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type)
 | 
			
		||||
{
 | 
			
		||||
	RTLIL::Cell *cell = new RTLIL::Cell;
 | 
			
		||||
	// std::cout << "alloc " << (long long)cell << " called " << cell->name.c_str() << "\n";
 | 
			
		||||
	cell->name = name;
 | 
			
		||||
	cell->type = type;
 | 
			
		||||
	add(cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -3441,7 +3443,6 @@ RTLIL::Wire::Wire()
 | 
			
		|||
	port_output = false;
 | 
			
		||||
	upto = false;
 | 
			
		||||
	is_signed = false;
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_PYTHON
 | 
			
		||||
	RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -3785,14 +3786,10 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.list");
 | 
			
		||||
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	log_assert(parts.size() > 0);
 | 
			
		||||
	auto ie = parts.begin();
 | 
			
		||||
	auto it = ie + parts.size() - 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -3801,149 +3798,114 @@ RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.const");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (GetSize(value) != 0) {
 | 
			
		||||
		chunks_.emplace_back(value);
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(RTLIL::Const &&value)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.const.move");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (GetSize(value) != 0) {
 | 
			
		||||
		chunks_.emplace_back(std::move(value));
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.chunk");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (chunk.width != 0) {
 | 
			
		||||
		chunks_.emplace_back(chunk);
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(RTLIL::SigChunk &&chunk)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.chunk.move");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (chunk.width != 0) {
 | 
			
		||||
		chunks_.emplace_back(std::move(chunk));
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.wire");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (wire->width != 0) {
 | 
			
		||||
		chunks_.emplace_back(wire);
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.wire_part");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (width != 0) {
 | 
			
		||||
		chunks_.emplace_back(wire, offset, width);
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const std::string &str)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.str");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (str.size() != 0) {
 | 
			
		||||
		chunks_.emplace_back(str);
 | 
			
		||||
		width_ = chunks_.back().width;
 | 
			
		||||
	} else {
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(int val, int width)
 | 
			
		||||
: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.int");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (width != 0)
 | 
			
		||||
		chunks_.emplace_back(val, width);
 | 
			
		||||
	width_ = width;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
 | 
			
		||||
: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.state");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (width != 0)
 | 
			
		||||
		chunks_.emplace_back(bit, width);
 | 
			
		||||
	width_ = width;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
 | 
			
		||||
: width_(width), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.bit");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	if (width != 0) {
 | 
			
		||||
		if (bit.wire == NULL)
 | 
			
		||||
			chunks_.emplace_back(bit.data, width);
 | 
			
		||||
| 
						 | 
				
			
			@ -3951,109 +3913,91 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
 | 
			
		|||
			for (int i = 0; i < width; i++)
 | 
			
		||||
				chunks_.push_back(bit);
 | 
			
		||||
	}
 | 
			
		||||
	width_ = width;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigChunk> &chunks)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.stdvec_chunks");
 | 
			
		||||
 | 
			
		||||
	packed_ = true;
 | 
			
		||||
	(void)new (&this->chunks_) std::vector<SigChunk>();
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	for (const auto &c : chunks)
 | 
			
		||||
		append(c);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigBit> &bits)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.stdvec_bits");
 | 
			
		||||
 | 
			
		||||
	packed_ = false;
 | 
			
		||||
	(void)new (&this->bits_) std::vector<SigBit>();
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	for (const auto &bit : bits)
 | 
			
		||||
		append(bit);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const chunk_vec_type &chunks)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.mock_vec_chunks");
 | 
			
		||||
 | 
			
		||||
	for (const auto &c : chunks)
 | 
			
		||||
		append(c);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const bit_vec_type &bits)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.mock_vec_bits");
 | 
			
		||||
 | 
			
		||||
	for (const auto &bit : bits)
 | 
			
		||||
		append(bit);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const pool<RTLIL::SigBit> &bits)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.pool_bits");
 | 
			
		||||
 | 
			
		||||
	packed_ = false;
 | 
			
		||||
	(void)new (&this->bits_) std::vector<SigBit>();
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	for (const auto &bit : bits)
 | 
			
		||||
		append(bit);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(const std::set<RTLIL::SigBit> &bits)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.stdset_bits");
 | 
			
		||||
 | 
			
		||||
	packed_ = false;
 | 
			
		||||
	(void)new (&this->bits_) std::vector<SigBit>();
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	for (const auto &bit : bits)
 | 
			
		||||
		append(bit);
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec::SigSpec(bool bit)
 | 
			
		||||
: width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_)
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.init.bool");
 | 
			
		||||
 | 
			
		||||
	packed_ = false;
 | 
			
		||||
	(void)new (&this->bits_) std::vector<SigBit>();
 | 
			
		||||
	width_ = 0;
 | 
			
		||||
	hash_ = 0;
 | 
			
		||||
	append(SigBit(bit));
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RTLIL::SigSpec::switch_to_packed() const
 | 
			
		||||
{
 | 
			
		||||
	// TODO change to debug asserts
 | 
			
		||||
	// log_assert(!this->packed_);
 | 
			
		||||
	// log_assert(bits_.size() == 0);
 | 
			
		||||
	RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
 | 
			
		||||
	that->bits_.~vector();
 | 
			
		||||
	that->packed_ = true;
 | 
			
		||||
	(void)new (&that->chunks_) std::vector<SigChunk>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RTLIL::SigSpec::switch_to_unpacked() const
 | 
			
		||||
{
 | 
			
		||||
	// TODO change to debug asserts
 | 
			
		||||
	// log_assert(this->packed_);
 | 
			
		||||
	// log_assert(chunks_.size() == 0);
 | 
			
		||||
	RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
 | 
			
		||||
	that->chunks_.~vector();
 | 
			
		||||
	that->packed_ = false;
 | 
			
		||||
	(void)new (&that->bits_) std::vector<SigBit>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RTLIL::SigSpec::pack() const
 | 
			
		||||
{
 | 
			
		||||
	RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
 | 
			
		||||
 | 
			
		||||
	if (packed_ || that->bits_.empty())
 | 
			
		||||
	if (that->bits_.empty())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cover("kernel.rtlil.sigspec.convert.pack");
 | 
			
		||||
	log_assert(that->chunks_.empty());
 | 
			
		||||
 | 
			
		||||
	std::vector<RTLIL::SigBit> old_bits;
 | 
			
		||||
	std::vector<RTLIL::SigChunk> new_chunks;
 | 
			
		||||
	old_bits.swap(that->bits_);
 | 
			
		||||
	HellVector old_bit_hell;
 | 
			
		||||
	old_bit_hell.swap(that->hell_);
 | 
			
		||||
	HellVector::mock_vector<SigBit> old_bits(old_bit_hell);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigChunk *last = NULL;
 | 
			
		||||
	int last_end_offset = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -4070,14 +4014,11 @@ void RTLIL::SigSpec::pack() const
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		new_chunks.push_back(bit);
 | 
			
		||||
		last = &new_chunks.back();
 | 
			
		||||
		that->chunks_.push_back(bit);
 | 
			
		||||
		last = &that->chunks_.back();
 | 
			
		||||
		last_end_offset = bit.offset + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	that->switch_to_packed();
 | 
			
		||||
	that->chunks_.swap(new_chunks);
 | 
			
		||||
 | 
			
		||||
	check();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4085,21 +4026,19 @@ void RTLIL::SigSpec::unpack() const
 | 
			
		|||
{
 | 
			
		||||
	RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
 | 
			
		||||
 | 
			
		||||
	if (!packed_ || that->chunks_.empty())
 | 
			
		||||
	if (that->chunks_.empty())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cover("kernel.rtlil.sigspec.convert.unpack");
 | 
			
		||||
	log_assert(that->bits_.empty());
 | 
			
		||||
 | 
			
		||||
	std::vector<RTLIL::SigBit> new_bits;
 | 
			
		||||
	new_bits.reserve(that->width_);
 | 
			
		||||
	that->bits_.reserve(that->width_);
 | 
			
		||||
	for (auto &c : that->chunks_)
 | 
			
		||||
		for (int i = 0; i < c.width; i++)
 | 
			
		||||
			new_bits.emplace_back(c, i);
 | 
			
		||||
			that->bits_.emplace_back(c, i);
 | 
			
		||||
 | 
			
		||||
	that->chunks_.clear();
 | 
			
		||||
	that->hash_ = 0;
 | 
			
		||||
	that->switch_to_unpacked();
 | 
			
		||||
	that->bits_.swap(new_bits);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RTLIL::SigSpec::updhash() const
 | 
			
		||||
| 
						 | 
				
			
			@ -4142,7 +4081,7 @@ void RTLIL::SigSpec::sort_and_unify()
 | 
			
		|||
	// A copy of the bits vector is used to prevent duplicating the logic from
 | 
			
		||||
	// SigSpec::SigSpec(std::vector<SigBit>).  This incurrs an extra copy but
 | 
			
		||||
	// that isn't showing up as significant in profiles.
 | 
			
		||||
	std::vector<SigBit> unique_bits = bits_;
 | 
			
		||||
	bit_vec_type unique_bits = bits_;
 | 
			
		||||
	std::sort(unique_bits.begin(), unique_bits.end());
 | 
			
		||||
	auto last = std::unique(unique_bits.begin(), unique_bits.end());
 | 
			
		||||
	unique_bits.erase(last, unique_bits.end());
 | 
			
		||||
| 
						 | 
				
			
			@ -4383,11 +4322,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLI
 | 
			
		|||
	log_assert(other == NULL || width_ == other->width_);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec ret;
 | 
			
		||||
	std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
 | 
			
		||||
	bit_vec_type bits_match = to_sigbit_vector();
 | 
			
		||||
 | 
			
		||||
	for (auto& pattern_chunk : pattern.chunks()) {
 | 
			
		||||
		if (other) {
 | 
			
		||||
			std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
 | 
			
		||||
			bit_vec_type bits_other = other->to_sigbit_vector();
 | 
			
		||||
			for (int i = 0; i < width_; i++)
 | 
			
		||||
				if (bits_match[i].wire &&
 | 
			
		||||
					bits_match[i].wire == pattern_chunk.wire &&
 | 
			
		||||
| 
						 | 
				
			
			@ -4417,11 +4356,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const
 | 
			
		|||
 | 
			
		||||
	log_assert(other == NULL || width_ == other->width_);
 | 
			
		||||
 | 
			
		||||
	std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
 | 
			
		||||
	bit_vec_type bits_match = to_sigbit_vector();
 | 
			
		||||
	RTLIL::SigSpec ret;
 | 
			
		||||
 | 
			
		||||
	if (other) {
 | 
			
		||||
		std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
 | 
			
		||||
		bit_vec_type bits_other = other->to_sigbit_vector();
 | 
			
		||||
		for (int i = 0; i < width_; i++)
 | 
			
		||||
			if (bits_match[i].wire && pattern.count(bits_match[i]))
 | 
			
		||||
				ret.append(bits_other[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -4458,7 +4397,7 @@ void RTLIL::SigSpec::remove_const()
 | 
			
		|||
	{
 | 
			
		||||
		cover("kernel.rtlil.sigspec.remove_const.packed");
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::SigChunk> new_chunks;
 | 
			
		||||
		chunk_vec_type new_chunks(hell_);
 | 
			
		||||
		new_chunks.reserve(GetSize(chunks_));
 | 
			
		||||
 | 
			
		||||
		width_ = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -4480,7 +4419,7 @@ void RTLIL::SigSpec::remove_const()
 | 
			
		|||
	{
 | 
			
		||||
		cover("kernel.rtlil.sigspec.remove_const.unpacked");
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::SigBit> new_bits;
 | 
			
		||||
		bit_vec_type new_bits(hell_);
 | 
			
		||||
		new_bits.reserve(width_);
 | 
			
		||||
 | 
			
		||||
		for (auto &bit : bits_)
 | 
			
		||||
| 
						 | 
				
			
			@ -4679,6 +4618,7 @@ void RTLIL::SigSpec::check(Module *mod) const
 | 
			
		|||
			w += chunk.width;
 | 
			
		||||
		}
 | 
			
		||||
		log_assert(w == width_);
 | 
			
		||||
		log_assert(bits_.empty());
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -4689,7 +4629,9 @@ void RTLIL::SigSpec::check(Module *mod) const
 | 
			
		|||
				if (bits_[i].wire != nullptr)
 | 
			
		||||
					log_assert(bits_[i].wire->module == mod);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_assert(width_ == GetSize(bits_));
 | 
			
		||||
		log_assert(chunks_.empty());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -5022,7 +4964,7 @@ pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_pool() const
 | 
			
		|||
	return sigbits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
 | 
			
		||||
RTLIL::SigSpec::bit_vec_type RTLIL::SigSpec::to_sigbit_vector() const
 | 
			
		||||
{
 | 
			
		||||
	cover("kernel.rtlil.sigspec.to_sigbit_vector");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										296
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							
							
						
						
									
										296
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -843,6 +843,7 @@ struct RTLIL::SigSpecConstIterator
 | 
			
		|||
struct RTLIL::HellVector
 | 
			
		||||
{
 | 
			
		||||
	private:
 | 
			
		||||
		// TODO spend at least ten seconds thinking about alignment
 | 
			
		||||
		std::vector<char> backing;
 | 
			
		||||
		void dump() {
 | 
			
		||||
			std::cout << "Dumping, size is " << backing.size() << std::endl;
 | 
			
		||||
| 
						 | 
				
			
			@ -853,119 +854,243 @@ struct RTLIL::HellVector
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
	public:
 | 
			
		||||
		// template <typename T>
 | 
			
		||||
		// using iterator = T*;
 | 
			
		||||
		// template <typename T>
 | 
			
		||||
		// using const_iterator = T*;
 | 
			
		||||
		template<typename T> class mock_vector;
 | 
			
		||||
		template<typename T> class iterator {
 | 
			
		||||
			friend mock_vector<T>;
 | 
			
		||||
			private:
 | 
			
		||||
				HellVector *const parent;
 | 
			
		||||
				int position;
 | 
			
		||||
				char* position;
 | 
			
		||||
			public:
 | 
			
		||||
				typedef std::bidirectional_iterator_tag iterator_category;
 | 
			
		||||
				typedef std::random_access_iterator_tag iterator_category;
 | 
			
		||||
				typedef T value_type;
 | 
			
		||||
				typedef ptrdiff_t difference_type;
 | 
			
		||||
				typedef T* pointer;
 | 
			
		||||
				typedef T& reference;
 | 
			
		||||
				iterator (HellVector* parent, int position) : parent(parent), position(position) {}
 | 
			
		||||
				T& operator* () {
 | 
			
		||||
					char* as_char = &parent->backing[position * sizeof(T)];
 | 
			
		||||
					return *(T*)as_char;
 | 
			
		||||
				iterator (char* position) : position(position) {}
 | 
			
		||||
				T& operator* () const {
 | 
			
		||||
					return *(T*)position;
 | 
			
		||||
				}
 | 
			
		||||
				T* operator-> () const {
 | 
			
		||||
					return (const T*)position;
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> operator+(size_t i) {
 | 
			
		||||
					return iterator<T>((char*)((T*)position + i));
 | 
			
		||||
				}
 | 
			
		||||
				size_t operator-(iterator<T> other) {
 | 
			
		||||
					return (size_t)(position - other.position) / sizeof(T);
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> operator-(size_t i) {
 | 
			
		||||
					return iterator<T>(position - i * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T>& operator++() {
 | 
			
		||||
					position += 1;
 | 
			
		||||
					position += sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T>& operator--() {
 | 
			
		||||
					position -= 1;
 | 
			
		||||
					position -= sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T>& operator++(int) {
 | 
			
		||||
					position += sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T>& operator--(int) {
 | 
			
		||||
					position -= sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator<(const iterator& other) const {
 | 
			
		||||
					return position < other.position;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator==(const iterator &other) const {
 | 
			
		||||
					return position == other.position;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator!=(const iterator& other) const {
 | 
			
		||||
						return !operator==(other);
 | 
			
		||||
					return !operator==(other);
 | 
			
		||||
				}
 | 
			
		||||
		};
 | 
			
		||||
		template<typename T> class const_iterator {
 | 
			
		||||
			friend mock_vector<T>;
 | 
			
		||||
			private:
 | 
			
		||||
				const HellVector *const parent;
 | 
			
		||||
				int position;
 | 
			
		||||
				char* position;
 | 
			
		||||
			public:
 | 
			
		||||
				typedef std::input_iterator_tag iterator_category;
 | 
			
		||||
				typedef T value_type;
 | 
			
		||||
				typedef ptrdiff_t difference_type;
 | 
			
		||||
				typedef T* pointer;
 | 
			
		||||
				typedef T& reference;
 | 
			
		||||
				const_iterator (const HellVector* parent, int position) : parent(parent), position(position) {}
 | 
			
		||||
				const T& operator* () {
 | 
			
		||||
					const char* as_char = &parent->backing[position * sizeof(T)];
 | 
			
		||||
					return *(const T*)as_char;
 | 
			
		||||
				const_iterator (char* position) : position(position) {}
 | 
			
		||||
				const T& operator* () const {
 | 
			
		||||
					return *(const T*)position;
 | 
			
		||||
				}
 | 
			
		||||
				const T* operator-> () const {
 | 
			
		||||
					return (const T*)position;
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T> operator+(size_t i) {
 | 
			
		||||
					return const_iterator<T>((char*)((T*)position + i));
 | 
			
		||||
				}
 | 
			
		||||
				size_t operator-(const_iterator<T> other) {
 | 
			
		||||
					return (size_t)(position - other.position) / sizeof(T);
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T> operator-(size_t i) {
 | 
			
		||||
					return const_iterator<T>(position - i * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T>& operator++() {
 | 
			
		||||
					position += 1;
 | 
			
		||||
					position += sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T>& operator-() {
 | 
			
		||||
					position -= 1;
 | 
			
		||||
				const_iterator<T>& operator--() {
 | 
			
		||||
					position -= sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T>& operator++(int) {
 | 
			
		||||
					position += sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T>& operator--(int) {
 | 
			
		||||
					position -= sizeof(T);
 | 
			
		||||
					return *this;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator<(const const_iterator& other) const {
 | 
			
		||||
					return position < other.position;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator==(const const_iterator &other) const {
 | 
			
		||||
					return position == other.position;
 | 
			
		||||
				}
 | 
			
		||||
				bool operator!=(const const_iterator& other) const {
 | 
			
		||||
						return !operator==(other);
 | 
			
		||||
					return !operator==(other);
 | 
			
		||||
				}
 | 
			
		||||
		};
 | 
			
		||||
		template <typename T>
 | 
			
		||||
		using reverse_iterator = std::reverse_iterator<iterator<T>>;
 | 
			
		||||
		template <typename T>
 | 
			
		||||
		using const_reverse_iterator = std::reverse_iterator<const_iterator<T>>;
 | 
			
		||||
		template<typename T> class mock_vector {
 | 
			
		||||
				const HellVector *const parent;
 | 
			
		||||
				HellVector& parent;
 | 
			
		||||
			public:
 | 
			
		||||
				mock_vector(HellVector* parent) {parent(parent)}
 | 
			
		||||
				void clear() {
 | 
			
		||||
					backing.clear();
 | 
			
		||||
				mock_vector(HellVector& p) : parent(p) {}
 | 
			
		||||
				template<class... Args>
 | 
			
		||||
				T& emplace_back(Args&&... args) {
 | 
			
		||||
					// TODO optimize this
 | 
			
		||||
					push_back(T(std::forward<Args>(args)...));
 | 
			
		||||
					return back();
 | 
			
		||||
				}
 | 
			
		||||
				bool empty() const {
 | 
			
		||||
					return backing.empty();
 | 
			
		||||
				void reserve(size_t n) {
 | 
			
		||||
					parent.backing.reserve(sizeof(T) * n);
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> iterator<T> begin() {
 | 
			
		||||
					return iterator<T>(this, 0);
 | 
			
		||||
				void push_back(T t) {
 | 
			
		||||
					std::cout << "Pushing " << std::dec << sizeof(T) << " bytes" << std::endl;
 | 
			
		||||
					auto size = parent.backing.size();
 | 
			
		||||
					parent.backing.resize(size + sizeof(T));
 | 
			
		||||
					memcpy((void*) &parent.backing[size], (void*) &t, sizeof(T));
 | 
			
		||||
					// dump();
 | 
			
		||||
					// parent.backing.push_back<T>(t);
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> iterator<T> end() {
 | 
			
		||||
					return iterator<T>(this, backing.size() / sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> const_iterator<T> begin() const {
 | 
			
		||||
					return const_iterator<T>(this, 0);
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> const_iterator<T> end() const {
 | 
			
		||||
					return const_iterator<T>(this, backing.size() / sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> T& at(int i) {
 | 
			
		||||
					char* as_char = &parent->backing[i * sizeof(T)];
 | 
			
		||||
				T& operator[](size_t i) {
 | 
			
		||||
					char* as_char = &parent.backing[i * sizeof(T)];
 | 
			
		||||
					return *(T*)as_char;
 | 
			
		||||
				}
 | 
			
		||||
				template<typename T> const T& at(int i) {
 | 
			
		||||
					const char* as_char = &parent->backing[i * sizeof(T)];
 | 
			
		||||
					return *(const T*)as_char;
 | 
			
		||||
				const T& operator[](size_t i) const {
 | 
			
		||||
					const char* as_char = &parent.backing[i * sizeof(T)];
 | 
			
		||||
					return *(T*)as_char;
 | 
			
		||||
				}
 | 
			
		||||
				T& at(size_t i) {
 | 
			
		||||
					if (i >= parent.backing.size() / sizeof(T))
 | 
			
		||||
						throw std::out_of_range("HellVector::mock_vector.at(size_t i)");
 | 
			
		||||
					return (*this)[i];
 | 
			
		||||
				}
 | 
			
		||||
				const T& at(size_t i) const {
 | 
			
		||||
					if (i >= parent.backing.size() / sizeof(T))
 | 
			
		||||
						throw std::out_of_range("HellVector::mock_vector.at(size_t i)");
 | 
			
		||||
					return (*this)[i];
 | 
			
		||||
				}
 | 
			
		||||
				// Unlike with std::vector, this kind of signature doesn't provide a return value because I didn't feel like it
 | 
			
		||||
				void erase(iterator<T> it) {
 | 
			
		||||
					size_t position = it - begin();
 | 
			
		||||
					(void)parent.backing.erase(parent.backing.begin() + position * sizeof(T), parent.backing.begin() + (position + 1) * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				void erase(const_iterator<T> it) {
 | 
			
		||||
					size_t position = it - begin();
 | 
			
		||||
					(void)parent.backing.erase(parent.backing.begin() + position * sizeof(T), parent.backing.begin() + (position + 1) * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				void erase(iterator<T> first_it, iterator<T> last_it) {
 | 
			
		||||
					size_t first = first_it - begin();
 | 
			
		||||
					size_t last = last_it - begin();
 | 
			
		||||
					(void)parent.backing.erase(parent.backing.begin() + first * sizeof(T), parent.backing.begin() + last * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				void erase(const_iterator<T> first_it, const_iterator<T> last_it) {
 | 
			
		||||
					size_t first = first_it - begin();
 | 
			
		||||
					size_t last = last_it - begin();
 | 
			
		||||
					(void)parent.backing.erase(parent.backing.begin() + first * sizeof(T), parent.backing.begin() + last * sizeof(T));
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> insert(iterator<T> pos_it, const T& value) {
 | 
			
		||||
					size_t position = pos_it - begin();
 | 
			
		||||
					// vector<char> allows us to use char* as iterators for the source range of the insert
 | 
			
		||||
					auto backing_it = parent.backing.insert(parent.backing.begin() + (position * sizeof(T)), &value, &value + 1);
 | 
			
		||||
					size_t ret_position = (backing_it - parent.backing.begin()) / sizeof(T);
 | 
			
		||||
					return begin() + ret_position;
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> insert(iterator<T> pos_it, const_iterator<T> first_it, const_iterator<T> last_it) {
 | 
			
		||||
					size_t backing_position = (pos_it - begin()) * sizeof(T);
 | 
			
		||||
					// vector<char> allows us to use char* as iterators for the source range of the insert
 | 
			
		||||
					auto backing_it = parent.backing.insert(parent.backing.begin() + backing_position, first_it.position, last_it.position);
 | 
			
		||||
					size_t ret_position = (backing_it - parent.backing.begin()) / sizeof(T);
 | 
			
		||||
					return begin() + ret_position;
 | 
			
		||||
				}
 | 
			
		||||
				void swap(mock_vector<T>& other) {
 | 
			
		||||
					parent.backing.swap(other.parent.backing);
 | 
			
		||||
				}
 | 
			
		||||
				void clear() {
 | 
			
		||||
					parent.backing.clear();
 | 
			
		||||
				}
 | 
			
		||||
				size_t size() const {
 | 
			
		||||
					return parent.backing.size() / sizeof(T);
 | 
			
		||||
				}
 | 
			
		||||
				bool empty() const {
 | 
			
		||||
					return parent.backing.empty();
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> begin() {
 | 
			
		||||
					return iterator<T>(&parent.backing[0]);
 | 
			
		||||
				}
 | 
			
		||||
				iterator<T> end() {
 | 
			
		||||
					return iterator<T>(&parent.backing[parent.backing.size()]);
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T> begin() const {
 | 
			
		||||
					return const_iterator<T>(&parent.backing[0]);
 | 
			
		||||
				}
 | 
			
		||||
				const_iterator<T> end() const {
 | 
			
		||||
					return const_iterator<T>(&parent.backing[parent.backing.size()]);
 | 
			
		||||
				}
 | 
			
		||||
				reverse_iterator<T> rbegin() {
 | 
			
		||||
					return reverse_iterator<T>(end());
 | 
			
		||||
				}
 | 
			
		||||
				reverse_iterator<T> rend() {
 | 
			
		||||
					return reverse_iterator<T>(begin());
 | 
			
		||||
				}
 | 
			
		||||
				const_reverse_iterator<T> rbegin() const {
 | 
			
		||||
					return const_reverse_iterator<T>(end());
 | 
			
		||||
				}
 | 
			
		||||
				const_reverse_iterator<T> rend() const {
 | 
			
		||||
					return const_reverse_iterator<T>(begin());
 | 
			
		||||
				}
 | 
			
		||||
				T& front() {
 | 
			
		||||
					return (*this)[0];
 | 
			
		||||
				}
 | 
			
		||||
				T& back() {
 | 
			
		||||
					return (*this)[parent.backing.size() / sizeof(T) - 1];
 | 
			
		||||
				}
 | 
			
		||||
				const T& front() const {
 | 
			
		||||
					return (*this)[0];
 | 
			
		||||
				}
 | 
			
		||||
				const T& back() const {
 | 
			
		||||
					return (*this)[parent.backing.size() / sizeof(T) - 1];
 | 
			
		||||
				}
 | 
			
		||||
		};
 | 
			
		||||
		bool empty() const {
 | 
			
		||||
			return backing.empty();
 | 
			
		||||
		}
 | 
			
		||||
		template<typename T> size_t size() const {
 | 
			
		||||
			return backing.size() / sizeof(T);
 | 
			
		||||
		}
 | 
			
		||||
		template<typename T> void push_back(T& thing) {
 | 
			
		||||
			std::cout << "Pushing " << std::dec << sizeof(T) << " bytes" << std::endl;
 | 
			
		||||
			auto size = backing.size();
 | 
			
		||||
			backing.resize(size + sizeof(T));
 | 
			
		||||
			memcpy((void*) &backing[size], (void*) &thing, sizeof(T));
 | 
			
		||||
			// dump();
 | 
			
		||||
		}
 | 
			
		||||
		SigBit &bit(size_t position) const {
 | 
			
		||||
			void* eee = (void*)(&backing[position * sizeof(SigBit)]);
 | 
			
		||||
			return *(SigBit*) eee;
 | 
			
		||||
		}
 | 
			
		||||
		SigChunk &chunk(size_t position) const {
 | 
			
		||||
			void* eee = (void*)(&backing[position * sizeof(SigChunk)]);
 | 
			
		||||
			return *(SigChunk*) eee;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	void swap(HellVector& other) {
 | 
			
		||||
		other.backing.swap(backing);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct RTLIL::SigSpec
 | 
			
		||||
| 
						 | 
				
			
			@ -973,13 +1098,20 @@ struct RTLIL::SigSpec
 | 
			
		|||
private:
 | 
			
		||||
	int width_;
 | 
			
		||||
	bool packed_;
 | 
			
		||||
	unsigned long hash_;
 | 
			
		||||
	HellVector hell_;
 | 
			
		||||
	mutable unsigned long hash_;
 | 
			
		||||
	mutable HellVector hell_;
 | 
			
		||||
 | 
			
		||||
	typedef HellVector::mock_vector<SigBit> bit_vec_type;
 | 
			
		||||
	typedef HellVector::mock_vector<SigChunk> chunk_vec_type;
 | 
			
		||||
 | 
			
		||||
	bit_vec_type bits_;
 | 
			
		||||
	chunk_vec_type chunks_;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	void pack() const;
 | 
			
		||||
	void unpack() const;
 | 
			
		||||
	void switch_to_packed() const;
 | 
			
		||||
	void switch_to_unpacked() const;
 | 
			
		||||
	void switch_to_packed();
 | 
			
		||||
	void switch_to_unpacked();
 | 
			
		||||
	void updhash() const;
 | 
			
		||||
 | 
			
		||||
	inline bool packed() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -987,7 +1119,7 @@ private:
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	inline void inline_unpack() const {
 | 
			
		||||
		if (packed_ && !hell_.empty())
 | 
			
		||||
		if (packed_ && !chunks_.empty())
 | 
			
		||||
			unpack();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -996,10 +1128,10 @@ private:
 | 
			
		|||
	friend struct RTLIL::Module;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	SigSpec() : width_(0), packed_(true), hash_(0), hell_(), bits_(&hell_), chunks_(&hell_) {}
 | 
			
		||||
	SigSpec() : width_(0), packed_(true), hash_(0), hell_(), bits_(hell_), chunks_(hell_) {}
 | 
			
		||||
	// ~SigSpec() { if (packed_) chunks_.~vector(); else bits_.~vector(); }
 | 
			
		||||
	SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
 | 
			
		||||
	SigSpec(const Yosys::RTLIL::SigSpec &other) : width_(other.width_), packed_(other.packed_), hash_(other.hash_), hell_(other.hell_), bits_(&hell_), chunks_(&hell_) { check(); }
 | 
			
		||||
	SigSpec(const Yosys::RTLIL::SigSpec &other) : width_(other.width_), packed_(other.packed_), hash_(other.hash_), hell_(other.hell_), bits_(hell_), chunks_(hell_) { check(); }
 | 
			
		||||
	SigSpec& operator=(const Yosys::RTLIL::SigSpec & other)
 | 
			
		||||
	{
 | 
			
		||||
		hell_ = other.hell_;
 | 
			
		||||
| 
						 | 
				
			
			@ -1022,6 +1154,8 @@ public:
 | 
			
		|||
	SigSpec(const RTLIL::SigBit &bit, int width = 1);
 | 
			
		||||
	SigSpec(const std::vector<RTLIL::SigChunk> &chunks);
 | 
			
		||||
	SigSpec(const std::vector<RTLIL::SigBit> &bits);
 | 
			
		||||
	SigSpec(const chunk_vec_type &chunks);
 | 
			
		||||
	SigSpec(const bit_vec_type &bits);
 | 
			
		||||
	SigSpec(const pool<RTLIL::SigBit> &bits);
 | 
			
		||||
	SigSpec(const std::set<RTLIL::SigBit> &bits);
 | 
			
		||||
	explicit SigSpec(bool bit);
 | 
			
		||||
| 
						 | 
				
			
			@ -1031,19 +1165,19 @@ public:
 | 
			
		|||
		return hash_;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	HellVector::mock_vector<SigBit> bits_;
 | 
			
		||||
	HellVector::mock_vector<SigChunk> chunks_;
 | 
			
		||||
	inline const auto &chunks() const { pack(); return chunks_; }
 | 
			
		||||
	inline const auto &bits() const { inline_unpack(); return bits_; }
 | 
			
		||||
 | 
			
		||||
	inline int size() const { return width_; }
 | 
			
		||||
	inline bool empty() const { return width_ == 0; }
 | 
			
		||||
 | 
			
		||||
	inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); }
 | 
			
		||||
	inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return chunks_.at(index); }
 | 
			
		||||
	inline RTLIL::SigBit &operator[](int index) { inline_unpack();  SigBit& bit = bits_.at(index); return bit; }
 | 
			
		||||
	inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); const SigBit& bit = bits_.at(index); return bit; }
 | 
			
		||||
 | 
			
		||||
	inline auto begin() { HellVector::iterator<SigBit> it(&hell_, 0); return it; }
 | 
			
		||||
	inline auto end() { HellVector::iterator<SigBit> it(&hell_, hell_.size<SigBit>()); return it; }
 | 
			
		||||
	inline auto begin() const { HellVector::const_iterator<SigBit> it(&hell_, 0); return it; }
 | 
			
		||||
	inline auto end() const { HellVector::const_iterator<SigBit> it(&hell_, hell_.size<SigBit>()); return it; }
 | 
			
		||||
	inline auto begin() { return bits_.begin(); }
 | 
			
		||||
	inline auto end() { return bits_.end(); }
 | 
			
		||||
	inline auto begin() const { return bits_.begin(); }
 | 
			
		||||
	inline auto end() const { return bits_.end(); }
 | 
			
		||||
	// inline auto end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; }
 | 
			
		||||
 | 
			
		||||
	// inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; }
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,7 +1262,7 @@ public:
 | 
			
		|||
 | 
			
		||||
	std::set<RTLIL::SigBit> to_sigbit_set() const;
 | 
			
		||||
	pool<RTLIL::SigBit> to_sigbit_pool() const;
 | 
			
		||||
	std::vector<RTLIL::SigBit> to_sigbit_vector() const;
 | 
			
		||||
	bit_vec_type to_sigbit_vector() const;
 | 
			
		||||
	std::map<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_map(const RTLIL::SigSpec &other) const;
 | 
			
		||||
	dict<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_dict(const RTLIL::SigSpec &other) const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1864,7 +1998,7 @@ inline unsigned int RTLIL::SigBit::hash() const {
 | 
			
		|||
 | 
			
		||||
inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
 | 
			
		||||
	log_assert(sig.size() == 1);
 | 
			
		||||
	*this = SigBit(*sig.chunks());
 | 
			
		||||
	*this = SigBit(sig.chunks().front());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue