Merge pull request #1929 from YosysHQ/eddie/select_unset
authorwhitequark <whitequark@whitequark.org>
Thu, 16 Apr 2020 22:09:25 +0000 (22:09 +0000)
committerGitHub <noreply@github.com>
Thu, 16 Apr 2020 22:09:25 +0000 (22:09 +0000)
select: add select -unset option

backends/cxxrtl/cxxrtl.cc
backends/cxxrtl/cxxrtl.h

index d1a855bf0f3f3c6254c2c61773e30420b2a74710..e4fa430f398725f3441c647eb4fcedd9842b6f50 100644 (file)
@@ -1166,8 +1166,7 @@ struct CxxrtlWorker {
                });
 
                dump_attrs(memory);
-               f << indent << (writable_memories[memory] ? "" : "const ")
-                           << "memory<" << memory->width << "> " << mangle(memory)
+               f << indent << "memory<" << memory->width << "> " << mangle(memory)
                            << " { " << memory->size << "u";
                if (init_cells.empty()) {
                        f << " };\n";
@@ -1425,8 +1424,6 @@ struct CxxrtlWorker {
                                        if (cell->getPort(ID(CLK)).is_wire())
                                                register_edge_signal(sigmap, cell->getPort(ID(CLK)),
                                                        cell->parameters[ID(CLK_POLARITY)].as_bool() ? RTLIL::STp : RTLIL::STn);
-                                       // The $adff and $dffsr cells are level-sensitive, not edge-sensitive (in spite of the fact that they
-                                       // are inferred from an edge-sensitive Verilog process) and do not correspond to an edge-type sync rule.
                                }
                                // Similar for memory port cells.
                                if (cell->type.in(ID($memrd), ID($memwr))) {
@@ -1642,21 +1639,30 @@ struct CxxrtlBackend : public Backend {
                log("\n");
                log("    write_cxxrtl [options] [filename]\n");
                log("\n");
-               log("Write C++ code for simulating the design. The generated code requires a driver;\n");
-               log("the following simple driver is provided as an example:\n");
+               log("Write C++ code for simulating the design. The generated code requires a driver\n");
+               log("that instantiates the design, toggles its clock, and interacts with its ports.\n");
+               log("\n");
+               log("The following driver may be used as an example for a design with a single clock\n");
+               log("driving rising edge triggered flip-flops:\n");
                log("\n");
                log("    #include \"top.cc\"\n");
                log("\n");
                log("    int main() {\n");
                log("      cxxrtl_design::p_top top;\n");
+               log("      top.step();\n");
                log("      while (1) {\n");
-               log("        top.p_clk.next = value<1> {1u};\n");
-               log("        top.step();\n");
+               log("        /* user logic */\n");
                log("        top.p_clk.next = value<1> {0u};\n");
                log("        top.step();\n");
+               log("        top.p_clk.next = value<1> {1u};\n");
+               log("        top.step();\n");
                log("      }\n");
                log("    }\n");
                log("\n");
+               log("Note that CXXRTL simulations, just like the hardware they are simulating, are\n");
+               log("subject to race conditions. If, in then example above, the user logic would run\n");
+               log("simultaneously with the rising edge of the clock, the design would malfunction.\n");
+               log("\n");
                log("The following options are supported by this backend:\n");
                log("\n");
                log("    -header\n");
index 593c31c289b61059ba5e891ce7f1fb616377e4b4..fd390db7924beb5de8e4e6d2a568a8696d92a990 100644 (file)
@@ -604,12 +604,15 @@ struct memory {
                auto _ = {std::move(std::begin(init.data), std::end(init.data), data.begin() + init.offset)...};
        }
 
-       value<Width> &operator [](size_t index) {
+       // An operator for direct memory reads. May be used at any time during the simulation.
+       const value<Width> &operator [](size_t index) const {
                assert(index < data.size());
                return data[index];
        }
 
-       const value<Width> &operator [](size_t index) const {
+       // An operator for direct memory writes. May only be used before the simulation is started. If used
+       // after the simulation is started, the design may malfunction.
+       value<Width> &operator [](size_t index) {
                assert(index < data.size());
                return data[index];
        }