Four-state logic squash
Signed-off-by: Igor Zaworski <izaworski@antmicro.com>
This commit is contained in:
parent
276f2f344d
commit
e5dcf11cb8
|
|
@ -443,6 +443,24 @@ List Of Warnings
|
||||||
in decreased performance.
|
in decreased performance.
|
||||||
|
|
||||||
|
|
||||||
|
.. option:: CASTFOURSTATE
|
||||||
|
|
||||||
|
Warns about not supported four-state logic feature.
|
||||||
|
When two-state logic variant of a feature is fully supported,
|
||||||
|
an implicit cast to two-state type is made
|
||||||
|
|
||||||
|
.. code-block:: sv
|
||||||
|
:linenos:
|
||||||
|
:emphasize-lines: 5
|
||||||
|
|
||||||
|
module t;
|
||||||
|
integer fd;
|
||||||
|
initial begin
|
||||||
|
$fflush(fd); // <- implicit conversion to two-state value
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
.. option:: CDCRSTLOGIC
|
.. option:: CDCRSTLOGIC
|
||||||
|
|
||||||
Historical, never issued since version 5.008.
|
Historical, never issued since version 5.008.
|
||||||
|
|
@ -1346,7 +1364,6 @@ List Of Warnings
|
||||||
:option:`ASCRANGE`. While :option:`LITENDIAN` remains for
|
:option:`ASCRANGE`. While :option:`LITENDIAN` remains for
|
||||||
backwards compatibility, new projects should use :option:`ASCRANGE`.
|
backwards compatibility, new projects should use :option:`ASCRANGE`.
|
||||||
|
|
||||||
|
|
||||||
.. option:: MINTYPMAXDLY
|
.. option:: MINTYPMAXDLY
|
||||||
|
|
||||||
.. code-block:: sv
|
.. code-block:: sv
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,14 @@ void VerilatedFstBuffer::emitBit(uint32_t code, CData newval) {
|
||||||
m_fst->emitValueChange(m_symbolp[code], uint64_t(newval));
|
m_fst->emitValueChange(m_symbolp[code], uint64_t(newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitLogic(uint32_t code, CData newval, CData newvalXZ) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
const uint32_t newvals[2] = {static_cast<uint32_t>(newval), static_cast<uint32_t>(newvalXZ)};
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int) {
|
void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
|
@ -390,6 +398,14 @@ void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int) {
|
||||||
m_fst->emitValueChange(m_symbolp[code], newval);
|
m_fst->emitValueChange(m_symbolp[code], newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitFourstateCData(uint32_t code, CData newval, CData newvalXZ, int) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
const uint32_t newvals[2] = {static_cast<uint32_t>(newval), static_cast<uint32_t>(newvalXZ)};
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int) {
|
void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
|
@ -397,6 +413,14 @@ void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int) {
|
||||||
m_fst->emitValueChange(m_symbolp[code], newval);
|
m_fst->emitValueChange(m_symbolp[code], newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitFourstateSData(uint32_t code, SData newval, SData newvalXZ, int) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
const uint32_t newvals[2] = {static_cast<uint32_t>(newval), static_cast<uint32_t>(newvalXZ)};
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int) {
|
void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
|
@ -404,6 +428,14 @@ void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int) {
|
||||||
m_fst->emitValueChange(m_symbolp[code], newval);
|
m_fst->emitValueChange(m_symbolp[code], newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitFourstateIData(uint32_t code, IData newval, IData newvalXZ, int) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
const uint32_t newvals[2] = {newval, newvalXZ};
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int) {
|
void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
|
@ -412,12 +444,38 @@ void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitWData(uint32_t code, WDataInP newval, int) {
|
void VerilatedFstBuffer::emitFourstateQData(uint32_t code, QData newval, QData newvalXZ, int) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
const uint64_t newvals[2] = {newval, newvalXZ};
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitWData(uint32_t code, const WDataInP newval, int) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
m_owner.emitTimeChangeMaybe();
|
m_owner.emitTimeChangeMaybe();
|
||||||
m_fst->emitValueChange(m_symbolp[code], newval.datap());
|
m_fst->emitValueChange(m_symbolp[code], newval.datap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedFstBuffer::emitFourstateWData(uint32_t code, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZ, int bits) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
// TODO: When four-states will be shuffled remove it since copying will be no longer necessary
|
||||||
|
std::vector<uint32_t> newvals;
|
||||||
|
const size_t wordCount = static_cast<size_t>(VL_WORDS_I(bits));
|
||||||
|
newvals.resize(wordCount);
|
||||||
|
for (size_t i = 0; i < wordCount; ++i) {
|
||||||
|
newvals.push_back(newval[i]);
|
||||||
|
newvals.push_back(newvalXZ[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_owner.emitTimeChangeMaybe();
|
||||||
|
// call emitValueChange(handle, uint32_t*)
|
||||||
|
m_fst->emitValueChange(m_symbolp[code], newvals.data());
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFstBuffer::emitDouble(uint32_t code, double newval) {
|
void VerilatedFstBuffer::emitDouble(uint32_t code, double newval) {
|
||||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||||
|
|
|
||||||
|
|
@ -228,11 +228,18 @@ class VerilatedFstBuffer VL_NOT_FINAL {
|
||||||
// called from only one place (the full* methods), so always inline them.
|
// called from only one place (the full* methods), so always inline them.
|
||||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||||
|
VL_ATTR_ALWINLINE void emitLogic(uint32_t code, CData newval, CData newvalXZ);
|
||||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int);
|
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateCData(uint32_t code, CData newval, CData newvalXZ, int);
|
||||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int);
|
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateSData(uint32_t code, SData newval, SData newvalXZ, int);
|
||||||
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int);
|
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateIData(uint32_t code, IData newval, IData newvalXZ, int);
|
||||||
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int);
|
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateQData(uint32_t code, QData newval, QData newvalXZ, int);
|
||||||
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int);
|
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,20 +65,23 @@
|
||||||
class VerilatedSaifActivityBit final {
|
class VerilatedSaifActivityBit final {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
bool m_lastVal = false; // Last emitted activity bit value
|
bool m_lastVal = false; // Last emitted activity bit value
|
||||||
|
bool m_lastValXZ = false; // Last emitted activity bit value
|
||||||
uint64_t m_highTime = 0; // Total time when bit was high
|
uint64_t m_highTime = 0; // Total time when bit was high
|
||||||
size_t m_transitions = 0; // Total number of bit transitions
|
size_t m_transitions = 0; // Total number of bit transitions
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void aggregateVal(uint64_t dt, bool newVal) {
|
void aggregateVal(uint64_t dt, bool newVal, bool newValXZ = false) {
|
||||||
m_transitions += newVal != m_lastVal ? 1 : 0;
|
m_transitions += (newVal != m_lastVal || m_lastValXZ != newValXZ) ? 1 : 0;
|
||||||
m_highTime += m_lastVal ? dt : 0;
|
m_highTime += m_lastVal ? dt : 0;
|
||||||
m_lastVal = newVal;
|
m_lastVal = newVal;
|
||||||
|
m_lastValXZ = newValXZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
VL_ATTR_ALWINLINE bool bitValue() const { return m_lastVal; }
|
VL_ATTR_ALWINLINE bool bitValue() const { return m_lastVal; }
|
||||||
|
VL_ATTR_ALWINLINE bool bitValueXZ() const { return m_lastValXZ; }
|
||||||
VL_ATTR_ALWINLINE uint64_t highTime() const { return m_highTime; }
|
VL_ATTR_ALWINLINE uint64_t highTime() const { return m_highTime; }
|
||||||
VL_ATTR_ALWINLINE uint64_t toggleCount() const { return m_transitions; }
|
VL_ATTR_ALWINLINE uint64_t toggleCount() const { return m_transitions; }
|
||||||
};
|
};
|
||||||
|
|
@ -104,6 +107,7 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_ATTR_ALWINLINE void emitBit(uint64_t time, CData newval);
|
VL_ATTR_ALWINLINE void emitBit(uint64_t time, CData newval);
|
||||||
|
VL_ATTR_ALWINLINE void emitLogic(uint64_t time, CData newval, CData newvalXZ);
|
||||||
|
|
||||||
template <typename DataType>
|
template <typename DataType>
|
||||||
VL_ATTR_ALWINLINE void emitData(uint64_t time, DataType newval, uint32_t bits) {
|
VL_ATTR_ALWINLINE void emitData(uint64_t time, DataType newval, uint32_t bits) {
|
||||||
|
|
@ -117,7 +121,24 @@ public:
|
||||||
updateLastTime(time);
|
updateLastTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename DataType>
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateData(uint64_t time, DataType newval, DataType newvalXZ,
|
||||||
|
uint32_t bits) {
|
||||||
|
static_assert(std::is_integral<DataType>::value,
|
||||||
|
"The emitted value must be of integral type");
|
||||||
|
|
||||||
|
const uint64_t dt = time - m_lastTime;
|
||||||
|
for (size_t i = 0; i < std::min(m_width, bits); ++i) {
|
||||||
|
m_bits[i].aggregateVal(dt, newval & 1, newvalXZ & 1);
|
||||||
|
newval >>= 1;
|
||||||
|
newvalXZ >>= 1;
|
||||||
|
}
|
||||||
|
updateLastTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE void emitWData(uint64_t time, WDataInP newval, uint32_t bits);
|
VL_ATTR_ALWINLINE void emitWData(uint64_t time, WDataInP newval, uint32_t bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateWData(uint64_t time, WDataInP newval, WDataInP newvalXZ,
|
||||||
|
uint32_t bits);
|
||||||
VL_ATTR_ALWINLINE void updateLastTime(uint64_t val) { m_lastTime = val; }
|
VL_ATTR_ALWINLINE void updateLastTime(uint64_t val) { m_lastTime = val; }
|
||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
|
|
@ -229,7 +250,15 @@ void VerilatedSaifActivityVar::emitBit(const uint64_t time, const CData newval)
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifActivityVar::emitWData(const uint64_t time, WDataInP newval,
|
void VerilatedSaifActivityVar::emitLogic(const uint64_t time, const CData newval,
|
||||||
|
const CData newvalXZ) {
|
||||||
|
assert(m_lastTime <= time);
|
||||||
|
m_bits[0].aggregateVal(time - m_lastTime, newval, newvalXZ);
|
||||||
|
updateLastTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifActivityVar::emitWData(const uint64_t time, const WDataInP newval,
|
||||||
const uint32_t bits) {
|
const uint32_t bits) {
|
||||||
assert(m_lastTime <= time);
|
assert(m_lastTime <= time);
|
||||||
const uint64_t dt = time - m_lastTime;
|
const uint64_t dt = time - m_lastTime;
|
||||||
|
|
@ -241,6 +270,20 @@ void VerilatedSaifActivityVar::emitWData(const uint64_t time, WDataInP newval,
|
||||||
updateLastTime(time);
|
updateLastTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifActivityVar::emitFourstateWData(const uint64_t time, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZ, const uint32_t bits) {
|
||||||
|
assert(m_lastTime <= time);
|
||||||
|
const uint64_t dt = time - m_lastTime;
|
||||||
|
for (std::size_t i = 0; i < std::min(m_width, bits); ++i) {
|
||||||
|
const size_t wordIndex = i / VL_EDATASIZE;
|
||||||
|
m_bits[i].aggregateVal(dt, (newval[wordIndex] >> VL_BITBIT_E(i)) & 1,
|
||||||
|
(newvalXZ[wordIndex] >> VL_BITBIT_E(i)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLastTime(time);
|
||||||
|
}
|
||||||
|
|
||||||
VerilatedSaifActivityBit& VerilatedSaifActivityVar::bit(const std::size_t index) {
|
VerilatedSaifActivityBit& VerilatedSaifActivityVar::bit(const std::size_t index) {
|
||||||
assert(index < m_width);
|
assert(index < m_width);
|
||||||
return m_bits[index];
|
return m_bits[index];
|
||||||
|
|
@ -633,6 +676,15 @@ void VerilatedSaifBuffer::emitBit(const uint32_t code, const CData newval) {
|
||||||
activity.emitBit(m_owner.currentTime(), newval);
|
activity.emitBit(m_owner.currentTime(), newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitLogic(uint32_t code, CData newval, CData newvalXZ) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitLogic(m_owner.currentTime(), newval, newvalXZ);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, const int bits) {
|
void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, const int bits) {
|
||||||
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
|
@ -642,6 +694,16 @@ void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, con
|
||||||
activity.emitData<CData>(m_owner.currentTime(), newval, bits);
|
activity.emitData<CData>(m_owner.currentTime(), newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitFourstateCData(uint32_t code, CData newval, CData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitFourstateData<CData>(m_owner.currentTime(), newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, const int bits) {
|
void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, const int bits) {
|
||||||
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
|
@ -651,6 +713,16 @@ void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, con
|
||||||
activity.emitData<SData>(m_owner.currentTime(), newval, bits);
|
activity.emitData<SData>(m_owner.currentTime(), newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitFourstateSData(uint32_t code, SData newval, SData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitFourstateData<SData>(m_owner.currentTime(), newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, const int bits) {
|
void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, const int bits) {
|
||||||
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
|
@ -660,6 +732,16 @@ void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, con
|
||||||
activity.emitData<IData>(m_owner.currentTime(), newval, bits);
|
activity.emitData<IData>(m_owner.currentTime(), newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitFourstateIData(uint32_t code, IData newval, IData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitFourstateData<IData>(m_owner.currentTime(), newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, const int bits) {
|
void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, const int bits) {
|
||||||
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
|
@ -670,7 +752,17 @@ void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, con
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitWData(const uint32_t code, WDataInP newval, const int bits) {
|
void VerilatedSaifBuffer::emitFourstateQData(uint32_t code, QData newval, QData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitFourstateData<QData>(m_owner.currentTime(), newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitWData(const uint32_t code, const WDataInP newval, const int bits) {
|
||||||
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
&& "Activity must be declared earlier");
|
&& "Activity must be declared earlier");
|
||||||
VerilatedSaifActivityVar& activity
|
VerilatedSaifActivityVar& activity
|
||||||
|
|
@ -678,6 +770,16 @@ void VerilatedSaifBuffer::emitWData(const uint32_t code, WDataInP newval, const
|
||||||
activity.emitWData(m_owner.currentTime(), newval, bits);
|
activity.emitWData(m_owner.currentTime(), newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedSaifBuffer::emitFourstateWData(const uint32_t code, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZ, const int bits) {
|
||||||
|
assert(m_owner.m_activityAccumulators.at(m_fidx)->m_activity.count(code)
|
||||||
|
&& "Activity must be declared earlier");
|
||||||
|
VerilatedSaifActivityVar& activity
|
||||||
|
= m_owner.m_activityAccumulators.at(m_fidx)->m_activity.at(code);
|
||||||
|
activity.emitFourstateWData(m_owner.currentTime(), newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedSaifBuffer::emitDouble(const uint32_t code, const double newval) {
|
void VerilatedSaifBuffer::emitDouble(const uint32_t code, const double newval) {
|
||||||
// NOP
|
// NOP
|
||||||
|
|
|
||||||
|
|
@ -243,11 +243,22 @@ class VerilatedSaifBuffer VL_NOT_FINAL {
|
||||||
// called from only one place (the full* methods), so always inline them.
|
// called from only one place (the full* methods), so always inline them.
|
||||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||||
|
VL_ATTR_ALWINLINE void emitLogic(uint32_t code, CData newval, CData newvalXZ);
|
||||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateCData(uint32_t code, CData newval, CData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateSData(uint32_t code, SData newval, SData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateIData(uint32_t code, IData newval, IData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateQData(uint32_t code, QData newval, QData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int bits);
|
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -385,11 +385,17 @@ public:
|
||||||
|
|
||||||
// Write to previous value buffer value and emit trace entry.
|
// Write to previous value buffer value and emit trace entry.
|
||||||
void fullBit(uint32_t* oldp, CData newval);
|
void fullBit(uint32_t* oldp, CData newval);
|
||||||
|
void fullLogic(uint32_t* oldp, CData newval, CData newvalXZ);
|
||||||
void fullCData(uint32_t* oldp, CData newval, int bits);
|
void fullCData(uint32_t* oldp, CData newval, int bits);
|
||||||
|
void fullFourstateCData(uint32_t* oldp, CData newval, CData newvalXZ, int bits);
|
||||||
void fullSData(uint32_t* oldp, SData newval, int bits);
|
void fullSData(uint32_t* oldp, SData newval, int bits);
|
||||||
|
void fullFourstateSData(uint32_t* oldp, SData newval, SData newvalXZ, int bits);
|
||||||
void fullIData(uint32_t* oldp, IData newval, int bits);
|
void fullIData(uint32_t* oldp, IData newval, int bits);
|
||||||
|
void fullFourstateIData(uint32_t* oldp, IData newval, IData newvalXZ, int bits);
|
||||||
void fullQData(uint32_t* oldp, QData newval, int bits);
|
void fullQData(uint32_t* oldp, QData newval, int bits);
|
||||||
|
void fullFourstateQData(uint32_t* oldp, QData newval, QData newvalXZ, int bits);
|
||||||
void fullWData(uint32_t* oldp, WDataInP newval, int bits);
|
void fullWData(uint32_t* oldp, WDataInP newval, int bits);
|
||||||
|
void fullFourstateWData(uint32_t* oldp, WDataInP newval, WDataInP newvalXZ, int bits);
|
||||||
void fullDouble(uint32_t* oldp, double newval);
|
void fullDouble(uint32_t* oldp, double newval);
|
||||||
void fullEvent(uint32_t* oldp, const VlEventBase* newvalp);
|
void fullEvent(uint32_t* oldp, const VlEventBase* newvalp);
|
||||||
void fullEventTriggered(uint32_t* oldp);
|
void fullEventTriggered(uint32_t* oldp);
|
||||||
|
|
@ -399,32 +405,71 @@ public:
|
||||||
const uint32_t diff = *oldp ^ newval;
|
const uint32_t diff = *oldp ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) fullBit(oldp, newval);
|
if (VL_UNLIKELY(diff)) fullBit(oldp, newval);
|
||||||
}
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgLogic(uint32_t* oldp, CData newval, CData newvalXZ) {
|
||||||
|
CData* oldcp = reinterpret_cast<CData*>(oldp);
|
||||||
|
const uint32_t diff = (oldcp[0] ^ newval) | (oldcp[1] ^ newvalXZ);
|
||||||
|
if (VL_UNLIKELY(diff)) fullLogic(oldp, newval, newvalXZ);
|
||||||
|
}
|
||||||
VL_ATTR_ALWINLINE void chgCData(uint32_t* oldp, CData newval, int bits) {
|
VL_ATTR_ALWINLINE void chgCData(uint32_t* oldp, CData newval, int bits) {
|
||||||
const uint32_t diff = *oldp ^ newval;
|
const uint32_t diff = *oldp ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) fullCData(oldp, newval, bits);
|
if (VL_UNLIKELY(diff)) fullCData(oldp, newval, bits);
|
||||||
}
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgFourstateCData(uint32_t* oldp, CData newval, CData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
CData* oldcp = reinterpret_cast<CData*>(oldp);
|
||||||
|
const uint32_t diff = (oldcp[0] ^ newval) | (oldcp[1] ^ newvalXZ);
|
||||||
|
if (VL_UNLIKELY(diff)) fullFourstateCData(oldp, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
VL_ATTR_ALWINLINE void chgSData(uint32_t* oldp, SData newval, int bits) {
|
VL_ATTR_ALWINLINE void chgSData(uint32_t* oldp, SData newval, int bits) {
|
||||||
const uint32_t diff = *oldp ^ newval;
|
const uint32_t diff = *oldp ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) fullSData(oldp, newval, bits);
|
if (VL_UNLIKELY(diff)) fullSData(oldp, newval, bits);
|
||||||
}
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgFourstateSData(uint32_t* oldp, SData newval, SData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
SData* oldcp = reinterpret_cast<SData*>(oldp);
|
||||||
|
const uint32_t diff = (oldcp[0] ^ newval) | (oldcp[1] ^ newvalXZ);
|
||||||
|
if (VL_UNLIKELY(diff)) fullFourstateSData(oldp, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
VL_ATTR_ALWINLINE void chgIData(uint32_t* oldp, IData newval, int bits) {
|
VL_ATTR_ALWINLINE void chgIData(uint32_t* oldp, IData newval, int bits) {
|
||||||
const uint32_t diff = *oldp ^ newval;
|
const uint32_t diff = *oldp ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) fullIData(oldp, newval, bits);
|
if (VL_UNLIKELY(diff)) fullIData(oldp, newval, bits);
|
||||||
}
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgFourstateIData(uint32_t* oldp, IData newval, IData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
IData* oldcp = reinterpret_cast<IData*>(oldp);
|
||||||
|
const uint32_t diff = (oldcp[0] ^ newval) | (oldcp[1] ^ newvalXZ);
|
||||||
|
if (VL_UNLIKELY(diff)) fullFourstateIData(oldp, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
VL_ATTR_ALWINLINE void chgQData(uint32_t* oldp, QData newval, int bits) {
|
VL_ATTR_ALWINLINE void chgQData(uint32_t* oldp, QData newval, int bits) {
|
||||||
QData old;
|
QData old;
|
||||||
std::memcpy(&old, oldp, sizeof(old));
|
std::memcpy(&old, oldp, sizeof(old));
|
||||||
const uint64_t diff = old ^ newval;
|
const uint64_t diff = old ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) fullQData(oldp, newval, bits);
|
if (VL_UNLIKELY(diff)) fullQData(oldp, newval, bits);
|
||||||
}
|
}
|
||||||
VL_ATTR_ALWINLINE void chgWData(uint32_t* oldp, WDataInP newval, int bits) {
|
VL_ATTR_ALWINLINE void chgFourstateQData(uint32_t* oldp, QData newval, QData newvalXZ,
|
||||||
for (int i = 0; i < (bits + 31) / 32; ++i) {
|
int bits) {
|
||||||
|
QData* oldcp = reinterpret_cast<QData*>(oldp);
|
||||||
|
const uint32_t diff = (oldcp[0] ^ newval) | (oldcp[1] ^ newvalXZ);
|
||||||
|
if (VL_UNLIKELY(diff)) fullFourstateQData(oldp, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgWData(uint32_t* oldp, const WDataInP newval, int bits) {
|
||||||
|
for (int i = 0; i < VL_WORDS_I(bits); ++i) {
|
||||||
if (VL_UNLIKELY(oldp[i] ^ newval[i])) {
|
if (VL_UNLIKELY(oldp[i] ^ newval[i])) {
|
||||||
fullWData(oldp, newval, bits);
|
fullWData(oldp, newval, bits);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VL_ATTR_ALWINLINE void chgFourstateWData(uint32_t* oldp, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZ, int bits) {
|
||||||
|
for (int i = 0; i < VL_WORDS_I(bits); ++i) {
|
||||||
|
const int oldIdx = i << 1;
|
||||||
|
if (VL_UNLIKELY((oldp[oldIdx] ^ newval[i]) | (oldp[oldIdx | 1] ^ newvalXZ[i]))) {
|
||||||
|
fullFourstateWData(oldp, newval, newvalXZ, bits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, const VlEventBase* newvalp) {
|
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, const VlEventBase* newvalp) {
|
||||||
if (newvalp->isTriggered()) fullEvent(oldp, newvalp);
|
if (newvalp->isTriggered()) fullEvent(oldp, newvalp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -555,6 +555,16 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullBit(uint32_t* oldp, CData newval) {
|
||||||
emitBit(code, newval);
|
emitBit(code, newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullLogic(uint32_t* oldp, CData newval, CData newvalXZ) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
CData* oldcp = reinterpret_cast<CData*>(oldp);
|
||||||
|
oldcp[0] = newval; // Still copy even if not tracing so chg doesn't call full
|
||||||
|
oldcp[1] = newvalXZ;
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitLogic(code, newval, newvalXZ);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newvalp) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newvalp) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
|
@ -577,6 +587,17 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullCData(uint32_t* oldp, CData newval, int
|
||||||
emitCData(code, newval, bits);
|
emitCData(code, newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullFourstateCData(uint32_t* oldp, CData newval,
|
||||||
|
CData newvalXZ, int bits) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
CData* oldcp = reinterpret_cast<CData*>(oldp);
|
||||||
|
oldcp[0] = newval; // Still copy even if not tracing so chg doesn't call full
|
||||||
|
oldcp[1] = newvalXZ;
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitFourstateCData(code, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullSData(uint32_t* oldp, SData newval, int bits) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullSData(uint32_t* oldp, SData newval, int bits) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
|
@ -585,6 +606,17 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullSData(uint32_t* oldp, SData newval, int
|
||||||
emitSData(code, newval, bits);
|
emitSData(code, newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullFourstateSData(uint32_t* oldp, SData newval,
|
||||||
|
SData newvalXZ, int bits) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
SData* oldcp = reinterpret_cast<SData*>(oldp);
|
||||||
|
oldcp[0] = newval; // Still copy even if not tracing so chg doesn't call full
|
||||||
|
oldcp[1] = newvalXZ;
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitFourstateSData(code, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullIData(uint32_t* oldp, IData newval, int bits) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullIData(uint32_t* oldp, IData newval, int bits) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
|
@ -593,6 +625,17 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullIData(uint32_t* oldp, IData newval, int
|
||||||
emitIData(code, newval, bits);
|
emitIData(code, newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullFourstateIData(uint32_t* oldp, IData newval,
|
||||||
|
IData newvalXZ, int bits) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
IData* oldcp = reinterpret_cast<IData*>(oldp);
|
||||||
|
oldcp[0] = newval; // Still copy even if not tracing so chg doesn't call full
|
||||||
|
oldcp[1] = newvalXZ;
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitFourstateIData(code, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullQData(uint32_t* oldp, QData newval, int bits) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullQData(uint32_t* oldp, QData newval, int bits) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
|
@ -602,13 +645,37 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullQData(uint32_t* oldp, QData newval, int
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullWData(uint32_t* oldp, WDataInP newval, int bits) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullFourstateQData(uint32_t* oldp, QData newval,
|
||||||
|
QData newvalXZ, int bits) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
QData* oldcp = reinterpret_cast<QData*>(oldp);
|
||||||
|
oldcp[0] = newval; // Still copy even if not tracing so chg doesn't call full
|
||||||
|
oldcp[1] = newvalXZ;
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitFourstateQData(code, newval, newvalXZ, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullWData(uint32_t* oldp, const WDataInP newval, int bits) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
for (int i = 0; i < VL_WORDS_I(bits); ++i) oldp[i] = newval[i];
|
for (int i = 0; i < VL_WORDS_I(bits); ++i) oldp[i] = newval[i];
|
||||||
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
emitWData(code, newval, bits);
|
emitWData(code, newval, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void VerilatedTraceBuffer<VL_BUF_T>::fullFourstateWData(uint32_t* oldp, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZp, int bits) {
|
||||||
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
for (int i = 0; i < VL_WORDS_I(bits); ++i) {
|
||||||
|
const int oldIdx = i << 1;
|
||||||
|
oldp[oldIdx] = newval[i];
|
||||||
|
oldp[oldIdx | 1] = newvalXZp[i];
|
||||||
|
}
|
||||||
|
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
|
||||||
|
emitFourstateWData(code, newval, newvalXZp, bits);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void VerilatedTraceBuffer<VL_BUF_T>::fullDouble(uint32_t* oldp, double newval) {
|
void VerilatedTraceBuffer<VL_BUF_T>::fullDouble(uint32_t* oldp, double newval) {
|
||||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,18 @@ void VerilatedVcdBuffer::emitBit(uint32_t code, CData newval) {
|
||||||
finishLine(code, wp);
|
finishLine(code, wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitLogic(uint32_t code, CData newval, CData newvalXZ) {
|
||||||
|
// Don't prefetch suffix as it's a bit too late;
|
||||||
|
char* wp = m_writep;
|
||||||
|
if (newval) {
|
||||||
|
*wp++ = newvalXZ ? 'x' : '1';
|
||||||
|
} else {
|
||||||
|
*wp++ = newvalXZ ? 'z' : '0';
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
void VerilatedVcdBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
|
|
@ -643,6 +655,19 @@ void VerilatedVcdBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
||||||
finishLine(code, wp + bits);
|
finishLine(code, wp + bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitFourstateCData(uint32_t code, CData newval, CData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
char* wp = m_writep;
|
||||||
|
*wp++ = 'b';
|
||||||
|
for (int i = bits - 1; i >= 0; --i) {
|
||||||
|
const CData mask = 1 << i;
|
||||||
|
*wp++ = (newvalXZ & mask) ? (newval & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(newval >> i) & 1));
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
void VerilatedVcdBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
|
|
@ -651,6 +676,19 @@ void VerilatedVcdBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
||||||
finishLine(code, wp + bits);
|
finishLine(code, wp + bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitFourstateSData(uint32_t code, SData newval, SData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
char* wp = m_writep;
|
||||||
|
*wp++ = 'b';
|
||||||
|
for (int i = bits - 1; i >= 0; --i) {
|
||||||
|
const SData mask = 1 << i;
|
||||||
|
*wp++ = (newvalXZ & mask) ? (newval & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(newval >> i) & 1));
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
void VerilatedVcdBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
|
|
@ -659,6 +697,19 @@ void VerilatedVcdBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
||||||
finishLine(code, wp + bits);
|
finishLine(code, wp + bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitFourstateIData(uint32_t code, IData newval, IData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
char* wp = m_writep;
|
||||||
|
*wp++ = 'b';
|
||||||
|
for (int i = bits - 1; i >= 0; --i) {
|
||||||
|
const IData mask = 1 << i;
|
||||||
|
*wp++ = (newvalXZ & mask) ? (newval & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(newval >> i) & 1));
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
void VerilatedVcdBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
|
|
@ -668,7 +719,20 @@ void VerilatedVcdBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitWData(uint32_t code, WDataInP newval, int bits) {
|
void VerilatedVcdBuffer::emitFourstateQData(uint32_t code, QData newval, QData newvalXZ,
|
||||||
|
int bits) {
|
||||||
|
char* wp = m_writep;
|
||||||
|
*wp++ = 'b';
|
||||||
|
for (int i = bits - 1; i >= 0; --i) {
|
||||||
|
const QData mask = 1 << i;
|
||||||
|
*wp++ = (newvalXZ & mask) ? (newval & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(newval >> i) & 1));
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitWData(uint32_t code, const WDataInP newval, int bits) {
|
||||||
int words = VL_WORDS_I(bits);
|
int words = VL_WORDS_I(bits);
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
*wp++ = 'b';
|
*wp++ = 'b';
|
||||||
|
|
@ -684,6 +748,33 @@ void VerilatedVcdBuffer::emitWData(uint32_t code, WDataInP newval, int bits) {
|
||||||
finishLine(code, wp);
|
finishLine(code, wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VL_ATTR_ALWINLINE
|
||||||
|
void VerilatedVcdBuffer::emitFourstateWData(uint32_t code, const WDataInP newval,
|
||||||
|
const WDataInP newvalXZ, int bits) {
|
||||||
|
char* wp = m_writep;
|
||||||
|
*wp++ = 'b';
|
||||||
|
const int lastIdx = (bits - 1) / VL_EDATASIZE;
|
||||||
|
{
|
||||||
|
const EData value = newval[lastIdx];
|
||||||
|
const EData xz = newvalXZ[lastIdx];
|
||||||
|
for (int i = (bits - 1) % VL_EDATASIZE; i >= 0; --i) {
|
||||||
|
const EData mask = 1 << i;
|
||||||
|
*wp++ = (xz & mask) ? (value & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(value >> i) & 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int w = lastIdx - 1; w >= 0; --w) {
|
||||||
|
const EData value = newval[w];
|
||||||
|
const EData xz = newvalXZ[w];
|
||||||
|
for (int i = VL_EDATASIZE - 1; i >= 0; --i) {
|
||||||
|
const EData mask = 1 << i;
|
||||||
|
*wp++ = (xz & mask) ? (value & mask ? 'x' : 'z')
|
||||||
|
: ('0' | (static_cast<char>(value >> i) & 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finishLine(code, wp);
|
||||||
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedVcdBuffer::emitDouble(uint32_t code, double newval) {
|
void VerilatedVcdBuffer::emitDouble(uint32_t code, double newval) {
|
||||||
char* wp = m_writep;
|
char* wp = m_writep;
|
||||||
|
|
|
||||||
|
|
@ -247,11 +247,22 @@ class VerilatedVcdBuffer VL_NOT_FINAL {
|
||||||
// called from only one place (the full* methods), so always inline them.
|
// called from only one place (the full* methods), so always inline them.
|
||||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||||
|
VL_ATTR_ALWINLINE void emitLogic(uint32_t code, CData newval, CData newvalXZ);
|
||||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateCData(uint32_t code, CData newval, CData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateSData(uint32_t code, SData newval, SData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateIData(uint32_t code, IData newval, IData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateQData(uint32_t code, QData newval, QData newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int bits);
|
VL_ATTR_ALWINLINE void emitWData(uint32_t code, WDataInP newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||||
|
int bits);
|
||||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ set(HEADERS
|
||||||
V3Force.h
|
V3Force.h
|
||||||
V3FsmDetect.h
|
V3FsmDetect.h
|
||||||
V3Fork.h
|
V3Fork.h
|
||||||
|
V3Fourstate.h
|
||||||
V3FuncOpt.h
|
V3FuncOpt.h
|
||||||
V3FunctionTraits.h
|
V3FunctionTraits.h
|
||||||
V3Gate.h
|
V3Gate.h
|
||||||
|
|
@ -280,6 +281,7 @@ set(COMMON_SOURCES
|
||||||
V3Force.cpp
|
V3Force.cpp
|
||||||
V3FsmDetect.cpp
|
V3FsmDetect.cpp
|
||||||
V3Fork.cpp
|
V3Fork.cpp
|
||||||
|
V3Fourstate.cpp
|
||||||
V3FuncOpt.cpp
|
V3FuncOpt.cpp
|
||||||
V3Gate.cpp
|
V3Gate.cpp
|
||||||
V3Global.cpp
|
V3Global.cpp
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,7 @@ RAW_OBJS_PCH_ASTNOMT = \
|
||||||
V3Force.o \
|
V3Force.o \
|
||||||
V3FsmDetect.o \
|
V3FsmDetect.o \
|
||||||
V3Fork.o \
|
V3Fork.o \
|
||||||
|
V3Fourstate.o \
|
||||||
V3Gate.o \
|
V3Gate.o \
|
||||||
V3HierBlock.o \
|
V3HierBlock.o \
|
||||||
V3Inline.o \
|
V3Inline.o \
|
||||||
|
|
|
||||||
|
|
@ -1675,6 +1675,27 @@ public:
|
||||||
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
||||||
bool isSystemFunc() const override { return true; }
|
bool isSystemFunc() const override { return true; }
|
||||||
};
|
};
|
||||||
|
class AstFourstateExpr final : public AstNodeExpr {
|
||||||
|
// When AstNode wants a value as an child and that value is a splitted four-state value (so, it
|
||||||
|
// has value and xz part) this node shall be used to put them both there
|
||||||
|
// @astgen op1 := valuep : AstNodeExpr // value part of a four-state expression
|
||||||
|
// @astgen op2 := xzp : AstNodeExpr // xz part of a four-state expression
|
||||||
|
public:
|
||||||
|
AstFourstateExpr(FileLine* fl, AstNodeExpr* const valuePartp, AstNodeExpr* const xzPartp)
|
||||||
|
: ASTGEN_SUPER_FourstateExpr(fl) {
|
||||||
|
UASSERT_OBJ(valuePartp->width() == xzPartp->width(), this,
|
||||||
|
"Value and XZ part shall have same width but they have: "
|
||||||
|
<< valuePartp->width() << " and " << xzPartp->width());
|
||||||
|
valuep(valuePartp);
|
||||||
|
xzp(xzPartp);
|
||||||
|
dtypeSetLogicUnsized(valuePartp->width(), valuePartp->dtypep()->widthMin(),
|
||||||
|
valuePartp->dtypep()->numeric());
|
||||||
|
}
|
||||||
|
ASTGEN_MEMBERS_AstFourstateExpr;
|
||||||
|
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||||
|
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
|
bool cleanOut() const override { return true; }
|
||||||
|
};
|
||||||
class AstFuture final : public AstNodeExpr {
|
class AstFuture final : public AstNodeExpr {
|
||||||
// Verilog $future_gclk
|
// Verilog $future_gclk
|
||||||
// @astgen op1 := exprp : AstNodeExpr
|
// @astgen op1 := exprp : AstNodeExpr
|
||||||
|
|
@ -5504,6 +5525,7 @@ public:
|
||||||
void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); }
|
void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); }
|
||||||
string emitVerilog() override { return "(%l)"; }
|
string emitVerilog() override { return "(%l)"; }
|
||||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
|
string emitSMT() const override { return "%l"; }
|
||||||
bool cleanOut() const override { return false; }
|
bool cleanOut() const override { return false; }
|
||||||
bool cleanLhs() const override { return false; }
|
bool cleanLhs() const override { return false; }
|
||||||
bool sizeMattersLhs() const override { return false; }
|
bool sizeMattersLhs() const override { return false; }
|
||||||
|
|
|
||||||
|
|
@ -2117,6 +2117,8 @@ class AstVar final : public AstNode {
|
||||||
// @astgen op4 := attrsp : List[AstNode] // Attributes during early parse
|
// @astgen op4 := attrsp : List[AstNode] // Attributes during early parse
|
||||||
// @astgen ptr := m_sensIfacep : Optional[AstIface] // Interface type to which reads from this
|
// @astgen ptr := m_sensIfacep : Optional[AstIface] // Interface type to which reads from this
|
||||||
// var are sensitive
|
// var are sensitive
|
||||||
|
// @astgen ptr := m_fourstateComplementp : Optional[AstVar] // Set in four-state value part -
|
||||||
|
// points to an xz part
|
||||||
|
|
||||||
string m_name; // Name of variable
|
string m_name; // Name of variable
|
||||||
string m_origName; // Original name before dot addition
|
string m_origName; // Original name before dot addition
|
||||||
|
|
@ -2126,6 +2128,8 @@ class AstVar final : public AstNode {
|
||||||
VDirection m_declDirection; // Declared direction input/output etc
|
VDirection m_declDirection; // Declared direction input/output etc
|
||||||
VLifetime m_lifetime; // Lifetime
|
VLifetime m_lifetime; // Lifetime
|
||||||
VRandAttr m_rand; // Randomizability of this variable (rand, randc, etc)
|
VRandAttr m_rand; // Randomizability of this variable (rand, randc, etc)
|
||||||
|
VBasicDTypeKwd
|
||||||
|
m_fourstateOriginalDTypeKwd; // Original dtype of a four-state var - before splitting
|
||||||
int m_pinNum = 0; // For JSON, if non-zero the connection pin number
|
int m_pinNum = 0; // For JSON, if non-zero the connection pin number
|
||||||
bool m_ansi : 1; // Params or pins declared in the module header, rather than the body
|
bool m_ansi : 1; // Params or pins declared in the module header, rather than the body
|
||||||
bool m_declTyped : 1; // Declared as type (for dedup check)
|
bool m_declTyped : 1; // Declared as type (for dedup check)
|
||||||
|
|
@ -2190,7 +2194,9 @@ class AstVar final : public AstNode {
|
||||||
bool m_isStdRandomizeArg : 1; // Argument variable created for std::randomize (__Varg*)
|
bool m_isStdRandomizeArg : 1; // Argument variable created for std::randomize (__Varg*)
|
||||||
bool m_processQueue : 1; // Process queue variable
|
bool m_processQueue : 1; // Process queue variable
|
||||||
bool m_mtaskCacheLineAlign : 1; // Start MTask affinity group on a cache line
|
bool m_mtaskCacheLineAlign : 1; // Start MTask affinity group on a cache line
|
||||||
|
bool m_isFourstateComplement : 1; // Set in four-state xz part
|
||||||
void init() {
|
void init() {
|
||||||
|
m_fourstateOriginalDTypeKwd = VBasicDTypeKwd::UNKNOWN;
|
||||||
m_ansi = false;
|
m_ansi = false;
|
||||||
m_declTyped = false;
|
m_declTyped = false;
|
||||||
m_tristate = false;
|
m_tristate = false;
|
||||||
|
|
@ -2254,6 +2260,7 @@ class AstVar final : public AstNode {
|
||||||
m_isStdRandomizeArg = false;
|
m_isStdRandomizeArg = false;
|
||||||
m_processQueue = false;
|
m_processQueue = false;
|
||||||
m_mtaskCacheLineAlign = false;
|
m_mtaskCacheLineAlign = false;
|
||||||
|
m_isFourstateComplement = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -2356,6 +2363,19 @@ public:
|
||||||
void ansi(bool flag) { m_ansi = flag; }
|
void ansi(bool flag) { m_ansi = flag; }
|
||||||
void declTyped(bool flag) { m_declTyped = flag; }
|
void declTyped(bool flag) { m_declTyped = flag; }
|
||||||
void sensIfacep(AstIface* nodep) { m_sensIfacep = nodep; }
|
void sensIfacep(AstIface* nodep) { m_sensIfacep = nodep; }
|
||||||
|
void fourstateComplementp(AstVar* const varp) {
|
||||||
|
UASSERT_OBJ(!isFourstateComplement(), this, "Varp is four-state complement i");
|
||||||
|
UASSERT_OBJ(!m_fourstateComplementp, this, "Varp already has a complement");
|
||||||
|
UASSERT_OBJ(!varp->isFourstateComplement(), varp, "It is already a four-state complement");
|
||||||
|
varp->m_isFourstateComplement = true;
|
||||||
|
m_fourstateComplementp = varp;
|
||||||
|
}
|
||||||
|
AstVar* fourstateComplementp() const { return m_fourstateComplementp; }
|
||||||
|
VBasicDTypeKwd fourstateOriginalDTypeKwd() const { return m_fourstateOriginalDTypeKwd; }
|
||||||
|
void fourstateOriginalDTypeKwd(const VBasicDTypeKwd dtypeKwd) {
|
||||||
|
m_fourstateOriginalDTypeKwd = dtypeKwd;
|
||||||
|
}
|
||||||
|
bool isFourstateComplement() const { return m_isFourstateComplement; }
|
||||||
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
||||||
void attrScBv(bool flag) { m_attrScBv = flag; }
|
void attrScBv(bool flag) { m_attrScBv = flag; }
|
||||||
void attrScBigUint(bool flag) { m_attrScBigUint = flag; }
|
void attrScBigUint(bool flag) { m_attrScBigUint = flag; }
|
||||||
|
|
|
||||||
|
|
@ -1297,8 +1297,10 @@ class AstTraceDecl final : public AstNodeStmt {
|
||||||
const VNumRange m_arrayRange; // Property of var the trace details
|
const VNumRange m_arrayRange; // Property of var the trace details
|
||||||
const VVarType m_varType; // Type of variable (for localparam vs. param)
|
const VVarType m_varType; // Type of variable (for localparam vs. param)
|
||||||
const VDirection m_declDirection; // Declared direction input/output etc
|
const VDirection m_declDirection; // Declared direction input/output etc
|
||||||
|
const VBasicDTypeKwd m_dtypeKwd; // dtype keyword of traced signal
|
||||||
const bool m_inDtypeFunc; // Trace decl inside type init function
|
const bool m_inDtypeFunc; // Trace decl inside type init function
|
||||||
int m_codeInc{0}; // Code increment for type
|
int m_codeInc{0}; // Code increment for type
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AstTraceDecl(FileLine* fl, const string& showname,
|
AstTraceDecl(FileLine* fl, const string& showname,
|
||||||
AstVar* varp, // For input/output state etc
|
AstVar* varp, // For input/output state etc
|
||||||
|
|
@ -1310,6 +1312,7 @@ public:
|
||||||
, m_arrayRange{arrayRange}
|
, m_arrayRange{arrayRange}
|
||||||
, m_varType{varp->varType()}
|
, m_varType{varp->varType()}
|
||||||
, m_declDirection{varp->declDirection()}
|
, m_declDirection{varp->declDirection()}
|
||||||
|
, m_dtypeKwd{varp->fourstateOriginalDTypeKwd()}
|
||||||
, m_inDtypeFunc{inDtypeFunc} {
|
, m_inDtypeFunc{inDtypeFunc} {
|
||||||
dtypeFrom(valuep);
|
dtypeFrom(valuep);
|
||||||
this->valuep(valuep);
|
this->valuep(valuep);
|
||||||
|
|
@ -1335,12 +1338,15 @@ public:
|
||||||
if (m_codeInc) { return m_codeInc; }
|
if (m_codeInc) { return m_codeInc; }
|
||||||
return (m_arrayRange.ranged() ? m_arrayRange.elements() : 1)
|
return (m_arrayRange.ranged() ? m_arrayRange.elements() : 1)
|
||||||
* valuep()->dtypep()->widthWords()
|
* valuep()->dtypep()->widthWords()
|
||||||
|
* (1 + VN_IS(valuep(), FourstateExpr)) // Fourstate variables take twice
|
||||||
|
// as much space as they are wide
|
||||||
* (VL_EDATASIZE / 32); // A code is always 32-bits
|
* (VL_EDATASIZE / 32); // A code is always 32-bits
|
||||||
}
|
}
|
||||||
const VNumRange& bitRange() const { return m_bitRange; }
|
const VNumRange& bitRange() const { return m_bitRange; }
|
||||||
const VNumRange& arrayRange() const { return m_arrayRange; }
|
const VNumRange& arrayRange() const { return m_arrayRange; }
|
||||||
VVarType varType() const { return m_varType; }
|
VVarType varType() const { return m_varType; }
|
||||||
VDirection declDirection() const { return m_declDirection; }
|
VDirection declDirection() const { return m_declDirection; }
|
||||||
|
VBasicDTypeKwd dtypeKwd() const { return m_dtypeKwd; }
|
||||||
AstCCall* dtypeCallp() const { return m_dtypeCallp; }
|
AstCCall* dtypeCallp() const { return m_dtypeCallp; }
|
||||||
void dtypeCallp(AstCCall* const callp) { m_dtypeCallp = callp; }
|
void dtypeCallp(AstCCall* const callp) { m_dtypeCallp = callp; }
|
||||||
AstTraceDecl* dtypeDeclp() const { return m_dtypeDeclp; }
|
AstTraceDecl* dtypeDeclp() const { return m_dtypeDeclp; }
|
||||||
|
|
|
||||||
|
|
@ -3846,8 +3846,9 @@ class ConstVisitor final : public VNVisitor {
|
||||||
nodep->condp(new AstLogNot{condp->fileline(),
|
nodep->condp(new AstLogNot{condp->fileline(),
|
||||||
condp}); // LogNot, as C++ optimization also possible
|
condp}); // LogNot, as C++ optimization also possible
|
||||||
nodep->addThensp(elsesp);
|
nodep->addThensp(elsesp);
|
||||||
} else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|
} else if (v3Global.fourstateHandled()
|
||||||
|| VN_IS(nodep->condp(), LogNot))
|
&& ((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|
||||||
|
|| VN_IS(nodep->condp(), LogNot))
|
||||||
&& nodep->thensp() && nodep->elsesp()) {
|
&& nodep->thensp() && nodep->elsesp()) {
|
||||||
UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep);
|
UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep);
|
||||||
AstNodeExpr* const condp
|
AstNodeExpr* const condp
|
||||||
|
|
@ -3859,7 +3860,7 @@ class ConstVisitor final : public VNVisitor {
|
||||||
ifp->branchPred(nodep->branchPred().invert());
|
ifp->branchPred(nodep->branchPred().invert());
|
||||||
nodep->replaceWith(ifp);
|
nodep->replaceWith(ifp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
} else if (ifSameAssign(nodep)) {
|
} else if (v3Global.fourstateHandled() && ifSameAssign(nodep)) {
|
||||||
UINFO(4,
|
UINFO(4,
|
||||||
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})");
|
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})");
|
||||||
AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
|
AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
|
||||||
|
|
|
||||||
|
|
@ -489,8 +489,12 @@ class DeadVisitor final : public VNVisitor {
|
||||||
retry = false;
|
retry = false;
|
||||||
for (std::vector<AstVar*>::iterator it = m_varsp.begin(); it != m_varsp.end(); ++it) {
|
for (std::vector<AstVar*>::iterator it = m_varsp.begin(); it != m_varsp.end(); ++it) {
|
||||||
AstVar* const varp = *it;
|
AstVar* const varp = *it;
|
||||||
if (!varp) continue;
|
if (!varp || varp->isFourstateComplement()) continue;
|
||||||
if (varp->user1() == 0) {
|
if (varp->user1() == 0) {
|
||||||
|
if (AstVar* const varComplementp = varp->fourstateComplementp()) {
|
||||||
|
if (varComplementp->user1() != 0) continue;
|
||||||
|
deleting(varComplementp);
|
||||||
|
}
|
||||||
UINFO(4, " Dead " << varp);
|
UINFO(4, " Dead " << varp);
|
||||||
if (varp->dtypep()) varp->dtypep()->user1Inc(-1);
|
if (varp->dtypep()) varp->dtypep()->user1Inc(-1);
|
||||||
deleting(varp);
|
deleting(varp);
|
||||||
|
|
|
||||||
|
|
@ -645,6 +645,23 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
|
||||||
UASSERT_OBJ(constp, varp, "non-const initializer for variable");
|
UASSERT_OBJ(constp, varp, "non-const initializer for variable");
|
||||||
out += cvtToStr(constp->num().edataWord(0)) + "U;\n";
|
out += cvtToStr(constp->num().edataWord(0)) + "U;\n";
|
||||||
out += ";\n";
|
out += ";\n";
|
||||||
|
} else if (v3Global.opt.fourstate()
|
||||||
|
&& (varp->fourstateComplementp() || varp->isFourstateComplement())) {
|
||||||
|
V3Number xNum{varp->fileline(), varp->width(), 0};
|
||||||
|
bool setTozero = false;
|
||||||
|
if (varp->varType() == VVarType::PORT) {
|
||||||
|
const AstNode* iter = varp;
|
||||||
|
while (!iter->firstAbovep()) iter = iter->backp();
|
||||||
|
if (AstModule* const modep = VN_CAST(iter->firstAbovep(), Module)) {
|
||||||
|
setTozero = modep->isTop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!setTozero && (varp->isFourstateComplement() || !varp->varType().isNet())) {
|
||||||
|
xNum.setAllBits1();
|
||||||
|
}
|
||||||
|
out += " = ";
|
||||||
|
out += xNum.emitC();
|
||||||
|
out += ";\n";
|
||||||
} else if (zeroit) {
|
} else if (zeroit) {
|
||||||
out += " = 0;\n";
|
out += " = 0;\n";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -740,8 +740,9 @@ class EmitCTrace final : public EmitCFunc {
|
||||||
|
|
||||||
void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) {
|
void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) {
|
||||||
// Note: Both VTraceType::CHANGE and VTraceType::FULL use the 'full' methods
|
// Note: Both VTraceType::CHANGE and VTraceType::FULL use the 'full' methods
|
||||||
const std::string func = nodep->traceType() == VTraceType::CHANGE ? "chg" : "full";
|
std::string func = nodep->traceType() == VTraceType::CHANGE ? "chg" : "full";
|
||||||
bool emitWidth = true;
|
bool emitWidth = true;
|
||||||
|
const bool isFourstate = VN_IS(nodep->valuep(), FourstateExpr);
|
||||||
string stype;
|
string stype;
|
||||||
if (nodep->dtypep()->basicp()->isDouble()) {
|
if (nodep->dtypep()->basicp()->isDouble()) {
|
||||||
stype = "Double";
|
stype = "Double";
|
||||||
|
|
@ -759,10 +760,14 @@ class EmitCTrace final : public EmitCFunc {
|
||||||
} else if (nodep->dtypep()->basicp()->isEvent()) {
|
} else if (nodep->dtypep()->basicp()->isEvent()) {
|
||||||
stype = "Event";
|
stype = "Event";
|
||||||
emitWidth = false;
|
emitWidth = false;
|
||||||
|
} else if (isFourstate) {
|
||||||
|
stype = "Logic";
|
||||||
|
emitWidth = false;
|
||||||
} else {
|
} else {
|
||||||
stype = "Bit";
|
stype = "Bit";
|
||||||
emitWidth = false;
|
emitWidth = false;
|
||||||
}
|
}
|
||||||
|
if (isFourstate && stype != "Logic") func += "Fourstate";
|
||||||
putns(nodep, "bufp->" + func + stype);
|
putns(nodep, "bufp->" + func + stype);
|
||||||
|
|
||||||
const uint32_t offset = (arrayindex < 0) ? 0 : (arrayindex * nodep->declp()->widthWords());
|
const uint32_t offset = (arrayindex < 0) ? 0 : (arrayindex * nodep->declp()->widthWords());
|
||||||
|
|
@ -781,8 +786,8 @@ class EmitCTrace final : public EmitCFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitTraceValue(const AstTraceInc* nodep, int arrayindex) {
|
void emitTraceValue(const AstTraceInc* nodep, int arrayindex) {
|
||||||
if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) {
|
auto putVarRef = [this, nodep, arrayindex](AstVarRef* const varrefp) {
|
||||||
const AstVar* const varp = varrefp->varp();
|
AstVar* const varp = varrefp->varp();
|
||||||
if (varp->isEvent()) puts("&");
|
if (varp->isEvent()) puts("&");
|
||||||
puts("(");
|
puts("(");
|
||||||
if (emitTraceIsScBigUint(nodep)) {
|
if (emitTraceIsScBigUint(nodep)) {
|
||||||
|
|
@ -801,12 +806,29 @@ class EmitCTrace final : public EmitCFunc {
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
puts(")");
|
puts(")");
|
||||||
|
};
|
||||||
|
puts("(");
|
||||||
|
if (AstFourstateExpr* const exprp = VN_CAST(nodep->valuep(), FourstateExpr)) {
|
||||||
|
if (AstVarRef* const varrefp = VN_CAST(exprp->valuep(), VarRef)) {
|
||||||
|
putVarRef(varrefp);
|
||||||
|
} else {
|
||||||
|
iterateConst(exprp->valuep());
|
||||||
|
}
|
||||||
|
puts("), (");
|
||||||
|
if (AstVarRef* const varrefp = VN_CAST(exprp->xzp(), VarRef)) {
|
||||||
|
putVarRef(varrefp);
|
||||||
|
} else {
|
||||||
|
iterateConst(exprp->xzp());
|
||||||
|
}
|
||||||
|
} else if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) {
|
||||||
|
putVarRef(varrefp);
|
||||||
} else {
|
} else {
|
||||||
puts("(");
|
puts("(");
|
||||||
iterateConst(nodep->valuep());
|
iterateConst(nodep->valuep());
|
||||||
emitTraceIndex(nodep, arrayindex);
|
emitTraceIndex(nodep, arrayindex);
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
|
puts(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitTraceIndex(const AstTraceInc* const nodep, int arrayindex) {
|
void emitTraceIndex(const AstTraceInc* const nodep, int arrayindex) {
|
||||||
|
|
|
||||||
|
|
@ -639,6 +639,13 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
||||||
iterateConst(nodep->exprp());
|
iterateConst(nodep->exprp());
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
}
|
}
|
||||||
|
void visit(AstFourstateExpr* const nodep) override {
|
||||||
|
puts("Four-state expression: (Value part: ");
|
||||||
|
iterateConst(nodep->valuep());
|
||||||
|
puts(", XZ part:");
|
||||||
|
iterateConst(nodep->xzp());
|
||||||
|
puts(")");
|
||||||
|
}
|
||||||
|
|
||||||
// Nodes involing AstText
|
// Nodes involing AstText
|
||||||
void visit(AstText* nodep) override {
|
void visit(AstText* nodep) override {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ public:
|
||||||
CASEWITHX, // Case with X values
|
CASEWITHX, // Case with X values
|
||||||
CASEX, // Casex
|
CASEX, // Casex
|
||||||
CASTCONST, // Cast is constant
|
CASTCONST, // Cast is constant
|
||||||
|
CASTFOURSTATE, // Implicit logic (between 2/4 state logic)
|
||||||
CDCRSTLOGIC, // Logic in async reset path. Historical, never issued.
|
CDCRSTLOGIC, // Logic in async reset path. Historical, never issued.
|
||||||
CLKDATA, // Clock used as data. Historical, never issued.
|
CLKDATA, // Clock used as data. Historical, never issued.
|
||||||
CMPCONST, // Comparison is constant due to limited range
|
CMPCONST, // Comparison is constant due to limited range
|
||||||
|
|
@ -226,24 +227,24 @@ public:
|
||||||
" EC_FIRST_WARN", "ALWCOMBORDER", "ALWNEVER", "ASCRANGE", "ASSIGNDLY", "ASSIGNEQEXPR",
|
" EC_FIRST_WARN", "ALWCOMBORDER", "ALWNEVER", "ASCRANGE", "ASSIGNDLY", "ASSIGNEQEXPR",
|
||||||
"ASSIGNIN", "BADSTDPRAGMA", "BADVLTPRAGMA", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ",
|
"ASSIGNIN", "BADSTDPRAGMA", "BADVLTPRAGMA", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ",
|
||||||
"BSSPACE", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST",
|
"BSSPACE", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST",
|
||||||
"CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY", "CONSTRAINTIGN",
|
"CASTFOURSTATE", "CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY",
|
||||||
"CONTASSREG", "COVERIGN", "DECLFILENAME", "DEFOVERRIDE", "DEFPARAM", "DEPRECATED",
|
"CONSTRAINTIGN", "CONTASSREG", "COVERIGN", "DECLFILENAME", "DEFOVERRIDE", "DEFPARAM",
|
||||||
"ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE", "FINALDLY",
|
"DEPRECATED", "ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE",
|
||||||
"FSMMULTI", "FUNCTIMECTL", "FUTURE", "GENCLK", "GENUNNAMED", "HIERBLOCK", "HIERPARAM",
|
"FINALDLY", "FSMMULTI", "FUNCTIMECTL", "FUTURE", "GENCLK", "GENUNNAMED", "HIERBLOCK",
|
||||||
"IEEEMAYDEPRECATE", "IFDEPTH", "IGNOREDRETURN", "IMPERFECTSCH", "IMPLICIT",
|
"HIERPARAM", "IEEEMAYDEPRECATE", "IFDEPTH", "IGNOREDRETURN", "IMPERFECTSCH",
|
||||||
"IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP", "INITIALDLY",
|
"IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP",
|
||||||
"INSECURE", "INSIDETRUE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP",
|
"INITIALDLY", "INSECURE", "INSIDETRUE", "LATCH", "LITENDIAN", "MINTYPMAXDLY",
|
||||||
"MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD",
|
"MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT",
|
||||||
"NORETURN", "NOTREDOP", "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING",
|
"NOLATCH", "NONSTD", "NORETURN", "NOTREDOP", "NULLPORT", "PARAMNODEFAULT",
|
||||||
"PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT",
|
"PINCONNECTEMPTY", "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL",
|
||||||
"PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT",
|
"PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED",
|
||||||
"REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN",
|
"PROTOTYPEMIS", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY", "SELRANGE",
|
||||||
"SPLITVAR", "STATICVAR", "STMTDLY", "SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET",
|
"SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", "STATICVAR", "STMTDLY",
|
||||||
"TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
"SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN",
|
||||||
"UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED", "UNUSEDGENVAR", "UNUSEDLOOP",
|
"UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED",
|
||||||
"UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
"UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL",
|
||||||
"VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC",
|
"USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT",
|
||||||
"WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
|
"WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
}
|
}
|
||||||
// Warnings that default to off
|
// Warnings that default to off
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,32 @@
|
||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//*************************************************************************
|
||||||
|
// DESCRIPTION: Verilator: Four-state logic handler
|
||||||
|
//
|
||||||
|
// Code available from: https://verilator.org
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
// or the Perl Artistic License Version 2.0.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
#ifndef VERILATOR_V3FOURSTATE_METHOD_H_
|
||||||
|
#define VERILATOR_V3FOURSTATE_METHOD_H_
|
||||||
|
|
||||||
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
|
|
||||||
|
class AstNetlist;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
class V3Fourstate final {
|
||||||
|
public:
|
||||||
|
static void fourstateAll(AstNetlist* nodep) VL_MT_DISABLED;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Guard
|
||||||
|
|
@ -135,6 +135,7 @@ class V3Global final {
|
||||||
bool m_useCovergroup = false; // Has covergroup declarations
|
bool m_useCovergroup = false; // Has covergroup declarations
|
||||||
bool m_useRandomizeMethods = false; // Need to define randomize() class methods
|
bool m_useRandomizeMethods = false; // Need to define randomize() class methods
|
||||||
bool m_hasPrintedObjects = false; // Design has format args printed with to_string()
|
bool m_hasPrintedObjects = false; // Design has format args printed with to_string()
|
||||||
|
bool m_fourstateHandled = false; // There should be no more fourstate values
|
||||||
uint64_t m_currentHierBlockCost = 0; // Total cost of this hier block, used for scheduling
|
uint64_t m_currentHierBlockCost = 0; // Total cost of this hier block, used for scheduling
|
||||||
|
|
||||||
// Memory address to short string mapping (for debug)
|
// Memory address to short string mapping (for debug)
|
||||||
|
|
@ -224,6 +225,8 @@ public:
|
||||||
bool useCovergroup() const { return m_useCovergroup; }
|
bool useCovergroup() const { return m_useCovergroup; }
|
||||||
void useCovergroup(bool flag) { m_useCovergroup = flag; }
|
void useCovergroup(bool flag) { m_useCovergroup = flag; }
|
||||||
bool useRandomizeMethods() const { return m_useRandomizeMethods; }
|
bool useRandomizeMethods() const { return m_useRandomizeMethods; }
|
||||||
|
void setFourstateHandled() { m_fourstateHandled = true; }
|
||||||
|
bool fourstateHandled() const { return !opt.fourstate() || m_fourstateHandled; }
|
||||||
void useRandomizeMethods(bool flag) { m_useRandomizeMethods = flag; }
|
void useRandomizeMethods(bool flag) { m_useRandomizeMethods = flag; }
|
||||||
bool hasPrintedObjects() const { return m_hasPrintedObjects; }
|
bool hasPrintedObjects() const { return m_hasPrintedObjects; }
|
||||||
void hasPrintedObjects(bool flag) { m_hasPrintedObjects = flag; }
|
void hasPrintedObjects(bool flag) { m_hasPrintedObjects = flag; }
|
||||||
|
|
|
||||||
|
|
@ -1339,6 +1339,16 @@ V3Number& V3Number::opBitsOne(const V3Number& lhs) { // 1->1, 0/X/Z->0
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
V3Number& V3Number::opBitsOneX(const V3Number& lhs) {
|
||||||
|
// op i, L(lhs) bit return
|
||||||
|
NUM_ASSERT_OP_ARGS1(lhs);
|
||||||
|
NUM_ASSERT_LOGIC_ARGS1(lhs);
|
||||||
|
setZero();
|
||||||
|
for (int bit = 0; bit < width(); ++bit) {
|
||||||
|
if (lhs.bitIs1(bit) || lhs.bitIsX(bit)) setBit(bit, 1);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
V3Number& V3Number::opBitsXZ(const V3Number& lhs) { // 0/1->1, X/Z->0
|
V3Number& V3Number::opBitsXZ(const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
NUM_ASSERT_OP_ARGS1(lhs);
|
NUM_ASSERT_OP_ARGS1(lhs);
|
||||||
|
|
|
||||||
|
|
@ -744,6 +744,7 @@ public:
|
||||||
// "this" is the output, as we need the output width before some computations
|
// "this" is the output, as we need the output width before some computations
|
||||||
V3Number& opBitsNonXZ(const V3Number& lhs); // 0/1->1, X/Z->0
|
V3Number& opBitsNonXZ(const V3Number& lhs); // 0/1->1, X/Z->0
|
||||||
V3Number& opBitsOne(const V3Number& lhs); // 1->1, 0/X/Z->0
|
V3Number& opBitsOne(const V3Number& lhs); // 1->1, 0/X/Z->0
|
||||||
|
V3Number& opBitsOneX(const V3Number& lhs); // 1/X->1, 0/Z->0
|
||||||
V3Number& opBitsXZ(const V3Number& lhs); // 0/1->0, X/Z->1
|
V3Number& opBitsXZ(const V3Number& lhs); // 0/1->0, X/Z->1
|
||||||
V3Number& opBitsZ(const V3Number& lhs); // Z->1, 0/1/X->0
|
V3Number& opBitsZ(const V3Number& lhs); // Z->1, 0/1/X->0
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1054,6 +1054,9 @@ void V3Options::notify() VL_MT_DISABLED {
|
||||||
cmdfl->v3warn(E_UNSUPPORTED,
|
cmdfl->v3warn(E_UNSUPPORTED,
|
||||||
"--fourstate is not supported with hierarchical Verilation");
|
"--fourstate is not supported with hierarchical Verilation");
|
||||||
}
|
}
|
||||||
|
if (traceEnabledFst()) {
|
||||||
|
cmdfl->v3warn(E_UNSUPPORTED, "--fourstate is not supported with fst trace");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverage() && savable()) {
|
if (coverage() && savable()) {
|
||||||
|
|
|
||||||
|
|
@ -246,10 +246,40 @@ private:
|
||||||
= [this, flp, senp]() { return new AstVarRef{flp, getPrev(senp), VAccess::READ}; };
|
= [this, flp, senp]() { return new AstVarRef{flp, getPrev(senp), VAccess::READ}; };
|
||||||
const auto lsb = [=](AstNodeExpr* opp) { return new AstSel{flp, opp, 0, 1}; };
|
const auto lsb = [=](AstNodeExpr* opp) { return new AstSel{flp, opp, 0, 1}; };
|
||||||
|
|
||||||
|
// Four-state expression handlers
|
||||||
|
AstFourstateExpr* const fourstateExpr = VN_CAST(senp, FourstateExpr);
|
||||||
|
auto currValp = [this, fourstateExpr]() { return getCurr(fourstateExpr->valuep()); };
|
||||||
|
auto currXZp = [this, fourstateExpr]() { return getCurr(fourstateExpr->xzp()); };
|
||||||
|
auto prevValp = [this, fourstateExpr, flp]() {
|
||||||
|
return new AstVarRef{flp, getPrev(fourstateExpr->valuep()), VAccess::READ};
|
||||||
|
};
|
||||||
|
auto prevXZp = [this, fourstateExpr, flp]() {
|
||||||
|
return new AstVarRef{flp, getPrev(fourstateExpr->xzp()), VAccess::READ};
|
||||||
|
};
|
||||||
|
|
||||||
// All event signals should be 1-bit at this point
|
// All event signals should be 1-bit at this point
|
||||||
switch (senItemp->edgeType()) {
|
switch (senItemp->edgeType()) {
|
||||||
case VEdgeType::ET_CHANGED:
|
case VEdgeType::ET_CHANGED:
|
||||||
case VEdgeType::ET_HYBRID: //
|
case VEdgeType::ET_HYBRID: //
|
||||||
|
if (fourstateExpr) {
|
||||||
|
if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||||
|
AstCMethodHard* const resultValp
|
||||||
|
= new AstCMethodHard{flp, prevp(), VCMethod::UNPACKED_NEQ, currValp()};
|
||||||
|
AstCMethodHard* const resultXZp
|
||||||
|
= new AstCMethodHard{flp, prevp(), VCMethod::UNPACKED_NEQ, currXZp()};
|
||||||
|
resultValp->dtypeSetBit();
|
||||||
|
resultXZp->dtypeSetBit();
|
||||||
|
return {wrapExprWithNullCheck(flp, new AstOr{flp, resultValp, resultXZp},
|
||||||
|
baseClassRefp),
|
||||||
|
true};
|
||||||
|
}
|
||||||
|
return {wrapExprWithNullCheck(
|
||||||
|
flp,
|
||||||
|
lsb(new AstOr{flp, new AstXor{flp, prevValp(), currValp()},
|
||||||
|
new AstXor{flp, prevXZp(), currXZp()}}),
|
||||||
|
baseClassRefp),
|
||||||
|
true};
|
||||||
|
}
|
||||||
if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||||
// operand order reversed to avoid calling neq() method on non-VlUnpacked type, see
|
// operand order reversed to avoid calling neq() method on non-VlUnpacked type, see
|
||||||
// issue #5125
|
// issue #5125
|
||||||
|
|
@ -261,15 +291,46 @@ private:
|
||||||
return {wrapExprWithNullCheck(flp, new AstNeq{flp, currp(), prevp()}, baseClassRefp),
|
return {wrapExprWithNullCheck(flp, new AstNeq{flp, currp(), prevp()}, baseClassRefp),
|
||||||
true};
|
true};
|
||||||
case VEdgeType::ET_BOTHEDGE: //
|
case VEdgeType::ET_BOTHEDGE: //
|
||||||
|
if (fourstateExpr) {
|
||||||
|
return {wrapExprWithNullCheck(
|
||||||
|
flp,
|
||||||
|
lsb(new AstOr{flp, new AstXor{flp, currXZp(), prevXZp()},
|
||||||
|
new AstAnd{flp, new AstNot{flp, prevXZp()},
|
||||||
|
new AstXor{flp, currValp(), prevValp()}}}),
|
||||||
|
baseClassRefp),
|
||||||
|
false};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
wrapExprWithNullCheck(flp, lsb(new AstXor{flp, currp(), prevp()}), baseClassRefp),
|
wrapExprWithNullCheck(flp, lsb(new AstXor{flp, currp(), prevp()}), baseClassRefp),
|
||||||
false};
|
false};
|
||||||
case VEdgeType::ET_POSEDGE: //
|
case VEdgeType::ET_POSEDGE: //
|
||||||
|
if (fourstateExpr) {
|
||||||
|
return {wrapExprWithNullCheck(
|
||||||
|
flp,
|
||||||
|
lsb(new AstAnd{
|
||||||
|
flp,
|
||||||
|
new AstAnd{flp, new AstOr{flp, currValp(), currXZp()},
|
||||||
|
new AstOr{flp, prevXZp(), new AstNot{flp, prevValp()}}},
|
||||||
|
new AstNot{flp, new AstAnd{flp, prevXZp(), currXZp()}}}),
|
||||||
|
baseClassRefp),
|
||||||
|
false};
|
||||||
|
}
|
||||||
return {wrapExprWithNullCheck(flp,
|
return {wrapExprWithNullCheck(flp,
|
||||||
lsb(new AstAnd{flp, currp(), new AstNot{flp, prevp()}}),
|
lsb(new AstAnd{flp, currp(), new AstNot{flp, prevp()}}),
|
||||||
baseClassRefp),
|
baseClassRefp),
|
||||||
false};
|
false};
|
||||||
case VEdgeType::ET_NEGEDGE: //
|
case VEdgeType::ET_NEGEDGE: //
|
||||||
|
if (fourstateExpr) {
|
||||||
|
return {wrapExprWithNullCheck(
|
||||||
|
flp,
|
||||||
|
lsb(new AstAnd{
|
||||||
|
flp,
|
||||||
|
new AstAnd{flp, new AstOr{flp, prevValp(), prevXZp()},
|
||||||
|
new AstOr{flp, currXZp(), new AstNot{flp, currValp()}}},
|
||||||
|
new AstNot{flp, new AstAnd{flp, prevXZp(), currXZp()}}}),
|
||||||
|
baseClassRefp),
|
||||||
|
false};
|
||||||
|
}
|
||||||
return {wrapExprWithNullCheck(flp,
|
return {wrapExprWithNullCheck(flp,
|
||||||
lsb(new AstAnd{flp, new AstNot{flp, currp()}, prevp()}),
|
lsb(new AstAnd{flp, new AstNot{flp, currp()}, prevp()}),
|
||||||
baseClassRefp),
|
baseClassRefp),
|
||||||
|
|
@ -293,6 +354,9 @@ private:
|
||||||
return {wrapExprWithNullCheck(flp, callp, baseClassRefp), false};
|
return {wrapExprWithNullCheck(flp, callp, baseClassRefp), false};
|
||||||
}
|
}
|
||||||
case VEdgeType::ET_TRUE: //
|
case VEdgeType::ET_TRUE: //
|
||||||
|
if (fourstateExpr) {
|
||||||
|
return {lsb(new AstAnd{flp, currValp(), new AstNot{flp, currXZp()}}), false};
|
||||||
|
}
|
||||||
return {currp(), false};
|
return {currp(), false};
|
||||||
case VEdgeType::ET_INITIAL_NBA: //
|
case VEdgeType::ET_INITIAL_NBA: //
|
||||||
return {new AstConst{flp, AstConst::BitFalse{}}, true};
|
return {new AstConst{flp, AstConst::BitFalse{}}, true};
|
||||||
|
|
|
||||||
|
|
@ -230,8 +230,11 @@ class TraceDeclVisitor final : public VNVisitor {
|
||||||
FileLine& fileline() const { return m_vscp ? *m_vscp->fileline() : *m_cellp->fileline(); }
|
FileLine& fileline() const { return m_vscp ? *m_vscp->fileline() : *m_cellp->fileline(); }
|
||||||
};
|
};
|
||||||
std::vector<TraceEntry> m_entries; // Trace entries under current scope
|
std::vector<TraceEntry> m_entries; // Trace entries under current scope
|
||||||
|
std::map<const AstVar*, AstVarScope*>
|
||||||
|
m_varxzToVscp; // Map from variable with xz part to its variable scope
|
||||||
AstVarScope* m_traVscp = nullptr; // Current AstVarScope we are constructing AstTraceDecls for
|
AstVarScope* m_traVscp = nullptr; // Current AstVarScope we are constructing AstTraceDecls for
|
||||||
AstNodeExpr* m_traValuep = nullptr; // Value expression for current signal
|
AstNodeExpr* m_traValuep = nullptr; // Value expression for current signal
|
||||||
|
AstNodeExpr* m_traValueXZp = nullptr; // ValueXZ expression for current signal
|
||||||
string m_traName; // Name component for current signal
|
string m_traName; // Name component for current signal
|
||||||
|
|
||||||
VDouble0 m_statSigs; // Statistic tracking
|
VDouble0 m_statSigs; // Statistic tracking
|
||||||
|
|
@ -334,6 +337,10 @@ class TraceDeclVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
FileLine* const flp = m_traVscp->fileline();
|
FileLine* const flp = m_traVscp->fileline();
|
||||||
AstNodeExpr* valuep = m_traValuep->cloneTree(false);
|
AstNodeExpr* valuep = m_traValuep->cloneTree(false);
|
||||||
|
if (m_traValueXZp) {
|
||||||
|
valuep = new AstFourstateExpr{m_traVscp->fileline(), valuep,
|
||||||
|
m_traValueXZp->cloneTree(false)};
|
||||||
|
}
|
||||||
const bool validOffset = m_offset != std::numeric_limits<uint32_t>::max();
|
const bool validOffset = m_offset != std::numeric_limits<uint32_t>::max();
|
||||||
AstTraceDecl* const newp
|
AstTraceDecl* const newp
|
||||||
= new AstTraceDecl{flp, m_traName, m_traVscp->varp(), valuep,
|
= new AstTraceDecl{flp, m_traName, m_traVscp->varp(), valuep,
|
||||||
|
|
@ -685,6 +692,12 @@ class TraceDeclVisitor final : public VNVisitor {
|
||||||
// traversal.
|
// traversal.
|
||||||
m_traValuep
|
m_traValuep
|
||||||
= new AstVarRef{m_traVscp->fileline(), m_traVscp, VAccess::READ};
|
= new AstVarRef{m_traVscp->fileline(), m_traVscp, VAccess::READ};
|
||||||
|
if (AstVar* const complementp
|
||||||
|
= m_traVscp->varp()->fourstateComplementp()) {
|
||||||
|
m_traValueXZp
|
||||||
|
= new AstVarRef{m_traVscp->fileline(),
|
||||||
|
m_varxzToVscp.at(complementp), VAccess::READ};
|
||||||
|
}
|
||||||
// Recurse into data type of the signal. The visit methods will add
|
// Recurse into data type of the signal. The visit methods will add
|
||||||
// AstTraceDecls.
|
// AstTraceDecls.
|
||||||
iterate(m_traVscp->varp()->dtypep()->skipRefToEnump());
|
iterate(m_traVscp->varp()->dtypep()->skipRefToEnump());
|
||||||
|
|
@ -694,6 +707,10 @@ class TraceDeclVisitor final : public VNVisitor {
|
||||||
// Note: Sometimes VL_DANGLING is a no-op, but we have assertions
|
// Note: Sometimes VL_DANGLING is a no-op, but we have assertions
|
||||||
// on m_traValuep being nullptr, so make sure it is.
|
// on m_traValuep being nullptr, so make sure it is.
|
||||||
m_traValuep = nullptr;
|
m_traValuep = nullptr;
|
||||||
|
if (m_traValueXZp) {
|
||||||
|
VL_DO_DANGLING(m_traValueXZp->deleteTree(), m_traValueXZp);
|
||||||
|
m_traValueXZp = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -795,8 +812,12 @@ class TraceDeclVisitor final : public VNVisitor {
|
||||||
if (nodep->varp()->isParam() && VN_IS(nodep->scopep()->modp(), Package)) return;
|
if (nodep->varp()->isParam() && VN_IS(nodep->scopep()->modp(), Package)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to traced signal list
|
if (nodep->varp()->isFourstateComplement()) {
|
||||||
m_entries.emplace_back(m_currScopep, nodep);
|
m_varxzToVscp.emplace(nodep->varp(), nodep);
|
||||||
|
} else {
|
||||||
|
// Add to traced signal list
|
||||||
|
m_entries.emplace_back(m_currScopep, nodep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS - Data types when tracing
|
// VISITORS - Data types when tracing
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ class UnknownVisitor final : public VNVisitor {
|
||||||
|
|
||||||
void visit(AstSel* nodep) override {
|
void visit(AstSel* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (!nodep->user1SetOnce()) {
|
if (!v3Global.opt.fourstate() && !nodep->user1SetOnce()) {
|
||||||
// Guard against reading/writing past end of bit vector array
|
// Guard against reading/writing past end of bit vector array
|
||||||
const AstNode* const basefromp = AstArraySel::baseFromp(nodep, true);
|
const AstNode* const basefromp = AstArraySel::baseFromp(nodep, true);
|
||||||
bool lvalue = false;
|
bool lvalue = false;
|
||||||
|
|
|
||||||
|
|
@ -1071,7 +1071,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
const bool inParameterizedTemplate
|
const bool inParameterizedTemplate
|
||||||
= m_modep && (m_modep->dead() || m_modep->parameterizedTemplate());
|
= m_modep && (m_modep->dead() || m_modep->parameterizedTemplate());
|
||||||
|
|
||||||
if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() < nodep->lsbConst()) {
|
if (!v3Global.opt.fourstate() && VN_IS(nodep->lsbp(), Const)
|
||||||
|
&& nodep->msbConst() < nodep->lsbConst()) {
|
||||||
// Likely impossible given above width check
|
// Likely impossible given above width check
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
nodep->v3warn(E_UNSUPPORTED,
|
||||||
"Unsupported: left < right of bit extract: " // LCOV_EXCL_LINE
|
"Unsupported: left < right of bit extract: " // LCOV_EXCL_LINE
|
||||||
|
|
@ -1145,22 +1146,24 @@ class WidthVisitor final : public VNVisitor {
|
||||||
UINFO(1, " Related node: " << nodep);
|
UINFO(1, " Related node: " << nodep);
|
||||||
}
|
}
|
||||||
if (lrefp) UINFO(9, " Select extend lrefp " << lrefp);
|
if (lrefp) UINFO(9, " Select extend lrefp " << lrefp);
|
||||||
if (lrefp && lrefp->access().isWriteOrRW()) {
|
if (!v3Global.opt.fourstate()) {
|
||||||
// lvarref[X] = ..., the expression assigned is too wide
|
if (lrefp && lrefp->access().isWriteOrRW()) {
|
||||||
// WTF to do
|
// lvarref[X] = ..., the expression assigned is too wide
|
||||||
// Don't change the width of this lhsp, instead propagate up
|
// WTF to do
|
||||||
// to upper assign/expression the correct width
|
// Don't change the width of this lhsp, instead propagate up
|
||||||
AstNodeDType* const subDTypep
|
// to upper assign/expression the correct width
|
||||||
= nodep->findLogicDType(width, width, nodep->fromp()->dtypep()->numeric());
|
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
||||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep, EXTEND_EXP,
|
width, width, nodep->fromp()->dtypep()->numeric());
|
||||||
false /*noerror*/);
|
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep,
|
||||||
} else {
|
EXTEND_EXP, false /*noerror*/);
|
||||||
// Extend it
|
} else {
|
||||||
const int extendTo = nodep->msbConst() + 1;
|
// Extend it
|
||||||
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
const int extendTo = nodep->msbConst() + 1;
|
||||||
extendTo, extendTo, nodep->fromp()->dtypep()->numeric());
|
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
||||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep, EXTEND_EXP,
|
extendTo, extendTo, nodep->fromp()->dtypep()->numeric());
|
||||||
false /*noerror*/);
|
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep,
|
||||||
|
EXTEND_EXP, false /*noerror*/);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// iterate FINAL is two blocks above
|
// iterate FINAL is two blocks above
|
||||||
|
|
@ -1168,7 +1171,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
// If we have a width problem with GENERATE etc, this will reduce
|
// If we have a width problem with GENERATE etc, this will reduce
|
||||||
// it down and mask it, so we have no chance of finding a real
|
// it down and mask it, so we have no chance of finding a real
|
||||||
// error in the future. So don't do this for them.
|
// error in the future. So don't do this for them.
|
||||||
if (!m_doGenerate) {
|
if (!v3Global.opt.fourstate() && !m_doGenerate) {
|
||||||
// lsbp() must be self-determined, however for performance
|
// lsbp() must be self-determined, however for performance
|
||||||
// we want the select to be truncated to fit within the
|
// we want the select to be truncated to fit within the
|
||||||
// maximum select range, e.g. turn Xs outside of the select
|
// maximum select range, e.g. turn Xs outside of the select
|
||||||
|
|
|
||||||
|
|
@ -278,9 +278,6 @@ private:
|
||||||
void visit(AstCastWrap* nodep) override {
|
void visit(AstCastWrap* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
editDType(nodep);
|
editDType(nodep);
|
||||||
UINFO(6, " Replace " << nodep << " w/ " << nodep->lhsp());
|
|
||||||
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
}
|
||||||
void visit(AstConstraint* nodep) override {
|
void visit(AstConstraint* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
|
|
@ -557,3 +554,19 @@ void V3WidthCommit::widthCommit(AstNetlist* nodep) {
|
||||||
{ WidthCommitVisitor{nodep}; } // Destruct before checking
|
{ WidthCommitVisitor{nodep}; } // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("widthcommit", 0, dumpTreeEitherLevel() >= 6);
|
V3Global::dumpCheckGlobalTree("widthcommit", 0, dumpTreeEitherLevel() >= 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3WidthCommit::widthCommitClean(AstNetlist* nodep) {
|
||||||
|
UINFO(2, __FUNCTION__ << ":");
|
||||||
|
{
|
||||||
|
std::vector<AstCastWrap*> castWrapsToDelete;
|
||||||
|
v3Global.rootp()->foreach([&castWrapsToDelete](AstCastWrap* nodep) {
|
||||||
|
UINFO(6, " Replace " << nodep << " w/ " << nodep->lhsp());
|
||||||
|
castWrapsToDelete.push_back(nodep);
|
||||||
|
});
|
||||||
|
for (AstCastWrap* const nodep : castWrapsToDelete) {
|
||||||
|
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
||||||
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
V3Global::dumpCheckGlobalTree("widthcommit_clean", 0, dumpTreeEitherLevel() >= 6);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ public:
|
||||||
|
|
||||||
// Final step... Mark all widths as equal
|
// Final step... Mark all widths as equal
|
||||||
static void widthCommit(AstNetlist* nodep) VL_MT_DISABLED;
|
static void widthCommit(AstNetlist* nodep) VL_MT_DISABLED;
|
||||||
|
static void widthCommitClean(AstNetlist* nodep) VL_MT_DISABLED;
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
#include "V3File.h"
|
#include "V3File.h"
|
||||||
#include "V3Force.h"
|
#include "V3Force.h"
|
||||||
#include "V3Fork.h"
|
#include "V3Fork.h"
|
||||||
|
#include "V3Fourstate.h"
|
||||||
#include "V3FsmDetect.h"
|
#include "V3FsmDetect.h"
|
||||||
#include "V3FuncOpt.h"
|
#include "V3FuncOpt.h"
|
||||||
#include "V3Gate.h"
|
#include "V3Gate.h"
|
||||||
|
|
@ -301,6 +302,8 @@ static void process() {
|
||||||
// No more AstGenBlocks after this
|
// No more AstGenBlocks after this
|
||||||
V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner
|
V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner
|
||||||
|
|
||||||
|
if (v3Global.opt.fourstate()) V3Fourstate::fourstateAll(v3Global.rootp());
|
||||||
|
V3WidthCommit::widthCommitClean(v3Global.rootp());
|
||||||
// Expand inouts, stage 2
|
// Expand inouts, stage 2
|
||||||
// Also simplify pin connections to always be AssignWs in prep for V3Unknown
|
// Also simplify pin connections to always be AssignWs in prep for V3Unknown
|
||||||
V3Tristate::tristateAll(v3Global.rootp());
|
V3Tristate::tristateAll(v3Global.rootp());
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"modulesp": [
|
"modulesp": [
|
||||||
{"type":"MODULE","name":"t","addr":"(F)","loc":"d,67:8,67:9","origName":"t","verilogName":"t","level":1,"timeunit":"1ps","inlinesp": [],
|
{"type":"MODULE","name":"t","addr":"(F)","loc":"d,67:8,67:9","origName":"t","verilogName":"t","level":1,"timeunit":"1ps","inlinesp": [],
|
||||||
"stmtsp": [
|
"stmtsp": [
|
||||||
{"type":"VAR","name":"p","addr":"(G)","loc":"d,69:10,69:11","dtypep":"(H)","origName":"p","verilogName":"p","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"Packet","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"p","addr":"(G)","loc":"d,69:10,69:11","dtypep":"(H)","origName":"p","verilogName":"p","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"Packet","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"INITIAL","name":"","addr":"(I)","loc":"d,71:3,71:10",
|
{"type":"INITIAL","name":"","addr":"(I)","loc":"d,71:3,71:10",
|
||||||
"stmtsp": [
|
"stmtsp": [
|
||||||
{"type":"BEGIN","name":"","addr":"(J)","loc":"d,71:11,71:16","unnamed":true,"declsp": [],
|
{"type":"BEGIN","name":"","addr":"(J)","loc":"d,71:11,71:16","unnamed":true,"declsp": [],
|
||||||
|
|
@ -19,21 +19,21 @@
|
||||||
"stmtsp": [
|
"stmtsp": [
|
||||||
{"type":"CLASS","name":"Packet","addr":"(O)","loc":"d,7:1,7:6","origName":"Packet","verilogName":"Packet","level":3,"timeunit":"1ps","classOrPackagep":"UNLINKED","inlinesp": [],
|
{"type":"CLASS","name":"Packet","addr":"(O)","loc":"d,7:1,7:6","origName":"Packet","verilogName":"Packet","level":3,"timeunit":"1ps","classOrPackagep":"UNLINKED","inlinesp": [],
|
||||||
"stmtsp": [
|
"stmtsp": [
|
||||||
{"type":"VAR","name":"header","addr":"(P)","loc":"d,8:12,8:18","dtypep":"(Q)","origName":"header","verilogName":"header","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"header","addr":"(P)","loc":"d,8:12,8:18","dtypep":"(Q)","origName":"header","verilogName":"header","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"length","addr":"(R)","loc":"d,9:12,9:18","dtypep":"(Q)","origName":"length","verilogName":"length","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"length","addr":"(R)","loc":"d,9:12,9:18","dtypep":"(Q)","origName":"length","verilogName":"length","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"sublength","addr":"(S)","loc":"d,10:12,10:21","dtypep":"(Q)","origName":"sublength","verilogName":"sublength","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"sublength","addr":"(S)","loc":"d,10:12,10:21","dtypep":"(Q)","origName":"sublength","verilogName":"sublength","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"int","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"if_4","addr":"(T)","loc":"d,11:12,11:16","dtypep":"(U)","origName":"if_4","verilogName":"if_4","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"if_4","addr":"(T)","loc":"d,11:12,11:16","dtypep":"(U)","origName":"if_4","verilogName":"if_4","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"iff_5_6","addr":"(V)","loc":"d,12:12,12:19","dtypep":"(U)","origName":"iff_5_6","verilogName":"iff_5_6","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"iff_5_6","addr":"(V)","loc":"d,12:12,12:19","dtypep":"(U)","origName":"iff_5_6","verilogName":"iff_5_6","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"if_state_ok","addr":"(W)","loc":"d,13:12,13:23","dtypep":"(U)","origName":"if_state_ok","verilogName":"if_state_ok","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"if_state_ok","addr":"(W)","loc":"d,13:12,13:23","dtypep":"(U)","origName":"if_state_ok","verilogName":"if_state_ok","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"bit","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"array","addr":"(X)","loc":"d,15:12,15:17","dtypep":"(Y)","origName":"array","verilogName":"array","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"array","addr":"(X)","loc":"d,15:12,15:17","dtypep":"(Y)","origName":"array","verilogName":"array","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"state","addr":"(Z)","loc":"d,17:10,17:15","dtypep":"(M)","origName":"state","verilogName":"state","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"state","addr":"(Z)","loc":"d,17:10,17:15","dtypep":"(M)","origName":"state","verilogName":"state","direction":"NONE","lifetime":"VAUTOMI","varType":"MEMBER","dtypeName":"string","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:16,61:29","dtypep":"(U)","method":true,"cname":"strings_equal",
|
{"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:16,61:29","dtypep":"(U)","method":true,"cname":"strings_equal",
|
||||||
"fvarp": [
|
"fvarp": [
|
||||||
{"type":"VAR","name":"strings_equal","addr":"(BB)","loc":"d,61:16,61:29","dtypep":"(U)","origName":"strings_equal","verilogName":"strings_equal","direction":"OUTPUT","noCReset":true,"icoMaybeWritten":true,"isFuncReturn":true,"isFuncLocal":true,"lifetime":"VAUTOM","varType":"VAR","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
{"type":"VAR","name":"strings_equal","addr":"(BB)","loc":"d,61:16,61:29","dtypep":"(U)","origName":"strings_equal","verilogName":"strings_equal","direction":"OUTPUT","noCReset":true,"icoMaybeWritten":true,"isFuncReturn":true,"isFuncLocal":true,"lifetime":"VAUTOM","varType":"VAR","dtypeName":"bit","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
||||||
],"classOrPackagep": [],
|
],"classOrPackagep": [],
|
||||||
"stmtsp": [
|
"stmtsp": [
|
||||||
{"type":"VAR","name":"a","addr":"(CB)","loc":"d,61:37,61:38","dtypep":"(M)","origName":"a","verilogName":"a","direction":"INPUT","isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"a","addr":"(CB)","loc":"d,61:37,61:38","dtypep":"(M)","origName":"a","verilogName":"a","direction":"INPUT","isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"VAR","name":"b","addr":"(DB)","loc":"d,61:47,61:48","dtypep":"(M)","origName":"b","verilogName":"b","direction":"INPUT","isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
{"type":"VAR","name":"b","addr":"(DB)","loc":"d,61:47,61:48","dtypep":"(M)","origName":"b","verilogName":"b","direction":"INPUT","isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||||
{"type":"ASSIGN","name":"","addr":"(EB)","loc":"d,61:16,61:29","dtypep":"(U)",
|
{"type":"ASSIGN","name":"","addr":"(EB)","loc":"d,61:16,61:29","dtypep":"(U)",
|
||||||
"rhsp": [
|
"rhsp": [
|
||||||
{"type":"CONST","name":"1'h0","addr":"(FB)","loc":"d,61:16,61:29","dtypep":"(U)"}
|
{"type":"CONST","name":"1'h0","addr":"(FB)","loc":"d,61:16,61:29","dtypep":"(U)"}
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
],"timingControlp": []}
|
],"timingControlp": []}
|
||||||
],"scopeNamep": []},
|
],"scopeNamep": []},
|
||||||
{"type":"FUNC","name":"new","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","method":true,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
|
{"type":"FUNC","name":"new","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","method":true,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
|
||||||
{"type":"VAR","name":"constraint","addr":"(OB)","loc":"d,7:1,7:6","dtypep":"(PB)","origName":"constraint","verilogName":"constraint","direction":"NONE","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
{"type":"VAR","name":"constraint","addr":"(OB)","loc":"d,7:1,7:6","dtypep":"(PB)","origName":"constraint","verilogName":"constraint","direction":"NONE","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","sensIfacep":"UNLINKED","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
||||||
],"extendsp": []}
|
],"extendsp": []}
|
||||||
]}
|
]}
|
||||||
],"filesp": [],
|
],"filesp": [],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define IMPURE_ONE ($c(1))
|
||||||
|
`else
|
||||||
|
`define IMPURE_ONE (|($random | $random))
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function integer f(integer x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
function logic [31:0] g(logic [31:0] x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ((f(10) + f(-5)) !== 5) $stop;
|
||||||
|
if ((f(10) + f('b11x)) !== 'x) $stop;
|
||||||
|
if ((f(10) + f('b11z)) !== 'x) $stop;
|
||||||
|
if ((g(10) + g(5)) !== 15) $stop;
|
||||||
|
if ((g(10) + g('x)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((f(10) - f(-5)) !== 15) $stop;
|
||||||
|
if ((f(10) - f('b11x)) !== 'x) $stop;
|
||||||
|
if ((f(10) - f('b11z)) !== 'x) $stop;
|
||||||
|
if ((g(10) - g(5)) !== 5) $stop;
|
||||||
|
if ((g(10) - g('x)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((f(10) * f(-5)) !== -50) $stop;
|
||||||
|
if ((f(10) * f('b11x)) !== 'x) $stop;
|
||||||
|
if ((f(10) * f('b11z)) !== 'x) $stop;
|
||||||
|
if ((g(10) * g(5)) !== 50) $stop;
|
||||||
|
if ((g(10) * g('x)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((f(10) / f(5)) !== 2) $stop;
|
||||||
|
if ((f(9) / f(5)) !== 1) $stop;
|
||||||
|
if ((f(10) / f(2)) !== 5) $stop;
|
||||||
|
if ((f(-10) / f(5)) !== -2) $stop;
|
||||||
|
if ((f(9) / f(-5)) !== -1) $stop;
|
||||||
|
if ((f('bx) / f('bx)) !== 'x) $stop;
|
||||||
|
if ((f('bz) / f(5)) !== 'x) $stop;
|
||||||
|
if ((f(10) / f(0)) !== 'x) $stop;
|
||||||
|
if ((f(0) / f(0)) !== 'x) $stop;
|
||||||
|
if ((f(0) / f('z)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((g(10) / g(5)) !== 2) $stop;
|
||||||
|
if ((g(9) / g(5)) !== 1) $stop;
|
||||||
|
if ((g(10) / g(2)) !== 5) $stop;
|
||||||
|
if ((g('bx) / g('bx)) !== 'x) $stop;
|
||||||
|
if ((g('bz) / g(5)) !== 'x) $stop;
|
||||||
|
if ((g(10) / g(0)) !== 'x) $stop;
|
||||||
|
if ((g(0) / g(0)) !== 'x) $stop;
|
||||||
|
if ((g(0) / g('z)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((f(10) % f(5)) !== 0) $stop;
|
||||||
|
if ((f(9) % f(5)) !== 4) $stop;
|
||||||
|
if ((f(10) % f(2)) !== 0) $stop;
|
||||||
|
if ((f(-10) % f(5)) !== 0) $stop;
|
||||||
|
if ((f(9) % f(-5)) !== 4) $stop;
|
||||||
|
if ((f('bx) % f('bx)) !== 'x) $stop;
|
||||||
|
if ((f('bz) % f(5)) !== 'x) $stop;
|
||||||
|
if ((f(10) % f(0)) !== 'x) $stop;
|
||||||
|
if ((f(0) % f(0)) !== 'x) $stop;
|
||||||
|
if ((f(0) % f('z)) !== 'x) $stop;
|
||||||
|
|
||||||
|
if ((g(10) % g(5)) !== 0) $stop;
|
||||||
|
if ((g(9) % g(5)) !== 4) $stop;
|
||||||
|
if ((g(10) % g(2)) !== 0) $stop;
|
||||||
|
if ((g('bx) % g('bx)) !== 'x) $stop;
|
||||||
|
if ((g('bz) % g(5)) !== 'x) $stop;
|
||||||
|
if ((g(10) % g(0)) !== 'x) $stop;
|
||||||
|
if ((g(0) % g(0)) !== 'x) $stop;
|
||||||
|
if ((g(0) % g('z)) !== 'x) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_assign_complex_lhs_unsup.v:10:10: Fourstate LHS other than a simple variable reference is not supported
|
||||||
|
: ... note: In instance 't'
|
||||||
|
10 | x[1] = 1;
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
static logic [2:0] x;
|
||||||
|
x[1] = 1;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_case_onehot.v:88:15: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't.test'
|
||||||
|
88 | in[ST_0]: out <= 32'h1234;
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_case_onehot.v:89:15: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't.test'
|
||||||
|
89 | in[ST_1]: out <= 32'h4356;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_onehot.v:90:15: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't.test'
|
||||||
|
90 | in[ST_2]: out <= 32'h9874;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_onehot.v:87:5: Unsupported: Operator ONEHOT not supported in the four-state mode
|
||||||
|
87 | case (1'b1) /*verilator parallel_case*/
|
||||||
|
| ^~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_onehot.v:87:5: Unsupported: Operator LOGNOT not supported in the four-state mode
|
||||||
|
87 | case (1'b1) /*verilator parallel_case*/
|
||||||
|
| ^~~~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_case_onehot.v'
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE', '-Wno-CASTFOURSTATE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:21:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
21 | case (value)
|
||||||
|
| ^~~~
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:22:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
22 | 4'b1xxx: $stop;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:23:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
23 | 4'b1???: $stop;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:27:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
27 | case (valuex)
|
||||||
|
| ^~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:28:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
28 | 4'b1???: $stop;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:29:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
29 | 4'b1xxx: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:35:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
35 | casex (value)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:36:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
36 | 4'b100x: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:39:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
39 | casex (value)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:40:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
40 | 4'b100?: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:43:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
43 | casex (valuex)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:44:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
44 | 4'b100x: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:47:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
47 | casex (valuex)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:48:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
48 | 4'b100?: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:52:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
52 | casez (value)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:53:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
53 | 4'bxxxx: $stop;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:54:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
54 | 4'b100?: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:57:5: All case statements with four-state value as an expression are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
57 | casez (valuex)
|
||||||
|
| ^~~~~
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:58:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
58 | 4'b1xx?: ;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_case_x.v:59:14: Four-state case items values are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
59 | 4'b100?: ;
|
||||||
|
| ^
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_case_x.v"
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
static int n = 12;
|
||||||
|
static integer m = 'x;
|
||||||
|
static int v = 1 + int'(1 + (n + m));
|
||||||
|
if (v != 1) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define IMPURE_ONE ($c(1))
|
||||||
|
`else
|
||||||
|
`define IMPURE_ONE (|($random | $random))
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function integer f(integer x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
function logic [31:0] g(logic [31:0] x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ((f('b1) == f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b1) == f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) == f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) == f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) == f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) == f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) == f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) == f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) == f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) == f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) == f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) == f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((f('b1) != f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b1) != f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) != f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) != f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) != f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) != f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) != f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) != f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) != f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) != f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) != f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) != f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((f('b1) < f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b1) < f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) < f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) < f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) < f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) < f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) < f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) < f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) < f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) < f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) < f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) < f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((f('b1) <= f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b1) <= f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) <= f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) <= f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) <= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) <= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) <= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) <= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) <= f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) <= f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) <= f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) <= f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((f('b1) > f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b1) > f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) > f('b0)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) > f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) > f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) > f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) > f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) > f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) > f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) > f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) > f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) > f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((f('b1) >= f('b1)) !== 1'b1) $stop;
|
||||||
|
if ((f('b1) >= f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) >= f('b0)) !== 1'b1) $stop;
|
||||||
|
if ((f('b0) >= f('b1)) !== 1'b0) $stop;
|
||||||
|
if ((f('b0) >= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b0) >= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('b1) >= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) >= f('bx)) !== 1'bx) $stop;
|
||||||
|
if ((f('bx) >= f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) >= f('bz)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) >= f('b1)) !== 1'bx) $stop;
|
||||||
|
if ((f('bz) >= f('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
// Unsigned
|
||||||
|
if ((g('b1) < g('b1)) !== 1'b0) $stop;
|
||||||
|
if ((g('b1) < g('b0)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) < g('b0)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) < g('b1)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) < g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b0) < g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b1) < g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) < g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) < g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) < g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) < g('b1)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) < g('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((g('b1) <= g('b1)) !== 1'b1) $stop;
|
||||||
|
if ((g('b1) <= g('b0)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) <= g('b0)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) <= g('b1)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) <= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b0) <= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b1) <= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) <= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) <= g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) <= g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) <= g('b1)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) <= g('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((g('b1) > g('b1)) !== 1'b0) $stop;
|
||||||
|
if ((g('b1) > g('b0)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) > g('b0)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) > g('b1)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) > g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b0) > g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b1) > g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) > g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) > g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) > g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) > g('b1)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) > g('b0)) !== 1'bx) $stop;
|
||||||
|
|
||||||
|
if ((g('b1) >= g('b1)) !== 1'b1) $stop;
|
||||||
|
if ((g('b1) >= g('b0)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) >= g('b0)) !== 1'b1) $stop;
|
||||||
|
if ((g('b0) >= g('b1)) !== 1'b0) $stop;
|
||||||
|
if ((g('b0) >= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b0) >= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('b1) >= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) >= g('bx)) !== 1'bx) $stop;
|
||||||
|
if ((g('bx) >= g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) >= g('bz)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) >= g('b1)) !== 1'bx) $stop;
|
||||||
|
if ((g('bz) >= g('b0)) !== 1'bx) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
1
|
||||||
|
1
|
||||||
|
x
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
x
|
||||||
|
0
|
||||||
|
0
|
||||||
|
x
|
||||||
|
0
|
||||||
|
0
|
||||||
|
z
|
||||||
|
0
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute(expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function logic f(logic a);
|
||||||
|
if (a === 1'b1) $write("1");
|
||||||
|
else if (a === 1'b0) $write("0");
|
||||||
|
else if (a === 1'bx) $write("x");
|
||||||
|
else if (a === 1'bz) $write("z");
|
||||||
|
else $stop;
|
||||||
|
$write("\n");
|
||||||
|
return a;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ((
|
||||||
|
((f(1) ? f(1) : f('z)) && (f('x) ? f(1) : f(0))) ?
|
||||||
|
(((f(1) || f('z)) && (f('x))) && ((f(0) ? f('x) : f(0)))) :
|
||||||
|
((f('x) || f(0)) && (f(0) || (f('z) && (f(0) && f('z))))
|
||||||
|
)) !== 0) begin
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_complex_pin_unsup.v:13:8: Cells with pins that are not a variable reference or a constant are not supported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
13 | y h(x[0]);
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module y(input x);
|
||||||
|
initial $write("%d\n", bit'(x));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
logic [2:0] x;
|
||||||
|
y h(x[0]);
|
||||||
|
initial x = 3;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define IMPURE_ONE ($c(1))
|
||||||
|
`else
|
||||||
|
`define IMPURE_ONE (|($random | $random))
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function logic f(logic x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ({f(1'b0), f(1'b0)} !== 2'b00) $stop;
|
||||||
|
if ({f(1'b0), f(1'b1)} !== 2'b01) $stop;
|
||||||
|
if ({f(1'b0), f(1'bx)} !== 2'b0x) $stop;
|
||||||
|
if ({f(1'b0), f(1'bz)} !== 2'b0z) $stop;
|
||||||
|
|
||||||
|
if ({f(1'b1), f(1'b0)} !== 2'b10) $stop;
|
||||||
|
if ({f(1'b1), f(1'b1)} !== 2'b11) $stop;
|
||||||
|
if ({f(1'b1), f(1'bx)} !== 2'b1x) $stop;
|
||||||
|
if ({f(1'b1), f(1'bz)} !== 2'b1z) $stop;
|
||||||
|
|
||||||
|
if ({f(1'bz), f(1'b0)} !== 2'bz0) $stop;
|
||||||
|
if ({f(1'bz), f(1'b1)} !== 2'bz1) $stop;
|
||||||
|
if ({f(1'bz), f(1'bx)} !== 2'bzx) $stop;
|
||||||
|
if ({f(1'bz), f(1'bz)} !== 2'bzz) $stop;
|
||||||
|
|
||||||
|
if ({f(1'bx), f(1'b0)} !== 2'bx0) $stop;
|
||||||
|
if ({f(1'bx), f(1'b1)} !== 2'bx1) $stop;
|
||||||
|
if ({f(1'bx), f(1'bx)} !== 2'bxx) $stop;
|
||||||
|
if ({f(1'bx), f(1'bz)} !== 2'bxz) $stop;
|
||||||
|
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
x
|
||||||
|
1
|
||||||
|
0
|
||||||
|
x
|
||||||
|
1
|
||||||
|
1
|
||||||
|
z
|
||||||
|
1
|
||||||
|
0
|
||||||
|
z
|
||||||
|
0
|
||||||
|
0
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute(expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define IMPURE_ONE ($c(1))
|
||||||
|
`else
|
||||||
|
`define IMPURE_ONE (|($random | $random))
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t;
|
||||||
|
static int calls = 0;
|
||||||
|
|
||||||
|
function logic f(logic a);
|
||||||
|
if (a === 1'b1) $write("1");
|
||||||
|
else if (a === 1'b0) $write("0");
|
||||||
|
else if (a === 1'bx) $write("x");
|
||||||
|
else if (a === 1'bz) $write("z");
|
||||||
|
else $stop;
|
||||||
|
$write("\n");
|
||||||
|
return a;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function logic bar();
|
||||||
|
calls++;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ((f(0) ? f(1) : f(0)) !== 0) $stop;
|
||||||
|
if ((f(1) ? f(1) : f(0)) !== 1) $stop;
|
||||||
|
if ((f('x) ? f(1) : f(0)) !== 'x) $stop;
|
||||||
|
if ((f('x) ? f(1) : f(1)) !== 1) $stop;
|
||||||
|
if ((f('z) ? f(1) : f(0)) !== 'x) $stop;
|
||||||
|
if ((f('z) ? f(0) : f(0)) !== 0) $stop;
|
||||||
|
if ((`IMPURE_ONE ? 0 : bar()) !== 0) $stop;
|
||||||
|
if (calls !== 0) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_delay_var.v:14:8: Continuous assignment delays are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
14 | wire #1.1 d_const = in;
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_delay_var.v:15:8: Continuous assignment delays are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
15 | wire #idly d_int = in;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_delay_var.v:16:8: Continuous assignment delays are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
16 | wire #rdly d_real = in;
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_delay_var.v:17:8: Continuous assignment delays are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
17 | wire #PDLY d_param = in;
|
||||||
|
| ^
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_delay_var.v'
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
res: x
|
||||||
|
res: x
|
||||||
|
res: 1
|
||||||
|
res: 1
|
||||||
|
res: 0
|
||||||
|
ZERO | ONE | X | Z
|
||||||
|
ZERO 0 ^ 0 == 0 | 0 ^ 1 == 1 | 0 ^ x == x | 0 ^ z == x |
|
||||||
|
ONE 1 ^ 0 == 1 | 1 ^ 1 == 0 | 1 ^ x == x | 1 ^ z == x |
|
||||||
|
X x ^ 0 == x | x ^ 1 == x | x ^ x == x | x ^ z == x |
|
||||||
|
Z z ^ 0 == x | z ^ 1 == x | z ^ x == x | z ^ z == x |
|
||||||
|
x wire: 1
|
||||||
|
z wor: 1
|
||||||
|
u triand: 1
|
||||||
|
t wire: 1
|
||||||
|
x wire: 1
|
||||||
|
z wor: 1
|
||||||
|
u triand: 1
|
||||||
|
t wire: 1
|
||||||
|
vvv: x
|
||||||
|
Bye
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,185 @@
|
||||||
|
$version Generated by VerilatedVcd $end
|
||||||
|
$timescale 1ps $end
|
||||||
|
$scope module t $end
|
||||||
|
$var wire 1 C clk $end
|
||||||
|
$var wire 1 D x $end
|
||||||
|
$var wire 1 L y $end
|
||||||
|
$var wire 1 F t $end
|
||||||
|
$var wire 1 H u $end
|
||||||
|
$var wire 1 J z $end
|
||||||
|
$var wire 1 N z3 $end
|
||||||
|
$var wire 4 P z2 [3:0] $end
|
||||||
|
$var wire 1 R lost $end
|
||||||
|
$var wire 1 T open $end
|
||||||
|
$var wire 129 / xx [128:0] $end
|
||||||
|
$var wire 129 % xy [128:0] $end
|
||||||
|
$var wire 129 9 xz [128:0] $end
|
||||||
|
$var wire 1 V one $end
|
||||||
|
$var wire 1 W vvv $end
|
||||||
|
$scope module unnamedblk1 $end
|
||||||
|
$var wire 32 " n [31:0] $end
|
||||||
|
$var wire 32 # res [31:0] $end
|
||||||
|
$upscope $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
|
||||||
|
|
||||||
|
#1
|
||||||
|
b00000000000000000000000000001100 "
|
||||||
|
b000000000000000000000000000011xx #
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 %
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
zL
|
||||||
|
zN
|
||||||
|
bzzzz P
|
||||||
|
zR
|
||||||
|
zT
|
||||||
|
1V
|
||||||
|
xW
|
||||||
|
#5
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#10
|
||||||
|
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /
|
||||||
|
b010110011011001111110010010011010000100110110000011101010111001111111101010010100010100000111110010101110101010100101001101011110 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#15
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#20
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#25
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#30
|
||||||
|
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /
|
||||||
|
b010110011011001111110010010011010000100110110000011101010111001111111101010010100010100000111110010101110101010100101001101011110 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#35
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#40
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#45
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#50
|
||||||
|
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /
|
||||||
|
b010110011011001111110010010011010000100110110000011101010111001111111101010010100010100000111110010101110101010100101001101011110 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#55
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#60
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#65
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#70
|
||||||
|
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /
|
||||||
|
b010110011011001111110010010011010000100110110000011101010111001111111101010010100010100000111110010101110101010100101001101011110 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#75
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#80
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#85
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#90
|
||||||
|
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /
|
||||||
|
b010110011011001111110010010011010000100110110000011101010111001111111101010010100010100000111110010101110101010100101001101011110 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#95
|
||||||
|
0C
|
||||||
|
0D
|
||||||
|
0F
|
||||||
|
0H
|
||||||
|
0J
|
||||||
|
#100
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 /
|
||||||
|
b101001100100110000001101101100101111011001001111100010101000110000000010101101011101011111000001101010001010101011010110010100001 9
|
||||||
|
1C
|
||||||
|
1D
|
||||||
|
1F
|
||||||
|
1H
|
||||||
|
1J
|
||||||
|
#102
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '--trace-vcd', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute(expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.vcd_identical(test.trace_filename, test.golden_filename + '.vcd')
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`define STRINGIFY(x) `"x`"
|
||||||
|
|
||||||
|
module t;
|
||||||
|
bit clk = 1;
|
||||||
|
wire x;
|
||||||
|
tri y;
|
||||||
|
wire t;
|
||||||
|
triand u;
|
||||||
|
wor z;
|
||||||
|
wor z3;
|
||||||
|
wor [3:0] z2;
|
||||||
|
wire lost;
|
||||||
|
wire open = 'z;
|
||||||
|
assign x = clk;
|
||||||
|
assign z = x;
|
||||||
|
assign z = y;
|
||||||
|
assign u = z;
|
||||||
|
assign u = x;
|
||||||
|
assign t = u;
|
||||||
|
assign t = x;
|
||||||
|
assign t = y;
|
||||||
|
wire [128:0] xx;
|
||||||
|
logic [128:0] xy;
|
||||||
|
logic [128:0] xz;
|
||||||
|
bit one = 1;
|
||||||
|
always #5 clk <= ~clk;
|
||||||
|
|
||||||
|
always #10 xz = ~xz;
|
||||||
|
assign xx = xy;
|
||||||
|
assign xx = xz;
|
||||||
|
|
||||||
|
logic vvv;
|
||||||
|
// logic example;
|
||||||
|
task writeFourState(logic a);
|
||||||
|
if (a === 1'b1) $write("1");
|
||||||
|
else if (a === 1'b0) $write("0");
|
||||||
|
else if (a === 1'bx) $write("x");
|
||||||
|
else if (a === 1'bz) $write("z");
|
||||||
|
else $stop;
|
||||||
|
endtask
|
||||||
|
task print(logic a, logic b);
|
||||||
|
// $write(" %1d & %1d == %1d |", a, b, a & b);
|
||||||
|
$write(" ");
|
||||||
|
writeFourState(a);
|
||||||
|
$write(" ^ ");
|
||||||
|
writeFourState(b);
|
||||||
|
$write(" == ");
|
||||||
|
writeFourState(a ^ b);
|
||||||
|
$write(" |");
|
||||||
|
endtask
|
||||||
|
initial begin
|
||||||
|
static int n = integer'('b0z0x1100);
|
||||||
|
static integer res = 'b01xz | n;
|
||||||
|
if ((int'('b01xz | n)) === n);
|
||||||
|
else $stop;
|
||||||
|
#1;
|
||||||
|
xy = 442093479423423857275364882039482723489;
|
||||||
|
xz = 442093479423423857275364882039482723489;
|
||||||
|
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||||
|
$dumpvars();
|
||||||
|
$write("res: ");
|
||||||
|
writeFourState(res[0]);
|
||||||
|
$write("\n");
|
||||||
|
$write("res: ");
|
||||||
|
writeFourState(res[1]);
|
||||||
|
$write("\n");
|
||||||
|
$write("res: ");
|
||||||
|
writeFourState(res[2]);
|
||||||
|
$write("\n");
|
||||||
|
$write("res: ");
|
||||||
|
writeFourState(res[3]);
|
||||||
|
$write("\n");
|
||||||
|
$write("res: ");
|
||||||
|
writeFourState(res[31]);
|
||||||
|
$write("\n");
|
||||||
|
$write(" ZERO | ONE | X | Z \n");
|
||||||
|
$write("ZERO ");
|
||||||
|
print(0, 0);
|
||||||
|
print(0, 1);
|
||||||
|
print(0, 'x);
|
||||||
|
print(0, 'z);
|
||||||
|
$write("\nONE ");
|
||||||
|
print(1, 0);
|
||||||
|
print(1, 1);
|
||||||
|
print(1, 'x);
|
||||||
|
print(1, 'z);
|
||||||
|
$write("\nX ");
|
||||||
|
print('x, 0);
|
||||||
|
print('x, 1);
|
||||||
|
print('x, 'x);
|
||||||
|
print('x, 'z);
|
||||||
|
$write("\nZ ");
|
||||||
|
print('z, 0);
|
||||||
|
print('z, 1);
|
||||||
|
print('z, 'x);
|
||||||
|
print('z, 'z);
|
||||||
|
$write("\n");
|
||||||
|
$write("x wire: ");
|
||||||
|
writeFourState(x);
|
||||||
|
$write("\n");
|
||||||
|
$write("z wor: ");
|
||||||
|
writeFourState(z);
|
||||||
|
$write("\n");
|
||||||
|
$write("u triand: ");
|
||||||
|
writeFourState(u);
|
||||||
|
$write("\n");
|
||||||
|
$write("t wire: ");
|
||||||
|
writeFourState(t);
|
||||||
|
$write("\n");
|
||||||
|
#1;
|
||||||
|
$write("x wire: ");
|
||||||
|
writeFourState(x);
|
||||||
|
$write("\n");
|
||||||
|
$write("z wor: ");
|
||||||
|
writeFourState(z);
|
||||||
|
$write("\n");
|
||||||
|
$write("u triand: ");
|
||||||
|
writeFourState(u);
|
||||||
|
$write("\n");
|
||||||
|
$write("t wire: ");
|
||||||
|
writeFourState(t);
|
||||||
|
$write("\n");
|
||||||
|
$write("vvv: ");
|
||||||
|
writeFourState(vvv);
|
||||||
|
$write("\n");
|
||||||
|
if ('x & (t !== 0)) $stop;
|
||||||
|
else if (t != 1) $stop;
|
||||||
|
else if (~(t & one | t)) $stop;
|
||||||
|
else if (t | one) $write("Bye\n");
|
||||||
|
else $stop;
|
||||||
|
#100;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
[out] xxxx
|
||||||
|
[out] xxxx
|
||||||
|
[out] xxxx
|
||||||
|
[out] xxxx
|
||||||
|
[out] xxxx
|
||||||
|
[out] 0000
|
||||||
|
[out] 0001
|
||||||
|
[out] 0010
|
||||||
|
[out] 0011
|
||||||
|
[out] 0100
|
||||||
|
[out] 0101
|
||||||
|
[out] 0110
|
||||||
|
[out] 0111
|
||||||
|
[out] 1000
|
||||||
|
[out] 1001
|
||||||
|
*-* All Finished *-*
|
||||||
|
[out] 1010
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
$version Generated by VerilatedVcd $end
|
||||||
|
$timescale 1ps $end
|
||||||
|
$scope module tb_counter $end
|
||||||
|
$var wire 1 " clk $end
|
||||||
|
$var wire 1 $ rstn $end
|
||||||
|
$var wire 4 & out [3:0] $end
|
||||||
|
$scope module c $end
|
||||||
|
$var wire 1 " clk $end
|
||||||
|
$var wire 1 $ rstn $end
|
||||||
|
$var wire 4 & out [3:0] $end
|
||||||
|
$upscope $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
|
||||||
|
|
||||||
|
#0
|
||||||
|
x"
|
||||||
|
x$
|
||||||
|
bzzzz &
|
||||||
|
#20
|
||||||
|
1$
|
||||||
|
#40
|
||||||
|
1"
|
||||||
|
bxxxx &
|
||||||
|
#45
|
||||||
|
0"
|
||||||
|
#50
|
||||||
|
1"
|
||||||
|
#55
|
||||||
|
0"
|
||||||
|
#60
|
||||||
|
1"
|
||||||
|
#65
|
||||||
|
0"
|
||||||
|
#70
|
||||||
|
1"
|
||||||
|
#75
|
||||||
|
0"
|
||||||
|
#80
|
||||||
|
1"
|
||||||
|
#85
|
||||||
|
0"
|
||||||
|
0$
|
||||||
|
#90
|
||||||
|
1"
|
||||||
|
b0000 &
|
||||||
|
#95
|
||||||
|
0"
|
||||||
|
1$
|
||||||
|
#100
|
||||||
|
1"
|
||||||
|
b0001 &
|
||||||
|
#105
|
||||||
|
0"
|
||||||
|
#110
|
||||||
|
1"
|
||||||
|
b0010 &
|
||||||
|
#115
|
||||||
|
0"
|
||||||
|
#120
|
||||||
|
1"
|
||||||
|
b0011 &
|
||||||
|
#125
|
||||||
|
0"
|
||||||
|
#130
|
||||||
|
1"
|
||||||
|
b0100 &
|
||||||
|
#135
|
||||||
|
0"
|
||||||
|
#140
|
||||||
|
1"
|
||||||
|
b0101 &
|
||||||
|
#145
|
||||||
|
0"
|
||||||
|
#150
|
||||||
|
1"
|
||||||
|
b0110 &
|
||||||
|
#155
|
||||||
|
0"
|
||||||
|
#160
|
||||||
|
1"
|
||||||
|
b0111 &
|
||||||
|
#165
|
||||||
|
0"
|
||||||
|
#170
|
||||||
|
1"
|
||||||
|
b1000 &
|
||||||
|
#175
|
||||||
|
0"
|
||||||
|
#180
|
||||||
|
1"
|
||||||
|
b1001 &
|
||||||
|
#185
|
||||||
|
0"
|
||||||
|
#190
|
||||||
|
1"
|
||||||
|
b1010 &
|
||||||
|
#195
|
||||||
|
0"
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '--trace-vcd', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute(expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.vcd_identical(test.trace_filename, test.golden_filename + '.vcd')
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`define STRINGIFY(x) `"x`"
|
||||||
|
|
||||||
|
task writeFourState(logic a);
|
||||||
|
if (a === 1'b1) $write("1");
|
||||||
|
else if (a === 1'b0) $write("0");
|
||||||
|
else if (a === 1'bx) $write("x");
|
||||||
|
else if (a === 1'bz) $write("z");
|
||||||
|
else $stop;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
module counter (
|
||||||
|
input clk,
|
||||||
|
input rstn,
|
||||||
|
output reg [3:0] out
|
||||||
|
);
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (!rstn) out <= 0;
|
||||||
|
else out <= out + 1;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module tb_counter;
|
||||||
|
reg clk;
|
||||||
|
reg rstn;
|
||||||
|
wire [3:0] out;
|
||||||
|
|
||||||
|
counter c (
|
||||||
|
.clk (clk),
|
||||||
|
.rstn(rstn),
|
||||||
|
.out (out)
|
||||||
|
);
|
||||||
|
|
||||||
|
always #5 begin
|
||||||
|
if (clk) begin
|
||||||
|
$write("[out] ");
|
||||||
|
writeFourState(out[3]);
|
||||||
|
writeFourState(out[2]);
|
||||||
|
writeFourState(out[1]);
|
||||||
|
writeFourState(out[0]);
|
||||||
|
$write("\n");
|
||||||
|
end
|
||||||
|
clk = ~clk;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||||
|
$dumpvars();
|
||||||
|
#20 rstn = 1;
|
||||||
|
#20 clk = 0;
|
||||||
|
|
||||||
|
#25 rstn = 1;
|
||||||
|
#20 rstn = 0;
|
||||||
|
#10 rstn = 1;
|
||||||
|
|
||||||
|
#100;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('vlt')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_dfg_bin_to_one_hot.v'
|
||||||
|
|
||||||
|
test.skip("TODO: DFG does not detect one hot pattern created by V3Fourstate")
|
||||||
|
|
||||||
|
test.compile(
|
||||||
|
verilator_flags2=["--fourstate", "-Wno-FUTURE", "--stats", "-fno-table", "-fno-inline"])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.file_grep(test.stats, r'Optimizations, DFG, BinToOneHot, decoders created\s+(\d+)', 5)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
if (1 / $c(0) !== 'x) $stop;
|
||||||
|
if ($c(1) / $c(0) !== 'x) $stop;
|
||||||
|
if ($c(1) / 0 !== 'x) $stop;
|
||||||
|
if (1 / 0 !== 'x) $stop;
|
||||||
|
if (6 / 3 !== 2) $stop;
|
||||||
|
if ($c(6) / 3 !== 2) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_dtype_unsup.v:13:9: Variables of type: 'logic$[$]' are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
13 | logic q [$];
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_dtype_unsup.v:14:9: Variables of type: 'logic$[0:12]' are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
14 | logic p [13];
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_dtype_unsup.v:15:9: Variables of type: 'logic$[integer]' are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
15 | logic a [integer];
|
||||||
|
| ^
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_dtype_unsup.v:16:7: Variables of type: 'struct{}$unit::bar' are unsupported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
16 | bar c;
|
||||||
|
| ^
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic x;
|
||||||
|
logic y;
|
||||||
|
} bar;
|
||||||
|
|
||||||
|
module t;
|
||||||
|
logic q [$];
|
||||||
|
logic p [13];
|
||||||
|
logic a [integer];
|
||||||
|
bar c;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define IMPURE_ONE ($c(1))
|
||||||
|
`else
|
||||||
|
`define IMPURE_ONE (|($random | $random))
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function integer f(integer x);
|
||||||
|
if (`IMPURE_ONE) return x;
|
||||||
|
return 'x;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if ((f('b101) ==? f('b101)) !== 1) $stop;
|
||||||
|
if ((f('b101) ==? f('b10x)) !== 1) $stop;
|
||||||
|
if ((f('b101) ==? f('b1xz)) !== 1) $stop;
|
||||||
|
if ((f('b101) ==? f('b10z)) !== 1) $stop;
|
||||||
|
if ((f('b1z1) ==? f('b10z)) !== 'x) $stop;
|
||||||
|
if ((f('b1xx) ==? f('b1xx)) !== 1) $stop;
|
||||||
|
if ((f('b1x1) ==? f('b101)) !== 'x) $stop;
|
||||||
|
if ((f('b1zz) ==? f('b1xz)) !== 1) $stop;
|
||||||
|
if ((f('bz01) ==? f('b1zx)) !== 'x) $stop;
|
||||||
|
if ((f('b001) ==? f('b1zx)) !== 0) $stop;
|
||||||
|
if ((f('b001) ==? f('b111)) !== 0) $stop;
|
||||||
|
if ((f('bx00) ==? f('bxz1)) !== 0) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
bit posedgeTriggered = 0;
|
||||||
|
bit negedgeTriggered = 0;
|
||||||
|
bit bothedgeTriggered = 0;
|
||||||
|
bit changeTriggered = 0;
|
||||||
|
bit initialized = 0;
|
||||||
|
logic val = 0;
|
||||||
|
|
||||||
|
typedef enum bit [1:0] {
|
||||||
|
POS,
|
||||||
|
NEG,
|
||||||
|
CHANGE,
|
||||||
|
NONE
|
||||||
|
} expected_event_t;
|
||||||
|
|
||||||
|
task assertTriggered(expected_event_t eventType);
|
||||||
|
if (eventType == POS) begin
|
||||||
|
if (!posedgeTriggered) $stop;
|
||||||
|
if (negedgeTriggered) $stop;
|
||||||
|
if (!bothedgeTriggered) $stop;
|
||||||
|
if (!changeTriggered) $stop;
|
||||||
|
end else if (eventType == NEG) begin
|
||||||
|
if (posedgeTriggered) $stop;
|
||||||
|
if (!negedgeTriggered) $stop;
|
||||||
|
if (!bothedgeTriggered) $stop;
|
||||||
|
if (!changeTriggered) $stop;
|
||||||
|
end else if (eventType == CHANGE) begin
|
||||||
|
if (posedgeTriggered) $stop;
|
||||||
|
if (negedgeTriggered) $stop;
|
||||||
|
if (bothedgeTriggered) $stop;
|
||||||
|
if (!changeTriggered) $stop;
|
||||||
|
end else if (eventType == NONE) begin
|
||||||
|
if (posedgeTriggered) $stop;
|
||||||
|
if (negedgeTriggered) $stop;
|
||||||
|
if (bothedgeTriggered) $stop;
|
||||||
|
if (changeTriggered) $stop;
|
||||||
|
end
|
||||||
|
posedgeTriggered = 0;
|
||||||
|
negedgeTriggered = 0;
|
||||||
|
bothedgeTriggered = 0;
|
||||||
|
changeTriggered = 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
always @(val) begin
|
||||||
|
if (initialized & changeTriggered) $stop;
|
||||||
|
changeTriggered = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(edge val) begin
|
||||||
|
if (bothedgeTriggered) $stop;
|
||||||
|
bothedgeTriggered = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge val) begin
|
||||||
|
if (posedgeTriggered) $stop;
|
||||||
|
posedgeTriggered = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge val) begin
|
||||||
|
if (negedgeTriggered) $stop;
|
||||||
|
negedgeTriggered = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#1 changeTriggered = 0;
|
||||||
|
initialized = 1;
|
||||||
|
#1 val = 1;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 1;
|
||||||
|
#1 assertTriggered(NONE);
|
||||||
|
#1 val = 'x;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 'z;
|
||||||
|
#1 assertTriggered(CHANGE);
|
||||||
|
#1 val = 0;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 'z;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 'z;
|
||||||
|
#1 assertTriggered(NONE);
|
||||||
|
#1 val = 'x;
|
||||||
|
#1 assertTriggered(CHANGE);
|
||||||
|
#1 val = 'x;
|
||||||
|
#1 assertTriggered(NONE);
|
||||||
|
#1 val = 'z;
|
||||||
|
#1 assertTriggered(CHANGE);
|
||||||
|
#1 val = 'x;
|
||||||
|
#1 assertTriggered(CHANGE);
|
||||||
|
#1 val = 0;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 1;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 0;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 'x;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 1;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 'z;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 1;
|
||||||
|
#1 assertTriggered(POS);
|
||||||
|
#1 val = 0;
|
||||||
|
#1 assertTriggered(NEG);
|
||||||
|
#1 val = 0;
|
||||||
|
#1 assertTriggered(NONE);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_expr_not_handled_unsup.v:10:9: This four-state expression has not been handled
|
||||||
|
: ... note: In instance 't'
|
||||||
|
10 | alias y = x;
|
||||||
|
| ^
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_fourstate_expr_not_handled_unsup.v:10:13: This four-state expression has not been handled
|
||||||
|
: ... note: In instance 't'
|
||||||
|
10 | alias y = x;
|
||||||
|
| ^
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
wire x;
|
||||||
|
wire y;
|
||||||
|
alias y = x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
typedef logic unsigned [31:0] uinteger;
|
||||||
|
|
||||||
|
module t;
|
||||||
|
initial begin
|
||||||
|
static logic unsigned [15:0] foo = 16'bz000000000000001;
|
||||||
|
static logic signed [15:0] foo2 = 16'bz000000000000001;
|
||||||
|
static integer bar = integer'(foo);
|
||||||
|
if (bar !== 32'b0000000000000000z000000000000001) $stop;
|
||||||
|
bar = uinteger'(foo2);
|
||||||
|
if (bar !== 32'bzzzzzzzzzzzzzzzzz000000000000001) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
3
|
||||||
|
*-* All Finished *-*
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--binary', '--fourstate', '-Wno-FUTURE', '-Wno-CASTFOURSTATE'])
|
||||||
|
|
||||||
|
test.execute(expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
function integer foo(integer a, integer b);
|
||||||
|
return a + b;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
static logic v = 'x;
|
||||||
|
$write("%d\n", v);
|
||||||
|
v = 'z;
|
||||||
|
$write("%d\n", v);
|
||||||
|
v = 0;
|
||||||
|
$write("%d\n", v);
|
||||||
|
v = 1;
|
||||||
|
$write("%d\n", v);
|
||||||
|
$write("%d\n", foo(1, 2));
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
%Warning-CASTFOURSTATE: t/t_fourstate_format.v:14:20: Some features are not supported with four-state values - cast it to two-state logic or suppress this warning and it will be done implicitly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
14 | $write("%d\n", v);
|
||||||
|
| ^
|
||||||
|
... For warning description see https://verilator.org/warn/CASTFOURSTATE?v=latest
|
||||||
|
... Use "/* verilator lint_off CASTFOURSTATE */" and lint_on around source to disable this message.
|
||||||
|
%Warning-CASTFOURSTATE: t/t_fourstate_format.v:16:20: Some features are not supported with four-state values - cast it to two-state logic or suppress this warning and it will be done implicitly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
16 | $write("%d\n", v);
|
||||||
|
| ^
|
||||||
|
%Warning-CASTFOURSTATE: t/t_fourstate_format.v:18:20: Some features are not supported with four-state values - cast it to two-state logic or suppress this warning and it will be done implicitly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
18 | $write("%d\n", v);
|
||||||
|
| ^
|
||||||
|
%Warning-CASTFOURSTATE: t/t_fourstate_format.v:20:20: Some features are not supported with four-state values - cast it to two-state logic or suppress this warning and it will be done implicitly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
20 | $write("%d\n", v);
|
||||||
|
| ^
|
||||||
|
%Warning-CASTFOURSTATE: t/t_fourstate_format.v:21:20: Some features are not supported with four-state values - cast it to two-state logic or suppress this warning and it will be done implicitly
|
||||||
|
: ... note: In instance 't'
|
||||||
|
21 | $write("%d\n", foo(1, 2));
|
||||||
|
| ^~~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_fourstate_format.v"
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
%Warning-FUTURE: --fourstate is not supported as is under development
|
||||||
|
... For warning description see https://verilator.org/warn/FUTURE?v=latest
|
||||||
|
... Use "/* verilator lint_off FUTURE */" and lint_on around source to disable this message.
|
||||||
|
%Error-UNSUPPORTED: --fourstate is not supported with fst trace
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = "t_trace_split_cfuncs.v"
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '--trace-fst'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--fourstate', '-Wno-FUTURE', '-Wno-CASTFOURSTATE'])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.files_identical(test.obj_dir + "/" + test.name + "_logger.log", test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`define STRINGIFY(x) `"x`"
|
||||||
|
|
||||||
|
module t;
|
||||||
|
integer cycles;
|
||||||
|
initial begin
|
||||||
|
integer fd;
|
||||||
|
fd = $fopen({`STRINGIFY(`TEST_OBJ_DIR), "/t_fourstate_fwrite_logger.log"}, "w");
|
||||||
|
$fwrite(fd, "%0d\n", cycles);
|
||||||
|
cycles++;
|
||||||
|
$fwrite(fd, "%0d\n", cycles);
|
||||||
|
cycles = 0;
|
||||||
|
$fwrite(fd, "%0d\n", cycles);
|
||||||
|
cycles++;
|
||||||
|
$fwrite(fd, "%0d\n", cycles);
|
||||||
|
$fflush(fd);
|
||||||
|
$fclose(fd);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
%Error-UNSUPPORTED: --fourstate is not supported with hierarchical Verilation
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_hier_block_type_param.v'
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE', '--hierarchical'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_inst_sv.v:14:17: supply0/tri0 and supply1/tri1 are not supported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
14 | supply0 [1:0] low;
|
||||||
|
| ^~~
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_inst_sv.v:15:17: supply0/tri0 and supply1/tri1 are not supported with --fourstate
|
||||||
|
: ... note: In instance 't'
|
||||||
|
15 | supply1 [1:0] high;
|
||||||
|
| ^~~~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_inst_sv.v'
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
%Error-UNSUPPORTED: t/t_lint_unused_iface.v:10:23: modports are not supported with --fourstate
|
||||||
|
: ... note: In instance 't.sub'
|
||||||
|
10 | modport slave(input signal);
|
||||||
|
| ^~~~~~
|
||||||
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
|
%Error-UNSUPPORTED: t/t_lint_unused_iface.v:12:25: modports are not supported with --fourstate
|
||||||
|
: ... note: In instance 't.sub'
|
||||||
|
12 | modport master(output signal);
|
||||||
|
| ^~~~~~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of either the GNU Lesser General Public License Version 3
|
||||||
|
# or the Perl Artistic License Version 2.0.
|
||||||
|
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = 't/t_lint_unused_iface.v'
|
||||||
|
|
||||||
|
test.lint(verilator_flags2=['--fourstate', '-Wno-FUTURE', '--Wall', '-Wno-DECLFILENAME'],
|
||||||
|
fails=True,
|
||||||
|
expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue