mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Read fst and use data to set inputs
This commit is contained in:
parent
8a02616465
commit
9a8939f0a4
|
@ -21,7 +21,7 @@
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/mem.h"
|
#include "kernel/mem.h"
|
||||||
#include "libs/fst/fstapi.h"
|
#include "kernel/fstdata.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ struct SimShared
|
||||||
bool writeback = false;
|
bool writeback = false;
|
||||||
bool zinit = false;
|
bool zinit = false;
|
||||||
int rstlen = 1;
|
int rstlen = 1;
|
||||||
|
FstData *fst = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void zinit(State &v)
|
void zinit(State &v)
|
||||||
|
@ -52,7 +53,8 @@ void zinit(Const &v)
|
||||||
struct SimInstance
|
struct SimInstance
|
||||||
{
|
{
|
||||||
SimShared *shared;
|
SimShared *shared;
|
||||||
|
|
||||||
|
std::string scope;
|
||||||
Module *module;
|
Module *module;
|
||||||
Cell *instance;
|
Cell *instance;
|
||||||
|
|
||||||
|
@ -95,8 +97,8 @@ struct SimInstance
|
||||||
dict<Wire*, pair<int, Const>> vcd_database;
|
dict<Wire*, pair<int, Const>> vcd_database;
|
||||||
dict<Wire*, pair<fstHandle, Const>> fst_database;
|
dict<Wire*, pair<fstHandle, Const>> fst_database;
|
||||||
|
|
||||||
SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) :
|
SimInstance(SimShared *shared, std::string scope, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) :
|
||||||
shared(shared), module(module), instance(instance), parent(parent), sigmap(module)
|
shared(shared), scope(scope), module(module), instance(instance), parent(parent), sigmap(module)
|
||||||
{
|
{
|
||||||
log_assert(module);
|
log_assert(module);
|
||||||
|
|
||||||
|
@ -146,7 +148,7 @@ struct SimInstance
|
||||||
Module *mod = module->design->module(cell->type);
|
Module *mod = module->design->module(cell->type);
|
||||||
|
|
||||||
if (mod != nullptr) {
|
if (mod != nullptr) {
|
||||||
dirty_children.insert(new SimInstance(shared, mod, cell, this));
|
dirty_children.insert(new SimInstance(shared, scope + "." + RTLIL::unescape_id(module->name), mod, cell, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &port : cell->connections()) {
|
for (auto &port : cell->connections()) {
|
||||||
|
@ -674,6 +676,8 @@ struct SimWorker : SimShared
|
||||||
struct fstContext *fstfile = nullptr;
|
struct fstContext *fstfile = nullptr;
|
||||||
pool<IdString> clock, clockn, reset, resetn;
|
pool<IdString> clock, clockn, reset, resetn;
|
||||||
std::string timescale;
|
std::string timescale;
|
||||||
|
std::string sim_filename;
|
||||||
|
std::string scope;
|
||||||
|
|
||||||
~SimWorker()
|
~SimWorker()
|
||||||
{
|
{
|
||||||
|
@ -708,10 +712,10 @@ struct SimWorker : SimShared
|
||||||
void write_fst_header()
|
void write_fst_header()
|
||||||
{
|
{
|
||||||
std::time_t t = std::time(nullptr);
|
std::time_t t = std::time(nullptr);
|
||||||
fstWriterSetDate(fstfile, asctime(std::localtime(&t)));
|
fstWriterSetDate(fstfile, asctime(std::localtime(&t)));
|
||||||
fstWriterSetVersion(fstfile, yosys_version_str);
|
fstWriterSetVersion(fstfile, yosys_version_str);
|
||||||
if (!timescale.empty())
|
if (!timescale.empty())
|
||||||
fstWriterSetTimescaleFromString(fstfile, timescale.c_str());
|
fstWriterSetTimescaleFromString(fstfile, timescale.c_str());
|
||||||
|
|
||||||
fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ);
|
fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ);
|
||||||
fstWriterSetRepackOnClose(fstfile, 1);
|
fstWriterSetRepackOnClose(fstfile, 1);
|
||||||
|
@ -786,7 +790,7 @@ struct SimWorker : SimShared
|
||||||
void run(Module *topmod, int numcycles)
|
void run(Module *topmod, int numcycles)
|
||||||
{
|
{
|
||||||
log_assert(top == nullptr);
|
log_assert(top == nullptr);
|
||||||
top = new SimInstance(this, topmod);
|
top = new SimInstance(this, scope, topmod);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
log("\n===== 0 =====\n");
|
log("\n===== 0 =====\n");
|
||||||
|
@ -841,6 +845,65 @@ struct SimWorker : SimShared
|
||||||
top->writeback(wbmods);
|
top->writeback(wbmods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_cosim(Module *topmod, int numcycles)
|
||||||
|
{
|
||||||
|
log_assert(top == nullptr);
|
||||||
|
top = new SimInstance(this, scope, topmod);
|
||||||
|
|
||||||
|
fst = new FstData(sim_filename);
|
||||||
|
|
||||||
|
std::vector<fstHandle> fst_clock;
|
||||||
|
|
||||||
|
for (auto portname : clock)
|
||||||
|
{
|
||||||
|
Wire *w = topmod->wire(portname);
|
||||||
|
if (!w)
|
||||||
|
log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module));
|
||||||
|
if (!w->port_input)
|
||||||
|
log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module));
|
||||||
|
fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname));
|
||||||
|
if (id==0)
|
||||||
|
log_error("Can't find port %s.%s in FST.\n", scope.c_str(), log_id(portname));
|
||||||
|
fst_clock.push_back(id);
|
||||||
|
}
|
||||||
|
for (auto portname : clockn)
|
||||||
|
{
|
||||||
|
Wire *w = topmod->wire(portname);
|
||||||
|
if (!w)
|
||||||
|
log_error("Can't find port %s on module %s.\n", log_id(portname), log_id(top->module));
|
||||||
|
if (!w->port_input)
|
||||||
|
log_error("Clock port %s on module %s is not input.\n", log_id(portname), log_id(top->module));
|
||||||
|
fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(portname));
|
||||||
|
if (id==0)
|
||||||
|
log_error("Can't find port %s.%s in FST.\n", scope.c_str(), log_id(portname));
|
||||||
|
fst_clock.push_back(id);
|
||||||
|
}
|
||||||
|
if (fst_clock.size()==0)
|
||||||
|
log_error("No clock signals defined for input file\n");
|
||||||
|
|
||||||
|
SigMap sigmap(topmod);
|
||||||
|
log ("Get inputs\n");
|
||||||
|
std::map<Wire*,fstHandle> inputs;
|
||||||
|
|
||||||
|
for (auto wire : topmod->wires()) {
|
||||||
|
if (wire->port_input) {
|
||||||
|
fstHandle id = fst->getHandle(scope + "." + RTLIL::unescape_id(wire->name));
|
||||||
|
log("Input %s\n",log_id(wire));
|
||||||
|
inputs[wire] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fst->reconstruct(fst_clock);
|
||||||
|
auto edges = fst->edges(fst_clock.back(), true, true);
|
||||||
|
fst->reconstructAllAtTimes(edges);
|
||||||
|
for(auto &time : edges) {
|
||||||
|
for(auto &item : inputs) {
|
||||||
|
std::string v = fst->valueAt(item.second, time);
|
||||||
|
top->set_state(item.first, Const::from_string(v));
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SimPass : public Pass {
|
struct SimPass : public Pass {
|
||||||
|
@ -889,6 +952,12 @@ struct SimPass : public Pass {
|
||||||
log(" -w\n");
|
log(" -w\n");
|
||||||
log(" writeback mode: use final simulation state as new init state\n");
|
log(" writeback mode: use final simulation state as new init state\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -r\n");
|
||||||
|
log(" read simulation results file (file formats supported: FST)\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -scope\n");
|
||||||
|
log(" scope of simulation top model\n");
|
||||||
|
log("\n");
|
||||||
log(" -d\n");
|
log(" -d\n");
|
||||||
log(" enable debug output\n");
|
log(" enable debug output\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
@ -958,6 +1027,16 @@ struct SimPass : public Pass {
|
||||||
worker.zinit = true;
|
worker.zinit = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-r" && argidx+1 < args.size()) {
|
||||||
|
std::string sim_filename = args[++argidx];
|
||||||
|
rewrite_filename(sim_filename);
|
||||||
|
worker.sim_filename = sim_filename;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-scope" && argidx+1 < args.size()) {
|
||||||
|
worker.scope = args[++argidx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -976,7 +1055,10 @@ struct SimPass : public Pass {
|
||||||
top_mod = mods.front();
|
top_mod = mods.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.run(top_mod, numcycles);
|
if (worker.sim_filename.empty())
|
||||||
|
worker.run(top_mod, numcycles);
|
||||||
|
else
|
||||||
|
worker.run_cosim(top_mod, numcycles);
|
||||||
}
|
}
|
||||||
} SimPass;
|
} SimPass;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue