From 1fd3a642c94b642624f05efecff282c195f984d1 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 28 Feb 2022 10:41:44 +0100 Subject: Hotfix in AIGER witness reader state machine Signed-off-by: Claire Xenia Wolf --- passes/sat/sim.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 1cd0a0338..57d6182c0 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1225,6 +1225,7 @@ struct SimWorker : SimShared case 2: write_output_header(); top->setState(latches, line); + state = 3; break; default: if (cycle) { -- cgit v1.2.3 From 56b968f61c01600fde97f1b9b8e857b0f6ecd16d Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Mon, 28 Feb 2022 10:50:08 +0100 Subject: Add writing of aiw files to "sim" command Signed-off-by: Claire Xenia Wolf --- passes/sat/sim.cc | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 57d6182c0..304dfef13 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -857,9 +857,11 @@ struct SimInstance struct SimWorker : SimShared { SimInstance *top = nullptr; - std::ofstream vcdfile; + std::ofstream vcdfile, aiwfile; struct fstContext *fstfile = nullptr; pool clock, clockn, reset, resetn; + dict> aiw_latches; + dict aiw_inputs, aiw_inits; std::string timescale; std::string sim_filename; std::string map_filename; @@ -916,12 +918,82 @@ struct SimWorker : SimShared top->write_fst_step(fstfile); } + void write_aiw_header() + { + std::ifstream mf(map_filename); + std::string type, symbol; + int variable, index; + while (mf >> type >> variable >> index >> symbol) { + RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); + Wire *w = top->module->wire(escaped_s); + if (!w) + log_error("Wire %s not present in module %s\n",log_signal(w),log_id(top->module)); + if (index < w->start_offset || index > w->start_offset + w->width) + log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); + if (type == "input") { + aiw_inputs[variable] = SigBit(w,index); + } else if (type == "init") { + aiw_inits[variable] = SigBit(w,index); + } else if (type == "latch") { + aiw_latches[variable] = {SigBit(w,index), false}; + } else if (type == "invlatch") { + aiw_latches[variable] = {SigBit(w,index), true}; + } + } + + for (int i = 0;; i++) + { + if (aiw_latches.count(i)) { + auto v = top->get_state(aiw_latches.at(i).first); + if (v == State::S1) + aiwfile << (aiw_latches.at(i).second ? '0' : '1'); + else + aiwfile << (aiw_latches.at(i).second ? '1' : '0'); + continue; + } + aiwfile << '\n'; + break; + } + } + + void write_aiw_step() + { + for (int i = 0;; i++) + { + if (aiw_inputs.count(i)) { + auto v = top->get_state(aiw_inputs.at(i)); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + if (aiw_inits.count(i)) { + auto v = top->get_state(aiw_inits.at(i)); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + aiwfile << '\n'; + break; + } + } + + void write_aiw_end() + { + aiwfile << '.' << '\n'; + } + void write_output_header() { if (vcdfile.is_open()) write_vcd_header(); if (fstfile) write_fst_header(); + if (aiwfile.is_open()) + write_aiw_header(); } void write_output_step(int t) @@ -930,12 +1002,16 @@ struct SimWorker : SimShared write_vcd_step(t); if (fstfile) write_fst_step(t); + if (aiwfile.is_open()) + write_aiw_step(); } void write_output_end() { if (fstfile) fstWriterClose(fstfile); + if (aiwfile.is_open()) + write_aiw_end(); } void update() @@ -1269,6 +1345,10 @@ struct SimPass : public Pass { log(" -fst \n"); log(" write the simulation results to the given FST file\n"); log("\n"); + log(" -aiw \n"); + log(" write the simulation results to an AIGER witness file\n"); + log(" (requires a *.aim file via -map)\n"); + log("\n"); log(" -clock \n"); log(" name of top-level clock input\n"); log("\n"); @@ -1355,6 +1435,12 @@ struct SimPass : public Pass { worker.fstfile = (struct fstContext *)fstWriterCreate(fst_filename.c_str(),1); continue; } + if (args[argidx] == "-aiw" && argidx+1 < args.size()) { + std::string aiw_filename = args[++argidx]; + rewrite_filename(aiw_filename); + worker.aiwfile.open(aiw_filename.c_str()); + continue; + } if (args[argidx] == "-n" && argidx+1 < args.size()) { numcycles = atoi(args[++argidx].c_str()); worker.cycles_set = true; -- cgit v1.2.3 From dfd4c81eac47bd06fc4f419c43e6fe508b4252df Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 28 Feb 2022 11:40:06 +0100 Subject: Quick fix --- passes/sat/sim.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 304dfef13..1ce563ac2 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1304,6 +1304,8 @@ struct SimWorker : SimShared state = 3; break; default: + log("Simulating cycle %d.\n", cycle); + top->setState(inputs, line); if (cycle) { set_inports(clock, State::S1); set_inports(clockn, State::S0); -- cgit v1.2.3 From 94505395a92c6522b060fb982c8c3a81ff58c12d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 28 Feb 2022 18:22:39 +0100 Subject: Refactor sim output writers --- passes/sat/sim.cc | 470 +++++++++++++++++++++++++++++------------------------- 1 file changed, 257 insertions(+), 213 deletions(-) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 1ce563ac2..988da0eb0 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -65,6 +65,20 @@ static double stringToTime(std::string str) return value * pow(10.0, g_units.at(endptr)); } +struct SimWorker; +struct OutputWriter +{ + OutputWriter(SimWorker *w) { worker = w;}; + virtual ~OutputWriter() {}; + virtual void write_header() = 0; + virtual void write_step_header(int t) = 0; + virtual void enter_scope(IdString name) = 0; + virtual void exit_scope() = 0; + virtual void register_signal(Wire *wire, int id) = 0; + virtual void write_value(int id, Const& value) = 0; + SimWorker *worker; +}; + struct SimShared { bool debug = false; @@ -77,6 +91,7 @@ struct SimShared double stop_time = -1; SimulationMode sim_mode = SimulationMode::sim; bool cycles_set = false; + std::vector> outputfiles; }; void zinit(State &v) @@ -140,8 +155,7 @@ struct SimInstance std::vector memories; - dict> vcd_database; - dict> fst_database; + dict> signal_database; dict fst_handles; SimInstance(SimShared *shared, std::string scope, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : @@ -685,28 +699,29 @@ struct SimInstance it.second->writeback(wbmods); } - void write_vcd_header(std::ofstream &f, int &id) + void write_output_header(OutputWriter *writer, int &id) { - f << stringf("$scope module %s $end\n", log_id(name())); + writer->enter_scope(name()); for (auto wire : module->wires()) { if (shared->hide_internal && wire->name[0] == '$') continue; - f << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); - vcd_database[wire] = make_pair(id++, Const()); + signal_database[wire] = make_pair(id, Const()); + writer->register_signal(wire, id); + id++; } for (auto child : children) - child.second->write_vcd_header(f, id); + child.second->write_output_header(writer, id); - f << stringf("$upscope $end\n"); + writer->exit_scope(); } - void write_vcd_step(std::ofstream &f) + void write_output_step_values() { - for (auto &it : vcd_database) + for (auto &it : signal_database) { Wire *wire = it.first; Const value = get_state(wire); @@ -717,68 +732,12 @@ struct SimInstance it.second.second = value; - f << "b"; - for (int i = GetSize(value)-1; i >= 0; i--) { - switch (value[i]) { - case State::S0: f << "0"; break; - case State::S1: f << "1"; break; - case State::Sx: f << "x"; break; - default: f << "z"; - } - } - - f << stringf(" n%d\n", id); - } - - 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& writer : shared->outputfiles) + writer->write_value(id, value); } for (auto child : children) - child.second->write_fst_step(f); + child.second->write_output_step_values(); } void setInitState() @@ -857,11 +816,7 @@ struct SimInstance struct SimWorker : SimShared { SimInstance *top = nullptr; - std::ofstream vcdfile, aiwfile; - struct fstContext *fstfile = nullptr; pool clock, clockn, reset, resetn; - dict> aiw_latches; - dict aiw_inputs, aiw_inits; std::string timescale; std::string sim_filename; std::string map_filename; @@ -869,151 +824,25 @@ struct SimWorker : SimShared ~SimWorker() { + outputfiles.clear(); delete top; } - void write_vcd_header() - { - vcdfile << stringf("$version %s $end\n", yosys_version_str); - - std::time_t t = std::time(nullptr); - char mbstr[255]; - if (std::strftime(mbstr, sizeof(mbstr), "%c", std::localtime(&t))) { - vcdfile << stringf("$date ") << mbstr << stringf(" $end\n"); - } - - if (!timescale.empty()) - vcdfile << stringf("$timescale %s $end\n", timescale.c_str()); - - int id = 1; - top->write_vcd_header(vcdfile, id); - - vcdfile << stringf("$enddefinitions $end\n"); - } - - void write_vcd_step(int t) - { - 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_aiw_header() - { - std::ifstream mf(map_filename); - std::string type, symbol; - int variable, index; - while (mf >> type >> variable >> index >> symbol) { - RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); - Wire *w = top->module->wire(escaped_s); - if (!w) - log_error("Wire %s not present in module %s\n",log_signal(w),log_id(top->module)); - if (index < w->start_offset || index > w->start_offset + w->width) - log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); - if (type == "input") { - aiw_inputs[variable] = SigBit(w,index); - } else if (type == "init") { - aiw_inits[variable] = SigBit(w,index); - } else if (type == "latch") { - aiw_latches[variable] = {SigBit(w,index), false}; - } else if (type == "invlatch") { - aiw_latches[variable] = {SigBit(w,index), true}; - } - } - - for (int i = 0;; i++) - { - if (aiw_latches.count(i)) { - auto v = top->get_state(aiw_latches.at(i).first); - if (v == State::S1) - aiwfile << (aiw_latches.at(i).second ? '0' : '1'); - else - aiwfile << (aiw_latches.at(i).second ? '1' : '0'); - continue; - } - aiwfile << '\n'; - break; - } - } - - void write_aiw_step() - { - for (int i = 0;; i++) - { - if (aiw_inputs.count(i)) { - auto v = top->get_state(aiw_inputs.at(i)); - if (v == State::S1) - aiwfile << '1'; - else - aiwfile << '0'; - continue; - } - if (aiw_inits.count(i)) { - auto v = top->get_state(aiw_inits.at(i)); - if (v == State::S1) - aiwfile << '1'; - else - aiwfile << '0'; - continue; - } - aiwfile << '\n'; - break; - } - } - - void write_aiw_end() - { - aiwfile << '.' << '\n'; - } - void write_output_header() { - if (vcdfile.is_open()) - write_vcd_header(); - if (fstfile) - write_fst_header(); - if (aiwfile.is_open()) - write_aiw_header(); + for(auto& writer : outputfiles) + writer->write_header(); } void write_output_step(int t) { - if (vcdfile.is_open()) - write_vcd_step(t); - if (fstfile) - write_fst_step(t); - if (aiwfile.is_open()) - write_aiw_step(); - } + for(auto& writer : outputfiles) + writer->write_step_header(t); - void write_output_end() - { - if (fstfile) - fstWriterClose(fstfile); - if (aiwfile.is_open()) - write_aiw_end(); + top->write_output_step_values(); } + void update() { while (1) @@ -1101,8 +930,6 @@ struct SimWorker : SimShared write_output_step(10*numcycles + 2); - write_output_end(); - if (writeback) { pool wbmods; top->writeback(wbmods); @@ -1230,7 +1057,6 @@ struct SimWorker : SimShared } catch(fst_end_of_data_exception) { // end of data detected } - write_output_end(); if (writeback) { pool wbmods; @@ -1327,10 +1153,228 @@ struct SimWorker : SimShared } } write_output_step(10*cycle); - write_output_end(); } }; +struct VCDWriter : public OutputWriter +{ + VCDWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { + vcdfile.open(filename.c_str()); + } + + void write_header() override + { + if (!vcdfile.is_open()) return; + vcdfile << stringf("$version %s $end\n", yosys_version_str); + + std::time_t t = std::time(nullptr); + char mbstr[255]; + if (std::strftime(mbstr, sizeof(mbstr), "%c", std::localtime(&t))) { + vcdfile << stringf("$date ") << mbstr << stringf(" $end\n"); + } + + if (!worker->timescale.empty()) + vcdfile << stringf("$timescale %s $end\n", worker->timescale.c_str()); + + int id = 1; + worker->top->write_output_header(this, id); + + vcdfile << stringf("$enddefinitions $end\n"); + } + + void write_step_header(int t) override + { + if (!vcdfile.is_open()) return; + vcdfile << stringf("#%d\n", t); + } + + void enter_scope(IdString name) override + { + vcdfile << stringf("$scope module %s $end\n", log_id(name)); + } + void exit_scope() override + { + vcdfile << stringf("$upscope $end\n"); + } + + void register_signal(Wire *wire, int id) override + { + vcdfile << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); + } + + void write_value(int id, Const& value) override + { + if (!vcdfile.is_open()) return; + vcdfile << "b"; + for (int i = GetSize(value)-1; i >= 0; i--) { + switch (value[i]) { + case State::S0: vcdfile << "0"; break; + case State::S1: vcdfile << "1"; break; + case State::Sx: vcdfile << "x"; break; + default: vcdfile << "z"; + } + } + + vcdfile << stringf(" n%d\n", id); + } + + std::ofstream vcdfile; +}; + +struct FSTWriter : public OutputWriter +{ + FSTWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { + fstfile = (struct fstContext *)fstWriterCreate(filename.c_str(),1); + } + + virtual ~FSTWriter() + { + fstWriterClose(fstfile); + } + + void write_header() override + { + if (!fstfile) return; + std::time_t t = std::time(nullptr); + fstWriterSetDate(fstfile, asctime(std::localtime(&t))); + fstWriterSetVersion(fstfile, yosys_version_str); + if (!worker->timescale.empty()) + fstWriterSetTimescaleFromString(fstfile, worker->timescale.c_str()); + + fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); + fstWriterSetRepackOnClose(fstfile, 1); + + int id = 1; + worker->top->write_output_header(this, id); + } + + void write_step_header(int t) override + { + if (!fstfile) return; + fstWriterEmitTimeChange(fstfile, t); + } + + void enter_scope(IdString name) override + { + fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",log_id(name)).c_str(), nullptr); + } + + void exit_scope() override + { + fstWriterSetUpscope(fstfile); + } + + void register_signal(Wire *wire, int id) override + { + fstHandle fst_id = fstWriterCreateVar(fstfile, 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); + } + void write_value(int id, Const& value) override + { + if (!fstfile) return; + 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(fstfile, mapping[id], ss.str().c_str()); + } + struct fstContext *fstfile = nullptr; + std::map mapping; +}; + +struct AIWWriter : public OutputWriter +{ + AIWWriter(SimWorker *worker, std::string filename) : OutputWriter(worker) { + aiwfile.open(filename.c_str()); + } + + virtual ~AIWWriter() + { + aiwfile << '.' << '\n'; + } + + void write_header() override + { + if (!aiwfile.is_open()) return; + std::ifstream mf(worker->map_filename); + std::string type, symbol; + int variable, index; + while (mf >> type >> variable >> index >> symbol) { + RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); + Wire *w = worker->top->module->wire(escaped_s); + if (!w) + log_error("Wire %s not present in module %s\n",log_signal(w),log_id(worker->top->module)); + if (index < w->start_offset || index > w->start_offset + w->width) + log_error("Index %d for wire %s is out of range\n", index, log_signal(w)); + if (type == "input") { + aiw_inputs[variable] = SigBit(w,index); + } else if (type == "init") { + aiw_inits[variable] = SigBit(w,index); + } else if (type == "latch") { + aiw_latches[variable] = {SigBit(w,index), false}; + } else if (type == "invlatch") { + aiw_latches[variable] = {SigBit(w,index), true}; + } + } + + for (int i = 0;; i++) + { + if (aiw_latches.count(i)) { + auto v = worker->top->get_state(aiw_latches.at(i).first); + if (v == State::S1) + aiwfile << (aiw_latches.at(i).second ? '0' : '1'); + else + aiwfile << (aiw_latches.at(i).second ? '1' : '0'); + continue; + } + aiwfile << '\n'; + break; + } + } + + void write_step_header(int) override + { + if (!aiwfile.is_open()) return; + for (int i = 0;; i++) + { + if (aiw_inputs.count(i)) { + auto v = worker->top->get_state(aiw_inputs.at(i)); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + if (aiw_inits.count(i)) { + auto v = worker->top->get_state(aiw_inits.at(i)); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + aiwfile << '\n'; + break; + } + } + + void enter_scope(IdString) override {} + void exit_scope() override {} + void register_signal(Wire*, int) override {} + void write_value(int , Const& ) override {} + + std::ofstream aiwfile; + dict> aiw_latches; + dict aiw_inputs, aiw_inits; +}; + struct SimPass : public Pass { SimPass() : Pass("sim", "simulate the circuit") { } void help() override @@ -1428,19 +1472,19 @@ struct SimPass : public Pass { if (args[argidx] == "-vcd" && argidx+1 < args.size()) { std::string vcd_filename = args[++argidx]; rewrite_filename(vcd_filename); - worker.vcdfile.open(vcd_filename.c_str()); + worker.outputfiles.emplace_back(std::unique_ptr(new VCDWriter(&worker, 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); + worker.outputfiles.emplace_back(std::unique_ptr(new FSTWriter(&worker, fst_filename.c_str()))); continue; } if (args[argidx] == "-aiw" && argidx+1 < args.size()) { std::string aiw_filename = args[++argidx]; rewrite_filename(aiw_filename); - worker.aiwfile.open(aiw_filename.c_str()); + worker.outputfiles.emplace_back(std::unique_ptr(new AIWWriter(&worker, aiw_filename.c_str()))); continue; } if (args[argidx] == "-n" && argidx+1 < args.size()) { -- cgit v1.2.3 From 28bc88a57e18ebd5ded2bae4cf2feb375a55cbd1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 2 Mar 2022 09:39:22 +0100 Subject: Cleanup --- passes/sat/sim.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 988da0eb0..7189b54e8 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -72,10 +72,10 @@ struct OutputWriter virtual ~OutputWriter() {}; virtual void write_header() = 0; virtual void write_step_header(int t) = 0; - virtual void enter_scope(IdString name) = 0; - virtual void exit_scope() = 0; - virtual void register_signal(Wire *wire, int id) = 0; - virtual void write_value(int id, Const& value) = 0; + virtual void enter_scope(IdString) {}; + virtual void exit_scope() {}; + virtual void register_signal(Wire *, int) {}; + virtual void write_value(int, Const&) {}; SimWorker *worker; }; @@ -1192,6 +1192,7 @@ struct VCDWriter : public OutputWriter { vcdfile << stringf("$scope module %s $end\n", log_id(name)); } + void exit_scope() override { vcdfile << stringf("$upscope $end\n"); @@ -1214,7 +1215,6 @@ struct VCDWriter : public OutputWriter default: vcdfile << "z"; } } - vcdfile << stringf(" n%d\n", id); } @@ -1271,6 +1271,7 @@ struct FSTWriter : public OutputWriter mapping.emplace(id, fst_id); } + void write_value(int id, Const& value) override { if (!fstfile) return; @@ -1285,6 +1286,7 @@ struct FSTWriter : public OutputWriter } fstWriterEmitValueChange(fstfile, mapping[id], ss.str().c_str()); } + struct fstContext *fstfile = nullptr; std::map mapping; }; @@ -1364,11 +1366,6 @@ struct AIWWriter : public OutputWriter break; } } - - void enter_scope(IdString) override {} - void exit_scope() override {} - void register_signal(Wire*, int) override {} - void write_value(int , Const& ) override {} std::ofstream aiwfile; dict> aiw_latches; -- cgit v1.2.3 From 48b56a4f7fb13b27522dc243e68d8f67bcde705a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 2 Mar 2022 15:23:07 +0100 Subject: Write simulation files after simulation is performed --- passes/sat/sim.cc | 296 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 151 insertions(+), 145 deletions(-) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 7189b54e8..6be8c080b 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -70,12 +70,7 @@ struct OutputWriter { OutputWriter(SimWorker *w) { worker = w;}; virtual ~OutputWriter() {}; - virtual void write_header() = 0; - virtual void write_step_header(int t) = 0; - virtual void enter_scope(IdString) {}; - virtual void exit_scope() {}; - virtual void register_signal(Wire *, int) {}; - virtual void write_value(int, Const&) {}; + virtual void write() = 0; SimWorker *worker; }; @@ -92,6 +87,7 @@ struct SimShared SimulationMode sim_mode = SimulationMode::sim; bool cycles_set = false; std::vector> outputfiles; + std::vector>> output_data; }; void zinit(State &v) @@ -699,27 +695,37 @@ struct SimInstance it.second->writeback(wbmods); } - void write_output_header(OutputWriter *writer, int &id) + void register_signals(int &id) { - writer->enter_scope(name()); - for (auto wire : module->wires()) { if (shared->hide_internal && wire->name[0] == '$') continue; signal_database[wire] = make_pair(id, Const()); - writer->register_signal(wire, id); id++; } for (auto child : children) - child.second->write_output_header(writer, id); + child.second->register_signals(id); + } + + void write_output_header(std::function enter_scope, std::function exit_scope, std::function register_signal) + { + enter_scope(name()); - writer->exit_scope(); + for (auto signal : signal_database) + { + register_signal(signal.first, signal.second.first); + } + + for (auto child : children) + child.second->write_output_header(enter_scope, exit_scope, register_signal); + + exit_scope(); } - void write_output_step_values() + void register_output_step_values(std::map *data) { for (auto &it : signal_database) { @@ -731,13 +737,11 @@ struct SimInstance continue; it.second.second = value; - - for(auto& writer : shared->outputfiles) - writer->write_value(id, value); + data->emplace(id, value); } for (auto child : children) - child.second->write_output_step_values(); + child.second->register_output_step_values(data); } void setInitState() @@ -828,20 +832,24 @@ struct SimWorker : SimShared delete top; } - void write_output_header() + void register_signals() { - for(auto& writer : outputfiles) - writer->write_header(); + int id = 1; + top->register_signals(id); } - void write_output_step(int t) + void register_output_step(int t) { - for(auto& writer : outputfiles) - writer->write_step_header(t); - - top->write_output_step_values(); + std::map data; + top->register_output_step_values(&data); + output_data.emplace_back(t, data); } + void write_output_files() + { + for(auto& writer : outputfiles) + writer->write(); + } void update() { @@ -882,6 +890,7 @@ struct SimWorker : SimShared { log_assert(top == nullptr); top = new SimInstance(this, scope, topmod); + register_signals(); if (debug) log("\n===== 0 =====\n"); @@ -896,8 +905,7 @@ struct SimWorker : SimShared update(); - write_output_header(); - write_output_step(0); + register_output_step(0); for (int cycle = 0; cycle < numcycles; cycle++) { @@ -909,7 +917,7 @@ struct SimWorker : SimShared set_inports(clockn, State::S1); update(); - write_output_step(10*cycle + 5); + register_output_step(10*cycle + 5); if (debug) log("\n===== %d =====\n", 10*cycle + 10); @@ -925,10 +933,12 @@ struct SimWorker : SimShared } update(); - write_output_step(10*cycle + 10); + register_output_step(10*cycle + 10); } - write_output_step(10*numcycles + 2); + register_output_step(10*numcycles + 2); + + write_output_files(); if (writeback) { pool wbmods; @@ -945,6 +955,7 @@ struct SimWorker : SimShared log_error("Scope must be defined for co-simulation.\n"); top = new SimInstance(this, scope, topmod); + register_signals(); std::vector fst_clock; @@ -1036,12 +1047,11 @@ struct SimWorker : SimShared if (initial) { top->setInitState(); - write_output_header(); initial = false; } if (did_something) update(); - write_output_step(time); + register_output_step(time); bool status = top->checkSignals(); if (status) @@ -1058,6 +1068,8 @@ struct SimWorker : SimShared // end of data detected } + write_output_files(); + if (writeback) { pool wbmods; top->writeback(wbmods); @@ -1098,6 +1110,8 @@ struct SimWorker : SimShared std::string status; int cycle = 0; top = new SimInstance(this, scope, topmod); + register_signals(); + while (!f.eof()) { std::string line; @@ -1109,7 +1123,6 @@ struct SimWorker : SimShared state = 2; } if (state==1 && line[0]!='b' && line[0]!='c') { - write_output_header(); // was old format but with 1 bit latch top->setState(latches, status); state = 3; @@ -1125,7 +1138,6 @@ struct SimWorker : SimShared state = 2; break; case 2: - write_output_header(); top->setState(latches, line); state = 3; break; @@ -1141,18 +1153,19 @@ struct SimWorker : SimShared set_inports(clockn, State::S1); } update(); - write_output_step(10*cycle); + register_output_step(10*cycle); if (cycle) { set_inports(clock, State::S0); set_inports(clockn, State::S1); update(); - write_output_step(10*cycle + 5); + register_output_step(10*cycle + 5); } cycle++; break; } } - write_output_step(10*cycle); + register_output_step(10*cycle); + write_output_files(); } }; @@ -1162,7 +1175,7 @@ struct VCDWriter : public OutputWriter vcdfile.open(filename.c_str()); } - void write_header() override + void write() override { if (!vcdfile.is_open()) return; vcdfile << stringf("$version %s $end\n", yosys_version_str); @@ -1176,46 +1189,33 @@ struct VCDWriter : public OutputWriter if (!worker->timescale.empty()) vcdfile << stringf("$timescale %s $end\n", worker->timescale.c_str()); - int id = 1; - worker->top->write_output_header(this, id); + 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](Wire *wire, int id) { vcdfile << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); } + ); vcdfile << stringf("$enddefinitions $end\n"); - } - void write_step_header(int t) override - { - if (!vcdfile.is_open()) return; - vcdfile << stringf("#%d\n", t); - } - - void enter_scope(IdString name) override - { - vcdfile << stringf("$scope module %s $end\n", log_id(name)); - } - - void exit_scope() override - { - vcdfile << stringf("$upscope $end\n"); - } - - void register_signal(Wire *wire, int id) override - { - vcdfile << stringf("$var wire %d n%d %s%s $end\n", GetSize(wire), id, wire->name[0] == '$' ? "\\" : "", log_id(wire)); - } + for(auto& d : worker->output_data) + { + vcdfile << stringf("#%d\n", d.first); + for (auto &data : d.second) + { - void write_value(int id, Const& value) override - { - if (!vcdfile.is_open()) return; - vcdfile << "b"; - for (int i = GetSize(value)-1; i >= 0; i--) { - switch (value[i]) { - case State::S0: vcdfile << "0"; break; - case State::S1: vcdfile << "1"; break; - case State::Sx: vcdfile << "x"; break; - default: vcdfile << "z"; + Const value = data.second; + vcdfile << "b"; + for (int i = GetSize(value)-1; i >= 0; i--) { + switch (value[i]) { + case State::S0: vcdfile << "0"; break; + case State::S1: vcdfile << "1"; break; + case State::Sx: vcdfile << "x"; break; + default: vcdfile << "z"; + } + } + vcdfile << stringf(" n%d\n", data.first); } } - vcdfile << stringf(" n%d\n", id); } std::ofstream vcdfile; @@ -1232,7 +1232,7 @@ struct FSTWriter : public OutputWriter fstWriterClose(fstfile); } - void write_header() override + void write() override { if (!fstfile) return; std::time_t t = std::time(nullptr); @@ -1244,47 +1244,35 @@ struct FSTWriter : public OutputWriter fstWriterSetPackType(fstfile, FST_WR_PT_FASTLZ); fstWriterSetRepackOnClose(fstfile, 1); - int id = 1; - worker->top->write_output_header(this, id); - } - - void write_step_header(int t) override - { - if (!fstfile) return; - fstWriterEmitTimeChange(fstfile, t); - } - - void enter_scope(IdString name) override - { - fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",log_id(name)).c_str(), nullptr); - } - - void exit_scope() override - { - fstWriterSetUpscope(fstfile); - } - - void register_signal(Wire *wire, int id) override - { - fstHandle fst_id = fstWriterCreateVar(fstfile, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), + 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](Wire *wire, int id) { + fstHandle fst_id = fstWriterCreateVar(fstfile, 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); - } + mapping.emplace(id, fst_id); + } + ); - void write_value(int id, Const& value) override - { - if (!fstfile) return; - 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"; + for(auto& d : worker->output_data) + { + fstWriterEmitTimeChange(fstfile, d.first); + for (auto &data : d.second) + { + Const value = data.second; + 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(fstfile, mapping[data.first], ss.str().c_str()); } } - fstWriterEmitValueChange(fstfile, mapping[id], ss.str().c_str()); } struct fstContext *fstfile = nullptr; @@ -1302,7 +1290,7 @@ struct AIWWriter : public OutputWriter aiwfile << '.' << '\n'; } - void write_header() override + void write() override { if (!aiwfile.is_open()) return; std::ifstream mf(worker->map_filename); @@ -1326,50 +1314,68 @@ struct AIWWriter : public OutputWriter } } - for (int i = 0;; i++) - { - if (aiw_latches.count(i)) { - auto v = worker->top->get_state(aiw_latches.at(i).first); - if (v == State::S1) - aiwfile << (aiw_latches.at(i).second ? '0' : '1'); - else - aiwfile << (aiw_latches.at(i).second ? '1' : '0'); - continue; - } - aiwfile << '\n'; - break; - } - } + worker->top->write_output_header( + [](IdString) {}, + []() {}, + [this](Wire *wire, int id) { mapping[wire] = id; } + ); - void write_step_header(int) override - { - if (!aiwfile.is_open()) return; - for (int i = 0;; i++) + std::map current; + bool first = true; + for(auto& d : worker->output_data) { - if (aiw_inputs.count(i)) { - auto v = worker->top->get_state(aiw_inputs.at(i)); - if (v == State::S1) - aiwfile << '1'; - else - aiwfile << '0'; - continue; + for (auto &data : d.second) + { + current[data.first] = data.second; } - if (aiw_inits.count(i)) { - auto v = worker->top->get_state(aiw_inits.at(i)); - if (v == State::S1) - aiwfile << '1'; - else - aiwfile << '0'; - continue; + if (first) { + for (int i = 0;; i++) + { + if (aiw_latches.count(i)) { + SigBit bit = aiw_latches.at(i).first; + auto v = current[mapping[bit.wire]].bits.at(bit.offset); + if (v == State::S1) + aiwfile << (aiw_latches.at(i).second ? '0' : '1'); + else + aiwfile << (aiw_latches.at(i).second ? '1' : '0'); + continue; + } + aiwfile << '\n'; + break; + } + first = false; } - aiwfile << '\n'; - break; - } + + for (int i = 0;; i++) + { + if (aiw_inputs.count(i)) { + SigBit bit = aiw_inputs.at(i); + auto v = current[mapping[bit.wire]].bits.at(bit.offset); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + if (aiw_inits.count(i)) { + SigBit bit = aiw_inits.at(i); + auto v = current[mapping[bit.wire]].bits.at(bit.offset); + if (v == State::S1) + aiwfile << '1'; + else + aiwfile << '0'; + continue; + } + aiwfile << '\n'; + break; + } + } } std::ofstream aiwfile; dict> aiw_latches; dict aiw_inputs, aiw_inits; + std::map mapping; }; struct SimPass : public Pass { -- cgit v1.2.3 From 59983eda1788b927fa60d1efc04b5e66a45d85aa Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 2 Mar 2022 16:02:13 +0100 Subject: Add option to ignore X only signals in output --- passes/sat/sim.cc | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'passes') diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 6be8c080b..391a25581 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -70,7 +70,7 @@ struct OutputWriter { OutputWriter(SimWorker *w) { worker = w;}; virtual ~OutputWriter() {}; - virtual void write() = 0; + virtual void write(std::map &use_signal) = 0; SimWorker *worker; }; @@ -88,6 +88,7 @@ struct SimShared bool cycles_set = false; std::vector> outputfiles; std::vector>> output_data; + bool ignore_x = false; }; void zinit(State &v) @@ -847,8 +848,22 @@ struct SimWorker : SimShared void write_output_files() { + std::map use_signal; + bool first = ignore_x; + for(auto& d : output_data) + { + if (first) { + for (auto &data : d.second) + use_signal[data.first] = !data.second.is_fully_undef(); + first = false; + } else { + for (auto &data : d.second) + use_signal[data.first] = true; + } + if (!ignore_x) break; + } for(auto& writer : outputfiles) - writer->write(); + writer->write(use_signal); } void update() @@ -1175,7 +1190,7 @@ struct VCDWriter : public OutputWriter vcdfile.open(filename.c_str()); } - void write() override + void write(std::map &use_signal) override { if (!vcdfile.is_open()) return; vcdfile << stringf("$version %s $end\n", yosys_version_str); @@ -1192,7 +1207,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](Wire *wire, int 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) { 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)); } ); vcdfile << stringf("$enddefinitions $end\n"); @@ -1202,7 +1217,7 @@ struct VCDWriter : public OutputWriter vcdfile << stringf("#%d\n", d.first); for (auto &data : d.second) { - + if (!use_signal.at(data.first)) continue; Const value = data.second; vcdfile << "b"; for (int i = GetSize(value)-1; i >= 0; i--) { @@ -1232,7 +1247,7 @@ struct FSTWriter : public OutputWriter fstWriterClose(fstfile); } - void write() override + void write(std::map &use_signal) override { if (!fstfile) return; std::time_t t = std::time(nullptr); @@ -1247,7 +1262,8 @@ 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](Wire *wire, int id) { + [this,use_signal](Wire *wire, int id) { + if (!use_signal.at(id)) return; fstHandle fst_id = fstWriterCreateVar(fstfile, FST_VT_VCD_WIRE, FST_VD_IMPLICIT, GetSize(wire), stringf("%s%s", wire->name[0] == '$' ? "\\" : "", log_id(wire)).c_str(), 0); @@ -1260,6 +1276,7 @@ struct FSTWriter : public OutputWriter fstWriterEmitTimeChange(fstfile, d.first); for (auto &data : d.second) { + if (!use_signal.at(data.first)) continue; Const value = data.second; std::stringstream ss; for (int i = GetSize(value)-1; i >= 0; i--) { @@ -1290,7 +1307,7 @@ struct AIWWriter : public OutputWriter aiwfile << '.' << '\n'; } - void write() override + void write(std::map &) override { if (!aiwfile.is_open()) return; std::ifstream mf(worker->map_filename); @@ -1398,6 +1415,9 @@ struct SimPass : public Pass { log(" write the simulation results to an AIGER witness file\n"); log(" (requires a *.aim file via -map)\n"); log("\n"); + log(" -x\n"); + log(" ignore constant x outputs in simulation file.\n"); + log("\n"); log(" -clock \n"); log(" name of top-level clock input\n"); log("\n"); @@ -1583,6 +1603,10 @@ struct SimPass : public Pass { worker.sim_mode = SimulationMode::gate; continue; } + if (args[argidx] == "-x") { + worker.ignore_x = true; + continue; + } break; } extra_args(args, argidx, design); -- cgit v1.2.3