Merge pull request #411 from antmicro/mglb/UhdmSurelogAstFrontendRTTI
systemverilog: use RTTI for resource management in UhdmSurelogAstFrontend
diff --git a/systemverilog-plugin/tests/Makefile b/systemverilog-plugin/tests/Makefile
index e078fa7..1843a05 100644
--- a/systemverilog-plugin/tests/Makefile
+++ b/systemverilog-plugin/tests/Makefile
@@ -16,10 +16,14 @@
TESTS = counter \
break_continue \
- separate-compilation
+ separate-compilation \
+ debug-flag \
+ report-flag
include $(shell pwd)/../../Makefile_test.common
counter_verify = true
break_continue_verify = $(call diff_test,break_continue,out)
separate-compilation_verify = true
+debug-flag_verify = true
+report-flag_verify = true
diff --git a/systemverilog-plugin/tests/debug-flag/debug-flag-buf.sv b/systemverilog-plugin/tests/debug-flag/debug-flag-buf.sv
new file mode 100644
index 0000000..565946b
--- /dev/null
+++ b/systemverilog-plugin/tests/debug-flag/debug-flag-buf.sv
@@ -0,0 +1,21 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module BUF (
+ input I,
+ output O
+);
+ assign O = I;
+endmodule;
diff --git a/systemverilog-plugin/tests/debug-flag/debug-flag-pkg.sv b/systemverilog-plugin/tests/debug-flag/debug-flag-pkg.sv
new file mode 100644
index 0000000..b0362fc
--- /dev/null
+++ b/systemverilog-plugin/tests/debug-flag/debug-flag-pkg.sv
@@ -0,0 +1,19 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+package pkg;
+ parameter BITS = 4;
+ parameter LOG2DELAY = 22;
+endpackage
diff --git a/systemverilog-plugin/tests/debug-flag/debug-flag.tcl b/systemverilog-plugin/tests/debug-flag/debug-flag.tcl
new file mode 100644
index 0000000..86cfee5
--- /dev/null
+++ b/systemverilog-plugin/tests/debug-flag/debug-flag.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
+yosys -import ;# ingest plugin commands
+
+set TMP_DIR /tmp
+if { [info exists ::env(TMPDIR) ] } {
+ set TMP_DIR $::env(TMPDIR)
+}
+
+# Testing simple round-trip
+read_systemverilog -debug -odir $TMP_DIR/debug-flag-test -defer $::env(DESIGN_TOP)-pkg.sv
+read_systemverilog -debug -odir $TMP_DIR/debug-flag-test -defer $::env(DESIGN_TOP)-buf.sv
+read_systemverilog -debug -odir $TMP_DIR/debug-flag-test -defer $::env(DESIGN_TOP).v
+read_systemverilog -debug -odir $TMP_DIR/debug-flag-test -link
+hierarchy
+write_verilog
diff --git a/systemverilog-plugin/tests/debug-flag/debug-flag.v b/systemverilog-plugin/tests/debug-flag/debug-flag.v
new file mode 100644
index 0000000..5bd294a
--- /dev/null
+++ b/systemverilog-plugin/tests/debug-flag/debug-flag.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module top (
+ input clk,
+ output [3:0] led
+);
+
+ wire bufg;
+ BUF bufgctrl (
+ .I(clk),
+ .O(bufg)
+ );
+ reg [pkg::BITS + pkg::LOG2DELAY-1 : 0] counter = 0;
+ always @(posedge bufg) begin
+ counter <= counter + 1;
+ end
+ assign led[3:0] = counter >> pkg::LOG2DELAY;
+endmodule
diff --git a/systemverilog-plugin/tests/report-flag/report-flag-buf.sv b/systemverilog-plugin/tests/report-flag/report-flag-buf.sv
new file mode 100644
index 0000000..565946b
--- /dev/null
+++ b/systemverilog-plugin/tests/report-flag/report-flag-buf.sv
@@ -0,0 +1,21 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module BUF (
+ input I,
+ output O
+);
+ assign O = I;
+endmodule;
diff --git a/systemverilog-plugin/tests/report-flag/report-flag-pkg.sv b/systemverilog-plugin/tests/report-flag/report-flag-pkg.sv
new file mode 100644
index 0000000..b0362fc
--- /dev/null
+++ b/systemverilog-plugin/tests/report-flag/report-flag-pkg.sv
@@ -0,0 +1,19 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+package pkg;
+ parameter BITS = 4;
+ parameter LOG2DELAY = 22;
+endpackage
diff --git a/systemverilog-plugin/tests/report-flag/report-flag.tcl b/systemverilog-plugin/tests/report-flag/report-flag.tcl
new file mode 100644
index 0000000..3a3cc6d
--- /dev/null
+++ b/systemverilog-plugin/tests/report-flag/report-flag.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
+yosys -import ;# ingest plugin commands
+
+set TMP_DIR /tmp
+if { [info exists ::env(TMPDIR) ] } {
+ set TMP_DIR $::env(TMPDIR)
+}
+
+# Testing simple round-trip
+read_systemverilog -report $TMP_DIR/report-flag-test -odir $TMP_DIR/report-flag-test -defer $::env(DESIGN_TOP)-pkg.sv
+read_systemverilog -report $TMP_DIR/report-flag-test -odir $TMP_DIR/report-flag-test -defer $::env(DESIGN_TOP)-buf.sv
+read_systemverilog -report $TMP_DIR/report-flag-test -odir $TMP_DIR/report-flag-test -defer $::env(DESIGN_TOP).v
+read_systemverilog -report $TMP_DIR/report-flag-test -odir $TMP_DIR/report-flag-test -link
+hierarchy
+write_verilog
diff --git a/systemverilog-plugin/tests/report-flag/report-flag.v b/systemverilog-plugin/tests/report-flag/report-flag.v
new file mode 100644
index 0000000..5bd294a
--- /dev/null
+++ b/systemverilog-plugin/tests/report-flag/report-flag.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module top (
+ input clk,
+ output [3:0] led
+);
+
+ wire bufg;
+ BUF bufgctrl (
+ .I(clk),
+ .O(bufg)
+ );
+ reg [pkg::BITS + pkg::LOG2DELAY-1 : 0] counter = 0;
+ always @(posedge bufg) begin
+ counter <= counter + 1;
+ end
+ assign led[3:0] = counter >> pkg::LOG2DELAY;
+endmodule
diff --git a/systemverilog-plugin/uhdmastfrontend.cc b/systemverilog-plugin/uhdmastfrontend.cc
index 0ee97c0..5925d06 100644
--- a/systemverilog-plugin/uhdmastfrontend.cc
+++ b/systemverilog-plugin/uhdmastfrontend.cc
@@ -50,8 +50,8 @@
delete synthSubset;
if (this->shared.debug_flag || !this->report_directory.empty()) {
for (auto design : restoredDesigns) {
- std::stringstream strstr;
- UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : strstr);
+ std::ofstream null_stream;
+ UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : null_stream);
}
}
UhdmAst uhdm_ast(this->shared);
diff --git a/systemverilog-plugin/uhdmsurelogastfrontend.cc b/systemverilog-plugin/uhdmsurelogastfrontend.cc
index 4f664c7..c11c861 100644
--- a/systemverilog-plugin/uhdmsurelogastfrontend.cc
+++ b/systemverilog-plugin/uhdmsurelogastfrontend.cc
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <unistd.h>
#endif
+#include <memory>
#include "Surelog/ErrorReporting/Report.h"
#include "Surelog/surelog.h"
@@ -41,42 +42,66 @@
YOSYS_NAMESPACE_BEGIN
-std::vector<vpiHandle> executeCompilation(SURELOG::SymbolTable *symbolTable, SURELOG::ErrorContainer *errors, SURELOG::CommandLineParser *clp,
- SURELOG::scompiler *compiler)
+// SURELOG::scompiler wrapper.
+// Owns UHDM/VPI resources used by designs returned from `execute`
+class Compiler
{
- bool success = true;
- bool noFatalErrors = true;
- unsigned int codedReturn = 0;
- clp->setWriteUhdm(false);
- errors->printMessages(clp->muteStdout());
- std::vector<vpiHandle> the_design;
- if (success && (!clp->help())) {
- compiler = SURELOG::start_compiler(clp);
- if (!compiler)
+ public:
+ Compiler() = default;
+ ~Compiler()
+ {
+ if (this->scompiler) {
+ SURELOG::shutdown_compiler(this->scompiler);
+ }
+ }
+
+ const std::vector<vpiHandle> &execute(std::unique_ptr<SURELOG::ErrorContainer> errors, std::unique_ptr<SURELOG::CommandLineParser> clp)
+ {
+ log_assert(!this->errors && !this->clp && !this->scompiler);
+
+ bool success = true;
+ bool noFatalErrors = true;
+ unsigned int codedReturn = 0;
+ clp->setWriteUhdm(false);
+ errors->printMessages(clp->muteStdout());
+ if (success && (!clp->help())) {
+ this->scompiler = SURELOG::start_compiler(clp.get());
+ if (!this->scompiler)
+ codedReturn |= 1;
+ this->designs.push_back(SURELOG::get_uhdm_design(this->scompiler));
+ }
+ SURELOG::ErrorContainer::Stats stats;
+ if (!clp->help()) {
+ stats = errors->getErrorStats();
+ if (stats.nbFatal)
+ codedReturn |= 1;
+ if (stats.nbSyntax)
+ codedReturn |= 2;
+ }
+ bool noFErrors = true;
+ if (!clp->help())
+ noFErrors = errors->printStats(stats, clp->muteStdout());
+ if (noFErrors == false) {
+ noFatalErrors = false;
+ }
+ if ((!noFatalErrors) || (!success) || (errors->getErrorStats().nbError))
codedReturn |= 1;
- the_design.push_back(SURELOG::get_uhdm_design(compiler));
+ if (codedReturn) {
+ log_error("Error when parsing design. Aborting!\n");
+ }
+
+ this->clp = std::move(clp);
+ this->errors = std::move(errors);
+
+ return this->designs;
}
- SURELOG::ErrorContainer::Stats stats;
- if (!clp->help()) {
- stats = errors->getErrorStats();
- if (stats.nbFatal)
- codedReturn |= 1;
- if (stats.nbSyntax)
- codedReturn |= 2;
- }
- bool noFErrors = true;
- if (!clp->help())
- noFErrors = errors->printStats(stats, clp->muteStdout());
- if (noFErrors == false) {
- noFatalErrors = false;
- }
- if ((!noFatalErrors) || (!success) || (errors->getErrorStats().nbError))
- codedReturn |= 1;
- if (codedReturn) {
- log_error("Error when parsing design. Aborting!\n");
- }
- return the_design;
-}
+
+ private:
+ std::unique_ptr<SURELOG::ErrorContainer> errors = nullptr;
+ std::unique_ptr<SURELOG::CommandLineParser> clp = nullptr;
+ SURELOG::scompiler *scompiler = nullptr;
+ std::vector<vpiHandle> designs = {};
+};
struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
UhdmSurelogAstFrontend(std::string name, std::string short_help) : UhdmCommonFrontend(name, short_help) {}
@@ -98,9 +123,9 @@
for (size_t i = 0; i < this->args.size(); ++i)
cstrings.push_back(const_cast<char *>(this->args[i].c_str()));
- SURELOG::SymbolTable *symbolTable = new SURELOG::SymbolTable();
- SURELOG::ErrorContainer *errors = new SURELOG::ErrorContainer(symbolTable);
- SURELOG::CommandLineParser *clp = new SURELOG::CommandLineParser(errors, symbolTable, false, false);
+ auto symbolTable = std::make_unique<SURELOG::SymbolTable>();
+ auto errors = std::make_unique<SURELOG::ErrorContainer>(symbolTable.get());
+ auto clp = std::make_unique<SURELOG::CommandLineParser>(errors.get(), symbolTable.get(), false, false);
bool success = clp->parseCommandLine(cstrings.size(), &cstrings[0]);
if (!success) {
log_error("Error parsing Surelog arguments!\n");
@@ -122,25 +147,21 @@
clp->setLink(true);
}
- SURELOG::scompiler *compiler = nullptr;
- const std::vector<vpiHandle> uhdm_design = executeCompilation(symbolTable, errors, clp, compiler);
+ Compiler compiler;
+ const auto &uhdm_designs = compiler.execute(std::move(errors), std::move(clp));
+
if (this->shared.debug_flag || !this->report_directory.empty()) {
- for (auto design : uhdm_design) {
- std::stringstream strstr;
- UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : strstr);
+ for (auto design : uhdm_designs) {
+ std::ofstream null_stream;
+ UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : null_stream);
}
}
- SURELOG::shutdown_compiler(compiler);
- delete clp;
- delete symbolTable;
- delete errors;
// on parse_only mode, don't try to load design
// into yosys
if (this->shared.parse_only)
return nullptr;
- UhdmAst uhdm_ast(this->shared);
if (this->shared.defer && !this->shared.link)
return nullptr;
@@ -151,11 +172,12 @@
UHDM::Serializer serializer;
UHDM::SynthSubset *synthSubset =
make_new_object_with_optional_extra_true_arg<UHDM::SynthSubset>(&serializer, this->shared.nonSynthesizableObjects, false);
- synthSubset->listenDesigns(uhdm_design);
+ synthSubset->listenDesigns(uhdm_designs);
delete synthSubset;
}
- AST::AstNode *current_ast = uhdm_ast.visit_designs(uhdm_design);
+ UhdmAst uhdm_ast(this->shared);
+ AST::AstNode *current_ast = uhdm_ast.visit_designs(uhdm_designs);
if (!this->report_directory.empty()) {
this->shared.report.write(this->report_directory);
}