Four-state logic squash
Signed-off-by: Igor Zaworski <izaworski@antmicro.com>
This commit is contained in:
parent
3c7727a8f4
commit
3503b9d853
|
|
@ -0,0 +1,6 @@
|
|||
.. comment: generated by t_fourstate_format_unsup
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
|
||||
static logic v = 'x;
|
||||
$write("%d\n", v); // <- Warning
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.. comment: generated by t_fourstate_format_unsup
|
||||
.. code-block::
|
||||
|
||||
%Warning-CASTFOURSTATE: example.v:1: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
|
||||
|
|
@ -443,6 +443,26 @@ List Of Warnings
|
|||
in decreased performance.
|
||||
|
||||
|
||||
.. option:: CASTFOURSTATE
|
||||
|
||||
Warns about implicit conversion from four-state logic to two-state logic.
|
||||
This warning is due to lack of a support to a feature in four-state mode.
|
||||
Warning may be removed by explicitly casting logic into two-state variant
|
||||
(e.g.: `integer` into `int`, `logic` into `bit`).
|
||||
|
||||
Ignoring this error may cause an unexpected behavior if value while
|
||||
being casted has an unknown value (`x` or `z`) - it will become `0`;
|
||||
in other cases (for known values) simulation will work correctly.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_CASTFOURSTATE_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_CASTFOURSTATE_msg.rst
|
||||
|
||||
|
||||
.. option:: CDCRSTLOGIC
|
||||
|
||||
Historical, never issued since version 5.008.
|
||||
|
|
@ -1346,7 +1366,6 @@ List Of Warnings
|
|||
:option:`ASCRANGE`. While :option:`LITENDIAN` remains for
|
||||
backwards compatibility, new projects should use :option:`ASCRANGE`.
|
||||
|
||||
|
||||
.. option:: MINTYPMAXDLY
|
||||
|
||||
.. code-block:: sv
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ public:
|
|||
} else {
|
||||
unsigned val = 0;
|
||||
for (unsigned i = 0; i < num_element; ++i) {
|
||||
val |= rh.peek<T>(i);
|
||||
val |= rh.peek<T>(i) << i;
|
||||
}
|
||||
uint64_t delta_time_index = time_index - prev_time_index;
|
||||
prev_time_index = time_index;
|
||||
|
|
@ -525,8 +525,8 @@ public:
|
|||
// clang-format off
|
||||
case 0: delta_time_index = (delta_time_index<<2) | (0<<1) | 0; break; // '0'
|
||||
case 1: delta_time_index = (delta_time_index<<2) | (1<<1) | 0; break; // '1'
|
||||
case 2: delta_time_index = (delta_time_index<<4) | (0<<1) | 1; break; // 'X'
|
||||
case 3: delta_time_index = (delta_time_index<<4) | (1<<1) | 1; break; // 'Z'
|
||||
case 2: delta_time_index = (delta_time_index<<4) | (1<<1) | 1; break; // 'Z'
|
||||
case 3: delta_time_index = (delta_time_index<<4) | (0<<1) | 1; break; // 'X'
|
||||
// Not supporting VHDL now
|
||||
// LCOV_EXCL_START
|
||||
case 4: delta_time_index = (delta_time_index<<4) | (2<<1) | 1; break; // 'H'
|
||||
|
|
@ -556,13 +556,27 @@ public:
|
|||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
FST_CHECK(enc == EncodingType::BINARY); // TODO
|
||||
const bool has_non_binary = enc != EncodingType::BINARY;
|
||||
const uint64_t delta_time_index = time_index - prev_time_index;
|
||||
prev_time_index = time_index;
|
||||
h //
|
||||
.writeLEB128((delta_time_index << 1) | has_non_binary)
|
||||
.writeUIntPartialForValueChange(rh.peek<T>(), bitwidth);
|
||||
switch (enc) {
|
||||
case EncodingType::BINARY: {
|
||||
h //
|
||||
.writeLEB128(delta_time_index << 1)
|
||||
.writeUIntPartialForValueChange(rh.peek<T>(), bitwidth);
|
||||
} break;
|
||||
case EncodingType::VERILOG: {
|
||||
h.writeLEB128((delta_time_index << 1) | 1);
|
||||
const T val = rh.peek<T>();
|
||||
const T xz = rh.peek<T>(1);
|
||||
for (int j = bitwidth; j > 0;) {
|
||||
--j;
|
||||
h.writeUIntBE("01zx"[(((xz >> j) << 1) & 2) | ((val >> j) & 1)]);
|
||||
}
|
||||
} break;
|
||||
[[unlikely]] case EncodingType::VHDL: {
|
||||
FST_FAIL_STRING("VHDL format is unsupported with wide values");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
rh.skip(num_byte);
|
||||
}
|
||||
|
|
@ -573,16 +587,26 @@ public:
|
|||
class VariableInfoLongInt {
|
||||
VariableInfo &info;
|
||||
unsigned num_words() const { return (info.bitwidth() + 63) / 64; }
|
||||
unsigned num_words32() const { return (info.bitwidth() + 31) / 32; }
|
||||
|
||||
public:
|
||||
VariableInfoLongInt(VariableInfo &info_) : info(info_) {}
|
||||
|
||||
public:
|
||||
size_t computeBytesNeededNoHeader(EncodingType encoding) const {
|
||||
switch (encoding) {
|
||||
case EncodingType::BINARY:
|
||||
return num_words() * sizeof(uint64_t);
|
||||
case EncodingType::VERILOG:
|
||||
return num_words32() * sizeof(uint32_t) * 2;
|
||||
[[unlikely]] case EncodingType::VHDL:
|
||||
FST_FAIL_STRING("VHDL format is unsupported with wide values");
|
||||
}
|
||||
FST_UNREACHABLE;
|
||||
}
|
||||
|
||||
size_t computeBytesNeeded(EncodingType encoding) const {
|
||||
return (
|
||||
kEmitTimeIndexAndEncodingSize +
|
||||
num_words() * sizeof(uint64_t) * bitPerEncodedBit(encoding)
|
||||
);
|
||||
return kEmitTimeIndexAndEncodingSize + computeBytesNeededNoHeader(encoding);
|
||||
}
|
||||
|
||||
EmitWriterHelper emitValueChangeCommonPart(uint64_t current_time_index, EncodingType encoding) {
|
||||
|
|
@ -600,13 +624,12 @@ public:
|
|||
|
||||
public:
|
||||
void construct() {
|
||||
const size_t nw = num_words();
|
||||
const size_t nw = num_words32();
|
||||
info.resize(computeBytesNeeded(EncodingType::VERILOG));
|
||||
EmitWriterHelper wh(info.data_ptr());
|
||||
wh //
|
||||
.writeTimeIndexAndEncoding(0, EncodingType::VERILOG)
|
||||
.fill(uint64_t(0), nw)
|
||||
.fill(uint64_t(-1), nw);
|
||||
.fill(static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) << 32, nw);
|
||||
}
|
||||
|
||||
void emitValueChange(uint64_t current_time_index, const uint64_t val) {
|
||||
|
|
@ -616,12 +639,13 @@ public:
|
|||
}
|
||||
|
||||
void emitValueChange(uint64_t current_time_index, const uint32_t *val, EncodingType encoding) {
|
||||
const unsigned nw32 = (info.bitwidth() + 31) / 32;
|
||||
const unsigned nw32 = num_words32();
|
||||
const unsigned bpb = bitPerEncodedBit(encoding);
|
||||
|
||||
auto wh = emitValueChangeCommonPart(current_time_index, encoding);
|
||||
|
||||
for (unsigned i = 0; i < bpb; ++i) {
|
||||
switch (encoding) {
|
||||
case EncodingType::BINARY: {
|
||||
for (unsigned j = 0; j < nw32 / 2; ++j) {
|
||||
uint64_t v = val[1]; // high bits
|
||||
v <<= 32;
|
||||
|
|
@ -634,13 +658,25 @@ public:
|
|||
wh.write(v);
|
||||
val += 1;
|
||||
}
|
||||
} break;
|
||||
case EncodingType::VERILOG: {
|
||||
for (unsigned j = 0; j < nw32; ++j) {
|
||||
uint64_t v = val[1]; // high bits
|
||||
v <<= 32;
|
||||
v |= val[0]; // low bits
|
||||
wh.write(v);
|
||||
val += 2;
|
||||
}
|
||||
} break;
|
||||
[[unlikely]] case EncodingType::VHDL:
|
||||
FST_FAIL_STRING("VHDL format is unsupported with wide values");
|
||||
}
|
||||
}
|
||||
|
||||
void emitValueChange(uint64_t current_time_index, const uint64_t *val, EncodingType encoding) {
|
||||
const unsigned nw_encoded = num_words() * bitPerEncodedBit(encoding);
|
||||
auto wh = emitValueChangeCommonPart(current_time_index, encoding);
|
||||
wh.write(val, nw_encoded);
|
||||
FST_CHECK(encoding != EncodingType::VHDL);
|
||||
wh.write(val, encoding == EncodingType::VERILOG ? num_words32() : num_words());
|
||||
}
|
||||
|
||||
void dumpInitialBits(std::vector<uint8_t> &buf) const {
|
||||
|
|
@ -717,33 +753,58 @@ public:
|
|||
FST_DCHECK_GT(tail, rh.ptr);
|
||||
const auto time_index = rh.read<uint64_t>();
|
||||
const auto enc = rh.read<EncodingType>();
|
||||
const auto num_element = bitPerEncodedBit(enc);
|
||||
const auto num_byte = num_element * nw * sizeof(uint64_t);
|
||||
const auto num_byte = computeBytesNeededNoHeader(enc);
|
||||
if (first) {
|
||||
// Note: [0] is initial value, which is already dumped in dumpInitialBits()
|
||||
first = false;
|
||||
} else {
|
||||
FST_CHECK(enc == EncodingType::BINARY); // TODO
|
||||
const bool has_non_binary = enc != EncodingType::BINARY;
|
||||
const uint64_t delta_time_index = time_index - prev_time_index;
|
||||
prev_time_index = time_index;
|
||||
h.writeLEB128((delta_time_index << 1) | has_non_binary);
|
||||
if (bitwidth % 64 != 0) {
|
||||
const unsigned remaining = bitwidth % 64;
|
||||
uint64_t hi64 = rh.peek<uint64_t>(nw - 1);
|
||||
// write from nw-1 to 1
|
||||
for (unsigned j = nw - 1; j > 0; --j) {
|
||||
uint64_t lo64 = rh.peek<uint64_t>(j - 1);
|
||||
h.writeUIntBE((hi64 << (64 - remaining)) | (lo64 >> remaining));
|
||||
hi64 = lo64;
|
||||
switch (enc) {
|
||||
case EncodingType::BINARY: {
|
||||
h.writeLEB128((delta_time_index << 1));
|
||||
if (bitwidth % 64 != 0) {
|
||||
const unsigned remaining = bitwidth % 64;
|
||||
uint64_t hi64 = rh.peek<uint64_t>(nw - 1);
|
||||
// write from nw-1 to 1
|
||||
for (unsigned j = nw - 1; j > 0; --j) {
|
||||
uint64_t lo64 = rh.peek<uint64_t>(j - 1);
|
||||
h.writeUIntBE((hi64 << (64 - remaining)) | (lo64 >> remaining));
|
||||
hi64 = lo64;
|
||||
}
|
||||
// write 0
|
||||
h.writeUIntPartialForValueChange(hi64, remaining);
|
||||
} else {
|
||||
// write from nw-1 to 0
|
||||
for (unsigned j = nw; j-- > 0;) {
|
||||
h.writeUIntBE(rh.peek<uint64_t>(j));
|
||||
}
|
||||
}
|
||||
// write 0
|
||||
h.writeUIntPartialForValueChange(hi64, remaining);
|
||||
} else {
|
||||
// write from nw-1 to 0
|
||||
for (unsigned j = nw; j-- > 0;) {
|
||||
h.writeUIntBE(rh.peek<uint64_t>(j));
|
||||
} break;
|
||||
case EncodingType::VERILOG: {
|
||||
h.writeLEB128((delta_time_index << 1) | 1);
|
||||
const int fullWords = (bitwidth / 32);
|
||||
if (int j = bitwidth % 32) {
|
||||
const uint64_t val = rh.peek<uint64_t>(fullWords);
|
||||
while (j > 0) {
|
||||
--j;
|
||||
const uint64_t v = val >> j;
|
||||
h.writeUIntBE("01zx"[((v >> 31) & 2) | (v & 1)]);
|
||||
}
|
||||
}
|
||||
for (size_t i = fullWords; i > 0;) {
|
||||
--i;
|
||||
const uint64_t val = rh.peek<uint64_t>(i);
|
||||
for (int j = 32; j > 0;) {
|
||||
--j;
|
||||
const uint64_t v = val >> j;
|
||||
h.writeUIntBE("01zx"[((v >> 31) & 2) | (v & 1)]);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
[[unlikely]] case EncodingType::VHDL: {
|
||||
FST_FAIL_STRING("VHDL format is unsupported with wide values");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
rh.skip(num_byte);
|
||||
|
|
|
|||
|
|
@ -605,7 +605,7 @@ void detail::ValueChangeData::writeEncodedPositions(
|
|||
}
|
||||
|
||||
// encode as signed (value << 1) | 1 and write as signed LEB128
|
||||
h.writeLEB128Signed((value_to_encode << 1) | 1);
|
||||
h.writeLEB128Signed((static_cast<uint64_t>(value_to_encode) << 1) | 1);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,7 +382,15 @@ VL_ATTR_ALWINLINE
|
|||
void VerilatedFstBuffer::emitBit(uint32_t code, CData newval) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||
m_owner.emitTimeChangeMaybe();
|
||||
m_fst->emitValueChange(m_symbolp[code], uint64_t(newval));
|
||||
m_fst->emitValueChange(m_symbolp[code], 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
|
||||
|
|
@ -392,6 +400,14 @@ void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int) {
|
|||
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
|
||||
void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||
|
|
@ -399,6 +415,14 @@ void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int) {
|
|||
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 uint64_t newvals[2] = {static_cast<uint64_t>(newval), static_cast<uint64_t>(newvalXZ)};
|
||||
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||
|
|
@ -406,6 +430,14 @@ void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int) {
|
|||
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 uint64_t newvals[2] = {static_cast<uint64_t>(newval), static_cast<uint64_t>(newvalXZ)};
|
||||
m_fst->emitValueChange(m_symbolp[code], newvals, fst::EncodingType::VERILOG);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]);); // LCOV_EXCL_BR_LINE
|
||||
|
|
@ -414,12 +446,39 @@ void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int) {
|
|||
}
|
||||
|
||||
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
|
||||
m_owner.emitTimeChangeMaybe();
|
||||
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
|
||||
thread_local std::vector<uint32_t> newvals;
|
||||
newvals.clear();
|
||||
const size_t wordCount = static_cast<size_t>(VL_WORDS_I(bits));
|
||||
newvals.reserve(wordCount * 2);
|
||||
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(), fst::EncodingType::VERILOG);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFstBuffer::emitDouble(uint32_t code, double newval) {
|
||||
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.
|
||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||
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 emitFourstateCData(uint32_t code, CData newval, CData newvalXZ, 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 emitFourstateIData(uint32_t code, IData newval, IData newvalXZ, 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 emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||
int bits);
|
||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,20 +65,23 @@
|
|||
class VerilatedSaifActivityBit final {
|
||||
// MEMBERS
|
||||
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
|
||||
size_t m_transitions = 0; // Total number of bit transitions
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
VL_ATTR_ALWINLINE
|
||||
void aggregateVal(uint64_t dt, bool newVal) {
|
||||
m_transitions += newVal != m_lastVal ? 1 : 0;
|
||||
void aggregateVal(uint64_t dt, bool newVal, bool newValXZ = false) {
|
||||
m_transitions += (newVal != m_lastVal || m_lastValXZ != newValXZ) ? 1 : 0;
|
||||
m_highTime += m_lastVal ? dt : 0;
|
||||
m_lastVal = newVal;
|
||||
m_lastValXZ = newValXZ;
|
||||
}
|
||||
|
||||
// ACCESSORS
|
||||
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 toggleCount() const { return m_transitions; }
|
||||
};
|
||||
|
|
@ -104,6 +107,7 @@ public:
|
|||
|
||||
// METHODS
|
||||
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>
|
||||
VL_ATTR_ALWINLINE void emitData(uint64_t time, DataType newval, uint32_t bits) {
|
||||
|
|
@ -112,12 +116,29 @@ public:
|
|||
|
||||
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 >> i) & 1);
|
||||
m_bits[i].aggregateVal(dt, VL_BITISSET_Q(newval, i));
|
||||
}
|
||||
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 emitFourstateWData(uint64_t time, WDataInP newval, WDataInP newvalXZ,
|
||||
uint32_t bits);
|
||||
VL_ATTR_ALWINLINE void updateLastTime(uint64_t val) { m_lastTime = val; }
|
||||
|
||||
// ACCESSORS
|
||||
|
|
@ -229,13 +250,35 @@ void VerilatedSaifActivityVar::emitBit(const uint64_t time, const CData newval)
|
|||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
m_bits[i].aggregateVal(dt, VL_BITISSET_E(newval[wordIndex], i));
|
||||
}
|
||||
|
||||
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, VL_BITISSET_E(newval[wordIndex], i),
|
||||
VL_BITISSET_E(newvalXZ[wordIndex], i));
|
||||
}
|
||||
|
||||
updateLastTime(time);
|
||||
|
|
@ -633,6 +676,15 @@ void VerilatedSaifBuffer::emitBit(const uint32_t code, const CData 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
|
||||
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)
|
||||
|
|
@ -642,6 +694,16 @@ void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, con
|
|||
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
|
||||
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)
|
||||
|
|
@ -651,6 +713,16 @@ void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, con
|
|||
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
|
||||
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)
|
||||
|
|
@ -660,6 +732,16 @@ void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, con
|
|||
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
|
||||
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)
|
||||
|
|
@ -670,7 +752,17 @@ void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, con
|
|||
}
|
||||
|
||||
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)
|
||||
&& "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity
|
||||
|
|
@ -678,6 +770,16 @@ void VerilatedSaifBuffer::emitWData(const uint32_t code, WDataInP newval, const
|
|||
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
|
||||
void VerilatedSaifBuffer::emitDouble(const uint32_t code, const double newval) {
|
||||
// NOP
|
||||
|
|
|
|||
|
|
@ -243,11 +243,22 @@ class VerilatedSaifBuffer VL_NOT_FINAL {
|
|||
// called from only one place (the full* methods), so always inline them.
|
||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||
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 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 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 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 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 emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||
int bits);
|
||||
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.
|
||||
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 fullFourstateCData(uint32_t* oldp, CData newval, CData newvalXZ, 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 fullFourstateIData(uint32_t* oldp, IData newval, IData newvalXZ, 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 fullFourstateWData(uint32_t* oldp, WDataInP newval, WDataInP newvalXZ, int bits);
|
||||
void fullDouble(uint32_t* oldp, double newval);
|
||||
void fullEvent(uint32_t* oldp, const VlEventBase* newvalp);
|
||||
void fullEventTriggered(uint32_t* oldp);
|
||||
|
|
@ -399,32 +405,74 @@ public:
|
|||
const uint32_t diff = *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) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
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) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
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) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
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) {
|
||||
QData old;
|
||||
std::memcpy(&old, oldp, sizeof(old));
|
||||
const uint64_t diff = old ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullQData(oldp, newval, bits);
|
||||
}
|
||||
VL_ATTR_ALWINLINE void chgWData(uint32_t* oldp, WDataInP newval, int bits) {
|
||||
for (int i = 0; i < (bits + 31) / 32; ++i) {
|
||||
VL_ATTR_ALWINLINE void chgFourstateQData(uint32_t* oldp, QData newval, QData newvalXZ,
|
||||
int bits) {
|
||||
QData oldVal;
|
||||
QData oldXZ;
|
||||
std::memcpy(&oldVal, oldp, sizeof(QData));
|
||||
std::memcpy(&oldXZ, oldp + (sizeof(QData) / sizeof(uint32_t)), sizeof(QData));
|
||||
const uint64_t diff = (oldVal ^ newval) | (oldXZ ^ 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])) {
|
||||
fullWData(oldp, newval, bits);
|
||||
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) {
|
||||
if (newvalp->isTriggered()) fullEvent(oldp, newvalp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,6 +555,16 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullBit(uint32_t* oldp, CData 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 <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newvalp) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullSData(uint32_t* oldp, SData newval, int bits) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullIData(uint32_t* oldp, IData newval, int bits) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullQData(uint32_t* oldp, QData newval, int bits) {
|
||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||
|
|
@ -602,13 +645,36 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullQData(uint32_t* oldp, QData newval, int
|
|||
}
|
||||
|
||||
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;
|
||||
std::memcpy(oldp, &newval, sizeof(newval));
|
||||
std::memcpy(oldp + (sizeof(QData) / sizeof(uint32_t)), &newvalXZ, sizeof(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;
|
||||
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;
|
||||
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 <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullDouble(uint32_t* oldp, double newval) {
|
||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||
|
|
|
|||
|
|
@ -635,6 +635,14 @@ void VerilatedVcdBuffer::emitBit(uint32_t code, CData newval) {
|
|||
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;
|
||||
*wp++ = "01zx"[(newvalXZ << 1) | newval];
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
||||
char* wp = m_writep;
|
||||
|
|
@ -643,6 +651,18 @@ void VerilatedVcdBuffer::emitCData(uint32_t code, CData newval, int 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 index = (((newvalXZ >> i) & 1) << 1) | ((newval >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
||||
char* wp = m_writep;
|
||||
|
|
@ -651,6 +671,18 @@ void VerilatedVcdBuffer::emitSData(uint32_t code, SData newval, int 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 CData index = (((newvalXZ >> i) & 1) << 1) | ((newval >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
||||
char* wp = m_writep;
|
||||
|
|
@ -659,6 +691,18 @@ void VerilatedVcdBuffer::emitIData(uint32_t code, IData newval, int 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 CData index = (((newvalXZ >> i) & 1) << 1) | ((newval >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
||||
char* wp = m_writep;
|
||||
|
|
@ -668,7 +712,19 @@ void VerilatedVcdBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
|||
}
|
||||
|
||||
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 CData index = (((newvalXZ >> i) & 1) << 1) | ((newval >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitWData(uint32_t code, const WDataInP newval, int bits) {
|
||||
int words = VL_WORDS_I(bits);
|
||||
char* wp = m_writep;
|
||||
*wp++ = 'b';
|
||||
|
|
@ -684,6 +740,31 @@ void VerilatedVcdBuffer::emitWData(uint32_t code, WDataInP newval, int bits) {
|
|||
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 CData index = (((xz >> i) & 1) << 1) | ((value >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
}
|
||||
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 CData index = (((xz >> i) & 1) << 1) | ((value >> i) & 1);
|
||||
*wp++ = "01zx"[index];
|
||||
}
|
||||
}
|
||||
finishLine(code, wp);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedVcdBuffer::emitDouble(uint32_t code, double newval) {
|
||||
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.
|
||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
|
||||
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 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 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 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 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 emitFourstateWData(uint32_t code, WDataInP newval, WDataInP newvalXZ,
|
||||
int bits);
|
||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ set(HEADERS
|
|||
V3Force.h
|
||||
V3FsmDetect.h
|
||||
V3Fork.h
|
||||
V3Fourstate.h
|
||||
V3FuncOpt.h
|
||||
V3FunctionTraits.h
|
||||
V3Gate.h
|
||||
|
|
@ -280,6 +281,7 @@ set(COMMON_SOURCES
|
|||
V3Force.cpp
|
||||
V3FsmDetect.cpp
|
||||
V3Fork.cpp
|
||||
V3Fourstate.cpp
|
||||
V3FuncOpt.cpp
|
||||
V3Gate.cpp
|
||||
V3Global.cpp
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ RAW_OBJS_PCH_ASTNOMT = \
|
|||
V3Force.o \
|
||||
V3FsmDetect.o \
|
||||
V3Fork.o \
|
||||
V3Fourstate.o \
|
||||
V3Gate.o \
|
||||
V3HierBlock.o \
|
||||
V3Inline.o \
|
||||
|
|
|
|||
|
|
@ -1675,6 +1675,27 @@ public:
|
|||
bool sameNode(const AstNode* /*samep*/) 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 {
|
||||
// Verilog $future_gclk
|
||||
// @astgen op1 := exprp : AstNodeExpr
|
||||
|
|
@ -5504,6 +5525,7 @@ public:
|
|||
void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); }
|
||||
string emitVerilog() override { return "(%l)"; }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitSMT() const override { return "%l"; }
|
||||
bool cleanOut() const override { return false; }
|
||||
bool cleanLhs() const override { return false; }
|
||||
bool sizeMattersLhs() const override { return false; }
|
||||
|
|
|
|||
|
|
@ -2125,6 +2125,8 @@ class AstVar final : public AstNode {
|
|||
// @astgen op4 := attrsp : List[AstNode] // Attributes during early parse
|
||||
// @astgen ptr := m_sensIfacep : Optional[AstIface] // Interface type to which reads from this
|
||||
// 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_origName; // Original name before dot addition
|
||||
|
|
@ -2134,6 +2136,8 @@ class AstVar final : public AstNode {
|
|||
VDirection m_declDirection; // Declared direction input/output etc
|
||||
VLifetime m_lifetime; // Lifetime
|
||||
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
|
||||
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)
|
||||
|
|
@ -2198,7 +2202,9 @@ class AstVar final : public AstNode {
|
|||
bool m_isStdRandomizeArg : 1; // Argument variable created for std::randomize (__Varg*)
|
||||
bool m_processQueue : 1; // Process queue variable
|
||||
bool m_mtaskCacheLineAlign : 1; // Start MTask affinity group on a cache line
|
||||
bool m_isFourstateComplement : 1; // Set in four-state xz part
|
||||
void init() {
|
||||
m_fourstateOriginalDTypeKwd = VBasicDTypeKwd::UNKNOWN;
|
||||
m_ansi = false;
|
||||
m_declTyped = false;
|
||||
m_tristate = false;
|
||||
|
|
@ -2262,6 +2268,7 @@ class AstVar final : public AstNode {
|
|||
m_isStdRandomizeArg = false;
|
||||
m_processQueue = false;
|
||||
m_mtaskCacheLineAlign = false;
|
||||
m_isFourstateComplement = false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -2364,6 +2371,19 @@ public:
|
|||
void ansi(bool flag) { m_ansi = flag; }
|
||||
void declTyped(bool flag) { m_declTyped = flag; }
|
||||
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 attrScBv(bool flag) { m_attrScBv = 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 VVarType m_varType; // Type of variable (for localparam vs. param)
|
||||
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
|
||||
int m_codeInc{0}; // Code increment for type
|
||||
|
||||
public:
|
||||
AstTraceDecl(FileLine* fl, const string& showname,
|
||||
AstVar* varp, // For input/output state etc
|
||||
|
|
@ -1310,6 +1312,7 @@ public:
|
|||
, m_arrayRange{arrayRange}
|
||||
, m_varType{varp->varType()}
|
||||
, m_declDirection{varp->declDirection()}
|
||||
, m_dtypeKwd{varp->fourstateOriginalDTypeKwd()}
|
||||
, m_inDtypeFunc{inDtypeFunc} {
|
||||
dtypeFrom(valuep);
|
||||
this->valuep(valuep);
|
||||
|
|
@ -1335,12 +1338,15 @@ public:
|
|||
if (m_codeInc) { return m_codeInc; }
|
||||
return (m_arrayRange.ranged() ? m_arrayRange.elements() : 1)
|
||||
* 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
|
||||
}
|
||||
const VNumRange& bitRange() const { return m_bitRange; }
|
||||
const VNumRange& arrayRange() const { return m_arrayRange; }
|
||||
VVarType varType() const { return m_varType; }
|
||||
VDirection declDirection() const { return m_declDirection; }
|
||||
VBasicDTypeKwd dtypeKwd() const { return m_dtypeKwd; }
|
||||
AstCCall* dtypeCallp() const { return m_dtypeCallp; }
|
||||
void dtypeCallp(AstCCall* const callp) { m_dtypeCallp = callp; }
|
||||
AstTraceDecl* dtypeDeclp() const { return m_dtypeDeclp; }
|
||||
|
|
|
|||
|
|
@ -3846,8 +3846,9 @@ class ConstVisitor final : public VNVisitor {
|
|||
nodep->condp(new AstLogNot{condp->fileline(),
|
||||
condp}); // LogNot, as C++ optimization also possible
|
||||
nodep->addThensp(elsesp);
|
||||
} else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|
||||
|| VN_IS(nodep->condp(), LogNot))
|
||||
} else if (v3Global.fourstateHandled()
|
||||
&& ((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|
||||
|| VN_IS(nodep->condp(), LogNot))
|
||||
&& nodep->thensp() && nodep->elsesp()) {
|
||||
UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep);
|
||||
AstNodeExpr* const condp
|
||||
|
|
@ -3859,7 +3860,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
ifp->branchPred(nodep->branchPred().invert());
|
||||
nodep->replaceWith(ifp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (ifSameAssign(nodep)) {
|
||||
} else if (v3Global.fourstateHandled() && ifSameAssign(nodep)) {
|
||||
UINFO(4,
|
||||
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})");
|
||||
AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
|
||||
|
|
|
|||
|
|
@ -489,8 +489,12 @@ class DeadVisitor final : public VNVisitor {
|
|||
retry = false;
|
||||
for (std::vector<AstVar*>::iterator it = m_varsp.begin(); it != m_varsp.end(); ++it) {
|
||||
AstVar* const varp = *it;
|
||||
if (!varp) continue;
|
||||
if (!varp || varp->isFourstateComplement()) continue;
|
||||
if (varp->user1() == 0) {
|
||||
if (AstVar* const varComplementp = varp->fourstateComplementp()) {
|
||||
if (varComplementp->user1() != 0) continue;
|
||||
deleting(varComplementp);
|
||||
}
|
||||
UINFO(4, " Dead " << varp);
|
||||
if (varp->dtypep()) varp->dtypep()->user1Inc(-1);
|
||||
deleting(varp);
|
||||
|
|
|
|||
|
|
@ -617,6 +617,26 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
|
|||
out += varNameProtected + suffix + "[" + cvtToStr(w) + "] = ";
|
||||
out += cvtToStr(constp->num().edataWord(w)) + "U;\n";
|
||||
}
|
||||
} else if (v3Global.opt.fourstate()
|
||||
&& (varp->isFourstateComplement() || varp->fourstateComplementp())) {
|
||||
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())) {
|
||||
out += "VL_ALLONES_W("; // This is a temporary solution - interleaved signals
|
||||
// will change this
|
||||
} else {
|
||||
out += (slow ? "VL_ZERO_RESET_W(" : "VL_ZERO_W(");
|
||||
}
|
||||
out += cvtToStr(dtypep->widthMin());
|
||||
out += ", " + varNameProtected + suffix;
|
||||
out += ");\n";
|
||||
return out;
|
||||
} else {
|
||||
out += zeroit ? (slow ? "VL_ZERO_RESET_W(" : "VL_ZERO_W(")
|
||||
: (varp->isXTemp() ? "VL_SCOPED_RAND_RESET_ASSIGN_W("
|
||||
|
|
@ -645,6 +665,23 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, bool constructing,
|
|||
UASSERT_OBJ(constp, varp, "non-const initializer for variable");
|
||||
out += cvtToStr(constp->num().edataWord(0)) + "U;\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) {
|
||||
out += " = 0;\n";
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -740,8 +740,9 @@ class EmitCTrace final : public EmitCFunc {
|
|||
|
||||
void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) {
|
||||
// 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;
|
||||
const bool isFourstate = VN_IS(nodep->valuep(), FourstateExpr);
|
||||
string stype;
|
||||
if (nodep->dtypep()->basicp()->isDouble()) {
|
||||
stype = "Double";
|
||||
|
|
@ -759,10 +760,14 @@ class EmitCTrace final : public EmitCFunc {
|
|||
} else if (nodep->dtypep()->basicp()->isEvent()) {
|
||||
stype = "Event";
|
||||
emitWidth = false;
|
||||
} else if (isFourstate) {
|
||||
stype = "Logic";
|
||||
emitWidth = false;
|
||||
} else {
|
||||
stype = "Bit";
|
||||
emitWidth = false;
|
||||
}
|
||||
if (isFourstate && stype != "Logic") func += "Fourstate";
|
||||
putns(nodep, "bufp->" + func + stype);
|
||||
|
||||
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) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) {
|
||||
const AstVar* const varp = varrefp->varp();
|
||||
auto putVarRef = [this, nodep, arrayindex](AstVarRef* const varrefp) {
|
||||
AstVar* const varp = varrefp->varp();
|
||||
if (varp->isEvent()) puts("&");
|
||||
puts("(");
|
||||
if (emitTraceIsScBigUint(nodep)) {
|
||||
|
|
@ -801,12 +806,29 @@ class EmitCTrace final : public EmitCFunc {
|
|||
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 {
|
||||
puts("(");
|
||||
iterateConst(nodep->valuep());
|
||||
emitTraceIndex(nodep, arrayindex);
|
||||
puts(")");
|
||||
}
|
||||
puts(")");
|
||||
}
|
||||
|
||||
void emitTraceIndex(const AstTraceInc* const nodep, int arrayindex) {
|
||||
|
|
|
|||
|
|
@ -639,6 +639,13 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
iterateConst(nodep->exprp());
|
||||
puts(";\n");
|
||||
}
|
||||
void visit(AstFourstateExpr* const nodep) override {
|
||||
puts("FOUR_STATE_EXPR(VAL=");
|
||||
iterateConst(nodep->valuep());
|
||||
puts(", XZ=");
|
||||
iterateConst(nodep->xzp());
|
||||
puts(")");
|
||||
}
|
||||
|
||||
// Nodes involing AstText
|
||||
void visit(AstText* nodep) override {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public:
|
|||
CASEWITHX, // Case with X values
|
||||
CASEX, // Casex
|
||||
CASTCONST, // Cast is constant
|
||||
CASTFOURSTATE, // Implicit logic (between 2/4 state logic)
|
||||
CDCRSTLOGIC, // Logic in async reset path. Historical, never issued.
|
||||
CLKDATA, // Clock used as data. Historical, never issued.
|
||||
CMPCONST, // Comparison is constant due to limited range
|
||||
|
|
@ -226,24 +227,24 @@ public:
|
|||
" EC_FIRST_WARN", "ALWCOMBORDER", "ALWNEVER", "ASCRANGE", "ASSIGNDLY", "ASSIGNEQEXPR",
|
||||
"ASSIGNIN", "BADSTDPRAGMA", "BADVLTPRAGMA", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ",
|
||||
"BSSPACE", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST",
|
||||
"CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY", "CONSTRAINTIGN",
|
||||
"CONTASSREG", "COVERIGN", "DECLFILENAME", "DEFOVERRIDE", "DEFPARAM", "DEPRECATED",
|
||||
"ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE", "FINALDLY",
|
||||
"FSMMULTI", "FUNCTIMECTL", "FUTURE", "GENCLK", "GENUNNAMED", "HIERBLOCK", "HIERPARAM",
|
||||
"IEEEMAYDEPRECATE", "IFDEPTH", "IGNOREDRETURN", "IMPERFECTSCH", "IMPLICIT",
|
||||
"IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP", "INITIALDLY",
|
||||
"INSECURE", "INSIDETRUE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP",
|
||||
"MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD",
|
||||
"NORETURN", "NOTREDOP", "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING",
|
||||
"PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT",
|
||||
"PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT",
|
||||
"REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN",
|
||||
"SPLITVAR", "STATICVAR", "STMTDLY", "SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
||||
"UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED", "UNUSEDGENVAR", "UNUSEDLOOP",
|
||||
"UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
||||
"VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC",
|
||||
"WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
|
||||
"CASTFOURSTATE", "CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY",
|
||||
"CONSTRAINTIGN", "CONTASSREG", "COVERIGN", "DECLFILENAME", "DEFOVERRIDE", "DEFPARAM",
|
||||
"DEPRECATED", "ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE",
|
||||
"FINALDLY", "FSMMULTI", "FUNCTIMECTL", "FUTURE", "GENCLK", "GENUNNAMED", "HIERBLOCK",
|
||||
"HIERPARAM", "IEEEMAYDEPRECATE", "IFDEPTH", "IGNOREDRETURN", "IMPERFECTSCH",
|
||||
"IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP",
|
||||
"INITIALDLY", "INSECURE", "INSIDETRUE", "LATCH", "LITENDIAN", "MINTYPMAXDLY",
|
||||
"MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT",
|
||||
"NOLATCH", "NONSTD", "NORETURN", "NOTREDOP", "NULLPORT", "PARAMNODEFAULT",
|
||||
"PINCONNECTEMPTY", "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL",
|
||||
"PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED",
|
||||
"PROTOTYPEMIS", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY", "SELRANGE",
|
||||
"SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", "STATICVAR", "STMTDLY",
|
||||
"SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN",
|
||||
"UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED",
|
||||
"UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL",
|
||||
"USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT",
|
||||
"WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
|
||||
return names[m_e];
|
||||
}
|
||||
// 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
|
||||
|
|
@ -199,6 +199,7 @@ class V3Global final {
|
|||
bool m_useCovergroup = false; // Has covergroup declarations
|
||||
bool m_useRandomizeMethods = false; // Need to define randomize() class methods
|
||||
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
|
||||
|
||||
// Memory address to short string mapping (for debug)
|
||||
|
|
@ -288,6 +289,8 @@ public:
|
|||
bool useCovergroup() const { return m_useCovergroup; }
|
||||
void useCovergroup(bool flag) { m_useCovergroup = flag; }
|
||||
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; }
|
||||
bool hasPrintedObjects() const { return m_hasPrintedObjects; }
|
||||
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;
|
||||
}
|
||||
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
|
||||
// op i, L(lhs) bit return
|
||||
NUM_ASSERT_OP_ARGS1(lhs);
|
||||
|
|
|
|||
|
|
@ -744,6 +744,7 @@ public:
|
|||
// "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& 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& opBitsZ(const V3Number& lhs); // Z->1, 0/1/X->0
|
||||
//
|
||||
|
|
|
|||
|
|
@ -246,10 +246,40 @@ private:
|
|||
= [this, flp, senp]() { return new AstVarRef{flp, getPrev(senp), VAccess::READ}; };
|
||||
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
|
||||
switch (senItemp->edgeType()) {
|
||||
case VEdgeType::ET_CHANGED:
|
||||
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)) {
|
||||
// operand order reversed to avoid calling neq() method on non-VlUnpacked type, see
|
||||
// issue #5125
|
||||
|
|
@ -261,15 +291,46 @@ private:
|
|||
return {wrapExprWithNullCheck(flp, new AstNeq{flp, currp(), prevp()}, baseClassRefp),
|
||||
true};
|
||||
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 {
|
||||
wrapExprWithNullCheck(flp, lsb(new AstXor{flp, currp(), prevp()}), baseClassRefp),
|
||||
false};
|
||||
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,
|
||||
lsb(new AstAnd{flp, currp(), new AstNot{flp, prevp()}}),
|
||||
baseClassRefp),
|
||||
false};
|
||||
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,
|
||||
lsb(new AstAnd{flp, new AstNot{flp, currp()}, prevp()}),
|
||||
baseClassRefp),
|
||||
|
|
@ -293,6 +354,9 @@ private:
|
|||
return {wrapExprWithNullCheck(flp, callp, baseClassRefp), false};
|
||||
}
|
||||
case VEdgeType::ET_TRUE: //
|
||||
if (fourstateExpr) {
|
||||
return {lsb(new AstAnd{flp, currValp(), new AstNot{flp, currXZp()}}), false};
|
||||
}
|
||||
return {currp(), false};
|
||||
case VEdgeType::ET_INITIAL_NBA: //
|
||||
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(); }
|
||||
};
|
||||
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
|
||||
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
|
||||
|
||||
VDouble0 m_statSigs; // Statistic tracking
|
||||
|
|
@ -334,6 +337,10 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
}
|
||||
FileLine* const flp = m_traVscp->fileline();
|
||||
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();
|
||||
AstTraceDecl* const newp
|
||||
= new AstTraceDecl{flp, m_traName, m_traVscp->varp(), valuep,
|
||||
|
|
@ -685,6 +692,12 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
// traversal.
|
||||
m_traValuep
|
||||
= 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
|
||||
// AstTraceDecls.
|
||||
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
|
||||
// on m_traValuep being nullptr, so make sure it is.
|
||||
m_traValuep = nullptr;
|
||||
if (m_traValueXZp) {
|
||||
VL_DO_DANGLING(m_traValueXZp->deleteTree(), m_traValueXZp);
|
||||
m_traValueXZp = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -795,8 +812,12 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
if (nodep->varp()->isParam() && VN_IS(nodep->scopep()->modp(), Package)) return;
|
||||
}
|
||||
|
||||
// Add to traced signal list
|
||||
m_entries.emplace_back(m_currScopep, nodep);
|
||||
if (nodep->varp()->isFourstateComplement()) {
|
||||
m_varxzToVscp.emplace(nodep->varp(), nodep);
|
||||
} else {
|
||||
// Add to traced signal list
|
||||
m_entries.emplace_back(m_currScopep, nodep);
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS - Data types when tracing
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ class UnknownVisitor final : public VNVisitor {
|
|||
|
||||
void visit(AstSel* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
if (!v3Global.opt.fourstate() && !nodep->user1SetOnce()) {
|
||||
// Guard against reading/writing past end of bit vector array
|
||||
const AstNode* const basefromp = AstArraySel::baseFromp(nodep, true);
|
||||
bool lvalue = false;
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,8 @@ class WidthVisitor final : public VNVisitor {
|
|||
const bool inParameterizedTemplate
|
||||
= 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
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: left < right of bit extract: " // LCOV_EXCL_LINE
|
||||
|
|
@ -1188,22 +1189,24 @@ class WidthVisitor final : public VNVisitor {
|
|||
UINFO(1, " Related node: " << nodep);
|
||||
}
|
||||
if (lrefp) UINFO(9, " Select extend lrefp " << lrefp);
|
||||
if (lrefp && lrefp->access().isWriteOrRW()) {
|
||||
// lvarref[X] = ..., the expression assigned is too wide
|
||||
// WTF to do
|
||||
// Don't change the width of this lhsp, instead propagate up
|
||||
// to upper assign/expression the correct width
|
||||
AstNodeDType* const subDTypep
|
||||
= nodep->findLogicDType(width, width, nodep->fromp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep, EXTEND_EXP,
|
||||
false /*noerror*/);
|
||||
} else {
|
||||
// Extend it
|
||||
const int extendTo = nodep->msbConst() + 1;
|
||||
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
||||
extendTo, extendTo, nodep->fromp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep, EXTEND_EXP,
|
||||
false /*noerror*/);
|
||||
if (!v3Global.opt.fourstate()) {
|
||||
if (lrefp && lrefp->access().isWriteOrRW()) {
|
||||
// lvarref[X] = ..., the expression assigned is too wide
|
||||
// WTF to do
|
||||
// Don't change the width of this lhsp, instead propagate up
|
||||
// to upper assign/expression the correct width
|
||||
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
||||
width, width, nodep->fromp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep,
|
||||
EXTEND_EXP, false /*noerror*/);
|
||||
} else {
|
||||
// Extend it
|
||||
const int extendTo = nodep->msbConst() + 1;
|
||||
AstNodeDType* const subDTypep = nodep->findLogicDType(
|
||||
extendTo, extendTo, nodep->fromp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep,
|
||||
EXTEND_EXP, false /*noerror*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
// iterate FINAL is two blocks above
|
||||
|
|
@ -1211,7 +1214,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
// 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
|
||||
// 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
|
||||
// we want the select to be truncated to fit within the
|
||||
// maximum select range, e.g. turn Xs outside of the select
|
||||
|
|
|
|||
|
|
@ -278,9 +278,6 @@ private:
|
|||
void visit(AstCastWrap* nodep) override {
|
||||
iterateChildren(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 {
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -557,3 +554,19 @@ void V3WidthCommit::widthCommit(AstNetlist* nodep) {
|
|||
{ WidthCommitVisitor{nodep}; } // Destruct before checking
|
||||
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
|
||||
static void widthCommit(AstNetlist* nodep) VL_MT_DISABLED;
|
||||
static void widthCommitClean(AstNetlist* nodep) VL_MT_DISABLED;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "V3File.h"
|
||||
#include "V3Force.h"
|
||||
#include "V3Fork.h"
|
||||
#include "V3Fourstate.h"
|
||||
#include "V3FsmDetect.h"
|
||||
#include "V3FuncOpt.h"
|
||||
#include "V3Gate.h"
|
||||
|
|
@ -302,6 +303,8 @@ static void process() {
|
|||
// No more AstGenBlocks after this
|
||||
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
|
||||
// Also simplify pin connections to always be AssignWs in prep for V3Unknown
|
||||
V3Tristate::tristateAll(v3Global.rootp());
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"modulesp": [
|
||||
{"type":"MODULE","name":"t","addr":"(F)","loc":"d,67:8,67:9","origName":"t","verilogName":"t","level":1,"timeunit":"1ps","inlinesp": [],
|
||||
"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",
|
||||
"stmtsp": [
|
||||
{"type":"BEGIN","name":"","addr":"(J)","loc":"d,71:11,71:16","unnamed":true,"declsp": [],
|
||||
|
|
@ -19,21 +19,21 @@
|
|||
"stmtsp": [
|
||||
{"type":"CLASS","name":"Packet","addr":"(O)","loc":"d,7:1,7:6","origName":"Packet","verilogName":"Packet","level":3,"timeunit":"1ps","classOrPackagep":"UNLINKED","inlinesp": [],
|
||||
"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":"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":"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":"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":"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":"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":"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":"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":"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","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","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","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","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","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","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","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",
|
||||
"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": [],
|
||||
"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":"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":"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","fourstateComplementp":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(EB)","loc":"d,61:16,61:29","dtypep":"(U)",
|
||||
"rhsp": [
|
||||
{"type":"CONST","name":"1'h0","addr":"(FB)","loc":"d,61:16,61:29","dtypep":"(U)"}
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
],"timingControlp": []}
|
||||
],"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": []}
|
||||
]}
|
||||
],"filesp": [],
|
||||
|
|
|
|||
|
|
@ -77,20 +77,24 @@ for filename in files:
|
|||
with open(open_filename, 'r', encoding="utf8") as fh:
|
||||
spdx = None
|
||||
copyright_msg = None
|
||||
for line in fh:
|
||||
line = line.rstrip()
|
||||
if 'SP' + 'DX-License-Identifier:' in line:
|
||||
spdx = line
|
||||
elif re.search(r'(SP()DX-FileCopyrightText: 20[0-9][0-9])', line):
|
||||
copyright_msg = line
|
||||
if 'Wilson Snyder' in line:
|
||||
pass
|
||||
elif re.search(EXEMPT_AUTHOR_RE, filename):
|
||||
pass
|
||||
else:
|
||||
print(" " + copyright_msg)
|
||||
test.error_keep_going(filename + ": Please use standard 'SP" +
|
||||
"DX-FileCopyrightText: " + yeardash + " Wilson Snyder'")
|
||||
try:
|
||||
for line in fh:
|
||||
line = line.rstrip()
|
||||
if 'SP' + 'DX-License-Identifier:' in line:
|
||||
spdx = line
|
||||
elif re.search(r'(SP()DX-FileCopyrightText: 20[0-9][0-9])', line):
|
||||
copyright_msg = line
|
||||
if 'Wilson Snyder' in line:
|
||||
pass
|
||||
elif re.search(EXEMPT_AUTHOR_RE, filename):
|
||||
pass
|
||||
else:
|
||||
print(" " + copyright_msg)
|
||||
test.error_keep_going(filename + ": Please use standard 'SP" +
|
||||
"DX-FileCopyrightText: " + yeardash +
|
||||
" Wilson Snyder'")
|
||||
except UnicodeDecodeError as e:
|
||||
test.error_keep_going(filename + ": " + e.reason)
|
||||
|
||||
if not copyright_msg:
|
||||
test.error_keep_going(filename + ": Please add standard 'SP" +
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Binary file not shown.
|
|
@ -0,0 +1,22 @@
|
|||
#!/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_demo.v"
|
||||
|
||||
test.compile(verilator_flags2=['--binary', '--fourstate', '--trace-fst', '-Wno-FUTURE'])
|
||||
|
||||
test.execute(expect_filename='t/t_fourstate_demo.out')
|
||||
|
||||
test.trace_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -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); // <- Warning
|
||||
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,28 @@
|
|||
#!/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.extract(in_filename=test.top_filename,
|
||||
out_filename=test.root + "/docs/gen/ex_CASTFOURSTATE_faulty.rst",
|
||||
lines="13-14")
|
||||
|
||||
test.extract(in_filename=test.golden_filename,
|
||||
out_filename=test.root + "/docs/gen/ex_CASTFOURSTATE_msg.rst",
|
||||
lines="1-1")
|
||||
|
||||
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()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue