mirror of
https://github.com/verilator/verilator.git
synced 2026-08-29 09:20:11 +02:00
@@ -423,18 +423,26 @@ public:
|
||||
|
||||
void emitValueChange(uint64_t current_time_index, const uint32_t *val, EncodingType encoding) {
|
||||
auto wh = emitValueChangeCommonPart(current_time_index, encoding);
|
||||
for (unsigned i = 0; i < bitPerEncodedBit(encoding); ++i) {
|
||||
// C++17: replace this with if constexpr
|
||||
if (sizeof(T) == 8) {
|
||||
// C++17: replace this with if constexpr
|
||||
if (sizeof(T) == 8) {
|
||||
if (encoding == EncodingType::VERILOG) {
|
||||
uint64_t v = val[2]; // high bits
|
||||
v <<= 32;
|
||||
v |= val[0]; // low bits
|
||||
wh.template write<uint64_t>(v);
|
||||
v = val[3]; // high bits
|
||||
v <<= 32;
|
||||
v |= val[1]; // low bits
|
||||
wh.template write<uint64_t>(v);
|
||||
} else {
|
||||
uint64_t v = val[1]; // high bits
|
||||
v <<= 32;
|
||||
v |= val[0]; // low bits
|
||||
wh.template write<uint64_t>(v);
|
||||
val += 2;
|
||||
} else {
|
||||
wh.template write<T>(val[0]);
|
||||
val += 1;
|
||||
}
|
||||
} else {
|
||||
wh.template write<T>(val[0]);
|
||||
if (encoding == EncodingType::VERILOG) wh.template write<T>(val[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +525,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 +533,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 +564,29 @@ 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(
|
||||
kEncodedBitToCharTable[(((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 +597,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 +634,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 +649,12 @@ public:
|
||||
}
|
||||
|
||||
void emitValueChange(uint64_t current_time_index, const uint32_t *val, EncodingType encoding) {
|
||||
const unsigned nw32 = (info.bitwidth() + 31) / 32;
|
||||
const unsigned bpb = bitPerEncodedBit(encoding);
|
||||
const unsigned nw32 = num_words32();
|
||||
|
||||
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 +667,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::BINARY);
|
||||
wh.write(val, num_words());
|
||||
}
|
||||
|
||||
void dumpInitialBits(std::vector<uint8_t> &buf) const {
|
||||
@@ -663,15 +708,16 @@ public:
|
||||
break;
|
||||
}
|
||||
case EncodingType::VERILOG: {
|
||||
for (unsigned word_index = nw; word_index-- > 0;) {
|
||||
const uint64_t v0 = rh.peek<uint64_t>(nw * 0 + word_index);
|
||||
const uint64_t v1 = rh.peek<uint64_t>(nw * 1 + word_index);
|
||||
for (unsigned word_index = num_words32(); word_index-- > 0;) {
|
||||
const uint64_t val = rh.peek<uint64_t>(word_index);
|
||||
const uint32_t aval = static_cast<uint32_t>(val);
|
||||
const uint32_t bval = static_cast<uint32_t>(val >> 32);
|
||||
const unsigned num_bit =
|
||||
(word_index * 64 + 64 > info.bitwidth()) ? (info.bitwidth() % 64) : 64;
|
||||
(word_index * 32 + 32 > info.bitwidth()) ? (info.bitwidth() % 32) : 32;
|
||||
for (unsigned bit_index = num_bit; bit_index-- > 0;) {
|
||||
const bool b0 = ((v0 >> bit_index) & uint64_t(1));
|
||||
const bool b1 = ((v1 >> bit_index) & uint64_t(1));
|
||||
const char c = kEncodedBitToCharTable[(b1 << 1) | b0];
|
||||
const bool a = ((aval >> bit_index) & 1);
|
||||
const bool b = ((bval >> bit_index) & 1);
|
||||
const char c = kEncodedBitToCharTable[(b << 1) | a];
|
||||
buf.push_back(c);
|
||||
}
|
||||
}
|
||||
@@ -717,33 +763,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(kEncodedBitToCharTable[((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(kEncodedBitToCharTable[((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);
|
||||
|
||||
Reference in New Issue
Block a user