Error out if no top module given before 'sim'
[yosys.git] / passes / sat / sim.cc
index a80d89a81c154f0989010781b99f9f3fbd1f7922..4c3022c709d451d7a48d5f63800209025fb178ac 100644 (file)
@@ -29,8 +29,22 @@ struct SimShared
        bool debug = false;
        bool hide_internal = true;
        bool writeback = false;
+       bool zinit = false;
+       int rstlen = 1;
 };
 
+void zinit(State &v)
+{
+       if (v != State::S1)
+               v = State::S0;
+}
+
+void zinit(Const &v)
+{
+       for (auto &bit : v.bits)
+               zinit(bit);
+}
+
 struct SimInstance
 {
        SimShared *shared;
@@ -74,6 +88,8 @@ struct SimInstance
        SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) :
                        shared(shared), module(module), instance(instance), parent(parent), sigmap(module)
        {
+               log_assert(module);
+
                if (parent) {
                        log_assert(parent->children.count(instance) == 0);
                        parent->children[instance] = this;
@@ -148,6 +164,27 @@ struct SimInstance
                                formal_database.insert(cell);
                        }
                }
+
+               if (shared->zinit)
+               {
+                       for (auto &it : ff_database)
+                       {
+                               Cell *cell = it.first;
+                               ff_state_t &ff = it.second;
+                               zinit(ff.past_d);
+
+                               SigSpec qsig = cell->getPort("\\Q");
+                               Const qdata = get_state(qsig);
+                               zinit(qdata);
+                               set_state(qsig, qdata);
+                       }
+
+                       for (auto &it : mem_database) {
+                               mem_state_t &mem = it.second;
+                               zinit(mem.past_wr_en);
+                               zinit(mem.data);
+                       }
+               }
        }
 
        ~SimInstance()
@@ -491,7 +528,7 @@ struct SimInstance
        void writeback(pool<Module*> &wbmods)
        {
                if (wbmods.count(module))
-                       log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'singleton'.)\n", hiername().c_str(), log_id(module));
+                       log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'uniquify'.)\n", hiername().c_str(), log_id(module));
 
                wbmods.insert(module);
 
@@ -663,6 +700,9 @@ struct SimWorker : SimShared
                set_inports(reset, State::S1);
                set_inports(resetn, State::S0);
 
+               set_inports(clock, State::Sx);
+               set_inports(clockn, State::Sx);
+
                update();
 
                write_vcd_header();
@@ -687,7 +727,7 @@ struct SimWorker : SimShared
                        set_inports(clock, State::S1);
                        set_inports(clockn, State::S0);
 
-                       if (cycle == 0) {
+                       if (cycle+1 == rstlen) {
                                set_inports(reset, State::S0);
                                set_inports(resetn, State::S1);
                        }
@@ -707,7 +747,7 @@ struct SimWorker : SimShared
 
 struct SimPass : public Pass {
        SimPass() : Pass("sim", "simulate the circuit") { }
-       virtual void help()
+       void help() YS_OVERRIDE
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -730,11 +770,17 @@ struct SimPass : public Pass {
                log("    -resetn <portname>\n");
                log("        name of top-level inverted reset input (active low)\n");
                log("\n");
+               log("    -rstlen <integer>\n");
+               log("        number of cycles reset should stay active (default: 1)\n");
+               log("\n");
+               log("    -zinit\n");
+               log("        zero-initialize all uninitialized regs and memories\n");
+               log("\n");
                log("    -n <integer>\n");
                log("        number of cycles to simulate (default: 20)\n");
                log("\n");
                log("    -a\n");
-               log("        include all nets in VCD output, nut just those with public names\n");
+               log("        include all nets in VCD output, not just those with public names\n");
                log("\n");
                log("    -w\n");
                log("        writeback mode: use final simulation state as new init state\n");
@@ -743,7 +789,7 @@ struct SimPass : public Pass {
                log("        enable debug output\n");
                log("\n");
        }
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
        {
                SimWorker worker;
                int numcycles = 20;
@@ -760,6 +806,10 @@ struct SimPass : public Pass {
                                numcycles = atoi(args[++argidx].c_str());
                                continue;
                        }
+                       if (args[argidx] == "-rstlen" && argidx+1 < args.size()) {
+                               worker.rstlen = atoi(args[++argidx].c_str());
+                               continue;
+                       }
                        if (args[argidx] == "-clock" && argidx+1 < args.size()) {
                                worker.clock.insert(RTLIL::escape_id(args[++argidx]));
                                continue;
@@ -788,6 +838,10 @@ struct SimPass : public Pass {
                                worker.writeback = true;
                                continue;
                        }
+                       if (args[argidx] == "-zinit") {
+                               worker.zinit = true;
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
@@ -796,6 +850,9 @@ struct SimPass : public Pass {
 
                if (design->full_selection()) {
                        top_mod = design->top_module();
+
+                       if (!top_mod)
+                               log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n");
                } else {
                        auto mods = design->selected_whole_modules();
                        if (GetSize(mods) != 1)