aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-04-16 21:28:13 +0000
committerGitHub <noreply@github.com>2020-04-16 21:28:13 +0000
commitb4b2345a10babf055e01db0a3d91b51c3f79e3bf (patch)
treea9e491030d5cc8404a53ac76be3fc501eeac881d /backends
parent8d3f6d0d792a1cd688ce4d9c05bef8ec601f9334 (diff)
parent06c0338f2c19ca50675f3928de7fa19b05d304c4 (diff)
downloadyosys-b4b2345a10babf055e01db0a3d91b51c3f79e3bf.tar.gz
yosys-b4b2345a10babf055e01db0a3d91b51c3f79e3bf.tar.bz2
yosys-b4b2345a10babf055e01db0a3d91b51c3f79e3bf.zip
Merge pull request #1947 from whitequark/cxxrtl-usability
cxxrtl: minor documentation and usability improvements
Diffstat (limited to 'backends')
-rw-r--r--backends/cxxrtl/cxxrtl.cc22
-rw-r--r--backends/cxxrtl/cxxrtl.h7
2 files changed, 19 insertions, 10 deletions
diff --git a/backends/cxxrtl/cxxrtl.cc b/backends/cxxrtl/cxxrtl.cc
index d1a855bf0..e4fa430f3 100644
--- a/backends/cxxrtl/cxxrtl.cc
+++ b/backends/cxxrtl/cxxrtl.cc
@@ -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");
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index 593c31c28..fd390db79 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -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];
}