108 lines
3.8 KiB
C++
108 lines
3.8 KiB
C++
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||
|
|
//*************************************************************************
|
||
|
|
// DESCRIPTION: Verilator: Resolve module/signal name references
|
||
|
|
//
|
||
|
|
// Code available from: https://verilator.org
|
||
|
|
//
|
||
|
|
//*************************************************************************
|
||
|
|
//
|
||
|
|
// Copyright 2003-2025 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
|
||
|
|
//
|
||
|
|
//*************************************************************************
|
||
|
|
// Visitor to build library mapping patterns from --libmap files, which may
|
||
|
|
// be overridden on command line with --work. Patterns are relative to
|
||
|
|
// libmap file location.
|
||
|
|
//*************************************************************************
|
||
|
|
|
||
|
|
#include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT
|
||
|
|
|
||
|
|
#include "V3LibMap.h"
|
||
|
|
|
||
|
|
#include "V3Graph.h"
|
||
|
|
#include "V3Options.h"
|
||
|
|
#include "V3Os.h"
|
||
|
|
#include "V3Parse.h"
|
||
|
|
#include "V3SymTable.h"
|
||
|
|
|
||
|
|
#include <unordered_set>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
VL_DEFINE_DEBUG_FUNCTIONS;
|
||
|
|
|
||
|
|
class LibMapVisitor final : public VNVisitor {
|
||
|
|
// STATE
|
||
|
|
string m_lib; // Library currently being mapped
|
||
|
|
string m_rel; // Relative path of current libmap file
|
||
|
|
|
||
|
|
// VISITORS
|
||
|
|
void visit(AstParseRef* nodep) override {
|
||
|
|
if (!m_lib.empty()) {
|
||
|
|
const string& pattern = nodep->name();
|
||
|
|
v3Global.libMapp()->addPattern(pattern, m_lib, m_rel);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void visit(AstLibrary* nodep) override {
|
||
|
|
VL_RESTORER(m_lib);
|
||
|
|
VL_RESTORER(m_rel);
|
||
|
|
m_lib = nodep->name();
|
||
|
|
m_rel = V3Os::filenameDir(nodep->fileline()->filename());
|
||
|
|
iterateChildren(nodep);
|
||
|
|
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||
|
|
}
|
||
|
|
|
||
|
|
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||
|
|
|
||
|
|
public:
|
||
|
|
// CONSTRUCTORS
|
||
|
|
LibMapVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||
|
|
};
|
||
|
|
|
||
|
|
//######################################################################
|
||
|
|
// LibMap class functions
|
||
|
|
|
||
|
|
string V3LibMap::matchMapping(const string& filename) {
|
||
|
|
// Check explicit mappings first
|
||
|
|
for (const auto& mapping : m_explicitMappings) {
|
||
|
|
const string& filepath = V3Os::filenameRelativePath(filename, mapping.base());
|
||
|
|
if (VString::wildmatch(filepath, mapping.pattern())) { return mapping.libname(); }
|
||
|
|
}
|
||
|
|
// Then check wildcard mappings
|
||
|
|
for (const auto& mapping : m_wildcardMappings) {
|
||
|
|
const string& filepath = V3Os::filenameRelativePath(filename, mapping.base());
|
||
|
|
if (VString::wildmatch(filepath, mapping.pattern())) { return mapping.libname(); }
|
||
|
|
}
|
||
|
|
// Then check directory mappings
|
||
|
|
for (const auto& mapping : m_directoryMappings) {
|
||
|
|
const string& filepath = V3Os::filenameRelativePath(filename, mapping.base());
|
||
|
|
const string& dirpart = V3Os::filenameDir(filepath);
|
||
|
|
if (VString::wildmatch(dirpart, mapping.pattern())) { return mapping.libname(); }
|
||
|
|
}
|
||
|
|
return "work";
|
||
|
|
}
|
||
|
|
|
||
|
|
void V3LibMap::addPattern(const string& pattern, const string& libname, const string& base) {
|
||
|
|
UINFO(4, __FUNCTION__ << ": pattern '" << pattern << "' => library '" << libname << "'");
|
||
|
|
|
||
|
|
bool isIncDir = pattern.back() == '/';
|
||
|
|
const string& nondir = V3Os::filenameNonDir(pattern);
|
||
|
|
const string& cleanPattern = V3Os::filenameCleanup(pattern);
|
||
|
|
|
||
|
|
if (isIncDir) {
|
||
|
|
m_directoryMappings.push_back({cleanPattern, libname, base});
|
||
|
|
} else if (nondir.find('*') != string::npos || nondir.find('?') != string::npos) {
|
||
|
|
m_wildcardMappings.push_back({cleanPattern, libname, base});
|
||
|
|
} else {
|
||
|
|
m_explicitMappings.push_back({cleanPattern, libname, base});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void V3LibMap::map(AstNetlist* nodep) {
|
||
|
|
UINFO(4, __FUNCTION__ << ": ");
|
||
|
|
{ LibMapVisitor{nodep}; }
|
||
|
|
}
|