OpenSTA/sdf/SdfReader.cc

1122 lines
30 KiB
C++
Raw Normal View History

2018-09-28 17:54:21 +02:00
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, Parallax Software, Inc.
2018-09-28 17:54:21 +02: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
2018-09-28 17:54:21 +02:00
// 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/>.
2018-09-28 17:54:21 +02:00
2020-04-05 20:35:51 +02:00
#include "sdf/SdfReader.hh"
#include <cstdarg>
#include <cctype>
2020-04-05 20:35:51 +02:00
2020-04-05 23:53:44 +02:00
#include "Error.hh"
#include "Debug.hh"
2020-04-05 23:53:44 +02:00
#include "Report.hh"
#include "MinMax.hh"
#include "TimingArc.hh"
#include "Network.hh"
#include "SdcNetwork.hh"
#include "Graph.hh"
#include "Corner.hh"
#include "DcalcAnalysisPt.hh"
#include "Sdc.hh"
#include "sdf/SdfReaderPvt.hh"
2018-09-28 17:54:21 +02:00
extern int
SdfParse_parse();
extern int SdfParse_debug;
2018-09-28 17:54:21 +02:00
namespace sta {
class SdfTriple
{
public:
SdfTriple(float *min,
float *typ,
float *max);
~SdfTriple();
float **values() { return values_; }
bool hasValue() const;
private:
float *values_[3];
};
class SdfPortSpec
{
public:
SdfPortSpec(Transition *tr,
const char *port,
const char *cond);
~SdfPortSpec();
2018-09-28 17:54:21 +02:00
const char *port() const { return port_; }
Transition *transition() const { return tr_; }
const char *cond() const { return cond_; }
private:
Transition *tr_;
const char *port_;
const char *cond_; // timing checks only
};
2019-03-13 01:25:53 +01:00
SdfReader *sdf_reader = nullptr;
2018-09-28 17:54:21 +02:00
bool
readSdf(const char *filename,
const char *path,
Corner *corner,
bool unescaped_dividers,
bool incremental_only,
MinMaxAll *cond_use,
StaState *sta)
2018-09-28 17:54:21 +02:00
{
int arc_min_index = corner->findDcalcAnalysisPt(MinMax::min())->index();
int arc_max_index = corner->findDcalcAnalysisPt(MinMax::max())->index();
SdfReader reader(filename, path,
arc_min_index, arc_max_index,
sta->sdc()->analysisType(),
unescaped_dividers, incremental_only,
2018-09-28 17:54:21 +02:00
cond_use, sta);
sdf_reader = &reader;
bool success = reader.read();
sdf_reader = nullptr;
return success;
2018-09-28 17:54:21 +02:00
}
SdfReader::SdfReader(const char *filename,
const char *path,
int arc_min_index,
int arc_max_index,
AnalysisType analysis_type,
bool unescaped_dividers,
bool is_incremental_only,
MinMaxAll *cond_use,
StaState *sta) :
StaState(sta),
filename_(filename),
path_(path),
triple_min_index_(0),
triple_max_index_(2),
2018-09-28 17:54:21 +02:00
arc_delay_min_index_(arc_min_index),
arc_delay_max_index_(arc_max_index),
analysis_type_(analysis_type),
unescaped_dividers_(unescaped_dividers),
is_incremental_only_(is_incremental_only),
cond_use_(cond_use),
line_(1),
divider_('/'),
2018-09-28 17:54:21 +02:00
escape_('\\'),
2019-03-13 01:25:53 +01:00
instance_(nullptr),
cell_name_(nullptr),
2018-09-28 17:54:21 +02:00
in_timing_check_(false),
in_incremental_(false),
timescale_(1.0E-9F) // default units of ns
{
if (unescaped_dividers)
network_ = makeSdcNetwork(network_);
}
SdfReader::~SdfReader()
{
if (unescaped_dividers_)
delete network_;
}
bool
SdfReader::read()
{
// Use zlib to uncompress gzip'd files automagically.
stream_ = gzopen(filename_, "rb");
//::SdfParse_debug = 1;
2018-09-28 17:54:21 +02:00
if (stream_) {
// yyparse returns 0 on success.
bool success = (::SdfParse_parse() == 0);
gzclose(stream_);
return success;
}
else
throw FileNotReadable(filename_);
}
void
SdfReader::setDivider(char divider)
{
divider_ = divider;
}
void
SdfReader::setTimescale(float multiplier,
const char *units)
{
if (multiplier == 1.0
|| multiplier == 10.0
|| multiplier == 100.0) {
if (stringEq(units, "us"))
timescale_ = multiplier * 1E-6F;
else if (stringEq(units, "ns"))
timescale_ = multiplier * 1E-9F;
else if (stringEq(units, "ps"))
timescale_ = multiplier * 1E-12F;
else
2020-12-14 02:21:35 +01:00
sdfError(180, "TIMESCALE units not us, ns, or ps.");
2018-09-28 17:54:21 +02:00
}
else
2020-12-14 02:21:35 +01:00
sdfError(181, "TIMESCALE multiplier not 1, 10, or 100.");
2018-09-28 17:54:21 +02:00
stringDelete(units);
}
void
SdfReader::interconnect(const char *from_pin_name,
const char *to_pin_name,
SdfTripleSeq *triples)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)) {
Pin *from_pin = findPin(from_pin_name);
Pin *to_pin = findPin(to_pin_name);
if (from_pin && to_pin) {
// Assume the pins are non-hierarchical and on the same net.
Edge *edge = findWireEdge(from_pin, to_pin);
if (edge)
setEdgeDelays(edge, triples, "INTERCONNECT");
else {
bool from_is_hier = network_->isHierarchical(from_pin);
bool to_is_hier = network_->isHierarchical(to_pin);
if (from_is_hier || to_is_hier) {
if (from_is_hier)
2020-12-14 02:21:35 +01:00
sdfError(182, "pin %s is a hierarchical pin.", from_pin_name);
2018-09-28 17:54:21 +02:00
if (to_is_hier)
2020-12-14 02:21:35 +01:00
sdfError(183, "pin %s is a hierarchical pin.", to_pin_name);
2018-09-28 17:54:21 +02:00
}
else
2020-12-25 00:53:25 +01:00
sdfWarn(184, "INTERCONNECT from %s to %s not found.",
from_pin_name, to_pin_name);
2018-09-28 17:54:21 +02:00
}
}
else {
2019-03-13 01:25:53 +01:00
if (from_pin == nullptr)
2020-12-25 00:53:25 +01:00
sdfWarn(185, "pin %s not found.", from_pin_name);
2019-03-13 01:25:53 +01:00
if (to_pin == nullptr)
2020-12-25 00:53:25 +01:00
sdfWarn(186, "pin %s not found.", to_pin_name);
2018-09-28 17:54:21 +02:00
}
}
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
stringDelete(from_pin_name);
stringDelete(to_pin_name);
2018-09-28 17:54:21 +02:00
deleteTripleSeq(triples);
}
void
SdfReader::port(const char *to_pin_name,
SdfTripleSeq *triples)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)) {
Pin *to_pin = (instance_)
? network_->findPinRelative(instance_, to_pin_name)
: network_->findPin(to_pin_name);
2019-03-13 01:25:53 +01:00
if (to_pin == nullptr)
2020-12-25 00:53:25 +01:00
sdfWarn(187, "pin %s not found.", to_pin_name);
2018-09-28 17:54:21 +02:00
else {
Vertex *vertex = graph_->pinLoadVertex(to_pin);
VertexInEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
if (edge->role()->sdfRole()->isWire())
setEdgeDelays(edge, triples, "PORT");
}
}
}
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
stringDelete(to_pin_name);
2018-09-28 17:54:21 +02:00
deleteTripleSeq(triples);
}
Edge *
SdfReader::findWireEdge(Pin *from_pin,
Pin *to_pin)
{
Vertex *to_vertex, *to_vertex_bidirect_drvr;
graph_->pinVertices(to_pin, to_vertex, to_vertex_bidirect_drvr);
if (to_vertex) {
// Fanin < fanout, so search for driver from load.
VertexInEdgeIterator edge_iter(to_vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
const TimingRole *edge_role = edge->role();
if (edge->from(graph_)->pin() == from_pin
&& edge_role->sdfRole()->isWire())
return edge;
}
2018-09-28 17:54:21 +02:00
}
2019-03-13 01:25:53 +01:00
return nullptr;
2018-09-28 17:54:21 +02:00
}
void
SdfReader::setEdgeDelays(Edge *edge,
SdfTripleSeq *triples,
const char *sdf_cmd)
{
// Rise/fall triples.
size_t triple_count = triples->size();
if (triple_count == 1
|| triple_count == 2) {
TimingArcSet *arc_set = edge->timingArcSet();
for (TimingArc *arc : arc_set->arcs()) {
2018-09-28 17:54:21 +02:00
size_t triple_index;
if (triple_count == 1)
triple_index = 0;
else
triple_index = arc->toEdge()->sdfTripleIndex();
2018-09-28 17:54:21 +02:00
SdfTriple *triple = (*triples)[triple_index];
setEdgeArcDelays(edge, arc, triple);
}
}
else if (triple_count == 0)
2020-12-14 02:21:35 +01:00
sdfError(188, "%s with no triples.", sdf_cmd);
2018-09-28 17:54:21 +02:00
else
2020-12-14 02:21:35 +01:00
sdfError(189, "%s with more than 2 triples.", sdf_cmd);
2018-09-28 17:54:21 +02:00
}
void
SdfReader::setCell(const char *cell_name)
{
cell_name_ = cell_name;
}
void
SdfReader::setInstance(const char *instance_name)
{
if (instance_name) {
if (stringEq(instance_name, "*")) {
notSupported("INSTANCE wildcards");
2019-03-13 01:25:53 +01:00
instance_ = nullptr;
2018-09-28 17:54:21 +02:00
}
else {
instance_ = findInstance(instance_name);
if (instance_) {
Cell *inst_cell = network_->cell(instance_);
const char *inst_cell_name = network_->name(inst_cell);
if (cell_name_ && !stringEqual(inst_cell_name, cell_name_))
2020-12-25 00:53:25 +01:00
sdfWarn(190, "instance %s cell %s does not match enclosing cell %s.",
instance_name,
inst_cell_name,
cell_name_);
2018-09-28 17:54:21 +02:00
}
}
}
else
2019-03-13 01:25:53 +01:00
instance_ = nullptr;
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
stringDelete(instance_name);
2018-09-28 17:54:21 +02:00
}
void
SdfReader::setInstanceWildcard()
{
notSupported("INSTANCE wildcards");
2019-03-13 01:25:53 +01:00
instance_ = nullptr;
2018-09-28 17:54:21 +02:00
}
void
SdfReader::cellFinish()
{
stringDelete(cell_name_);
2019-03-13 01:25:53 +01:00
cell_name_ = nullptr;
instance_ = nullptr;
2018-09-28 17:54:21 +02:00
}
void
SdfReader::iopath(SdfPortSpec *from_edge,
const char *to_port_name,
SdfTripleSeq *triples,
const char *cond,
bool condelse)
{
if (instance_) {
const char *from_port_name = from_edge->port();
Cell *cell = network_->cell(instance_);
Port *from_port = findPort(cell, from_port_name);
Port *to_port = findPort(cell, to_port_name);
2018-09-28 17:54:21 +02:00
if (from_port && to_port) {
Pin *from_pin = network_->findPin(instance_, from_port_name);
Pin *to_pin = network_->findPin(instance_, to_port_name);
// Do not report an error if the pin is not found because the
// instance may not have the pin.
if (from_pin && to_pin) {
Vertex *to_vertex = graph_->pinDrvrVertex(to_pin);
if (to_vertex) {
size_t triple_count = triples->size();
bool matched = false;
// Fanin < fanout, so search for driver from load.
// Search for multiple matching edges because of
// tristate enable/disable.
VertexInEdgeIterator edge_iter(to_vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
TimingArcSet *arc_set = edge->timingArcSet();
const char *lib_cond = arc_set->sdfCond();
const TimingRole *edge_role = arc_set->role();
bool cond_use_flag = cond_use_ && cond && lib_cond == nullptr
&& !(!is_incremental_only_ && in_incremental_);
if (edge->from(graph_)->pin() == from_pin
&& edge_role->sdfRole() == TimingRole::sdfIopath()
&& (cond_use_flag
|| (!condelse && condMatch(cond, lib_cond))
// condelse matches the default (unconditional) arc.
|| (condelse && lib_cond == nullptr))) {
matched = true;
for (TimingArc *arc : arc_set->arcs()) {
if ((from_edge->transition() == Transition::riseFall())
|| (arc->fromEdge() == from_edge->transition())) {
size_t triple_index = arc->toEdge()->sdfTripleIndex();
SdfTriple *triple = nullptr;
if (triple_index < triple_count)
triple = (*triples)[triple_index];
if (triple_count == 1)
triple = (*triples)[0];
// Rules for matching when triple is missing not implemented.
// See SDF pg 3-17.
if (triple) {
if (cond_use_flag)
setEdgeArcDelaysCondUse(edge, arc, triple);
else
setEdgeArcDelays(edge, arc, triple);
}
}
}
}
}
if (!matched)
sdfWarn(191, "cell %s IOPATH %s -> %s not found.",
network_->cellName(instance_),
from_port_name,
to_port_name);
}
2018-09-28 17:54:21 +02:00
}
}
}
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
stringDelete(to_port_name);
2018-09-28 17:54:21 +02:00
deletePortSpec(from_edge);
deleteTripleSeq(triples);
stringDelete(cond);
}
Port *
SdfReader::findPort(const Cell *cell,
const char *port_name)
{
Port *port = network_->findPort(cell, port_name);
if (port == nullptr)
sdfWarn(194, "instance %s port %s not found.",
network_->pathName(instance_),
port_name);
return port;
2018-09-28 17:54:21 +02:00
}
void
SdfReader::timingCheck(TimingRole *role, SdfPortSpec *data_edge,
SdfPortSpec *clk_edge, SdfTriple *triple)
{
const char *data_port_name = data_edge->port();
const char *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name);
if (data_port && clk_port)
timingCheck1(role, data_port, data_edge, clk_port, clk_edge, triple);
2018-09-28 17:54:21 +02:00
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(triple);
}
void
SdfReader::timingCheck1(TimingRole *role,
Port *data_port,
2018-09-28 17:54:21 +02:00
SdfPortSpec *data_edge,
Port *clk_port,
2018-09-28 17:54:21 +02:00
SdfPortSpec *clk_edge,
SdfTriple *triple)
2018-09-28 17:54:21 +02:00
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
Pin *data_pin = network_->findPin(instance_, data_port);
Pin *clk_pin = network_->findPin(instance_, clk_port);
if (data_pin && clk_pin) {
// Hack: always use triple max value for check.
float **values = triple->values();
float *value_min = values[triple_min_index_];
float *value_max = values[triple_max_index_];
if (value_min && value_max) {
switch (analysis_type_) {
case AnalysisType::single:
break;
case AnalysisType::bc_wc:
if (role->genericRole() == TimingRole::setup())
*value_min = *value_max;
else
*value_max = *value_min;
break;
case AnalysisType::ocv:
*value_min = *value_max;
break;
}
2018-09-28 17:54:21 +02:00
}
bool matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, false);
// Liberty setup/hold checks on preset/clear pins can be translated
// into recovery/removal checks, so be flexible about matching.
if (!matched)
matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, true);
if (!matched
// Only warn when non-null values are present.
&& triple->hasValue())
sdfWarn(192, "cell %s %s -> %s %s check not found.",
network_->cellName(instance_),
network_->name(data_port),
network_->name(clk_port),
role->asString());
2018-09-28 17:54:21 +02:00
}
}
}
// Return true if matched.
bool
SdfReader::annotateCheckEdges(Pin *data_pin,
SdfPortSpec *data_edge,
Pin *clk_pin,
SdfPortSpec *clk_edge,
TimingRole *sdf_role,
SdfTriple *triple,
bool match_generic)
{
bool matched = false;
const char *cond_start = data_edge->cond();
const char *cond_end = clk_edge->cond();
// Timing check graph edges from clk to data.
Vertex *to_vertex = graph_->pinLoadVertex(data_pin);
// Fanin < fanout, so search for driver from load.
VertexInEdgeIterator edge_iter(to_vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
if (edge->from(graph_)->pin() == clk_pin) {
TimingArcSet *arc_set = edge->timingArcSet();
const TimingRole *edge_role = arc_set->role();
const char *lib_cond_start = arc_set->sdfCondStart();
const char *lib_cond_end = arc_set->sdfCondEnd();
bool cond_matches = condMatch(cond_start, lib_cond_start)
&& condMatch(cond_end, lib_cond_end);
if (((!match_generic && edge_role->sdfRole() == sdf_role)
|| (match_generic
&& edge_role->genericRole() == sdf_role->genericRole()))
&& cond_matches) {
TimingArcSet *arc_set = edge->timingArcSet();
for (TimingArc *arc : arc_set->arcs()) {
2018-09-28 17:54:21 +02:00
if (((data_edge->transition() == Transition::riseFall())
|| (arc->toEdge() == data_edge->transition()))
2018-09-28 17:54:21 +02:00
&& ((clk_edge->transition() == Transition::riseFall())
|| (arc->fromEdge() == clk_edge->transition()))) {
2018-09-28 17:54:21 +02:00
setEdgeArcDelays(edge, arc, triple);
}
}
matched = true;
}
}
}
return matched;
}
void
SdfReader::timingCheckWidth(SdfPortSpec *edge,
SdfTriple *triple)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
const char *port_name = edge->port();
Cell *cell = network_->cell(instance_);
Port *port = findPort(cell, port_name);
if (port) {
2018-09-28 17:54:21 +02:00
Pin *pin = network_->findPin(instance_, port_name);
if (pin) {
2019-11-11 23:30:19 +01:00
const RiseFall *rf = edge->transition()->asRiseFall();
2018-09-28 17:54:21 +02:00
float **values = triple->values();
float *value_ptr = values[triple_min_index_];
if (value_ptr) {
float value = *value_ptr;
2019-11-11 23:30:19 +01:00
graph_->setWidthCheckAnnotation(pin, rf, arc_delay_min_index_,
2018-09-28 17:54:21 +02:00
value);
}
if (triple_max_index_ != null_index_) {
value_ptr = values[triple_max_index_];
if (value_ptr) {
float value = *value_ptr;
2019-11-11 23:30:19 +01:00
graph_->setWidthCheckAnnotation(pin, rf, arc_delay_max_index_,
2018-09-28 17:54:21 +02:00
value);
}
}
}
}
}
deletePortSpec(edge);
deleteTriple(triple);
}
void
SdfReader::timingCheckSetupHold(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple)
{
timingCheckSetupHold1(data_edge, clk_edge, setup_triple, hold_triple,
TimingRole::setup(), TimingRole::hold());
}
void
SdfReader::timingCheckRecRem(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *rec_triple,
SdfTriple *rem_triple)
{
timingCheckSetupHold1(data_edge, clk_edge, rec_triple, rem_triple,
TimingRole::recovery(), TimingRole::removal());
}
void
SdfReader::timingCheckSetupHold1(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple,
TimingRole *setup_role,
TimingRole *hold_role)
{
const char *data_port_name = data_edge->port();
const char *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name);
if (data_port && clk_port) {
timingCheck1(setup_role, data_port, data_edge, clk_port, clk_edge, setup_triple);
timingCheck1(hold_role, data_port, data_edge, clk_port, clk_edge, hold_triple);
}
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(setup_triple);
deleteTriple(hold_triple);
}
2018-09-28 17:54:21 +02:00
void
SdfReader::timingCheckPeriod(SdfPortSpec *edge,
SdfTriple *triple)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
const char *port_name = edge->port();
Cell *cell = network_->cell(instance_);
Port *port = findPort(cell, port_name);
if (port) {
2018-09-28 17:54:21 +02:00
// Edge specifier is ignored for period checks.
Pin *pin = network_->findPin(instance_, port_name);
if (pin) {
float **values = triple->values();
float *value_ptr = values[triple_min_index_];
if (value_ptr) {
float value = *value_ptr;
graph_->setPeriodCheckAnnotation(pin, arc_delay_min_index_, value);
}
if (triple_max_index_ != null_index_) {
value_ptr = values[triple_max_index_];
if (value_ptr) {
float value = *value_ptr;
graph_->setPeriodCheckAnnotation(pin, arc_delay_max_index_, value);
}
}
}
}
}
deletePortSpec(edge);
deleteTriple(triple);
}
void
SdfReader::timingCheckNochange(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *before_triple,
SdfTriple *after_triple)
{
notSupported("NOCHANGE");
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(before_triple);
deleteTriple(after_triple);
}
void
SdfReader::device(SdfTripleSeq *triples)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
InstancePinIterator *pin_iter = network_->pinIterator(instance_);
while (pin_iter->hasNext()) {
Pin *to_pin = pin_iter->next();
setDevicePinDelays(to_pin, triples);
}
delete pin_iter;
}
deleteTripleSeq(triples);
}
void
SdfReader::device(const char *to_port_name,
SdfTripleSeq *triples)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
Cell *cell = network_->cell(instance_);
Port *to_port = findPort(cell, to_port_name);
if (to_port) {
2018-09-28 17:54:21 +02:00
Pin *to_pin = network_->findPin(instance_, to_port_name);
setDevicePinDelays(to_pin, triples);
}
}
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
stringDelete(to_port_name);
2018-09-28 17:54:21 +02:00
deleteTripleSeq(triples);
}
void
SdfReader::setDevicePinDelays(Pin *to_pin,
SdfTripleSeq *triples)
{
Vertex *vertex = graph_->pinDrvrVertex(to_pin);
if (vertex) {
VertexInEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
if (edge->role()->sdfRole() == TimingRole::sdfIopath())
setEdgeDelays(edge, triples, "DEVICE");
}
2018-09-28 17:54:21 +02:00
}
}
void
SdfReader::setEdgeArcDelays(Edge *edge,
TimingArc *arc,
SdfTriple *triple)
{
setEdgeArcDelays(edge, arc, triple, triple_min_index_, arc_delay_min_index_);
setEdgeArcDelays(edge, arc, triple, triple_max_index_, arc_delay_max_index_);
}
void
SdfReader::setEdgeArcDelays(Edge *edge,
TimingArc *arc,
SdfTriple *triple,
int triple_index,
int arc_delay_index)
{
if (triple_index != null_index_) {
float **values = triple->values();
float *value_ptr = values[triple_index];
if (value_ptr) {
ArcDelay delay;
if (in_incremental_)
delay = *value_ptr + graph_->arcDelay(edge, arc, arc_delay_index);
else
delay = *value_ptr;
graph_->setArcDelay(edge, arc, arc_delay_index, delay);
graph_->setArcDelayAnnotated(edge, arc, arc_delay_index, true);
2018-09-28 17:54:21 +02:00
edge->setDelayAnnotationIsIncremental(is_incremental_only_);
}
}
}
void
SdfReader::setEdgeArcDelaysCondUse(Edge *edge,
TimingArc *arc,
SdfTriple *triple)
{
float **values = triple->values();
float *value_min = values[triple_min_index_];
float *value_max = values[triple_max_index_];
2018-09-28 17:54:21 +02:00
MinMax *min, *max;
if (cond_use_ == MinMaxAll::min()) {
min = MinMax::min();
max = MinMax::min();
}
else if (cond_use_ == MinMaxAll::max()) {
min = MinMax::max();
max = MinMax::max();
}
else {
min = MinMax::min();
max = MinMax::max();
}
setEdgeArcDelaysCondUse(edge, arc, value_min, triple_min_index_,
arc_delay_min_index_, min);
setEdgeArcDelaysCondUse(edge, arc, value_max, triple_max_index_,
arc_delay_max_index_, max);
}
void
SdfReader::setEdgeArcDelaysCondUse(Edge *edge,
TimingArc *arc,
float *value,
int triple_index,
int arc_delay_index,
const MinMax *min_max)
{
if (value
&& triple_index != null_index_) {
ArcDelay delay(*value);
if (!is_incremental_only_ && in_incremental_)
delay = graph_->arcDelay(edge, arc, arc_delay_index) + *value;
else if (graph_->arcDelayAnnotated(edge, arc, arc_delay_index)) {
2018-09-28 17:54:21 +02:00
ArcDelay prev_value = graph_->arcDelay(edge, arc, arc_delay_index);
2020-07-12 02:43:30 +02:00
if (delayGreater(prev_value, delay, min_max, this))
2018-09-28 17:54:21 +02:00
delay = prev_value;
}
graph_->setArcDelay(edge, arc, arc_delay_index, delay);
graph_->setArcDelayAnnotated(edge, arc, arc_delay_index, true);
2018-09-28 17:54:21 +02:00
edge->setDelayAnnotationIsIncremental(is_incremental_only_);
}
}
bool
SdfReader::condMatch(const char *sdf_cond,
const char *lib_cond)
{
// If the sdf is not conditional it matches any library condition.
2019-03-13 01:25:53 +01:00
if (sdf_cond == nullptr)
2018-09-28 17:54:21 +02:00
return true;
else if (sdf_cond && lib_cond) {
// Match sdf_cond and lib_cond ignoring blanks.
const char *c1 = sdf_cond;
const char *c2 = lib_cond;
char ch1, ch2;
do {
ch1 = *c1++;
ch2 = *c2++;
while (ch1 && isspace(ch1))
ch1 = *c1++;
while (ch2 && isspace(ch2))
ch2 = *c2++;
if (ch1 != ch2)
return false;
} while (ch1 && ch2);
return (ch1 == '\0' && ch2 == '\0');
}
else
return false;
}
SdfPortSpec *
SdfReader::makePortSpec(Transition *tr,
const char *port,
const char *cond)
{
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
SdfPortSpec *port_spec = new SdfPortSpec(tr, port, cond);
stringDelete(port);
stringDelete(cond);
return port_spec;
2018-09-28 17:54:21 +02:00
}
SdfPortSpec *
SdfReader::makeCondPortSpec(const char *cond_port)
2018-09-28 17:54:21 +02:00
{
// Search from end to find port name because condition may contain spaces.
string cond_port1(cond_port);
trimRight(cond_port1);
auto port_idx = cond_port1.find_last_of(" ");
if (port_idx != cond_port1.npos) {
string port1 = cond_port1.substr(port_idx + 1);
auto cond_end = cond_port1.find_last_not_of(" ", port_idx);
if (cond_end != cond_port1.npos) {
string cond1 = cond_port1.substr(0, cond_end + 1);
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(),
port1.c_str(),
cond1.c_str());
stringDelete(cond_port);
return port_spec;
}
}
stringDelete(cond_port);
return nullptr;
2018-09-28 17:54:21 +02:00
}
void
SdfReader::deletePortSpec(SdfPortSpec *edge)
{
delete edge;
}
SdfTripleSeq *
SdfReader::makeTripleSeq()
{
return new SdfTripleSeq;
}
void
SdfReader::deleteTripleSeq(SdfTripleSeq *triples)
{
SdfTripleSeq::Iterator iter(triples);
while (iter.hasNext()) {
SdfTriple *triple = iter.next();
delete triple;
}
delete triples;
}
SdfTriple *
SdfReader::makeTriple()
{
return new SdfTriple(0, 0, 0);
}
SdfTriple *
SdfReader::makeTriple(float value)
{
value *= timescale_;
float *fp = new float(value);
return new SdfTriple(fp, fp, fp);
}
SdfTriple *
SdfReader::makeTriple(float *min,
float *typ,
float *max)
{
if (min) *min *= timescale_;
if (typ) *typ *= timescale_;
if (max) *max *= timescale_;
return new SdfTriple(min, typ, max);
}
void
SdfReader::deleteTriple(SdfTriple *triple)
{
delete triple;
}
void
SdfReader::setInTimingCheck(bool in)
{
in_timing_check_ = in;
}
void
SdfReader::setInIncremental(bool incr)
{
in_incremental_ = incr;
}
const char *
SdfReader::unescaped(const char *token)
{
char path_escape = network_->pathEscape();
char path_divider = network_->pathDivider();
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
char *unescaped = new char[strlen(token) + 1];
2018-09-28 17:54:21 +02:00
char *u = unescaped;
size_t token_length = strlen(token);
2018-09-28 17:54:21 +02:00
for (size_t i = 0; i < token_length; i++) {
char ch = token[i];
2018-09-28 17:54:21 +02:00
if (ch == escape_) {
char next_ch = token[i + 1];
2018-09-28 17:54:21 +02:00
if (next_ch == divider_) {
// Escaped divider.
2018-09-28 17:54:21 +02:00
// Translate sdf escape to network escape.
*u++ = path_escape;
// Translate sdf divider to network divider.
*u++ = path_divider;
}
else if (next_ch == '['
|| next_ch == ']'
|| next_ch == escape_) {
// Escaped bus bracket or escape.
// Translate sdf escape to network escape.
*u++ = path_escape;
*u++ = next_ch;
}
else
// Escaped non-divider character.
*u++ = next_ch;
i++;
2018-09-28 17:54:21 +02:00
}
else
// Just the normal noises.
*u++ = ch;
}
*u = '\0';
debugPrint(debug_, "sdf_name", 1, "token %s -> %s", token, unescaped);
stringDelete(token);
2018-09-28 17:54:21 +02:00
return unescaped;
}
// Translate sdf divider to network divider.
char *
SdfReader::makePath(const char *head,
const char *tail)
{
rm tmp string uses commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 21:25:37 2023 -0700 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5514910a91707d615bac0bbed3a29f579eca8de2 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 18:21:54 2023 -0700 foo Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 076a51d5816444e883232933c2ded7309291d0bc Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 16:38:42 2023 -0700 parse bus string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2b80e563cbbb6563a6b716431f391bbb6639f816 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 15:57:05 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 14:37:35 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ebad3afd49b08e7194452dd082c3c7c05767f875 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:59:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 69647913932312a04ca06e7a04cca17ed50d4daf Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 10:42:43 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 73cee43925c0d32940989c616440b4da18640121 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:55:17 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit eba6d1413b8d87a64a90141e5263a56eede1df51 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 09:40:16 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 08:18:46 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit faf82464d7be7fd6c958a21d401fa48ece4ac341 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:49:11 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 25 07:37:12 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 21:02:20 2023 -0700 rm tmp string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a Author: James Cherry <cherry@parallaxsw.com> Date: Fri Mar 24 19:53:44 2023 -0700 rm TmpString uses Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-03-26 15:34:36 +02:00
char *path = stringPrint("%s%c%s",
head,
network_->pathDivider(),
tail);
sta::stringDelete(head);
sta::stringDelete(tail);
return path;
}
2018-09-28 17:54:21 +02:00
void
SdfReader::incrLine()
{
line_++;
}
void
SdfReader::getChars(char *buf,
size_t &result,
size_t max_size)
{
char *status = gzgets(stream_, buf, max_size);
if (status == Z_NULL)
2019-03-13 01:25:53 +01:00
result = 0; // YY_nullptr
2018-09-28 17:54:21 +02:00
else
result = strlen(buf);
}
void
SdfReader::getChars(char *buf,
int &result,
size_t max_size)
{
char *status = gzgets(stream_, buf, max_size);
if (status == Z_NULL)
2019-03-13 01:25:53 +01:00
result = 0; // YY_nullptr
2018-09-28 17:54:21 +02:00
else
result = strlen(buf);
}
void
SdfReader::notSupported(const char *feature)
{
2020-12-14 02:21:35 +01:00
sdfError(193, "%s not supported.", feature);
2018-09-28 17:54:21 +02:00
}
2020-12-25 00:53:25 +01:00
void
SdfReader::sdfWarn(int id,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report_->vfileWarn(id, filename_, line_, fmt, args);
va_end(args);
2018-09-28 17:54:21 +02:00
}
void
2020-12-14 02:21:35 +01:00
SdfReader::sdfError(int id,
const char *fmt, ...)
2018-09-28 17:54:21 +02:00
{
va_list args;
va_start(args, fmt);
2020-12-14 02:21:35 +01:00
report_->vfileError(id, filename_, line_, fmt, args);
2018-09-28 17:54:21 +02:00
va_end(args);
}
Pin *
SdfReader::findPin(const char *name)
{
2019-01-17 00:37:31 +01:00
if (path_) {
string path_name;
2020-01-17 03:49:43 +01:00
stringPrint(path_name, "%s%c%s", path_, divider_, name);
2019-01-17 00:37:31 +01:00
Pin *pin = network_->findPin(path_name.c_str());
return pin;
}
else
return network_->findPin(name);
2018-09-28 17:54:21 +02:00
}
Instance *
SdfReader::findInstance(const char *name)
{
2019-01-17 00:37:31 +01:00
string inst_name = name;
if (path_)
stringPrint(inst_name, "%s%c%s", path_, divider_, name);
Instance *inst = network_->findInstance(inst_name.c_str());
2019-03-13 01:25:53 +01:00
if (inst == nullptr)
2020-12-25 00:53:25 +01:00
sdfWarn(195, "instance %s not found.", inst_name.c_str());
2018-09-28 17:54:21 +02:00
return inst;
}
////////////////////////////////////////////////////////////////
SdfPortSpec::SdfPortSpec(Transition *tr,
const char *port,
const char *cond) :
tr_(tr),
port_(stringCopy(port)),
cond_(stringCopy(cond))
{
}
SdfPortSpec::~SdfPortSpec()
{
stringDelete(port_);
stringDelete(cond_);
}
////////////////////////////////////////////////////////////////
2018-09-28 17:54:21 +02:00
SdfTriple::SdfTriple(float *min,
float *typ,
float *max)
{
values_[0] = min;
values_[1] = typ;
values_[2] = max;
}
SdfTriple::~SdfTriple()
{
if (values_[0] == values_[1] && values_[0] == values_[2])
delete values_[0];
else {
if (values_[0]) delete values_[0];
if (values_[1]) delete values_[1];
if (values_[2]) delete values_[2];
}
}
bool
SdfTriple::hasValue() const
{
return values_[0] || values_[1] || values_[2];
}
} // namespace
// Global namespace
void sdfFlushBuffer();
int
SdfParse_error(const char *msg)
{
sdfFlushBuffer();
sta::sdf_reader->sdfError(196, "%s.\n", msg);
2018-09-28 17:54:21 +02:00
return 0;
}