3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-10-23 16:04:37 +00:00

Merge pull request #5430 from YosysHQ/micko/sim_cycle_width

sim: Make cycle width small as possible and configurable
This commit is contained in:
Jannis Harder 2025-10-20 18:51:32 +02:00 committed by GitHub
commit f6fb423ee8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 31 deletions

View file

@ -1392,7 +1392,7 @@ struct SimWorker : SimShared
} }
} }
void run(Module *topmod, int numcycles) void run(Module *topmod, int cycle_width, int numcycles)
{ {
log_assert(top == nullptr); log_assert(top == nullptr);
top = new SimInstance(this, scope, topmod); top = new SimInstance(this, scope, topmod);
@ -1418,20 +1418,20 @@ struct SimWorker : SimShared
for (int cycle = 0; cycle < numcycles; cycle++) for (int cycle = 0; cycle < numcycles; cycle++)
{ {
if (debug) if (debug)
log("\n===== %d =====\n", 10*cycle + 5); log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width/2));
else if (verbose) else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+1); log("Simulating cycle %d.\n", (cycle*2)+1);
set_inports(clock, State::S0); set_inports(clock, State::S0);
set_inports(clockn, State::S1); set_inports(clockn, State::S1);
update(true); update(true);
register_output_step(10*cycle + 5); register_output_step(cycle_width*cycle + cycle_width/2);
if (cycle == 0) if (cycle == 0)
top->set_initstate_outputs(State::S0); top->set_initstate_outputs(State::S0);
if (debug) if (debug)
log("\n===== %d =====\n", 10*cycle + 10); log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width));
else if (verbose) else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+2); log("Simulating cycle %d.\n", (cycle*2)+2);
@ -1444,10 +1444,10 @@ struct SimWorker : SimShared
} }
update(true); update(true);
register_output_step(10*cycle + 10); register_output_step(cycle_width*cycle + cycle_width);
} }
register_output_step(10*numcycles + 2); register_output_step(cycle_width*numcycles + 2);
write_output_files(); write_output_files();
} }
@ -1582,7 +1582,7 @@ struct SimWorker : SimShared
return atoi(name.substr(pos+1).c_str()); return atoi(name.substr(pos+1).c_str());
} }
void run_cosim_aiger_witness(Module *topmod) void run_cosim_aiger_witness(Module *topmod, int cycle_width)
{ {
log_assert(top == nullptr); log_assert(top == nullptr);
if (!multiclock && (clock.size()+clockn.size())==0) if (!multiclock && (clock.size()+clockn.size())==0)
@ -1691,18 +1691,18 @@ struct SimWorker : SimShared
set_inports(clockn, State::S1); set_inports(clockn, State::S1);
} }
update(true); update(true);
register_output_step(10*cycle); register_output_step(cycle_width*cycle);
if (!multiclock && cycle) { if (!multiclock && cycle) {
set_inports(clock, State::S0); set_inports(clock, State::S0);
set_inports(clockn, State::S1); set_inports(clockn, State::S1);
update(true); update(true);
register_output_step(10*cycle + 5); register_output_step(cycle_width*cycle + cycle_width/2);
} }
cycle++; cycle++;
break; break;
} }
} }
register_output_step(10*cycle); register_output_step(cycle_width*cycle);
write_output_files(); write_output_files();
} }
@ -1730,7 +1730,7 @@ struct SimWorker : SimShared
return name.substr(0, pos); return name.substr(0, pos);
} }
void run_cosim_btor2_witness(Module *topmod) void run_cosim_btor2_witness(Module *topmod, int cycle_width)
{ {
log_assert(top == nullptr); log_assert(top == nullptr);
if (!multiclock && (clock.size()+clockn.size())==0) if (!multiclock && (clock.size()+clockn.size())==0)
@ -1768,12 +1768,12 @@ struct SimWorker : SimShared
set_inports(clock, State::S1); set_inports(clock, State::S1);
set_inports(clockn, State::S0); set_inports(clockn, State::S0);
update(true); update(true);
register_output_step(10*cycle+0); register_output_step(cycle_width*cycle + 0);
if (!multiclock) { if (!multiclock) {
set_inports(clock, State::S0); set_inports(clock, State::S0);
set_inports(clockn, State::S1); set_inports(clockn, State::S1);
update(true); update(true);
register_output_step(10*cycle+5); register_output_step(cycle_width*cycle + cycle_width/2);
} }
cycle++; cycle++;
prev_cycle = curr_cycle; prev_cycle = curr_cycle;
@ -1832,7 +1832,7 @@ struct SimWorker : SimShared
break; break;
} }
} }
register_output_step(10*cycle); register_output_step(cycle_width*cycle);
write_output_files(); write_output_files();
} }
@ -1983,7 +1983,7 @@ struct SimWorker : SimShared
} }
} }
void run_cosim_yw_witness(Module *topmod, int append) void run_cosim_yw_witness(Module *topmod, int cycle_width, int append)
{ {
if (!clock.empty()) if (!clock.empty())
log_cmd_error("The -clock option is not required nor supported when reading a Yosys witness file.\n"); log_cmd_error("The -clock option is not required nor supported when reading a Yosys witness file.\n");
@ -2013,7 +2013,7 @@ struct SimWorker : SimShared
log("Simulating non-active clock edge.\n"); log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, false); set_yw_clocks(yw, hierarchy, false);
update(false); update(false);
register_output_step(5); register_output_step(cycle_width/2);
} }
top->set_initstate_outputs(State::S0); top->set_initstate_outputs(State::S0);
} }
@ -2026,18 +2026,18 @@ struct SimWorker : SimShared
set_yw_state(yw, hierarchy, cycle); set_yw_state(yw, hierarchy, cycle);
set_yw_clocks(yw, hierarchy, true); set_yw_clocks(yw, hierarchy, true);
update(true); update(true);
register_output_step(10 * cycle); register_output_step(cycle_width*cycle);
if (!yw.clocks.empty()) { if (!yw.clocks.empty()) {
if (debug) if (debug)
log("Simulating non-active clock edge.\n"); log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, false); set_yw_clocks(yw, hierarchy, false);
update(false); update(false);
register_output_step(5 + 10 * cycle); register_output_step(cycle_width*cycle + cycle_width/2);
} }
} }
register_output_step(10 * (GetSize(yw.steps) + append)); register_output_step(cycle_width * (GetSize(yw.steps) + append));
write_output_files(); write_output_files();
} }
@ -2630,6 +2630,9 @@ struct SimPass : public Pass {
log(" File formats supported: FST, VCD, AIW, WIT and .yw\n"); log(" File formats supported: FST, VCD, AIW, WIT and .yw\n");
log(" VCD support requires vcd2fst external tool to be present\n"); log(" VCD support requires vcd2fst external tool to be present\n");
log("\n"); log("\n");
log(" -width <integer>\n");
log(" cycle width in generated simulation output (must be divisible by 2).\n");
log("\n");
log(" -append <integer>\n"); log(" -append <integer>\n");
log(" number of extra clock cycles to simulate for a Yosys witness input\n"); log(" number of extra clock cycles to simulate for a Yosys witness input\n");
log("\n"); log("\n");
@ -2689,6 +2692,7 @@ struct SimPass : public Pass {
{ {
SimWorker worker; SimWorker worker;
int numcycles = 20; int numcycles = 20;
int cycle_width = 10;
int append = 0; int append = 0;
bool start_set = false, stop_set = false, at_set = false; bool start_set = false, stop_set = false, at_set = false;
@ -2781,6 +2785,12 @@ struct SimPass : public Pass {
append = atoi(args[++argidx].c_str()); append = atoi(args[++argidx].c_str());
continue; continue;
} }
if (args[argidx] == "-width" && argidx+1 < args.size()) {
cycle_width = atoi(args[++argidx].c_str());
if (cycle_width <= 0 || (cycle_width % 2))
log_cmd_error("Cycle width must be positive even number.\n");
continue;
}
if (args[argidx] == "-map" && argidx+1 < args.size()) { if (args[argidx] == "-map" && argidx+1 < args.size()) {
std::string map_filename = args[++argidx]; std::string map_filename = args[++argidx];
rewrite_filename(map_filename); rewrite_filename(map_filename);
@ -2872,7 +2882,7 @@ struct SimPass : public Pass {
} }
if (worker.sim_filename.empty()) if (worker.sim_filename.empty())
worker.run(top_mod, numcycles); worker.run(top_mod, cycle_width, numcycles);
else { else {
std::string filename_trim = file_base_name(worker.sim_filename); std::string filename_trim = file_base_name(worker.sim_filename);
if (filename_trim.size() > 4 && ((filename_trim.compare(filename_trim.size()-4, std::string::npos, ".fst") == 0) || if (filename_trim.size() > 4 && ((filename_trim.compare(filename_trim.size()-4, std::string::npos, ".fst") == 0) ||
@ -2881,11 +2891,11 @@ struct SimPass : public Pass {
} else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".aiw") == 0) { } else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".aiw") == 0) {
if (worker.map_filename.empty()) if (worker.map_filename.empty())
log_cmd_error("For AIGER witness file map parameter is mandatory.\n"); log_cmd_error("For AIGER witness file map parameter is mandatory.\n");
worker.run_cosim_aiger_witness(top_mod); worker.run_cosim_aiger_witness(top_mod, cycle_width);
} else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".wit") == 0) { } else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".wit") == 0) {
worker.run_cosim_btor2_witness(top_mod); worker.run_cosim_btor2_witness(top_mod, cycle_width);
} else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".yw") == 0) { } else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".yw") == 0) {
worker.run_cosim_yw_witness(top_mod, append); worker.run_cosim_yw_witness(top_mod, cycle_width, append);
} else { } else {
log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename); log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename);
} }

View file

@ -2,7 +2,7 @@ read_verilog dff.v
prep prep
# create fst with 20 clock cycles (41 samples, 202ns) # create fst with 20 clock cycles (41 samples, 202ns)
sim -clock clk -fst sim_cycles.fst -n 20 sim -clock clk -fst sim_cycles.fst -width 2 -n 20
logger -expect-no-warnings logger -expect-no-warnings
@ -10,7 +10,7 @@ logger -expect-no-warnings
logger -expect log "Co-simulating cycle 41" 2 logger -expect log "Co-simulating cycle 41" 2
logger -warn "Co-simulating cycle 42" logger -warn "Co-simulating cycle 42"
sim -clock clk -r sim_cycles.fst -scope dff -n 21 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -n 21 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 202 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -stop 41 -sim-cmp
logger -check-expected logger -check-expected
# over limit stops at final step # over limit stops at final step
@ -18,29 +18,29 @@ logger -expect log "Co-simulating cycle 41" 2
sim -clock clk -r sim_cycles.fst -scope dff -n 30 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -n 30 -sim-cmp
# -stop warns for over limit # -stop warns for over limit
logger -nowarn "Stop time is after simulation file end time" logger -nowarn "Stop time is after simulation file end time"
sim -clock clk -r sim_cycles.fst -scope dff -stop 300 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -stop 50 -sim-cmp
logger -check-expected logger -check-expected
# don't auto step last # don't auto step last
logger -expect log "Co-simulating cycle 40" 2 logger -expect log "Co-simulating cycle 40" 2
logger -warn "Co-simulating cycle 41" logger -warn "Co-simulating cycle 41"
sim -clock clk -r sim_cycles.fst -scope dff -n 20 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -n 20 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 200 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -stop 40 -sim-cmp
logger -check-expected logger -check-expected
# -n 10 == -stop 100 # -n 10 == -stop 20
# should simulate up to 20 and not more # should simulate up to 20 and not more
logger -expect log "Co-simulating cycle 20" 2 logger -expect log "Co-simulating cycle 20" 2
logger -warn "Co-simulating cycle 21" logger -warn "Co-simulating cycle 21"
sim -clock clk -r sim_cycles.fst -scope dff -n 10 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -n 10 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 100 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -stop 20 -sim-cmp
logger -check-expected logger -check-expected
# -n 1 == -stop 10 # -n 1 == -stop 2
logger -expect log "Co-simulating cycle 2" 2 logger -expect log "Co-simulating cycle 2" 2
logger -warn "Co-simulating cycle 3" logger -warn "Co-simulating cycle 3"
sim -clock clk -r sim_cycles.fst -scope dff -n 1 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -n 1 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 10 -sim-cmp sim -clock clk -r sim_cycles.fst -scope dff -stop 2 -sim-cmp
logger -check-expected logger -check-expected
# -n 0 == -stop 0 # -n 0 == -stop 0