Skip to content

Commit

Permalink
Waveform demo for riscv-mini , rocket16 and VCD header comparison (mo…
Browse files Browse the repository at this point in the history
…dule and signal) (#9)

* Test to compare modules and signals between two vcds

* waveform demo for riscv-mini and rocket16

* waveform comp test for header

* update

* updating to soft link

* updated as suggested

* Delete waveform-test directory

* Delete libfesvr.so

* FST version of essent

* review updates

* review updates

---------

Co-authored-by: Priyanka Dutta <[email protected]>
  • Loading branch information
MSPDUTTA and Priyanka Dutta authored Apr 26, 2023
1 parent 8a6793a commit 3805209
Show file tree
Hide file tree
Showing 12 changed files with 453 additions and 1 deletion.
37 changes: 37 additions & 0 deletions waveform-demo/riscv-mini/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Run Rocket Chip to get .fir (FIRRTL) file of design
generated_dir = $(abspath riscv-mini/generated-src)
fir_filename = Tile.fir
fir_path = $(abspath $(fir_filename))

Tile.h: $(fir_filename)
cd ../../essent; sbt 'run -O3 $(fir_path)'

withVCD: $(fir_filename)
cd ../../essent; sbt 'run -O3 -withVCD $(fir_path)'

withFST: $(fir_filename)
cd ../../essent; sbt 'run -O3 -withFST $(fir_path)'

CXXFLAGS = -O3 -std=c++11
INCLUDES = -I../../firrtl-sig

top: top.cc mm.cc mm.h Tile.h
$(CXX) $(CXXFLAGS) $(INCLUDES) top.cc mm.cc -o top

top_withVCD: top.cc mm.cc mm.h withVCD
$(CXX) $(CXXFLAGS) $(INCLUDES) top.cc mm.cc -o top_vcd

top_withFST: top.cc mm.cc mm.h withFST
$(CXX) $(CXXFLAGS) $(INCLUDES) top.cc mm.cc -o top_fst

.PHONY: clean
clean:
rm -rf $(fir_filename) Tile.h top VTile test-*

VTile: riscv-mini/README.md
cd riscv-mini; make verilator
cp riscv-mini/VTile .

.PHONY: test
test: top VTile
./test.sh
1 change: 1 addition & 0 deletions waveform-demo/riscv-mini/mm.cc
1 change: 1 addition & 0 deletions waveform-demo/riscv-mini/mm.h
1 change: 1 addition & 0 deletions waveform-demo/riscv-mini/riscv-mini
109 changes: 109 additions & 0 deletions waveform-demo/riscv-mini/top.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include <cstdint>
#include <iostream>

#include "mm.h"
#include "uint.h"
#include "Tile.h"

// Adapted from riscv-mini/src/main/cc/top.cc

using namespace std;

static uint64_t trace_count = 0;
static uint64_t main_time = 0;
Tile *top;
mm_magic_t* mem;


void tick(bool verbose, bool done_reset) {
main_time++;

top->io_nasti_aw_ready = UInt<1>(mem->aw_ready());
top->io_nasti_ar_ready = UInt<1>(mem->ar_ready());
top->io_nasti_w_ready = UInt<1>(mem->w_ready());
top->io_nasti_b_valid = UInt<1>(mem->b_valid());
top->io_nasti_b_bits_id = UInt<5>(mem->b_id());
top->io_nasti_b_bits_resp = UInt<2>(mem->b_resp());
top->io_nasti_r_valid = UInt<1>(mem->r_valid());
top->io_nasti_r_bits_id = UInt<5>(mem->r_id());
top->io_nasti_r_bits_resp = UInt<2>(mem->r_resp());
top->io_nasti_r_bits_last = UInt<1>(mem->r_last());
memcpy(&top->io_nasti_r_bits_data, mem->r_data(), 8);

top->eval(true, verbose, done_reset);
mem->tick(
top->reset,
top->io_nasti_ar_valid,
top->io_nasti_ar_bits_addr.as_single_word(),
top->io_nasti_ar_bits_id.as_single_word(),
top->io_nasti_ar_bits_size.as_single_word(),
top->io_nasti_ar_bits_len.as_single_word(),
top->io_nasti_aw_valid,
top->io_nasti_aw_bits_addr.as_single_word(),
top->io_nasti_aw_bits_id.as_single_word(),
top->io_nasti_aw_bits_size.as_single_word(),
top->io_nasti_aw_bits_len.as_single_word(),
top->io_nasti_w_valid,
top->io_nasti_w_bits_strb.as_single_word(),
&top->io_nasti_w_bits_data,
top->io_nasti_w_bits_last,
top->io_nasti_r_ready,
top->io_nasti_b_ready
);
main_time++;
}


int main(int argc, char** argv) {
uint64_t timeout = 10000000L;
top = new Tile;
mem = new mm_magic_t(1L << 32, 8);
//cout << "Enabling waves..." << endl;
load_mem(mem->get_data(), (const char*)(argv[1]));

// reset
top->reset = UInt<1>(1);
top->io_host_fromhost_bits = UInt<32>(0);
top->io_host_fromhost_valid = UInt<1>(0);
top->genWaveHeader();
// cout << "Starting simulation!" << endl;
for (size_t i = 0; i < 5 ; i++) {
tick(true, false);
}
top->reset = UInt<1>(0);

// actual sim
top->io_host_fromhost_bits = UInt<32>(0);
top->io_host_fromhost_valid = UInt<1>(0);
do {
tick(true,true);
} while(!top->io_host_tohost.as_single_word() && main_time < timeout);

int retcode = top->io_host_tohost.as_single_word() >> 1;

// run 10 cycles past termination
// FUTURE: small off-by-1 hack in detecting termination
for (size_t i = 0 ; i < 9 ; i++) {
tick(true, true);
}

// note: don't know why riscv-mini /10 (instead of /2), but same for testing
if (main_time >= timeout) {
cerr << "Simulation terminated by timeout at time " << main_time
<< " (cycle " << main_time / 10 << ")"<< endl;
return -1;
} else {
cerr << "Simulation completed at time " << main_time
<< " (cycle " << main_time / 10 << ")"<< endl;
if (retcode) {
cerr << "TOHOST = " << retcode << endl;
}
}

delete top;
delete mem;

//cout << "Finishing simulation!\n";

return 0;
}
39 changes: 39 additions & 0 deletions waveform-demo/rocket16/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FIR_PATH = $(shell pwd)/TestHarness.DefaultConfig.1609.fir

CXXFLAGS = -O3 -std=c++11
CLANG_FLAGS = -fno-slp-vectorize -fbracket-depth=1024

UNAME_OS := $(shell uname -s)
ifeq ($(UNAME_OS),Darwin)
CXXFLAGS += $(CLANG_FLAGS)
endif

ifeq ($(ALL_ON),1)
CXXFLAGS += -DALL_ON
endif

INCLUDES = -Iriscv/include -I../../firrtl-sig

LIBS = -Lriscv/lib -Wl,-rpath,riscv/lib -lfesvr -lpthread

riscv_dir := $(shell pwd)/riscv

riscv/lib/libfesvr.so:
git submodule update --init riscv-fesvr
cd riscv-fesvr; git checkout `cat ../fesvr.commit`
patch riscv-fesvr/fesvr/dtm.cc ../riscv-fesvr.patch
mkdir $(riscv_dir)
cd riscv-fesvr; mkdir build; cd build; ../configure --prefix=$(riscv_dir) --target=riscv64-unknown-elf; make install

withVCD_TestHarness.h:
cd ../../essent; sbt 'run -O3 -withVCD $(FIR_PATH)'

withFST_TestHarness.h:
cd ../../essent; sbt 'run -O3 -withFST $(FIR_PATH)'

withVCD_emulator: emulator.cc withVCD_TestHarness.h riscv/lib/libfesvr.so
$(CXX) $(CXXFLAGS) $(INCLUDES) emulator.cc -o emulator_vcd $(LIBS)

withFST_emulator: emulator.cc withFST_TestHarness.h riscv/lib/libfesvr.so
$(CXX) $(CXXFLAGS) $(INCLUDES) emulator.cc -o emulator_fst $(LIBS)

1 change: 1 addition & 0 deletions waveform-demo/rocket16/TestHarness.DefaultConfig.1609.fir
116 changes: 116 additions & 0 deletions waveform-demo/rocket16/emulator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include <fesvr/dtm.h>
#include <iostream>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "TestHarness.h"

dtm_t* dtm;
static uint64_t trace_count = 0;

void handle_sigterm(int sig) {
dtm->stop();
}

void tick_dtm(TestHarness *tile, bool done_reset) {
// PRINT_SIG(tile->SimDTM_1.debug_req_ready);
// PRINT_SIG(tile->SimDTM_1.debug_resp_valid);
// PRINT_SIG(tile->SimDTM_1.debug_resp_bits_resp);
// PRINT_SIG(tile->SimDTM_1.debug_resp_bits_data);
if (done_reset) {
dtm_t::resp resp_bits;
resp_bits.resp = tile->SimDTM_1.debug_resp_bits_resp.as_single_word();
resp_bits.data = tile->SimDTM_1.debug_resp_bits_data.as_single_word();

dtm->tick(tile->SimDTM_1.debug_req_ready.as_single_word(),
tile->SimDTM_1.debug_resp_valid.as_single_word(),
resp_bits);

tile->SimDTM_1.debug_resp_ready = UInt<1>(dtm->resp_ready());
tile->SimDTM_1.debug_req_valid = UInt<1>(dtm->req_valid());
tile->SimDTM_1.debug_req_bits_addr = UInt<5>(dtm->req_bits().addr);
tile->SimDTM_1.debug_req_bits_op = UInt<2>(dtm->req_bits().op);
tile->SimDTM_1.debug_req_bits_data = UInt<34>(dtm->req_bits().data);

tile->SimDTM_1.exit = UInt<32>(dtm->done() ? (dtm->exit_code() << 1 | 1) : 0);
} else {
tile->SimDTM_1.debug_req_valid = UInt<1>(0);
tile->SimDTM_1.debug_resp_ready = UInt<1>(0);
tile->SimDTM_1.exit = UInt<32>(0);
}
// PRINT_SIG(tile->SimDTM_1.debug_req_valid);
// PRINT_SIG(tile->SimDTM_1.debug_req_bits_addr);
// PRINT_SIG(tile->SimDTM_1.debug_req_bits_op);
// PRINT_SIG(tile->SimDTM_1.debug_req_bits_data);
// PRINT_SIG(tile->SimDTM_1.debug_resp_ready);
}

int main(int argc, char** argv) {
unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid();
uint64_t max_cycles = -1;
uint64_t start = 0;
int ret = 0;
bool print_cycles = false;
bool verbose = false;
bool done_reset = false;

for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg.substr(0, 2) == "-s")
random_seed = atoi(argv[i]+2);
else if (arg == "+verbose")
verbose = true;
else if (arg.substr(0, 12) == "+max-cycles=")
max_cycles = atoll(argv[i]+12);
else if (arg.substr(0, 7) == "+start=")
start = atoll(argv[i]+7);
else if (arg.substr(0, 12) == "+cycle-count")
print_cycles = true;
}

srand(random_seed);
srand48(random_seed);

TestHarness *tile = new TestHarness;

dtm = new dtm_t(std::vector<std::string>(argv + 1, argv + argc));

signal(SIGTERM, handle_sigterm);
tile->genWaveHeader();
tile->reset = UInt<1>(1);
tick_dtm(tile, done_reset);
tile->eval(false, verbose, done_reset);
// reset for several cycles to handle pipelined reset
for (int i = 0; i < 10; i++) {
tile->eval(true, verbose, done_reset);
tick_dtm(tile, done_reset);
}
tile->reset = UInt<1>(0);
tile->eval(false, verbose, done_reset);
tick_dtm(tile, done_reset);
done_reset = true;

while (!dtm->done() && !tile->io_success && trace_count < max_cycles) {
tile->eval(true, verbose, done_reset);
tick_dtm(tile, done_reset);
trace_count++;
}

if (dtm->exit_code()) {
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %" PRIu64 " cycles\n", dtm->exit_code(), random_seed, trace_count);
ret = dtm->exit_code();
} else if (trace_count == max_cycles) {
fprintf(stderr, "*** FAILED *** (timeout, seed %d) after %" PRIu64 " cycles\n", random_seed, trace_count);
ret = 2;
} else if (verbose || print_cycles) {
fprintf(stderr, "Completed after %" PRIu64 " cycles\n", trace_count);
}

delete tile;
delete dtm;

return ret;
}
1 change: 1 addition & 0 deletions waveform-demo/rocket16/riscv
1 change: 1 addition & 0 deletions waveform-demo/rocket16/riscv-fesvr
Loading

0 comments on commit 3805209

Please sign in to comment.