2025-01-22 02:35:21 +01:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2026-03-10 21:21:17 +01:00
|
|
|
// Copyright (c) 2026, Parallax Software, Inc.
|
2025-01-22 02:35:21 +01:00
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2025-01-22 02:54:33 +01:00
|
|
|
//
|
|
|
|
|
// The origin of this software must not be misrepresented; you must not
|
|
|
|
|
// claim that you wrote the original software.
|
|
|
|
|
//
|
|
|
|
|
// Altered source versions must be plainly marked as such, and must not be
|
|
|
|
|
// misrepresented as being the original software.
|
|
|
|
|
//
|
|
|
|
|
// This notice may not be removed or altered from any source distribution.
|
2025-01-22 02:35:21 +01:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <string>
|
2026-03-15 22:35:24 +01:00
|
|
|
#include <string_view>
|
2026-01-04 01:59:35 +01:00
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
2025-01-22 02:35:21 +01:00
|
|
|
|
2026-03-15 22:35:24 +01:00
|
|
|
#include "Format.hh"
|
|
|
|
|
#include "Report.hh"
|
2026-03-08 23:39:41 +01:00
|
|
|
#include "StringUtil.hh"
|
2025-01-22 02:35:21 +01:00
|
|
|
#include "NetworkClass.hh"
|
|
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
class VerilogScanner;
|
|
|
|
|
class VerilogParse;
|
|
|
|
|
class Debug;
|
|
|
|
|
class Report;
|
|
|
|
|
class VerilogAttrEntry;
|
|
|
|
|
class VerilogAttrStmt;
|
|
|
|
|
class VerilogReader;
|
|
|
|
|
class VerilogStmt;
|
|
|
|
|
class VerilogNet;
|
|
|
|
|
class VerilogNetScalar;
|
|
|
|
|
class VerilogModule;
|
|
|
|
|
class VerilogInst;
|
|
|
|
|
class VerilogModuleInst;
|
|
|
|
|
class VerilogLibertyInst;
|
|
|
|
|
class VerilogDcl;
|
|
|
|
|
class VerilogDclBus;
|
|
|
|
|
class VerilogDclArg;
|
|
|
|
|
class VerilogAssign;
|
|
|
|
|
class VerilogNetConcat;
|
|
|
|
|
class VerilogNetConstant;
|
|
|
|
|
class VerilogNetBitSelect;
|
|
|
|
|
class VerilogNetPartSelect;
|
|
|
|
|
class StringRegistry;
|
|
|
|
|
class VerilogBindingTbl;
|
|
|
|
|
class VerilogNetNameIterator;
|
|
|
|
|
class VerilogNetPortRef;
|
|
|
|
|
class LibertyCell;
|
2026-03-15 22:35:24 +01:00
|
|
|
class VerilogErrorCmp;
|
|
|
|
|
|
|
|
|
|
class VerilogError
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
VerilogError(int id,
|
|
|
|
|
std::string_view filename,
|
|
|
|
|
int line,
|
|
|
|
|
std::string_view msg,
|
|
|
|
|
bool warn);
|
|
|
|
|
const char *msg() const { return msg_.c_str(); }
|
2026-03-29 04:13:35 +02:00
|
|
|
std::string_view filename() const { return filename_; }
|
2026-03-15 22:35:24 +01:00
|
|
|
int id() const { return id_; }
|
|
|
|
|
int line() const { return line_; }
|
|
|
|
|
bool warn() const { return warn_; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
int id_;
|
|
|
|
|
std::string filename_;
|
|
|
|
|
int line_;
|
|
|
|
|
std::string msg_;
|
|
|
|
|
bool warn_;
|
|
|
|
|
|
|
|
|
|
friend class VerilogErrorCmp;
|
|
|
|
|
};
|
2025-01-22 02:35:21 +01:00
|
|
|
|
2026-01-04 01:59:35 +01:00
|
|
|
using VerilogModuleMap = std::map<Cell*, VerilogModule*>;
|
|
|
|
|
using VerilogStmtSeq = std::vector<VerilogStmt*>;
|
|
|
|
|
using VerilogNetSeq = std::vector<VerilogNet*>;
|
|
|
|
|
using VerilogDclArgSeq = std::vector<VerilogDclArg*>;
|
|
|
|
|
using VerilogAttrStmtSeq = std::vector<VerilogAttrStmt*>;
|
|
|
|
|
using VerilogAttrEntrySeq = std::vector<VerilogAttrEntry*>;
|
|
|
|
|
using VerilogErrorSeq = std::vector<VerilogError*>;
|
2025-01-22 02:35:21 +01:00
|
|
|
|
|
|
|
|
class VerilogReader
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
VerilogReader(NetworkReader *network);
|
|
|
|
|
~VerilogReader();
|
2026-03-29 04:13:35 +02:00
|
|
|
bool read(std::string_view filename);
|
2025-01-22 02:35:21 +01:00
|
|
|
|
2026-03-29 04:13:35 +02:00
|
|
|
void makeModule(std::string &&module_name,
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogNetSeq *ports,
|
|
|
|
|
VerilogStmtSeq *stmts,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
2026-03-29 04:13:35 +02:00
|
|
|
void makeModule(std::string &&module_name,
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogStmtSeq *port_dcls,
|
|
|
|
|
VerilogStmtSeq *stmts,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
|
|
|
|
VerilogDcl *makeDcl(PortDirection *dir,
|
|
|
|
|
VerilogDclArgSeq *args,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
|
|
|
|
VerilogDcl *makeDcl(PortDirection *dir,
|
|
|
|
|
VerilogDclArg *arg,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogDclArg *makeDclArg(std::string &&net_name);
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogDclArg*makeDclArg(VerilogAssign *assign);
|
|
|
|
|
VerilogDclBus *makeDclBus(PortDirection *dir,
|
|
|
|
|
int from_index,
|
|
|
|
|
int to_index,
|
|
|
|
|
VerilogDclArg *arg,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
|
|
|
|
VerilogDclBus *makeDclBus(PortDirection *dir,
|
|
|
|
|
int from_index,
|
|
|
|
|
int to_index,
|
|
|
|
|
VerilogDclArgSeq *args,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
int line);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogInst *makeModuleInst(std::string &&module_name,
|
|
|
|
|
std::string &&inst_name,
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogNetSeq *pins,
|
|
|
|
|
VerilogAttrStmtSeq *attr_stmts,
|
|
|
|
|
const int line);
|
|
|
|
|
VerilogAssign *makeAssign(VerilogNet *lhs,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogNet *rhs,
|
|
|
|
|
int line);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetScalar *makeNetScalar(std::string &&name);
|
|
|
|
|
VerilogNetPortRef *makeNetNamedPortRefScalarNet(std::string &&port_vname);
|
|
|
|
|
VerilogNetPortRef *makeNetNamedPortRefScalarNet(std::string &&port_name,
|
|
|
|
|
std::string &&net_name);
|
|
|
|
|
VerilogNetPortRef *makeNetNamedPortRefBitSelect(std::string &&port_name,
|
|
|
|
|
std::string &&bus_name,
|
2026-01-04 01:59:35 +01:00
|
|
|
int index);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetPortRef *makeNetNamedPortRefScalar(std::string &&port_name,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogNet *net);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetPortRef *makeNetNamedPortRefBit(std::string &&port_name,
|
2026-01-04 01:59:35 +01:00
|
|
|
int index,
|
|
|
|
|
VerilogNet *net);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetPortRef *makeNetNamedPortRefPart(std::string &&port_name,
|
2026-01-04 01:59:35 +01:00
|
|
|
int from_index,
|
|
|
|
|
int to_index,
|
|
|
|
|
VerilogNet *net);
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogNetConcat *makeNetConcat(VerilogNetSeq *nets);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetConstant *makeNetConstant(std::string &&constant,
|
|
|
|
|
int line);
|
|
|
|
|
VerilogNetBitSelect *makeNetBitSelect(std::string &&name,
|
2026-01-04 01:59:35 +01:00
|
|
|
int index);
|
2026-03-29 04:13:35 +02:00
|
|
|
VerilogNetPartSelect *makeNetPartSelect(std::string &&name,
|
2026-01-04 01:59:35 +01:00
|
|
|
int from_index,
|
|
|
|
|
int to_index);
|
2025-01-22 02:35:21 +01:00
|
|
|
VerilogModule *module(Cell *cell);
|
2026-03-29 04:13:35 +02:00
|
|
|
Instance *linkNetwork(std::string_view top_cell_name,
|
2026-01-04 01:59:35 +01:00
|
|
|
bool make_black_boxes,
|
2025-02-05 22:32:08 +01:00
|
|
|
bool delete_modules);
|
2026-03-29 04:13:35 +02:00
|
|
|
std::string_view filename() const { return filename_; }
|
2025-01-22 02:35:21 +01:00
|
|
|
void incrLine();
|
|
|
|
|
Report *report() const { return report_; }
|
2026-03-15 22:35:24 +01:00
|
|
|
template <typename... Args>
|
2025-01-22 02:35:21 +01:00
|
|
|
void error(int id,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view filename,
|
2026-01-04 01:59:35 +01:00
|
|
|
int line,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view fmt,
|
|
|
|
|
Args &&...args)
|
|
|
|
|
{
|
|
|
|
|
report_->fileError(id, filename, line, fmt, std::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
template <typename... Args>
|
2025-01-22 02:35:21 +01:00
|
|
|
void warn(int id,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view filename,
|
2026-01-04 01:59:35 +01:00
|
|
|
int line,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view fmt,
|
|
|
|
|
Args &&...args)
|
|
|
|
|
{
|
|
|
|
|
report_->fileWarn(id, filename, line, fmt, std::forward<Args>(args)...);
|
|
|
|
|
}
|
2025-04-12 01:59:48 +02:00
|
|
|
const std::string &zeroNetName() const { return zero_net_name_; }
|
|
|
|
|
const std::string &oneNetName() const { return one_net_name_; }
|
2025-01-22 02:35:21 +01:00
|
|
|
void deleteModules();
|
2025-04-12 01:59:48 +02:00
|
|
|
const std::string &constant10Max() const { return constant10_max_; }
|
2025-01-22 02:35:21 +01:00
|
|
|
|
|
|
|
|
protected:
|
2026-03-29 04:13:35 +02:00
|
|
|
void init(std::string_view filename);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeCellPorts(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModule *module,
|
|
|
|
|
VerilogNetSeq *ports);
|
2025-01-22 02:35:21 +01:00
|
|
|
Port *makeCellPort(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModule *module,
|
|
|
|
|
const std::string &port_name);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeNamedPortRefCellPorts(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModule *module,
|
|
|
|
|
VerilogNet *mod_port,
|
2026-03-08 23:55:12 +01:00
|
|
|
StringSet &port_names);
|
2025-01-22 02:35:21 +01:00
|
|
|
void checkModuleDcls(VerilogModule *module,
|
2026-01-04 01:59:35 +01:00
|
|
|
std::set<std::string> &port_names);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeModuleInstBody(VerilogModule *module,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *inst,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
bool make_black_boxes);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeModuleInstNetwork(VerilogModuleInst *mod_inst,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *parent,
|
|
|
|
|
VerilogModule *parent_module,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool make_black_boxes);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeLibertyInst(VerilogLibertyInst *lib_inst,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *parent,
|
|
|
|
|
VerilogModule *parent_module,
|
|
|
|
|
VerilogBindingTbl *parent_bindings);
|
2025-01-22 02:35:21 +01:00
|
|
|
void bindGlobalNets(VerilogBindingTbl *bindings);
|
|
|
|
|
void makeNamedInstPins1(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *inst,
|
|
|
|
|
VerilogModuleInst *mod_inst,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
Instance *parent,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool is_leaf);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeNamedInstPins(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *inst,
|
|
|
|
|
VerilogModuleInst *mod_inst,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
Instance *parent,
|
|
|
|
|
VerilogModule *parent_module,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool is_leaf);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeOrderedInstPins(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
Instance *inst,
|
|
|
|
|
VerilogModuleInst *mod_inst,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
Instance *parent,
|
|
|
|
|
VerilogModule *parent_module,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool is_leaf);
|
2025-01-22 02:35:21 +01:00
|
|
|
void mergeAssignNet(VerilogAssign *assign,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModule *module,
|
|
|
|
|
Instance *inst,
|
|
|
|
|
VerilogBindingTbl *bindings);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeInstPin(Instance *inst,
|
2026-01-04 01:59:35 +01:00
|
|
|
Port *port,
|
|
|
|
|
VerilogNetNameIterator *net_name_iter,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
Instance *parent,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool is_leaf);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeInstPin(Instance *inst,
|
2026-01-04 01:59:35 +01:00
|
|
|
Port *port,
|
|
|
|
|
const std::string &net_name,
|
|
|
|
|
VerilogBindingTbl *bindings,
|
|
|
|
|
Instance *parent,
|
|
|
|
|
VerilogBindingTbl *parent_bindings,
|
|
|
|
|
bool is_leaf);
|
2026-03-15 22:35:24 +01:00
|
|
|
template <typename... Args>
|
2025-01-22 02:35:21 +01:00
|
|
|
void linkWarn(int id,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view filename,
|
2026-01-04 01:59:35 +01:00
|
|
|
int line,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view msg,
|
|
|
|
|
Args &&...args)
|
|
|
|
|
{
|
|
|
|
|
std::string msg_str = sta::formatRuntime(msg, std::forward<Args>(args)...);
|
|
|
|
|
link_errors_.push_back(new VerilogError(id, filename, line, msg_str, true));
|
|
|
|
|
}
|
|
|
|
|
template <typename... Args>
|
2025-01-22 02:35:21 +01:00
|
|
|
void linkError(int id,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view filename,
|
2026-01-04 01:59:35 +01:00
|
|
|
int line,
|
2026-03-15 22:35:24 +01:00
|
|
|
std::string_view msg,
|
|
|
|
|
Args &&...args)
|
|
|
|
|
{
|
|
|
|
|
std::string msg_str = sta::formatRuntime(msg, std::forward<Args>(args)...);
|
|
|
|
|
link_errors_.push_back(new VerilogError(id, filename, line, msg_str, false));
|
|
|
|
|
}
|
2025-01-22 02:35:21 +01:00
|
|
|
bool reportLinkErrors();
|
|
|
|
|
bool haveLinkErrors();
|
|
|
|
|
Cell *makeBlackBox(VerilogModuleInst *mod_inst,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModule *parent_module);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeBlackBoxNamedPorts(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModuleInst *mod_inst,
|
|
|
|
|
VerilogModule *parent_module);
|
2025-01-22 02:35:21 +01:00
|
|
|
void makeBlackBoxOrderedPorts(Cell *cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogModuleInst *mod_inst,
|
|
|
|
|
VerilogModule *parent_module);
|
2025-01-22 02:35:21 +01:00
|
|
|
bool isBlackBox(Cell *cell);
|
|
|
|
|
bool hasScalarNamedPortRefs(LibertyCell *liberty_cell,
|
2026-01-04 01:59:35 +01:00
|
|
|
VerilogNetSeq *pins);
|
2025-01-22 02:35:21 +01:00
|
|
|
|
2025-04-12 01:59:48 +02:00
|
|
|
std::string filename_;
|
2025-01-22 02:35:21 +01:00
|
|
|
Report *report_;
|
|
|
|
|
Debug *debug_;
|
|
|
|
|
NetworkReader *network_;
|
|
|
|
|
|
|
|
|
|
Library *library_;
|
|
|
|
|
int black_box_index_;
|
|
|
|
|
VerilogModuleMap module_map_;
|
|
|
|
|
VerilogErrorSeq link_errors_;
|
2025-04-12 01:59:48 +02:00
|
|
|
const std::string zero_net_name_;
|
|
|
|
|
const std::string one_net_name_;
|
|
|
|
|
std::string constant10_max_;
|
2025-01-22 02:35:21 +01:00
|
|
|
ViewType *view_type_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace sta
|