Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions passes/sat/sim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
top = new SimInstance(this, scope, topmod);
Expand All @@ -1418,20 +1418,20 @@ struct SimWorker : SimShared
for (int cycle = 0; cycle < numcycles; cycle++)
{
if (debug)
log("\n===== %d =====\n", 10*cycle + 5);
log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width/2));
else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+1);
set_inports(clock, State::S0);
set_inports(clockn, State::S1);

update(true);
register_output_step(10*cycle + 5);
register_output_step(cycle_width*cycle + cycle_width/2);

if (cycle == 0)
top->set_initstate_outputs(State::S0);

if (debug)
log("\n===== %d =====\n", 10*cycle + 10);
log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width));
else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+2);

Expand All @@ -1444,10 +1444,10 @@ struct SimWorker : SimShared
}

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();
}
Expand Down Expand Up @@ -1582,7 +1582,7 @@ struct SimWorker : SimShared
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);
if (!multiclock && (clock.size()+clockn.size())==0)
Expand Down Expand Up @@ -1691,18 +1691,18 @@ struct SimWorker : SimShared
set_inports(clockn, State::S1);
}
update(true);
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
if (!multiclock && cycle) {
set_inports(clock, State::S0);
set_inports(clockn, State::S1);
update(true);
register_output_step(10*cycle + 5);
register_output_step(cycle_width*cycle + cycle_width/2);
}
cycle++;
break;
}
}
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
write_output_files();
}

Expand Down Expand Up @@ -1730,7 +1730,7 @@ struct SimWorker : SimShared
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);
if (!multiclock && (clock.size()+clockn.size())==0)
Expand Down Expand Up @@ -1768,12 +1768,12 @@ struct SimWorker : SimShared
set_inports(clock, State::S1);
set_inports(clockn, State::S0);
update(true);
register_output_step(10*cycle+0);
register_output_step(cycle_width*cycle + 0);
if (!multiclock) {
set_inports(clock, State::S0);
set_inports(clockn, State::S1);
update(true);
register_output_step(10*cycle+5);
register_output_step(cycle_width*cycle + cycle_width/2);
}
cycle++;
prev_cycle = curr_cycle;
Expand Down Expand Up @@ -1832,7 +1832,7 @@ struct SimWorker : SimShared
break;
}
}
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
write_output_files();
}

Expand Down Expand Up @@ -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())
log_cmd_error("The -clock option is not required nor supported when reading a Yosys witness file.\n");
Expand Down Expand Up @@ -2013,7 +2013,7 @@ struct SimWorker : SimShared
log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, false);
update(false);
register_output_step(5);
register_output_step(cycle_width/2);
}
top->set_initstate_outputs(State::S0);
}
Expand All @@ -2026,18 +2026,18 @@ struct SimWorker : SimShared
set_yw_state(yw, hierarchy, cycle);
set_yw_clocks(yw, hierarchy, true);
update(true);
register_output_step(10 * cycle);
register_output_step(cycle_width*cycle);

if (!yw.clocks.empty()) {
if (debug)
log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, 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();
}

Expand Down Expand Up @@ -2630,6 +2630,9 @@ struct SimPass : public Pass {
log(" File formats supported: FST, VCD, AIW, WIT and .yw\n");
log(" VCD support requires vcd2fst external tool to be present\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(" number of extra clock cycles to simulate for a Yosys witness input\n");
log("\n");
Expand Down Expand Up @@ -2689,6 +2692,7 @@ struct SimPass : public Pass {
{
SimWorker worker;
int numcycles = 20;
int cycle_width = 10;
int append = 0;
bool start_set = false, stop_set = false, at_set = false;

Expand Down Expand Up @@ -2781,6 +2785,12 @@ struct SimPass : public Pass {
append = atoi(args[++argidx].c_str());
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()) {
std::string map_filename = args[++argidx];
rewrite_filename(map_filename);
Expand Down Expand Up @@ -2872,7 +2882,7 @@ struct SimPass : public Pass {
}

if (worker.sim_filename.empty())
worker.run(top_mod, numcycles);
worker.run(top_mod, cycle_width, numcycles);
else {
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) ||
Expand All @@ -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) {
if (worker.map_filename.empty())
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) {
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) {
worker.run_cosim_yw_witness(top_mod, append);
worker.run_cosim_yw_witness(top_mod, cycle_width, append);
} else {
log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename);
}
Expand Down
16 changes: 8 additions & 8 deletions tests/sim/sim_cycles.ys
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,45 @@ read_verilog dff.v
prep

# 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

# final step is 41
logger -expect log "Co-simulating cycle 41" 2
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 -stop 202 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 41 -sim-cmp
logger -check-expected

# over limit stops at final step
logger -expect log "Co-simulating cycle 41" 2
sim -clock clk -r sim_cycles.fst -scope dff -n 30 -sim-cmp
# -stop warns for over limit
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

# don't auto step last
logger -expect log "Co-simulating cycle 40" 2
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 -stop 200 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 40 -sim-cmp
logger -check-expected

# -n 10 == -stop 100
# -n 10 == -stop 20
# should simulate up to 20 and not more
logger -expect log "Co-simulating cycle 20" 2
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 -stop 100 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 20 -sim-cmp
logger -check-expected

# -n 1 == -stop 10
# -n 1 == -stop 2
logger -expect log "Co-simulating cycle 2" 2
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 -stop 10 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 2 -sim-cmp
logger -check-expected

# -n 0 == -stop 0
Expand Down
Loading