blob: e9c75ff27746a35dd47a6449b5a87de7b7abdef2 [file] [log] [blame]
// 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_