mirror of https://github.com/YosysHQ/yosys.git
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
|
@ -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);
|
||||||
|
|
|
@ -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…
Reference in New Issue