From ccfc00705a1658260e792e9604ae5319ec7b7c2a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 26 Jan 2022 09:26:19 +0100 Subject: [PATCH] Add ability to write to FST file --- passes/sat/sim.cc | 120 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 11 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 4e158da62..ba7519be5 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/mem.h" +#include "libs/fst/fstapi.h" #include @@ -92,6 +93,7 @@ struct SimInstance std::vector memories; dict> vcd_database; + dict> fst_database; SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : shared(shared), module(module), instance(instance), parent(parent), sigmap(module) @@ -616,12 +618,60 @@ struct SimInstance for (auto child : children) child.second->write_vcd_step(f); } + + void write_fst_header(struct fstContext *f) + { + fstWriterSetScope(f, FST_ST_VCD_MODULE, stringf("%s",log_id(name())).c_str(), nullptr); + for (auto wire : module->wires()) + { + if (shared->hide_internal && wire->name[0] == '$') + continue; + + fstHandle id = fstWriterCreateVar(f, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), + stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); + fst_database[wire] = make_pair(id, Const()); + } + + for (auto child : children) + child.second->write_fst_header(f); + + fstWriterSetUpscope(f); + } + + void write_fst_step(struct fstContext *f) + { + for (auto &it : fst_database) + { + Wire *wire = it.first; + Const value = get_state(wire); + fstHandle id = it.second.first; + + if (it.second.second == value) + continue; + + it.second.second = value; + std::stringstream ss; + for (int i = GetSize(value)-1; i >= 0; i--) { + switch (value[i]) { + case State::S0: ss << "0"; break; + case State::S1: ss << "1"; break; + case State::Sx: ss << "x"; break; + default: ss << "z"; + } + } + fstWriterEmitValueChange(f, id, ss.str().c_str()); + } + + for (auto child : children) + child.second->write_fst_step(f); + } }; struct SimWorker : SimShared { SimInstance *top = nullptr; std::ofstream vcdfile; + struct fstContext *fstfile = nullptr; pool clock, clockn, reset, resetn; std::string timescale; @@ -632,9 +682,6 @@ struct SimWorker : SimShared void write_vcd_header() { - if (!vcdfile.is_open()) - return; - vcdfile << stringf("$version %s $end\n", yosys_version_str); std::time_t t = std::time(nullptr); @@ -654,13 +701,53 @@ struct SimWorker : SimShared void write_vcd_step(int t) { - if (!vcdfile.is_open()) - return; - vcdfile << stringf("#%d\n", t); top->write_vcd_step(vcdfile); } + void write_fst_header() + { + std::time_t t = std::time(nullptr); + fstWriterSetDate(fstfile, asctime(std::localtime(&t))); + fstWriterSetVersion(fstfile, yosys_version_str); + if (!timescale.empty()) + fstWriterSetTimescaleFromString(fstfile, timescale.c_str()); + + fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); + fstWriterSetRepackOnClose(fstfile, 1); + + top->write_fst_header(fstfile); + } + + void write_fst_step(int t) + { + fstWriterEmitTimeChange(fstfile, t); + + top->write_fst_step(fstfile); + } + + void write_output_header() + { + if (vcdfile.is_open()) + write_vcd_header(); + if (fstfile) + write_fst_header(); + } + + void write_output_step(int t) + { + if (vcdfile.is_open()) + write_vcd_step(t); + if (fstfile) + write_fst_step(t); + } + + void write_output_end() + { + if (fstfile) + fstWriterClose(fstfile); + } + void update() { while (1) @@ -714,8 +801,8 @@ struct SimWorker : SimShared update(); - write_vcd_header(); - write_vcd_step(0); + write_output_header(); + write_output_step(0); for (int cycle = 0; cycle < numcycles; cycle++) { @@ -726,7 +813,7 @@ struct SimWorker : SimShared set_inports(clockn, State::S1); update(); - write_vcd_step(10*cycle + 5); + write_output_step(10*cycle + 5); if (debug) log("\n===== %d =====\n", 10*cycle + 10); @@ -742,10 +829,12 @@ struct SimWorker : SimShared } update(); - write_vcd_step(10*cycle + 10); + write_output_step(10*cycle + 10); } - write_vcd_step(10*numcycles + 2); + write_output_step(10*numcycles + 2); + + write_output_end(); if (writeback) { pool wbmods; @@ -767,6 +856,9 @@ struct SimPass : public Pass { log(" -vcd \n"); log(" write the simulation results to the given VCD file\n"); log("\n"); + log(" -fst \n"); + log(" write the simulation results to the given FST file\n"); + log("\n"); log(" -clock \n"); log(" name of top-level clock input\n"); log("\n"); @@ -816,6 +908,12 @@ struct SimPass : public Pass { worker.vcdfile.open(vcd_filename.c_str()); continue; } + if (args[argidx] == "-fst" && argidx+1 < args.size()) { + std::string fst_filename = args[++argidx]; + rewrite_filename(fst_filename); + worker.fstfile = (struct fstContext *)fstWriterCreate(fst_filename.c_str(),1); + continue; + } if (args[argidx] == "-n" && argidx+1 < args.size()) { numcycles = atoi(args[++argidx].c_str()); continue;