Skip to content

Commit

Permalink
Created tests for functional C++ backend, comparing its VCD output to…
Browse files Browse the repository at this point in the history
… CXXRTL VCD output, using vcdiff from CERN
  • Loading branch information
RCoeurjoly committed May 25, 2024
1 parent b018502 commit 27975e3
Show file tree
Hide file tree
Showing 8 changed files with 546 additions and 368 deletions.
714 changes: 357 additions & 357 deletions backends/functional/cxx.cc

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions backends/functional/cxx_runtime/sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#define SIM_H

#include <array>
#include <cstdint>
#include <cassert>

template<size_t n>
using Signal = std::array<bool, n>;
Expand Down
27 changes: 26 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,36 @@
maintainers = with maintainers; [ ];
};
};
vcdiff = pkgs.stdenv.mkDerivation {
pname = "vcdiff";
version = "1.1";

src = pkgs.fetchFromGitHub {
owner = "orsonmmz";
repo = "vcdiff";
rev = "master";
hash = "sha256-jTuok3TjuGW7+ATc11R9osKDPxbhRtuEbM8tRE4+AAI=";
};

buildInputs = [ pkgs.gcc ];

installPhase = ''
mkdir -p $out/bin
cp vcdiff $out/bin/
'';

meta = with pkgs.lib; {
description = "The ultimate VCD files comparator";
license = licenses.gpl3;
maintainers = with maintainers; [ orsonmmz ];
};
};
in {
packages.default = yosys;
defaultPackage = yosys;
packages.vcdiff = vcdiff;
devShell = pkgs.mkShell {
buildInputs = with pkgs; [ clang bison flex libffi tcl readline python3 llvmPackages.libcxxClang zlib git gtest abc-verifier ];
buildInputs = with pkgs; [ clang bison flex libffi tcl readline python3 llvmPackages.libcxxClang zlib git gtest abc-verifier gtkwave vcdiff ];
};
}
);
Expand Down
5 changes: 5 additions & 0 deletions tests/functional/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
and_cxxrtl.cc
and_functional_cxx.cc
vcd_harness
cxxrtl.vcd
functional_cxx.vcd
10 changes: 0 additions & 10 deletions tests/functional/and.v

This file was deleted.

7 changes: 7 additions & 0 deletions tests/functional/run-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

set -ex

../../yosys -p "read_verilog verilog/and.v; write_cxxrtl and_cxxrtl.cc; write_functional_cxx and_functional_cxx.cc"
${CXX:-g++} -g -fprofile-arcs -ftest-coverage vcd_harness.cpp -I ../../backends/functional/cxx_runtime/ -I ../../backends/cxxrtl/runtime/ -o vcd_harness
./vcd_harness
140 changes: 140 additions & 0 deletions tests/functional/vcd_harness.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <cstdio>
#include <iostream>
#include <fstream>
#include <random>

#include <cxxrtl/cxxrtl_vcd.h>

#include "and_cxxrtl.cc"
#include "and_functional_cxx.cc"

struct DumpHeader {
std::ofstream &ofs;
DumpHeader(std::ofstream &ofs) : ofs(ofs) {}
template <size_t n>
void operator()(const char *name, Signal<n> value) {
ofs << "$var wire " << n << " " << name[0] << " " << name << " $end\n";
}
};

struct Dump {
std::ofstream &ofs;
Dump(std::ofstream &ofs) : ofs(ofs) {}
template <size_t n>
void operator()(const char *name, Signal<n> value) {
// Bit
if (n == 1) {
ofs << (value[0] ? '1' : '0');
ofs << name[0] << "\n";
return;
}
// vector (multi-bit) signals
ofs << "b";
for (size_t i = n; i-- > 0;)
ofs << (value[i] ? '1' : '0');
ofs << " " << name[0] << "\n";
}
};

int main(int argc, char **argv)
{
constexpr int steps = 10;
constexpr int number_timescale = 1;
const std::string units_timescale = "us";
Adder_Inputs inputs;
Adder_Outputs outputs;
Adder_State state;
Adder_State next_state;

std::ofstream vcd_file("functional_cxx.vcd");

vcd_file << "$timescale " << number_timescale << " " << units_timescale << " $end\n"; //$scope module logic $end\n";
{
DumpHeader d(vcd_file);
inputs.dump(d);
outputs.dump(d);
// vcd_file << "$scope module state $end\n";
state.dump(d);
}
vcd_file << "$enddefinitions $end\n$dumpvars\n";

cxxrtl_design::p_Adder top;

// debug_items maps the hierarchical names of signals and memories in the design
// to a cxxrtl_object (a value, a wire, or a memory)
cxxrtl::debug_items all_debug_items;
cxxrtl::debug_scope debug_scope;
// Load the debug items of the top down the whole design hierarchy
top.debug_info(&all_debug_items, nullptr, "");

// vcd_writer is the CXXRTL object that's responsible for creating a string with
// the VCD file contents.
cxxrtl::vcd_writer vcd;
vcd.timescale(number_timescale, units_timescale);

// Here we tell the vcd writer to dump all the signals of the design, except for the
// memories, to the VCD file.
//
// It's not necessary to load all debug objects to the VCD. There is, for example,
// a vcd.add(<debug items>, <filter>)) method which allows creating your custom filter to decide
// what to add and what not.
vcd.add_without_memories(all_debug_items);

std::ofstream waves("cxxrtl.vcd");

top.p_a.set<bool>(false);
top.p_b.set<bool>(false);
top.step();

// We need to manually tell the VCD writer when to sample and write out the traced items.
// This is only a slight inconvenience and allows for complete flexibility.
// E.g. you could only start waveform tracing when an internal signal has reached some specific
// value etc.
vcd.sample(0);
vcd_file << "#0\n";
inputs.a = $const<1>(false);
inputs.b = $const<1>(false);
{
Dump d(vcd_file);
inputs.dump(d);
outputs.dump(d);
state.dump(d);
}

// Initialize random number generator
std::random_device rd;
std::mt19937 gen(rd());
std::bernoulli_distribution dist(0.5); // 50% chance for true or false

for (int step = 0; step < steps; ++step) {
const bool a_value = dist(gen);
const bool b_value = dist(gen);

// cxxrtl
top.p_a.set<bool>(a_value);
top.p_b.set<bool>(b_value);
top.step();
vcd.sample(step + 1);

waves << vcd.buffer;
vcd.buffer.clear();

// Functional backend cxx
vcd_file << "#" << (step + 1) << "\n";
inputs.a = $const<1>(a_value);
inputs.b = $const<1>(b_value);
Adder(inputs, outputs, state, next_state);
{
Dump d(vcd_file);
inputs.dump(d);
outputs.dump(d);
state.dump(d);
}
state = next_state;
}

vcd_file.close();
waves.close();

return 0;
}
9 changes: 9 additions & 0 deletions tests/functional/verilog/and.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Adder(
input a,
input b,
output sum
);
// Perform addition
assign sum = a + b;

endmodule

0 comments on commit 27975e3

Please sign in to comment.