Merge pull request #538 from QuantamHD/fix_param_union

Allows Union Types in Parameter Fields
diff --git a/systemverilog-plugin/Makefile b/systemverilog-plugin/Makefile
index e809349..525d43a 100644
--- a/systemverilog-plugin/Makefile
+++ b/systemverilog-plugin/Makefile
@@ -21,7 +21,6 @@
           uhdmastfrontend.cc \
           uhdmcommonfrontend.cc \
           uhdmsurelogastfrontend.cc \
-          uhdmastreport.cc \
           third_party/yosys/const2ast.cc \
           third_party/yosys/simplify.cc
 
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index bfc20b9..45240c2 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -309,51 +309,58 @@
     }
 }
 
-static size_t add_multirange_attribute(AST::AstNode *wire_node, const std::vector<AST::AstNode *> ranges)
+// Sets the `wire_node->multirange_dimensions` attribute and returns the total sizes of packed and unpacked ranges.
+static std::pair<size_t, size_t> set_multirange_dimensions(AST::AstNode *wire_node, const std::vector<AST::AstNode *> packed_ranges,
+                                                           const std::vector<AST::AstNode *> unpacked_ranges)
 {
     // node->multirange_dimensions stores dimensions' offsets and widths.
     // It shall have even number of elements.
     // For a range of [A:B] it should be appended with {min(A,B)} and {max(A,B)-min(A,B)+1}
     // For a range of [A] it should be appended with {0} and {A}
 
-    size_t size = 1;
-    for (size_t i = 0; i < ranges.size(); i++) {
-        log_assert(AST_INTERNAL::current_ast_mod);
-        if (ranges[i]->children.size() == 1) {
-            ranges[i]->children.push_back(ranges[i]->children[0]->clone());
-        }
-        simplify_sv(ranges[i], wire_node);
-        while (simplify(ranges[i], true, false, false, 1, -1, false, false)) {
-        }
-        // this workaround case, where yosys doesn't follow id2ast and simplifies it to resolve constant
-        if (ranges[i]->children[0]->id2ast) {
-            simplify_sv(ranges[i]->children[0]->id2ast, ranges[i]->children[0]);
-            while (simplify(ranges[i]->children[0]->id2ast, true, false, false, 1, -1, false, false)) {
+    auto calc_range_size = [wire_node](const std::vector<AST::AstNode *> &ranges) -> size_t {
+        size_t size = 1;
+        for (size_t i = 0; i < ranges.size(); i++) {
+            log_assert(AST_INTERNAL::current_ast_mod);
+            simplify_sv(ranges[i], wire_node);
+            // If it's a range of [A], make it [A:A].
+            if (ranges[i]->children.size() == 1) {
+                ranges[i]->children.push_back(ranges[i]->children[0]->clone());
             }
-        }
-        if (ranges[i]->children[1]->id2ast) {
-            simplify_sv(ranges[i]->children[1]->id2ast, ranges[i]->children[1]);
-            while (simplify(ranges[i]->children[1]->id2ast, true, false, false, 1, -1, false, false)) {
+            while (simplify(ranges[i], true, false, false, 1, -1, false, false)) {
             }
-        }
-        simplify_sv(ranges[i], wire_node);
-        while (simplify(ranges[i], true, false, false, 1, -1, false, false)) {
-        }
-        log_assert(ranges[i]->children[0]->type == AST::AST_CONSTANT);
-        log_assert(ranges[i]->children[1]->type == AST::AST_CONSTANT);
+            // this workaround case, where yosys doesn't follow id2ast and simplifies it to resolve constant
+            if (ranges[i]->children[0]->id2ast) {
+                simplify_sv(ranges[i]->children[0]->id2ast, ranges[i]->children[0]);
+                while (simplify(ranges[i]->children[0]->id2ast, true, false, false, 1, -1, false, false)) {
+                }
+            }
+            if (ranges[i]->children[1]->id2ast) {
+                simplify_sv(ranges[i]->children[1]->id2ast, ranges[i]->children[1]);
+                while (simplify(ranges[i]->children[1]->id2ast, true, false, false, 1, -1, false, false)) {
+                }
+            }
+            simplify_sv(ranges[i], wire_node);
+            while (simplify(ranges[i], true, false, false, 1, -1, false, false)) {
+            }
+            log_assert(ranges[i]->children[0]->type == AST::AST_CONSTANT);
+            log_assert(ranges[i]->children[1]->type == AST::AST_CONSTANT);
 
-        const auto low = min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
-        const auto high = max(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
-        const auto elem_size = high - low + 1;
+            const auto low = min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
+            const auto high = max(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
+            const auto elem_size = high - low + 1;
 
-        wire_node->multirange_dimensions.push_back(low);
-        wire_node->multirange_dimensions.push_back(elem_size);
-        wire_node->multirange_swapped.push_back(ranges[i]->range_swapped);
-        size *= elem_size;
-    }
+            wire_node->multirange_dimensions.push_back(low);
+            wire_node->multirange_dimensions.push_back(elem_size);
+            wire_node->multirange_swapped.push_back(ranges[i]->range_swapped);
+            size *= elem_size;
+        }
+        return size;
+    };
+    size_t packed_size = calc_range_size(packed_ranges);
+    size_t unpacked_size = calc_range_size(unpacked_ranges);
     log_assert(wire_node->multirange_dimensions.size() % 2 == 0);
-
-    return size;
+    return {packed_size, unpacked_size};
 }
 
 static AST::AstNode *convert_range(AST::AstNode *id, int packed_ranges_size, int unpacked_ranges_size, int i)
@@ -669,8 +676,7 @@
     if (convert_node) {
         // if not already converted
         if (wire_node->multirange_dimensions.empty()) {
-            const size_t packed_size = add_multirange_attribute(wire_node, packed_ranges);
-            const size_t unpacked_size = add_multirange_attribute(wire_node, unpacked_ranges);
+            const auto [packed_size, unpacked_size] = set_multirange_dimensions(wire_node, packed_ranges, unpacked_ranges);
             if (packed_ranges.size() == 1 && unpacked_ranges.empty()) {
                 ranges.push_back(packed_ranges[0]->clone());
             } else if (unpacked_ranges.size() == 1 && packed_ranges.empty()) {
@@ -1957,7 +1963,6 @@
             }
         });
         cell_node->children.push_back(arg_node);
-        shared.report.mark_handled(port_h);
         vpi_release_handle(port_h);
     }
     vpi_release_handle(port_itr);
@@ -2428,33 +2433,28 @@
     case vpiLogicTypespec: {
         current_node->is_logic = true;
         visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-        shared.report.mark_handled(typespec_h);
         break;
     }
     case vpiByteTypespec: {
         current_node->is_signed = vpi_get(vpiSigned, typespec_h);
         packed_ranges.push_back(make_range(7, 0));
-        shared.report.mark_handled(typespec_h);
         break;
     }
     case vpiShortIntTypespec: {
         current_node->is_signed = vpi_get(vpiSigned, typespec_h);
         packed_ranges.push_back(make_range(15, 0));
-        shared.report.mark_handled(typespec_h);
         break;
     }
     case vpiIntTypespec:
     case vpiIntegerTypespec: {
         current_node->is_signed = vpi_get(vpiSigned, typespec_h);
         packed_ranges.push_back(make_range(31, 0));
-        shared.report.mark_handled(typespec_h);
         break;
     }
     case vpiTimeTypespec:
     case vpiLongIntTypespec: {
         current_node->is_signed = vpi_get(vpiSigned, typespec_h);
         packed_ranges.push_back(make_range(63, 0));
-        shared.report.mark_handled(typespec_h);
         break;
     }
     case vpiStructTypespec:
@@ -3116,7 +3116,6 @@
             } else {
                 visit_one_to_many({vpiRange}, net_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
             }
-            shared.report.mark_handled(net_h);
         } else if (net_type == vpiStructNet) {
             visit_one_to_one({vpiTypespec}, net_h, [&](AST::AstNode *node) {
                 if (node->str.empty()) {
@@ -3859,7 +3858,6 @@
         log_error("Unhandled list op, couldn't find parent node.");
     }
     // Do not create a node
-    shared.report.mark_handled(obj_h);
 }
 
 void UhdmAst::process_cast_op()
@@ -3870,7 +3868,6 @@
         delete node;
     });
     vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
-    shared.report.mark_handled(typespec_h);
     vpi_release_handle(typespec_h);
 }
 
@@ -4657,8 +4654,6 @@
                 // Skip '\' in cellName
                 typeNode->str = ifaceName + '.' + cellName.substr(1, cellName.length());
                 current_node->children.push_back(typeNode);
-                shared.report.mark_handled(actual_h);
-                shared.report.mark_handled(iface_h);
                 vpi_release_handle(iface_h);
             }
             break;
@@ -4671,7 +4666,6 @@
             }
             current_node->type = AST::AST_INTERFACEPORT;
             current_node->children.push_back(typeNode);
-            shared.report.mark_handled(actual_h);
             break;
         }
         case vpiLogicVar:
@@ -4679,7 +4673,6 @@
             current_node->is_logic = true;
             current_node->is_signed = vpi_get(vpiSigned, actual_h);
             visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-            shared.report.mark_handled(actual_h);
             break;
         }
         case vpiPackedArrayVar:
@@ -4693,15 +4686,12 @@
                 delete node;
             });
             visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-            shared.report.mark_handled(actual_h);
             break;
         case vpiPackedArrayNet:
             visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-            shared.report.mark_handled(actual_h);
             break;
         case vpiArrayVar:
             visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
-            shared.report.mark_handled(actual_h);
             break;
         case vpiEnumNet:
         case vpiStructNet:
@@ -4724,7 +4714,6 @@
             break;
         }
         }
-        shared.report.mark_handled(lowConn_h);
         vpi_release_handle(actual_h);
         vpi_release_handle(lowConn_h);
     }
@@ -4762,28 +4751,27 @@
 void UhdmAst::process_net()
 {
     current_node = make_ast_node(AST::AST_WIRE);
-    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
-    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
     auto net_type = vpi_get(vpiNetType, obj_h);
     current_node->is_reg = net_type == vpiReg;
     current_node->is_output = net_type == vpiOutput;
     current_node->is_logic = !current_node->is_reg;
     current_node->is_signed = vpi_get(vpiSigned, obj_h);
     visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
-        if (node && !node->str.empty()) {
+        if (!node)
+            return;
+        if (!node->str.empty()) {
             auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
             wiretype_node->str = node->str;
             // wiretype needs to be 1st node
             current_node->children.insert(current_node->children.begin(), wiretype_node);
             current_node->is_custom_type = true;
+        } else {
+            // Ranges from the typespec are copied to the current node as attributes.
+            // So that multiranges can be replaced with a single range as a node later.
+            copy_packed_unpacked_attribute(node, current_node);
         }
         delete node;
     });
-    if (vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h)) {
-        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-        vpi_release_handle(typespec_h);
-    }
-    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
 }
 
 void UhdmAst::process_parameter()
@@ -4801,18 +4789,15 @@
         case vpiLogicTypespec: {
             current_node->is_logic = true;
             visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiByteTypespec: {
             packed_ranges.push_back(make_range(7, 0));
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiEnumTypespec:
         case vpiRealTypespec:
         case vpiStringTypespec: {
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiIntTypespec:
@@ -4821,18 +4806,15 @@
             if (packed_ranges.empty()) {
                 packed_ranges.push_back(make_range(31, 0));
             }
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiShortIntTypespec: {
             packed_ranges.push_back(make_range(15, 0));
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiTimeTypespec:
         case vpiLongIntTypespec: {
             packed_ranges.push_back(make_range(63, 0));
-            shared.report.mark_handled(typespec_h);
             break;
         }
         case vpiUnionTypespec:
@@ -4855,7 +4837,6 @@
         }
         case vpiPackedArrayTypespec:
         case vpiArrayTypespec: {
-            shared.report.mark_handled(typespec_h);
             visit_one_to_one({vpiElemTypespec}, typespec_h, [&](AST::AstNode *node) {
                 if (!node->str.empty()) {
                     auto wiretype_node = make_ast_node(AST::AST_WIRETYPE);
@@ -5346,7 +5327,6 @@
     // Check if we initialized the node in switch-case
     if (current_node) {
         if (current_node->type != AST::AST_NONE) {
-            shared.report.mark_handled(object);
             return current_node;
         }
     }
diff --git a/systemverilog-plugin/tests/Makefile b/systemverilog-plugin/tests/Makefile
index dcdbafd..3caff14 100644
--- a/systemverilog-plugin/tests/Makefile
+++ b/systemverilog-plugin/tests/Makefile
@@ -18,7 +18,6 @@
 		break_continue \
 		separate-compilation \
 		debug-flag \
-		report-flag \
 		defines \
 		defaults \
 		formal \
@@ -30,7 +29,6 @@
 break_continue_verify = $(call diff_test,break_continue,out)
 separate-compilation_verify = true
 debug-flag_verify = true
-report-flag_verify = true
 defaults_verify = true
 defines_verify = true
 formal_verify = true
diff --git a/systemverilog-plugin/tests/report-flag/report-flag-buf.sv b/systemverilog-plugin/tests/report-flag/report-flag-buf.sv
deleted file mode 100644
index 565946b..0000000
--- a/systemverilog-plugin/tests/report-flag/report-flag-buf.sv
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
deleted file mode 100644
index b0362fc..0000000
--- a/systemverilog-plugin/tests/report-flag/report-flag-pkg.sv
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index d49a46b..0000000
--- a/systemverilog-plugin/tests/report-flag/report-flag.tcl
+++ /dev/null
@@ -1,14 +0,0 @@
-yosys -import
-if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
-yosys -import  ;# ingest plugin commands
-
-set TMP_DIR $::env(TEST_OUTPUT_PREFIX)/tmp
-file mkdir $TMP_DIR
-
-# Testing simple round-trip
-read_systemverilog -report $TMP_DIR -odir $TMP_DIR -defer $::env(DESIGN_TOP)-pkg.sv
-read_systemverilog -report $TMP_DIR -odir $TMP_DIR -defer $::env(DESIGN_TOP)-buf.sv
-read_systemverilog -report $TMP_DIR -odir $TMP_DIR -defer $::env(DESIGN_TOP).v
-read_systemverilog -report $TMP_DIR -odir $TMP_DIR -link
-hierarchy
-write_verilog
diff --git a/systemverilog-plugin/tests/report-flag/report-flag.v b/systemverilog-plugin/tests/report-flag/report-flag.v
deleted file mode 100644
index 5bd294a..0000000
--- a/systemverilog-plugin/tests/report-flag/report-flag.v
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 d8f782f..58bd36e 100644
--- a/systemverilog-plugin/uhdmastfrontend.cc
+++ b/systemverilog-plugin/uhdmastfrontend.cc
@@ -47,21 +47,8 @@
           make_new_object_with_optional_extra_true_arg<UHDM::SynthSubset>(&serializer, this->shared.nonSynthesizableObjects, false);
         synthSubset->listenDesigns(restoredDesigns);
         delete synthSubset;
-        if (this->shared.debug_flag || !this->report_directory.empty()) {
-            for (auto design : restoredDesigns) {
-                std::ofstream null_stream;
-#if UHDM_VERSION > 1057
-                UHDM::visit_object(design, this->shared.debug_flag ? std::cout : null_stream);
-#else
-                UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : null_stream);
-#endif
-            }
-        }
         UhdmAst uhdm_ast(this->shared);
         AST::AstNode *current_ast = uhdm_ast.visit_designs(restoredDesigns);
-        if (!this->report_directory.empty()) {
-            this->shared.report.write(this->report_directory);
-        }
         for (auto design : restoredDesigns)
             vpi_release_handle(design);
 
diff --git a/systemverilog-plugin/uhdmastreport.cc b/systemverilog-plugin/uhdmastreport.cc
deleted file mode 100644
index 10d6a94..0000000
--- a/systemverilog-plugin/uhdmastreport.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "uhdmastreport.h"
-#include "frontends/ast/ast.h"
-#include <fstream>
-#include <sys/stat.h>
-#include <uhdm/BaseClass.h>
-#include <unordered_set>
-
-namespace systemverilog_plugin
-{
-
-using namespace ::Yosys;
-
-void UhdmAstReport::mark_handled(const UHDM::BaseClass *object)
-{
-    handled_count_per_file.insert(std::make_pair(object->VpiFile(), 0));
-    auto it = unhandled.find(object);
-    if (it != unhandled.end()) {
-        unhandled.erase(it);
-        handled_count_per_file.at(std::string(object->VpiFile()))++;
-    }
-}
-
-void UhdmAstReport::mark_handled(const vpiHandle obj_h)
-{
-    auto handle = reinterpret_cast<const uhdm_handle *>(obj_h);
-    mark_handled(reinterpret_cast<const UHDM::BaseClass *>(handle->object));
-}
-
-static std::string replace_in_string(std::string str, const std::string &to_find, const std::string &to_replace_with)
-{
-    size_t pos = str.find(to_find);
-    while (pos != std::string::npos) {
-        str.replace(pos, to_find.length(), to_replace_with);
-        pos += to_replace_with.length();
-        pos = str.find(to_find, pos);
-    }
-    return str;
-}
-
-void UhdmAstReport::write(const std::string &directory)
-{
-    std::unordered_map<std::string, std::unordered_set<unsigned>> unhandled_per_file;
-    for (auto object : unhandled) {
-        if (!object->VpiFile().empty() && object->VpiFile() != AST::current_filename) {
-            unhandled_per_file.insert(std::make_pair(object->VpiFile(), std::unordered_set<unsigned>()));
-            unhandled_per_file.at(std::string(object->VpiFile())).insert(object->VpiLineNo());
-            handled_count_per_file.insert(std::make_pair(object->VpiFile(), 0));
-        }
-    }
-    unsigned total_handled = 0;
-    for (auto &hc : handled_count_per_file) {
-        if (!hc.first.empty() && hc.first != AST::current_filename) {
-            unhandled_per_file.insert(std::make_pair(hc.first, std::unordered_set<unsigned>()));
-            total_handled += hc.second;
-        }
-    }
-    float coverage = total_handled * 100.f / (total_handled + unhandled.size());
-    mkdir(directory.c_str(), 0777);
-    std::ofstream index_file(directory + "/index.html");
-    index_file << "<!DOCTYPE html>\n<html>\n<head>\n<style>h3{margin:0;padding:10}</style>\n</head><body>" << std::endl;
-    index_file << "<h2>Overall coverage: " << coverage << "%</h2>" << std::endl;
-    for (auto &unhandled_in_file : unhandled_per_file) {
-        // Calculate coverage in file
-        unsigned handled_count = handled_count_per_file.at(unhandled_in_file.first);
-        unsigned unhandled_count = unhandled_in_file.second.size();
-        float coverage = handled_count * 100.f / (handled_count + unhandled_count);
-        // Add to the index file
-        std::string report_filename = replace_in_string(unhandled_in_file.first, "/", ".") + ".html";
-        index_file << "<h3>Cov: " << coverage << "%<a href=\"" << report_filename << "\">" << unhandled_in_file.first << "</a></h3><br>" << std::endl;
-        // Write the report file
-        std::ofstream report_file(directory + '/' + report_filename);
-        report_file << "<!DOCTYPE html>\n<html>\n<head>\n<style>\nbody{font-size:12px;}pre{display:inline}</style>\n</head><body>" << std::endl;
-        report_file << "<h2>" << unhandled_in_file.first << " | Coverage: " << coverage << "%</h2>" << std::endl;
-        std::ifstream source_file(unhandled_in_file.first); // Read the source code
-        unsigned line_number = 1;
-        std::string line;
-        while (std::getline(source_file, line)) {
-            if (unhandled_in_file.second.find(line_number) == unhandled_in_file.second.end()) {
-                report_file << line_number << "<pre> " << line << "</pre><br>" << std::endl;
-            } else {
-                report_file << line_number << "<pre style=\"background-color: #FFB6C1;\"> " << line << "</pre><br>" << std::endl;
-            }
-            ++line_number;
-        }
-        report_file << "</body>\n</html>" << std::endl;
-    }
-    index_file << "</body>\n</html>" << std::endl;
-}
-
-} // namespace systemverilog_plugin
diff --git a/systemverilog-plugin/uhdmastreport.h b/systemverilog-plugin/uhdmastreport.h
deleted file mode 100644
index e2403fc..0000000
--- a/systemverilog-plugin/uhdmastreport.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _UHDM_AST_REPORT_H_
-#define _UHDM_AST_REPORT_H_ 1
-
-#include "kernel/yosys.h"
-#include <map>
-#include <string>
-#include <unordered_map>
-#undef cover
-#include <uhdm/uhdm.h>
-
-namespace systemverilog_plugin
-{
-
-class UhdmAstReport
-{
-  private:
-    // Maps a filename to the number of objects being handled by the frontend
-    std::unordered_map<std::string, unsigned> handled_count_per_file;
-
-  public:
-    // Objects not being handled by the frontend
-    std::set<const UHDM::BaseClass *> unhandled;
-
-    // Marks the specified object as being handled by the frontend
-    void mark_handled(const UHDM::BaseClass *object);
-
-    // Marks the object referenced by the specified handle as being handled by the frontend
-    void mark_handled(vpiHandle obj_h);
-
-    // Write the coverage report to the specified path
-    void write(const std::string &directory);
-};
-
-} // namespace systemverilog_plugin
-
-#endif
diff --git a/systemverilog-plugin/uhdmastshared.h b/systemverilog-plugin/uhdmastshared.h
index ef4ea04..1dcd260 100644
--- a/systemverilog-plugin/uhdmastshared.h
+++ b/systemverilog-plugin/uhdmastshared.h
@@ -3,8 +3,13 @@
 
 #include "frontends/ast/ast.h"
 
-#include "uhdmastreport.h"
+// Yosys defines a 'cover' macro in implicitly included kernel/log.h
+// that clashes with cover-class in UHDM
+#undef cover
+
 #include <string>
+#include <uhdm/uhdm.h>
+#include <uhdm/vpi_user.h>
 #include <unordered_map>
 
 namespace systemverilog_plugin
@@ -80,9 +85,6 @@
     // Top nodes of the design (modules, interfaces)
     std::unordered_map<std::string, ::Yosys::AST::AstNode *> top_nodes;
 
-    // UHDM node coverage report
-    UhdmAstReport report;
-
     // Map from AST param nodes to their types (used for params with struct types)
     std::unordered_map<std::string, ::Yosys::AST::AstNode *> param_types;
 
diff --git a/systemverilog-plugin/uhdmcommonfrontend.cc b/systemverilog-plugin/uhdmcommonfrontend.cc
index 7fd3871..da7ac31 100644
--- a/systemverilog-plugin/uhdmcommonfrontend.cc
+++ b/systemverilog-plugin/uhdmcommonfrontend.cc
@@ -56,9 +56,6 @@
     log("    -dump_rtlil\n");
     log("        dump generated RTLIL netlist\n");
     log("\n");
-    log("    -report [directory]\n");
-    log("        write a coverage report for the UHDM file\n");
-    log("\n");
     log("    -defer\n");
     log("        only read the abstract syntax tree and defer actual compilation\n");
     log("        to a later 'hierarchy' command. Useful in cases where the default\n");
@@ -101,9 +98,6 @@
             dump_vlog1 = true;
             dump_vlog2 = true;
             this->shared.debug_flag = true;
-        } else if (args[i] == "-report" && ++i < args.size()) {
-            this->report_directory = args[i];
-            this->shared.stop_on_error = false;
         } else if (args[i] == "-noassert") {
             this->shared.no_assert = true;
         } else if (args[i] == "-defer") {
diff --git a/systemverilog-plugin/uhdmcommonfrontend.h b/systemverilog-plugin/uhdmcommonfrontend.h
index 4c10d10..324cada 100644
--- a/systemverilog-plugin/uhdmcommonfrontend.h
+++ b/systemverilog-plugin/uhdmcommonfrontend.h
@@ -48,7 +48,6 @@
 
 struct UhdmCommonFrontend : public ::Yosys::Frontend {
     UhdmAstShared shared;
-    std::string report_directory;
     std::vector<std::string> args;
     UhdmCommonFrontend(std::string name, std::string short_help) : Frontend(name, short_help) {}
     virtual void print_read_options();
diff --git a/systemverilog-plugin/uhdmsurelogastfrontend.cc b/systemverilog-plugin/uhdmsurelogastfrontend.cc
index 2d03e6f..40d7a37 100644
--- a/systemverilog-plugin/uhdmsurelogastfrontend.cc
+++ b/systemverilog-plugin/uhdmsurelogastfrontend.cc
@@ -189,17 +189,6 @@
         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_designs) {
-                std::ofstream null_stream;
-#if UHDM_VERSION > 1057
-                UHDM::visit_object(design, this->shared.debug_flag ? std::cout : null_stream);
-#else
-                UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : null_stream);
-#endif
-            }
-        }
-
         // on parse_only mode, don't try to load design
         // into yosys
         if (this->shared.parse_only)
@@ -221,9 +210,6 @@
 
         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);
-        }
 
         // FIXME: Check and reset remaining shared data
         this->shared.top_nodes.clear();