Skip to content
Closed
7 changes: 4 additions & 3 deletions kernel/ffinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,12 @@ struct FfInitVals
}
}

void set_init(const RTLIL::SigSpec &sig, RTLIL::Const val)
void set_init(const RTLIL::SigSpec &sig, const RTLIL::Const &val)
{
log_assert(GetSize(sig) == GetSize(val));
for (int i = 0; i < GetSize(sig); i++)
set_init(sig[i], val[i]);
RTLIL::Const::const_iterator val_it = val.begin();
for (auto &bit : sig)
set_init(bit, *val_it++);
}

void remove_init(RTLIL::SigBit bit)
Expand Down
19 changes: 12 additions & 7 deletions kernel/modtools.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,23 @@ struct ModIndex : public RTLIL::Monitor

void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
{
for (int i = 0; i < GetSize(sig); i++) {
RTLIL::SigBit bit = sigmap(sig[i]);
int i = 0;
for (auto &sig_bit : sig) {
RTLIL::SigBit bit = sigmap(sig_bit);
if (bit.wire)
database[bit].ports.insert(PortInfo(cell, port, i));
++i;
}
}

void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
{
for (int i = 0; i < GetSize(sig); i++) {
RTLIL::SigBit bit = sigmap(sig[i]);
int i = 0;
for (auto &sig_bit : sig) {
RTLIL::SigBit bit = sigmap(sig_bit);
if (bit.wire)
database[bit].ports.erase(PortInfo(cell, port, i));
++i;
}
}

Expand Down Expand Up @@ -179,10 +183,11 @@ struct ModIndex : public RTLIL::Monitor
if (auto_reload_module)
return;

for (int i = 0; i < GetSize(sigsig.first); i++)
RTLIL::SigSpecConstIterator second_it = sigsig.second.begin();
for (auto &first_bit : sigsig.first)
{
RTLIL::SigBit lhs = sigmap(sigsig.first[i]);
RTLIL::SigBit rhs = sigmap(sigsig.second[i]);
RTLIL::SigBit lhs = sigmap(first_bit);
RTLIL::SigBit rhs = sigmap(*second_it++);
bool has_lhs = database.count(lhs) != 0;
bool has_rhs = database.count(rhs) != 0;

Expand Down
91 changes: 72 additions & 19 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2972,11 +2972,14 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
// ignore all attempts to assign constants to other constants
if (conn.first.has_const()) {
RTLIL::SigSig new_conn;
for (int i = 0; i < GetSize(conn.first); i++)
if (conn.first[i].wire) {
new_conn.first.append(conn.first[i]);
new_conn.second.append(conn.second[i]);
RTLIL::SigSpecConstIterator second_it = conn.second.begin();
for (auto &first_bit : conn.first) {
if (first_bit.wire) {
new_conn.first.append(first_bit);
new_conn.second.append(*second_it);
}
++second_it;
}
if (GetSize(new_conn.first))
connect(new_conn);
return;
Expand Down Expand Up @@ -4447,6 +4450,23 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const
return true;
}

const RTLIL::SigChunk &RTLIL::SigSpecConstIterator::find_chunk()
{
int low = 0;
int high = GetSize(sig_p->chunks_);
while (high - low >= 2) {
int mid = (low + high) / 2;
if (sig_p->chunks_[mid].offset_in_sigspec <= bit_index)
low = mid;
else
high = mid;
}
chunk_index_hint = low;
const RTLIL::SigChunk &chunk = sig_p->chunks_[chunk_index_hint];
log_assert(chunk.offset_in_sigspec <= bit_index && bit_index < chunk.offset_in_sigspec + chunk.width);
return chunk;
}

RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
{
cover("kernel.rtlil.sigspec.init.list");
Expand All @@ -4467,6 +4487,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)

if (GetSize(value) != 0) {
chunks_.emplace_back(value);
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4481,6 +4502,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Const &&value)

if (GetSize(value) != 0) {
chunks_.emplace_back(std::move(value));
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4495,6 +4517,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)

if (chunk.width != 0) {
chunks_.emplace_back(chunk);
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4509,6 +4532,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigChunk &&chunk)

if (chunk.width != 0) {
chunks_.emplace_back(std::move(chunk));
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4523,6 +4547,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)

if (wire->width != 0) {
chunks_.emplace_back(wire);
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4537,6 +4562,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)

if (width != 0) {
chunks_.emplace_back(wire, offset, width);
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4551,6 +4577,7 @@ RTLIL::SigSpec::SigSpec(const std::string &str)

if (str.size() != 0) {
chunks_.emplace_back(str);
chunks_.back().offset_in_sigspec = 0;
width_ = chunks_.back().width;
} else {
width_ = 0;
Expand All @@ -4563,8 +4590,10 @@ RTLIL::SigSpec::SigSpec(int val, int width)
{
cover("kernel.rtlil.sigspec.init.int");

if (width != 0)
if (width != 0) {
chunks_.emplace_back(val, width);
chunks_.back().offset_in_sigspec = 0;
}
width_ = width;
hash_ = 0;
check();
Expand All @@ -4574,8 +4603,10 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
{
cover("kernel.rtlil.sigspec.init.state");

if (width != 0)
if (width != 0) {
chunks_.emplace_back(bit, width);
chunks_.back().offset_in_sigspec = 0;
}
width_ = width;
hash_ = 0;
check();
Expand All @@ -4586,11 +4617,15 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
cover("kernel.rtlil.sigspec.init.bit");

if (width != 0) {
if (bit.wire == NULL)
if (bit.wire == NULL) {
chunks_.emplace_back(bit.data, width);
else
for (int i = 0; i < width; i++)
chunks_.back().offset_in_sigspec = 0;
} else {
for (int i = 0; i < width; i++) {
chunks_.push_back(bit);
chunks_.back().offset_in_sigspec = i;
}
}
}
width_ = width;
hash_ = 0;
Expand Down Expand Up @@ -4667,7 +4702,8 @@ void RTLIL::SigSpec::pack() const
RTLIL::SigChunk *last = NULL;
int last_end_offset = 0;

for (auto &bit : old_bits) {
for (int i = 0; i < GetSize(old_bits); ++i) {
const RTLIL::SigBit &bit = old_bits[i];
if (last && bit.wire == last->wire) {
if (bit.wire == NULL) {
last->data.push_back(bit.data);
Expand All @@ -4680,6 +4716,7 @@ void RTLIL::SigSpec::pack() const
}
}
that->chunks_.push_back(bit);
that->chunks_.back().offset_in_sigspec = i;
last = &that->chunks_.back();
last_end_offset = bit.offset + 1;
}
Expand Down Expand Up @@ -5074,6 +5111,7 @@ void RTLIL::SigSpec::remove_const()
new_chunks.back().width += chunk.width;
} else {
new_chunks.push_back(chunk);
new_chunks.back().offset_in_sigspec = width_;
}
width_ += chunk.width;
}
Expand Down Expand Up @@ -5127,10 +5165,13 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
extracted.width_ = length;

auto it = chunks_.begin();
int offset_in_extracted = 0;
for (; offset; offset -= it->width, it++) {
if (offset < it->width) {
int chunk_length = min(it->width - offset, length);
extracted.chunks_.emplace_back(it->extract(offset, chunk_length));
extracted.chunks_.back().offset_in_sigspec = 0;
offset_in_extracted = chunk_length;
length -= chunk_length;
it++;
break;
Expand All @@ -5139,8 +5180,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
for (; length; length -= it->width, it++) {
if (length >= it->width) {
extracted.chunks_.emplace_back(*it);
extracted.chunks_.back().offset_in_sigspec = offset_in_extracted;
offset_in_extracted += it->width;
} else {
extracted.chunks_.emplace_back(it->extract(0, length));
extracted.chunks_.back().offset_in_sigspec = offset_in_extracted;
break;
}
}
Expand Down Expand Up @@ -5168,7 +5212,8 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
signal.pack();
}

if (packed())
if (packed()) {
int offset_in_sigspec = width_;
for (auto &other_c : signal.chunks_)
{
auto &my_last_c = chunks_.back();
Expand All @@ -5177,13 +5222,15 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
auto &other_data = other_c.data;
this_data.insert(this_data.end(), other_data.begin(), other_data.end());
my_last_c.width += other_c.width;
} else
if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) {
} else if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) {
my_last_c.width += other_c.width;
} else
} else {
chunks_.push_back(other_c);
chunks_.back().offset_in_sigspec = offset_in_sigspec;
}
offset_in_sigspec += other_c.width;
}
else
} else
bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end());

width_ += signal.width_;
Expand All @@ -5196,20 +5243,25 @@ void RTLIL::SigSpec::append(const RTLIL::SigBit &bit)
{
cover("kernel.rtlil.sigspec.append_bit.packed");

if (chunks_.size() == 0)
if (chunks_.size() == 0) {
chunks_.push_back(bit);
else
chunks_.back().offset_in_sigspec = 0;
} else
if (bit.wire == NULL)
if (chunks_.back().wire == NULL) {
chunks_.back().data.push_back(bit.data);
chunks_.back().width++;
} else
} else {
chunks_.push_back(bit);
chunks_.back().offset_in_sigspec = width_;
}
else
if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset)
chunks_.back().width++;
else
else {
chunks_.push_back(bit);
chunks_.back().offset_in_sigspec = width_;
}
}
else
{
Expand Down Expand Up @@ -5265,6 +5317,7 @@ void RTLIL::SigSpec::check(Module *mod) const
for (size_t i = 0; i < chunks_.size(); i++) {
const RTLIL::SigChunk &chunk = chunks_[i];
log_assert(chunk.width != 0);
log_assert(chunk.offset_in_sigspec == w);
if (chunk.wire == NULL) {
if (i > 0)
log_assert(chunks_[i-1].wire != NULL);
Expand Down
Loading
Loading