| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| #ifndef OPENTITAN_HW_DV_VERILATOR_CPP_SV_SCOPED_H_ |
| #define OPENTITAN_HW_DV_VERILATOR_CPP_SV_SCOPED_H_ |
| |
| #include <cassert> |
| #include <stdexcept> |
| #include <string> |
| #include <svdpi.h> |
| |
| /** |
| * Wrapper and guard class for SV Scope |
| * |
| * Call the constructor with a string for the scope that should be used. If |
| * this string starts with '.', it is taken to be a name relative to the |
| * current scope. Multiple periods at the start of the string move up in the |
| * tree (like Python imports). |
| * |
| * If the resolved scope cannot be found, the constructor leaves the current |
| * scope unchanged and throws an SVScoped::Error detailing the non-existent |
| * scope it tried to use. |
| * |
| * For example, if the current scope has name "TOP.foo.bar", then the string |
| * ".baz" resolves to the scope with name "TOP.foo.bar.baz". The string "..baz" |
| * resolves to the scope with name "TOP.foo.baz". The string "qux" resolves to |
| * the scope with name "qux". |
| * |
| * This guard restores the previous scope at destruction. |
| */ |
| class SVScoped { |
| public: |
| SVScoped(const std::string &name); |
| ~SVScoped() { svSetScope(prev_scope_); } |
| |
| class Error : public std::exception { |
| public: |
| Error(const std::string &scope_name); |
| const char *what() const noexcept override { return msg_.c_str(); } |
| |
| std::string scope_name_; |
| |
| private: |
| std::string msg_; |
| }; |
| |
| // helper function to join two, possibly relative, scopes correctly. |
| static std::string join_sv_scopes(const std::string &a, const std::string &b); |
| |
| private: |
| svScope prev_scope_; |
| }; |
| |
| #endif // OPENTITAN_HW_DV_VERILATOR_CPP_SV_SCOPED_H_ |