Skip to content

Commit

Permalink
[VCD] Do not emit the leading zeroes when writing a value change.
Browse files Browse the repository at this point in the history
This helps to reduce the VCD files sizes.
  • Loading branch information
Arnaud-de-Grandmaison-ARM committed Apr 25, 2024
1 parent 1918805 commit 736d872
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
14 changes: 9 additions & 5 deletions include/PAF/WAN/VCDWaveFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,29 @@
namespace PAF {
namespace WAN {

// The VCDWaveFile class is an abstraction of the VCD file format.
/// The VCDWaveFile class is an abstraction of the VCD file format.
class VCDWaveFile : public WaveFile {
public:
VCDWaveFile() = delete;
VCDWaveFile(const VCDWaveFile &) = delete;
VCDWaveFile(const std::string &filename)
: WaveFile(filename, WaveFile::FileFormat::VCD) {}

// Convenience method to read from a single input file.
/// Convenience method to read from a single input file.
Waveform read();

// Construct a Waveform from file FileName.
/// Construct a Waveform from file FileName.
bool read(Waveform &W) override;

// Save Waveform W to file 'FileName'.
/// Save Waveform W to file 'FileName'.
bool write(const Waveform &W) override;

// Quickly read the file to collect all times with changes.
/// Quickly read the file to collect all times with changes.
std::vector<WAN::TimeTy> getAllChangesTimes() override;

/// Format the ValueChange string \p s for emitting in a VCD file by
/// stripping leading zeroes and lowercasing the string.
static std::string formatValueChange(const std::string &s);
};

} // namespace WAN
Expand Down
27 changes: 19 additions & 8 deletions lib/WAN/VCDWaveFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,14 +782,21 @@ struct VCDHierDumper : public Waveform::Visitor {
o << " $end\n";
}
};
} // namespace

string VCDWaveFile::formatValueChange(const string &s) {
// Count leading zeroes
size_t leadingZeroes = 0;
while (s.size() - leadingZeroes > 1 && s[leadingZeroes] == '0')
leadingZeroes += 1;

string to_lower(const string &s) {
string r(s);
std::transform(r.begin(), r.end(), r.begin(),
string r;
r.resize(s.size() - leadingZeroes);

std::transform(s.begin() + leadingZeroes, s.end(), r.begin(),
[](unsigned char c) { return std::tolower(c); });
return r;
}
} // namespace

bool VCDWaveFile::write(const Waveform &W) {
std::ofstream F(fileName.c_str());
Expand Down Expand Up @@ -826,9 +833,10 @@ bool VCDWaveFile::write(const Waveform &W) {
DIE("VCD signal id not found");
size_t ChangeIdx = ChangeIndexes[Idx];
if (W[Idx].getNumBits() == 1)
F << to_lower(W[Idx].getChange(ChangeIdx).value);
F << formatValueChange(W[Idx].getChange(ChangeIdx).value);
else
F << 'b' << to_lower(W[Idx].getChange(ChangeIdx).value)
F << 'b'
<< formatValueChange(W[Idx].getChange(ChangeIdx).value)
<< ' ';
F << r->second << '\n';
ChangeIndexes[Idx] += 1;
Expand All @@ -845,9 +853,12 @@ bool VCDWaveFile::write(const Waveform &W) {
if (r == VHD.sigMap.end())
DIE("VCD signal id not found");
if (W[Idx].getNumBits() == 1) {
F << to_lower(W[Idx].getChange(ChangeIdx).value);
F << formatValueChange(
W[Idx].getChange(ChangeIdx).value);
} else {
F << 'b' << to_lower(W[Idx].getChange(ChangeIdx).value)
F << 'b'
<< formatValueChange(
W[Idx].getChange(ChangeIdx).value)
<< ' ';
}
F << r->second << '\n';
Expand Down
43 changes: 41 additions & 2 deletions unit-tests/VCDWaveFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,36 @@ using namespace testing;

static const string VCDInput(SAMPLES_SRC_DIR "Counters.vcd");

TEST(VCDWaveFile, formatValueChange) {
EXPECT_EQ(VCDWaveFile::formatValueChange("0"), "0");
EXPECT_EQ(VCDWaveFile::formatValueChange("1"), "1");
EXPECT_EQ(VCDWaveFile::formatValueChange("A"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("a"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("F"), "f");
EXPECT_EQ(VCDWaveFile::formatValueChange("f"), "f");

EXPECT_EQ(VCDWaveFile::formatValueChange("00"), "0");
EXPECT_EQ(VCDWaveFile::formatValueChange("01"), "1");
EXPECT_EQ(VCDWaveFile::formatValueChange("0A"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("0a"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("0F"), "f");
EXPECT_EQ(VCDWaveFile::formatValueChange("0f"), "f");

EXPECT_EQ(VCDWaveFile::formatValueChange("000"), "0");
EXPECT_EQ(VCDWaveFile::formatValueChange("001"), "1");
EXPECT_EQ(VCDWaveFile::formatValueChange("00A"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("00a"), "a");
EXPECT_EQ(VCDWaveFile::formatValueChange("00F"), "f");
EXPECT_EQ(VCDWaveFile::formatValueChange("00f"), "f");

EXPECT_EQ(VCDWaveFile::formatValueChange("00100"), "100");
EXPECT_EQ(VCDWaveFile::formatValueChange("00201"), "201");
EXPECT_EQ(VCDWaveFile::formatValueChange("00a0A"), "a0a");
EXPECT_EQ(VCDWaveFile::formatValueChange("00e0a"), "e0a");
EXPECT_EQ(VCDWaveFile::formatValueChange("00F0F"), "f0f");
EXPECT_EQ(VCDWaveFile::formatValueChange("00c0f"), "c0f");
}

TEST(VCDWaveFile, Read) {
VCDWaveFile F(VCDInput);
EXPECT_EQ(F.getFileFormat(), WaveFile::FileFormat::VCD);
Expand Down Expand Up @@ -78,7 +108,10 @@ TEST_F(VCDWaveFileF, Write) {
W.getRootScope()->addModule("instance", "test", "test");
SignalIdxTy SIdx = W.addWire(S, "a_signal", 4);
W.addValueChange(SIdx, 0, "0000");
W.addValueChange(SIdx, 5, string("0010"));
W.addValueChange(SIdx, 10, string("1010"));
W.addValueChange(SIdx, 15, string("100"));
W.addValueChange(SIdx, 20, string("1"));
F.write(W);

EXPECT_TRUE(checkFileContent({
Expand All @@ -101,10 +134,16 @@ TEST_F(VCDWaveFileF, Write) {
"$enddefinitions $end",
"#0",
"$dumpvars",
"b0000 !",
"b0 !",
"$end",
"#5",
"b10 !",
"#10",
"b1010 !"
"b1010 !",
"#15",
"b100 !",
"#20",
"b1 !"
// clang-format off
}));
}

0 comments on commit 736d872

Please sign in to comment.