mirror of
https://github.com/verilator/verilator.git
synced 2024-12-29 10:47:34 +00:00
parent
de44ca8df3
commit
947b6fd23f
@ -357,6 +357,7 @@ detailed descriptions of these arguments.
|
||||
--dumpi-tree-json <level> Enable dumping Ast .tree.json files at level
|
||||
--dumpi-<srcfile> <level> Enable dumping everything in source file at level
|
||||
-E Preprocess, but do not compile
|
||||
--emit-accessors Emit getter and setter methods for model top class
|
||||
--error-limit <value> Abort after this number of errors
|
||||
--exe Link to create executable
|
||||
--expand-limit <value> Set expand optimization limit
|
||||
|
@ -483,6 +483,12 @@ Summary:
|
||||
See also :vlopt:`--dump-defines`, :vlopt:`-P`, and
|
||||
:vlopt:`--pp-comments` options.
|
||||
|
||||
.. option:: --emit-accessors
|
||||
|
||||
Emit getter and setter methods for each top-level signal in the
|
||||
model top class. Signals are still available as public members,
|
||||
but with the `__Vm_sig_` prefix.
|
||||
|
||||
.. option:: --error-limit <value>
|
||||
|
||||
After this number of errors are encountered during Verilator run, exit.
|
||||
|
@ -227,6 +227,15 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) {
|
||||
}
|
||||
}
|
||||
|
||||
void EmitCBaseVisitorConst::emitVarAccessors(const AstVar* nodep) {
|
||||
assert(nodep->name().rfind("__Vm_sig_") == 0 && nodep->isIO());
|
||||
const string privateName = nodep->name();
|
||||
const string publicName = nodep->name().substr(strlen("__Vm_sig_"));
|
||||
|
||||
puts("decltype("s + privateName + ") "s + publicName + "() {return "s + privateName + ";}\n");
|
||||
puts("void "s + publicName + "(decltype(" + privateName + ") v) {"s + privateName + "=v;}\n");
|
||||
}
|
||||
|
||||
void EmitCBaseVisitorConst::emitModCUse(const AstNodeModule* modp, VUseType useType) {
|
||||
bool nl = false;
|
||||
forModCUse(modp, useType, [&](string entry) {
|
||||
|
@ -118,6 +118,7 @@ public:
|
||||
void emitCFuncHeader(const AstCFunc* funcp, const AstNodeModule* modp, bool withScope);
|
||||
void emitCFuncDecl(const AstCFunc* funcp, const AstNodeModule* modp, bool cLinkage = false);
|
||||
void emitVarDecl(const AstVar* nodep, bool asRef = false);
|
||||
void emitVarAccessors(const AstVar* nodep);
|
||||
template <typename F>
|
||||
static void forModCUse(const AstNodeModule* modp, VUseType useType, F action) {
|
||||
for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) {
|
||||
|
@ -118,6 +118,17 @@ class EmitCModel final : public EmitCFunc {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(v3Global.opt.emitAccessors()) {
|
||||
puts("\n// ACCESSORS\n"
|
||||
"// The application code should use these methods to\n"
|
||||
"// propagate new values into/out from the Verilated model\n"
|
||||
"// instead of using signal variables directly.\n");
|
||||
for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isPrimaryIO()) emitVarAccessors(varp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (optSystemC() && v3Global.usesTiming()) puts("sc_core::sc_event trigger_eval;\n");
|
||||
|
||||
// Cells instantiated by the top level (for access to /* verilator public */)
|
||||
|
@ -65,6 +65,10 @@ class NameVisitor final : public VNVisitorConst {
|
||||
nodep->name(newname);
|
||||
nodep->editCountInc();
|
||||
} else if (VN_IS(nodep, CFunc) && VN_AS(nodep, CFunc)->isConstructor()) {
|
||||
} else if (v3Global.opt.emitAccessors() && VN_IS(nodep, Var) && VN_AS(nodep, Var)->isSigPublic()) {
|
||||
const string newname = "__Vm_sig_" + nodep->name();
|
||||
nodep->name(newname);
|
||||
nodep->editCountInc();
|
||||
} else {
|
||||
renameKeywordCheck(nodep);
|
||||
}
|
||||
|
@ -1240,6 +1240,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
||||
if (flag) m_std = false;
|
||||
m_preprocOnly = flag;
|
||||
});
|
||||
DECL_OPTION("-emit-accessors", OnOff, &m_emitAccessors);
|
||||
DECL_OPTION("-error-limit", CbVal, static_cast<void (*)(int)>(&V3Error::errorLimit));
|
||||
DECL_OPTION("-exe", OnOff, &m_exe);
|
||||
DECL_OPTION("-expand-limit", CbVal,
|
||||
|
@ -250,6 +250,7 @@ private:
|
||||
bool m_decoration = true; // main switch: --decoration
|
||||
bool m_decorationNodes = false; // main switch: --decoration=nodes
|
||||
bool m_dpiHdrOnly = false; // main switch: --dpi-hdr-only
|
||||
bool m_emitAccessors = false; // main switch: --emit-accessors
|
||||
bool m_exe = false; // main switch: --exe
|
||||
bool m_flatten = false; // main switch: --flatten
|
||||
bool m_hierarchical = false; // main switch: --hierarchical
|
||||
@ -499,6 +500,7 @@ public:
|
||||
bool dumpTreeDot() const {
|
||||
return m_dumpLevel.count("tree-dot") && m_dumpLevel.at("tree-dot");
|
||||
}
|
||||
bool emitAccessors() const { return m_emitAccessors; }
|
||||
bool exe() const { return m_exe; }
|
||||
bool flatten() const { return m_flatten; }
|
||||
bool gmake() const { return m_gmake; }
|
||||
|
34
test_regress/t/t_emit_accessors.cpp
Normal file
34
test_regress/t/t_emit_accessors.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
#include <verilated.h>
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
Verilated::debug(0);
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
VM_PREFIX* topp = new VM_PREFIX;
|
||||
CData small_in1 = 0;
|
||||
CData small_in2 = 1;
|
||||
IData big_in = 0xffffffff;
|
||||
|
||||
topp->in1(small_in1);
|
||||
topp->in2(small_in2);
|
||||
topp->in3(big_in);
|
||||
topp->in4(big_in);
|
||||
|
||||
topp->eval();
|
||||
|
||||
assert(topp->out1() == 0);
|
||||
assert(topp->out2() == 0xffffffff);
|
||||
assert(topp->out3().at(0) == 1);
|
||||
|
||||
topp->final();
|
||||
VL_DO_DANGLING(delete topp, topp);
|
||||
}
|
23
test_regress/t/t_emit_accessors.pl
Executable file
23
test_regress/t/t_emit_accessors.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile(
|
||||
make_main => 0,
|
||||
verilator_flags2 => [
|
||||
"--emit-accessors",
|
||||
"--exe",
|
||||
"$Self->{t_dir}/$Self->{name}.cpp"
|
||||
],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
19
test_regress/t/t_emit_accessors.v
Normal file
19
test_regress/t/t_emit_accessors.v
Normal file
@ -0,0 +1,19 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t_emit_accessors(
|
||||
input bit in1,
|
||||
input bit in2,
|
||||
input logic [31:0] in3,
|
||||
input logic [31:0] in4,
|
||||
output bit out1,
|
||||
output logic [31:0] out2,
|
||||
output logic [77:0] out3
|
||||
);
|
||||
assign out1 = in1 & in2;
|
||||
assign out2 = in3 & in4;
|
||||
assign out3 = 1;
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user