Files
OpenSTA/network/VerilogNamespace.cc
T

223 lines
5.6 KiB
C++
Raw Normal View History

2018-09-28 08:54:21 -07:00
// OpenSTA, Static Timing Analyzer
2026-03-10 13:21:17 -07:00
// Copyright (c) 2026, Parallax Software, Inc.
2018-09-28 08:54:21 -07: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
2022-01-04 10:17:08 -07:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2018-09-28 08:54:21 -07:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2022-01-04 10:17:08 -07:00
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2025-01-21 18:54:33 -07: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.
2018-09-28 08:54:21 -07:00
2020-04-05 14:53:44 -07:00
#include "VerilogNamespace.hh"
2020-04-05 11:35:51 -07:00
2023-06-15 08:59:56 -07:00
#include <cctype>
2020-04-05 11:35:51 -07:00
2020-04-05 14:53:44 -07:00
#include "ParseBus.hh"
2026-04-15 09:38:10 -07:00
#include "StringUtil.hh"
2018-09-28 08:54:21 -07:00
namespace sta {
2025-01-21 18:35:21 -07:00
constexpr char verilog_escape = '\\';
2026-03-02 12:13:13 -08:00
static std::string
2026-04-10 10:53:55 -07:00
staToVerilog(std::string_view sta_name);
2026-03-02 12:13:13 -08:00
static std::string
2026-04-10 10:53:55 -07:00
staToVerilog2(std::string_view sta_name);
2026-03-02 12:13:13 -08:00
static std::string
2026-04-15 09:38:10 -07:00
verilogToSta(std::string_view verilog_name);
2023-02-18 17:20:40 -07:00
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
cellVerilogName(std::string_view sta_name)
{
2025-01-21 18:35:21 -07:00
return staToVerilog(sta_name);
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
instanceVerilogName(std::string_view sta_name)
2018-09-28 08:54:21 -07:00
{
2025-01-21 18:35:21 -07:00
return staToVerilog(sta_name);
2018-09-28 08:54:21 -07:00
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
netVerilogName(std::string_view sta_name)
2018-09-28 08:54:21 -07:00
{
2023-03-26 06:34:36 -07:00
bool is_bus;
2026-03-02 12:13:13 -08:00
std::string bus_name;
int index;
2026-03-28 19:13:35 -07:00
parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index);
2023-03-26 06:34:36 -07:00
if (is_bus) {
2026-03-28 19:13:35 -07:00
std::string bus_vname = staToVerilog(bus_name);
2026-03-15 14:35:24 -07:00
std::string vname = bus_vname + '[' + std::to_string(index) + ']';
2019-08-12 22:56:32 -07:00
return vname;
}
else
2025-01-21 18:35:21 -07:00
return staToVerilog2(sta_name);
2018-09-28 08:54:21 -07:00
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
portVerilogName(std::string_view sta_name)
2018-09-28 08:54:21 -07:00
{
2025-01-21 18:35:21 -07:00
return staToVerilog2(sta_name);
2018-09-28 08:54:21 -07:00
}
2026-04-10 10:53:55 -07:00
// <cctype> functions expect a value representable as unsigned char or EOF.
static bool
isAlnumUnderscore(char ch)
{
return std::isalnum(static_cast<unsigned char>(ch)) != 0 || ch == '_';
}
2026-03-02 12:13:13 -08:00
static std::string
2026-04-10 10:53:55 -07:00
staToVerilog(std::string_view sta_name)
2018-09-28 08:54:21 -07:00
{
2023-02-18 17:20:40 -07:00
// Leave room for leading escape and trailing space if the name
// needs to be escaped.
// Assume the name has to be escaped and start copying while scanning.
2026-03-02 12:13:13 -08:00
std::string escaped_name = "\\";
2023-02-18 17:20:40 -07:00
bool escaped = false;
2026-03-15 14:35:24 -07:00
size_t sta_length = sta_name.size();
for (size_t i = 0; i < sta_length; i++) {
char ch = sta_name[i];
2025-01-21 18:35:21 -07:00
if (ch == verilog_escape) {
2026-03-03 00:48:15 +00:00
escaped = true;
2026-04-10 10:53:55 -07:00
if (i + 1 < sta_length) {
char next_ch = sta_name[i + 1];
if (next_ch == verilog_escape) {
escaped_name += next_ch;
i++;
}
2023-02-18 17:20:40 -07:00
}
2026-04-10 10:53:55 -07:00
else
escaped_name += ch;
2023-02-18 17:20:40 -07:00
}
else {
2026-04-10 10:53:55 -07:00
if (!isAlnumUnderscore(ch))
2026-01-03 16:59:35 -08:00
escaped = true;
2023-03-26 06:34:36 -07:00
escaped_name += ch;
2023-02-18 17:20:40 -07:00
}
2018-09-28 08:54:21 -07:00
}
2023-02-18 17:20:40 -07:00
if (escaped) {
// Add a terminating space.
2023-03-26 06:34:36 -07:00
escaped_name += ' ';
return escaped_name;
2023-02-18 17:20:40 -07:00
}
else
2026-04-10 10:53:55 -07:00
return std::string(sta_name);
2018-09-28 08:54:21 -07:00
}
2026-03-02 12:13:13 -08:00
static std::string
2026-04-10 10:53:55 -07:00
staToVerilog2(std::string_view sta_name)
2018-09-28 08:54:21 -07:00
{
2023-02-18 17:20:40 -07:00
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
2018-09-28 08:54:21 -07:00
// Leave room for leading escape and trailing space if the name
// needs to be escaped.
2026-03-02 12:13:13 -08:00
std::string escaped_name = "\\";
2018-09-28 08:54:21 -07:00
// Assume the name has to be escaped and start copying while scanning.
bool escaped = false;
2026-03-15 14:35:24 -07:00
size_t sta_length = sta_name.size();
for (size_t i = 0; i < sta_length; i++) {
char ch = sta_name[i];
2025-01-21 18:35:21 -07:00
if (ch == verilog_escape) {
2026-03-03 00:48:15 +00:00
escaped = true;
2026-04-10 10:53:55 -07:00
if (i + 1 < sta_length) {
char next_ch = sta_name[i + 1];
if (next_ch == verilog_escape) {
escaped_name += next_ch;
i++;
}
2018-09-28 08:54:21 -07:00
}
2026-04-10 10:53:55 -07:00
else
escaped_name += ch;
2018-09-28 08:54:21 -07:00
}
else {
bool is_brkt = (ch == bus_brkt_left || ch == bus_brkt_right);
2026-04-10 10:53:55 -07:00
if ((!isAlnumUnderscore(ch) && !is_brkt) || is_brkt)
2026-01-03 16:59:35 -08:00
escaped = true;
2023-03-26 06:34:36 -07:00
escaped_name += ch;
2018-09-28 08:54:21 -07:00
}
}
if (escaped) {
// Add a terminating space.
2023-03-26 06:34:36 -07:00
escaped_name += ' ';
return escaped_name;
2018-09-28 08:54:21 -07:00
}
else
2026-04-10 10:53:55 -07:00
return std::string(sta_name);
2018-09-28 08:54:21 -07:00
}
2023-02-18 17:20:40 -07:00
////////////////////////////////////////////////////////////////
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
moduleVerilogToSta(std::string_view module_name)
2023-02-18 17:20:40 -07:00
{
return verilogToSta(module_name);
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
instanceVerilogToSta(std::string_view inst_name)
2023-02-18 17:20:40 -07:00
{
return verilogToSta(inst_name);
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
netVerilogToSta(std::string_view net_name)
2023-02-18 17:20:40 -07:00
{
return verilogToSta(net_name);
}
2026-03-02 12:13:13 -08:00
std::string
2026-04-10 10:53:55 -07:00
portVerilogToSta(std::string_view port_name)
2023-02-18 17:20:40 -07:00
{
return verilogToSta(port_name);
}
2026-03-02 12:13:13 -08:00
static std::string
2026-04-10 10:53:55 -07:00
verilogToSta(std::string_view verilog_name)
2018-09-28 08:54:21 -07:00
{
2026-04-10 10:53:55 -07:00
if (verilog_name.empty())
return std::string(verilog_name);
2026-03-15 14:35:24 -07:00
if (verilog_name.front() == '\\') {
2023-02-18 17:20:40 -07:00
constexpr char divider = '/';
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
2026-03-15 14:35:24 -07:00
size_t verilog_name_length = verilog_name.size();
2026-04-10 10:53:55 -07:00
if (verilog_name_length > 1
&& std::isspace(static_cast<unsigned char>(verilog_name.back())) != 0)
2023-02-18 17:20:40 -07:00
verilog_name_length--;
2026-03-02 12:13:13 -08:00
std::string sta_name;
2025-01-21 18:35:21 -07:00
// Ignore leading '\'.
for (size_t i = 1; i < verilog_name_length; i++) {
2026-03-15 14:35:24 -07:00
char ch = verilog_name[i];
2023-02-18 17:20:40 -07:00
if (ch == bus_brkt_left
|| ch == bus_brkt_right
|| ch == divider
2025-01-21 18:35:21 -07:00
|| ch == verilog_escape)
2023-02-18 17:20:40 -07:00
// Escape bus brackets, dividers and escapes.
2026-01-03 16:59:35 -08:00
sta_name += verilog_escape;
2023-03-26 06:34:36 -07:00
sta_name += ch;
2018-09-28 08:54:21 -07:00
}
return sta_name;
}
else
2026-04-10 10:53:55 -07:00
return std::string(verilog_name);
2023-02-18 17:20:40 -07:00
}
2026-04-13 14:58:16 -07:00
} // namespace sta