From 1f3423cd7d72d764217378200d7d1bd5ab721112 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 16 Mar 2022 14:35:39 +0100 Subject: [PATCH] Recognize registers and set initial state for them in tb --- kernel/fstdata.cc | 1 + kernel/fstdata.h | 1 + passes/sat/sim.cc | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index 587678ce3..82f8ff1df 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -113,6 +113,7 @@ void FstData::extractVarNames() FstVar var; var.id = h->u.var.handle; var.is_alias = h->u.var.is_alias; + var.is_reg = (fstVarType)h->u.var.typ == FST_VT_VCD_REG; var.name = remove_spaces(h->u.var.name); var.scope = scopes.back(); var.width = h->u.var.length; diff --git a/kernel/fstdata.h b/kernel/fstdata.h index 4a355fd77..0e9d27e2c 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -33,6 +33,7 @@ struct FstVar fstHandle id; std::string name; bool is_alias; + bool is_reg; std::string scope; int width; }; diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 5e15faec0..46fe1e23a 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -723,13 +723,25 @@ struct SimInstance child.second->register_signals(id); } - void write_output_header(std::function enter_scope, std::function exit_scope, std::function register_signal) + void write_output_header(std::function enter_scope, std::function exit_scope, std::function register_signal) { enter_scope(name()); + dict registers; + for (auto cell : module->cells()) + { + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + FfData ff_data(nullptr, cell); + SigSpec q = sigmap(ff_data.sig_q); + if (q.is_wire() && signal_database.count(q.as_wire()) != 0) { + registers[q.as_wire()] = true; + } + } + } + for (auto signal : signal_database) { - register_signal(signal.first, signal.second.first); + register_signal(signal.first, signal.second.first, registers.count(signal.first)!=0); } for (auto child : children) @@ -1476,6 +1488,7 @@ struct SimWorker : SimShared uint64_t prev_time = startCount; log("Writing data to `%s`\n", (tb_filename+".txt").c_str()); std::ofstream data_file(tb_filename+".txt"); + std::stringstream initstate; try { fst->reconstructAllAtTimes(fst_clock, startCount, stopCount, [&](uint64_t time) { for(auto &item : clocks) @@ -1486,6 +1499,18 @@ struct SimWorker : SimShared data_file << stringf("%s",fst->valueOf(item.second).c_str()); data_file << stringf("%s\n",Const(time-prev_time).as_string().c_str()); + if (time==startCount) { + // initial state + for(auto var : fst->getVars()) { + if (var.is_reg && !Const::from_string(fst->valueOf(var.id).c_str()).is_fully_undef()) { + if (var.scope == scope) { + initstate << stringf("\t\tuut.%s = %d'b%s;\n", var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); + } else if (var.scope.find(scope+".")==0) { + initstate << stringf("\t\tuut.%s.%s = %d'b%s;\n",var.scope.substr(scope.size()+1).c_str(), var.name.c_str(), var.width, fst->valueOf(var.id).c_str()); + } + } + } + } cycle++; prev_time = time; @@ -1503,6 +1528,7 @@ struct SimWorker : SimShared f << "\tinitial begin;\n"; f << stringf("\t\t$dumpfile(\"%s\");\n",tb_filename.c_str()); f << stringf("\t\t$dumpvars(0,%s);\n",tb_filename.c_str()); + f << initstate.str(); f << stringf("\t\t$readmemb(\"%s.txt\", data);\n",tb_filename.c_str()); f << stringf("\t\t#(data[0][%d:%d]);\n", data_len-32, data_len-1); @@ -1558,7 +1584,7 @@ struct VCDWriter : public OutputWriter worker->top->write_output_header( [this](IdString name) { vcdfile << stringf("$scope module %s $end\n", log_id(name)); }, [this]() { vcdfile << stringf("$upscope $end\n");}, - [this,use_signal](Wire *wire, int id) { if (use_signal.at(id)) vcdfile << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); } + [this,use_signal](Wire *wire, int id, bool is_reg) { if (use_signal.at(id)) vcdfile << stringf("$var %s %d n%d %s%s $end\n", is_reg ? "reg" : "wire", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); } ); vcdfile << stringf("$enddefinitions $end\n"); @@ -1616,9 +1642,9 @@ struct FSTWriter : public OutputWriter worker->top->write_output_header( [this](IdString name) { fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",log_id(name)).c_str(), nullptr); }, [this]() { fstWriterSetUpscope(fstfile); }, - [this,use_signal](Wire *wire, int id) { + [this,use_signal](Wire *wire, int id, bool is_reg) { if (!use_signal.at(id)) return; - fstHandle fst_id = fstWriterCreateVar(fstfile, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), + fstHandle fst_id = fstWriterCreateVar(fstfile, is_reg ? FST_VT_VCD_REG : FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); mapping.emplace(id, fst_id); @@ -1693,7 +1719,7 @@ struct AIWWriter : public OutputWriter worker->top->write_output_header( [](IdString) {}, []() {}, - [this](Wire *wire, int id) { mapping[wire] = id; } + [this](Wire *wire, int id, bool) { mapping[wire] = id; } ); std::map current; -- 2.30.2