diff --git a/search/WriteSpice.cc b/search/WriteSpice.cc
deleted file mode 100644
index 65bdb990..00000000
--- a/search/WriteSpice.cc
+++ /dev/null
@@ -1,927 +0,0 @@
-// OpenSTA, Static Timing Analyzer
-// Copyright (c) 2023, Parallax Software, Inc.
-//
-// 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 .
-
-#include
-#include
-#include
-#include
-#include "Machine.hh"
-#include "Debug.hh"
-#include "Error.hh"
-#include "Report.hh"
-#include "StringUtil.hh"
-#include "FuncExpr.hh"
-#include "Liberty.hh"
-#include "TimingArc.hh"
-#include "Network.hh"
-#include "Graph.hh"
-#include "Sdc.hh"
-#include "DcalcAnalysisPt.hh"
-#include "Parasitics.hh"
-#include "PathAnalysisPt.hh"
-#include "Path.hh"
-#include "PathRef.hh"
-#include "PathExpanded.hh"
-#include "StaState.hh"
-#include "WriteSpice.hh"
-
-namespace sta {
-
-using std::string;
-using std::ofstream;
-using std::ifstream;
-
-typedef Vector StringVector;
-typedef Map CellSpicePortNames;
-typedef int Stage;
-typedef Map ParasiticNodeMap;
-
-void
-split(const string &text,
- const string &delims,
- // Return values.
- StringVector &tokens);
-void
-streamPrint(ofstream &stream,
- const char *fmt,
- ...) __attribute__((format (printf, 2, 3)));
-
-////////////////////////////////////////////////////////////////
-
-class WriteSpice : public StaState
-{
-public:
- WriteSpice(Path *path,
- const char *spice_filename,
- const char *subckts_filename,
- const char *lib_subckts_filename,
- const char *models_filename,
- const StaState *sta);
- ~WriteSpice();
- void writeSpice();;
-
-private:
- void writeHeader();
- void writeStageInstances();
- void writeInputSource();
- void writeStageSubckts();
- void writeInputStage(Stage stage);
- void writeMeasureStmts();
- void writeGateStage(Stage stage);
- void writeStageVoltageSources(LibertyCell *cell,
- StringVector *spice_port_names,
- const char *inst_name,
- LibertyPort *from_port,
- LibertyPort *drvr_port);
- void writeStageParasitics(Stage stage);
- void writeSubckts();
- void findPathCellnames(// Return values.
- StringSet &path_cell_names);
- void recordSpicePortNames(const char *cell_name,
- StringVector &tokens);
- float pgPortVoltage(const char *pg_port_name,
- LibertyCell *cell);
- float pgPortVoltage(LibertyPgPort *pg_port);
- float maxTime();
- const char *nodeName(ParasiticNode *node);
- void initNodeMap(const char *net_name);
-
- // Stage "accessors".
- // Internally a stage index from stageFirst() to stageLast()
- // is turned into an index into path_expanded_.
- Stage stageFirst();
- Stage stageLast();
- string stageName(Stage stage);
- int stageGateInputPathIndex(Stage stage);
- int stageDrvrPathIndex(Stage stage);
- int stageLoadPathIndex(Stage stage);
- PathRef *stageGateInputPath(Stage stage);
- PathRef *stageDrvrPath(Stage stage);
- PathRef *stageLoadPath(Stage stage);
- TimingArc *stageGateArc(Stage stage);
- TimingArc *stageWireArc(Stage stage);
- Edge *stageGateEdge(Stage stage);
- Edge *stageWireEdge(Stage stage);
- Pin *stageInputPin(Stage stage);
- Pin *stageDrvrPin(Stage stage);
- Pin *stageLoadPin(Stage stage);
- const char *stageInputPinName(Stage stage);
- const char *stageDrvrPinName(Stage stage);
- const char *stageLoadPinName(Stage stage);
-
- Path *path_;
- const char *spice_filename_;
- const char *subckts_filename_;
- const char *lib_subckts_filename_;
- const char *models_filename_;
-
- ofstream spice_stream_;
- PathExpanded path_expanded_;
- CellSpicePortNames cell_spice_port_names_;
- ParasiticNodeMap node_map_;
- int next_node_index_;
- const char *net_name_;
-
- // Resistance to use to simulate a short circuit between spice nodes.
- static const float short_ckt_resistance_;
-};
-
-////////////////////////////////////////////////////////////////
-
-class SubcktEndsMissing : public StaException
-{
-public:
- SubcktEndsMissing(const char *cell_name,
- const char *subckt_filename);;
- const char *what() const throw();
-
-protected:
- string what_;
-};
-
-SubcktEndsMissing::SubcktEndsMissing(const char *cell_name,
- const char *subckt_filename)
-{
- what_ = "Error: spice subckt for cell ";
- what_ += cell_name;
- what_ += " missing .ends in ";
- what_ += subckt_filename;
-}
-
-const char *
-SubcktEndsMissing::what() const throw()
-{
- return what_.c_str();
-}
-
-////////////////////////////////////////////////////////////////
-
-void
-writeSpice (Path *path,
- const char *spice_filename,
- const char *subckts_filename,
- const char *lib_subckts_filename,
- const char *models_filename,
- StaState *sta)
-{
- WriteSpice writer(path, spice_filename, subckts_filename,
- lib_subckts_filename, models_filename, sta);
- writer.writeSpice();
-}
-
-const float WriteSpice::short_ckt_resistance_ = .0001;
-
-WriteSpice::WriteSpice(Path *path,
- const char *spice_filename,
- const char *subckts_filename,
- const char *lib_subckts_filename,
- const char *models_filename,
- const StaState *sta) :
- StaState(sta),
- path_(path),
- spice_filename_(spice_filename),
- subckts_filename_(subckts_filename),
- lib_subckts_filename_(lib_subckts_filename),
- models_filename_(models_filename),
- path_expanded_(sta),
- net_name_(NULL)
-{
-}
-
-WriteSpice::~WriteSpice()
-{
- cell_spice_port_names_.deleteContents();
-}
-
-void
-WriteSpice::writeSpice()
-{
- spice_stream_.open(spice_filename_);
- if (spice_stream_.is_open()) {
- path_expanded_.expand(path_, true);
- // Find subckt port names as a side-effect of writeSubckts.
- writeSubckts();
- writeHeader();
- writeStageInstances();
- writeInputSource();
- writeStageSubckts();
- streamPrint(spice_stream_, ".end\n");
- spice_stream_.close();
- }
- else
- throw FileNotWritable(spice_filename_);
-}
-
-void
-WriteSpice::writeHeader()
-{
- const MinMax *min_max = path_->minMax(this);
- const Pvt *pvt = sdc_->operatingConditions(min_max);
- if (pvt == NULL)
- pvt = network_->defaultLibertyLibrary()->defaultOperatingConditions();
- float temp = pvt->temperature();
- streamPrint(spice_stream_, ".temp %.1f\n", temp);
- streamPrint(spice_stream_, ".include \"%s\"\n", models_filename_);
- streamPrint(spice_stream_, ".include \"%s\"\n", subckts_filename_);
-
- float max_time = maxTime();
- float time_step = max_time / 1e+3;
- streamPrint(spice_stream_, ".tran %.3g %.3g\n\n",
- time_step, max_time);
-}
-
-float
-WriteSpice::maxTime()
-{
- float end_slew = path_->slew(this);
- float max_time = (path_->arrival(this) + end_slew * 2) * 1.5;
- return max_time;
-}
-
-void
-WriteSpice::writeStageInstances()
-{
- streamPrint(spice_stream_, "*****************\n");
- streamPrint(spice_stream_, "* Stage instances\n");
- streamPrint(spice_stream_, "*****************\n\n");
-
- for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
- const char *stage_name = stageName(stage).c_str();
- if (stage == stageFirst())
- streamPrint(spice_stream_, "x%s %s %s %s\n",
- stage_name,
- stageDrvrPinName(stage),
- stageLoadPinName(stage),
- stage_name);
- else
- streamPrint(spice_stream_, "x%s %s %s %s %s\n",
- stage_name,
- stageInputPinName(stage),
- stageDrvrPinName(stage),
- stageLoadPinName(stage),
- stage_name);
- }
- streamPrint(spice_stream_, "\n");
-}
-
-float
-WriteSpice::pgPortVoltage(const char *pg_port_name,
- LibertyCell *cell)
-{
- auto pg_port = cell->findPgPort(pg_port_name);
- return pgPortVoltage(pg_port);
-}
-
-float
-WriteSpice::pgPortVoltage(LibertyPgPort *pg_port)
-{
- auto cell = pg_port->cell();
- auto voltage_name = pg_port->voltageName();
- auto lib = cell->libertyLibrary();
- float voltage = lib->supplyVoltage(voltage_name);
- return voltage;
-}
-
-void
-WriteSpice::writeInputSource()
-{
- streamPrint(spice_stream_, "**************\n");
- streamPrint(spice_stream_, "* Input source\n");
- streamPrint(spice_stream_, "**************\n\n");
-
- Stage input_stage = stageFirst();
- streamPrint(spice_stream_, "v1 %s 0 pwl(\n",
- stageDrvrPinName(input_stage));
- auto wire_arc = stageWireArc(input_stage);
- auto load_pin = stageLoadPin(input_stage);
- auto cell = network_->libertyCell(network_->instance(load_pin));
- auto load_port = network_->libertyPort(load_pin);
- const char *pg_gnd_port_name = load_port->relatedGroundPin();
- const char *pg_pwr_port_name = load_port->relatedPowerPin();
- auto gnd_volt = pgPortVoltage(pg_gnd_port_name, cell);
- auto pwr_volt = pgPortVoltage(pg_pwr_port_name, cell);
- float volt0, volt1;
- if (wire_arc->fromTrans()->asRiseFall() == TransRiseFall::rise()) {
- volt0 = gnd_volt;
- volt1 = pwr_volt;
- }
- else {
- volt0 = pwr_volt;
- volt1 = gnd_volt;
- }
- float time0 = .1e-9;
- float time1 = .2e-9;
- streamPrint(spice_stream_, "+%.3e %.3e\n", 0.0, volt0);
- streamPrint(spice_stream_, "+%.3e %.3e\n", time0, volt0);
- streamPrint(spice_stream_, "+%.3e %.3e\n", time1, volt1);
- streamPrint(spice_stream_, "+%.3e %.3e\n", maxTime(), volt1);
- streamPrint(spice_stream_, "+)\n\n");
-}
-
-void
-WriteSpice::writeMeasureStmts()
-{
- streamPrint(spice_stream_, "********************\n");
- streamPrint(spice_stream_, "* Measure statements\n");
- streamPrint(spice_stream_, "********************\n\n");
-}
-
-void
-WriteSpice::writeStageSubckts()
-{
- streamPrint(spice_stream_, "***************\n");
- streamPrint(spice_stream_, "* Stage subckts\n");
- streamPrint(spice_stream_, "***************\n\n");
-
- for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
- if (stage == stageFirst())
- writeInputStage(stage);
- else
- writeGateStage(stage);
- }
-}
-
-// Input port to first gate input.
-void
-WriteSpice::writeInputStage(Stage stage)
-{
- // Input arc.
- // External driver not handled.
- auto drvr_pin_name = stageDrvrPinName(stage);
- auto load_pin_name = stageLoadPinName(stage);
- streamPrint(spice_stream_, ".subckt %s %s %s\n",
- stageName(stage).c_str(),
- drvr_pin_name,
- load_pin_name);
- writeStageParasitics(stage);
- streamPrint(spice_stream_, ".ends\n\n");
-}
-
-// Gate and load parasitics.
-void
-WriteSpice::writeGateStage(Stage stage)
-{
- auto input_pin = stageInputPin(stage);
- auto input_pin_name = stageInputPinName(stage);
- auto drvr_pin = stageDrvrPin(stage);
- auto drvr_pin_name = stageDrvrPinName(stage);
- auto load_pin_name = stageLoadPinName(stage);
- streamPrint(spice_stream_, ".subckt stage%d %s %s %s\n",
- stage,
- input_pin_name,
- drvr_pin_name,
- load_pin_name);
- Instance *inst = network_->instance(input_pin);
- const char *inst_name = network_->pathName(inst);
- LibertyCell *cell = network_->libertyCell(inst);
- const char *cell_name = cell->name();
- auto spice_port_names = cell_spice_port_names_[cell_name];
-
- // Instance subckt call.
- streamPrint(spice_stream_, "x%s", inst_name);
- StringVector::Iterator port_iter(spice_port_names);
- while (port_iter.hasNext()) {
- const char *subckt_port_name = port_iter.next().c_str();
- auto pin = network_->findPin(inst, subckt_port_name);
- auto pg_port = cell->findPgPort(subckt_port_name);
- const char *pin_name;
- if (pin) {
- pin_name = network_->pathName(pin);
- streamPrint(spice_stream_, " %s", pin_name);
- }
- else if (pg_port)
- streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_name);
- }
- streamPrint(spice_stream_, " %s\n", cell_name);
-
- writeStageVoltageSources(cell, spice_port_names,
- inst_name,
- network_->libertyPort(input_pin),
- network_->libertyPort(drvr_pin));
- writeStageParasitics(stage);
- streamPrint(spice_stream_, ".ends\n\n");
-}
-
-typedef Map LibertyPortLogicValues;
-
-// Find the logic values for expression inputs to enable paths from_port.
-void
-sensitizationValues(FuncExpr *expr,
- LibertyPort *from_port,
- // Return values.
- LibertyPortLogicValues &port_values)
-{
- switch (expr->op()) {
- case FuncExpr::op_port: {
- break;
- }
- case FuncExpr::op_not: {
- sensitizationValues(expr->left(), from_port, port_values);
- break;
- }
- case FuncExpr::op_or: {
- FuncExpr *left = expr->left();
- FuncExpr *right = expr->right();
- if (left->port() == from_port
- && right->op() == FuncExpr::op_port)
- port_values[right->port()] = logic_zero;
- else if (right->port() == from_port
- && left->op() == FuncExpr::op_port)
- port_values[left->port()] = logic_zero;
- break;
- }
- case FuncExpr::op_and: {
- FuncExpr *left = expr->left();
- FuncExpr *right = expr->right();
- if (left->port() == from_port
- && right->op() == FuncExpr::op_port)
- port_values[right->port()] = logic_one;
- else if (right->port() == from_port
- && left->op() == FuncExpr::op_port)
- port_values[left->port()] = logic_one;
- break;
- }
- case FuncExpr::op_xor: {
- // Need to know timing arc sense to get this right.
- FuncExpr *left = expr->left();
- FuncExpr *right = expr->right();
- if (left->port() == from_port
- && right->op() == FuncExpr::op_port)
- port_values[right->port()] = logic_zero;
- else if (right->port() == from_port
- && left->op() == FuncExpr::op_port)
- port_values[left->port()] = logic_zero;
- break;
- }
- case FuncExpr::op_one:
- case FuncExpr::op_zero:
- break;
- }
-}
-
-// Power/ground and input voltage sources.
-void
-WriteSpice::writeStageVoltageSources(LibertyCell *cell,
- StringVector *spice_port_names,
- const char *inst_name,
- LibertyPort *from_port,
- LibertyPort *drvr_port)
-{
- auto from_port_name = from_port->name();
- auto drvr_port_name = drvr_port->name();
- LibertyLibrary *lib = cell->libertyLibrary();
- LibertyPortLogicValues port_values;
- sensitizationValues(drvr_port->function(), from_port, port_values);
- int volt_source = 1;
- debugPrint1(debug_, "write_spice", 2, "subckt %s\n", cell->name());
- StringVector::Iterator port_iter(spice_port_names);
- while (port_iter.hasNext()) {
- auto subckt_port_name = port_iter.next().c_str();
- auto pg_port = cell->findPgPort(subckt_port_name);
- debugPrint2(debug_, "write_spice", 2, " port %s%s\n",
- subckt_port_name,
- pg_port ? " pwr/gnd" : "");
- if (pg_port) {
- auto voltage = pgPortVoltage(pg_port);
- streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n",
- volt_source,
- inst_name, subckt_port_name,
- voltage);
- volt_source++;
- } else if (!(stringEq(subckt_port_name, from_port_name)
- || stringEq(subckt_port_name, drvr_port_name))) {
- // Input voltage to sensitize path from gate input to output.
- LibertyPort *port = cell->findLibertyPort(subckt_port_name);
- if (port) {
- const char *pg_port_name = NULL;
- bool port_has_value;
- LogicValue port_value;
- port_values.findKey(port, port_value, port_has_value);
- if (port_has_value) {
- switch (port_value) {
- case logic_zero:
- pg_port_name = port->relatedGroundPin();
- break;
- case logic_one:
- pg_port_name = port->relatedPowerPin();
- break;
- default:
- break;
- }
- if (pg_port_name) {
- auto pg_port = cell->findPgPort(pg_port_name);
- if (pg_port) {
- auto voltage_name = pg_port->voltageName();
- if (voltage_name) {
- float voltage = lib->supplyVoltage(voltage_name);
- streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n",
- volt_source,
- inst_name, subckt_port_name,
- voltage);
- volt_source++;
- }
- else
- report_->error("port %s %s voltage %s not found,\n",
- subckt_port_name,
- pg_port_name,
- voltage_name);
- }
- else
- report_->error("port %s %s not found,\n",
- subckt_port_name,
- pg_port_name);
- }
- }
- }
- }
- }
-}
-
-typedef Set ParasiticDeviceSet;
-typedef Set ParasiticNodeSet;
-
-void
-findParasiticDevicesNodes(ParasiticNode *node,
- Parasitics *parasitics,
- // Return values.
- ParasiticNodeSet &nodes,
- ParasiticDeviceSet &devices)
-{
- nodes.insert(node);
- auto device_iter = parasitics->deviceIterator(node);
- while (device_iter->hasNext()) {
- auto device = device_iter->next();
- if (!devices.hasKey(device)) {
- devices.insert(device);
- auto other_node = parasitics->otherNode(device, node);
- findParasiticDevicesNodes(other_node, parasitics, nodes, devices);
- }
- }
- delete device_iter;
-}
-
-void
-WriteSpice::writeStageParasitics(Stage stage)
-{
- auto drvr_path = stageDrvrPath(stage);
- auto drvr_pin = stageDrvrPin(stage);
- auto load_pin = stageLoadPin(stage);
- auto dcalc_ap = drvr_path->dcalcAnalysisPt(this);
- auto parasitic_ap = dcalc_ap->parasiticAnalysisPt();
- auto parasitic = parasitics_->findParasiticNetwork(drvr_pin, parasitic_ap);
- int resistor_index = 1;
- int cap_index = 1;
- if (parasitic) {
- Net *net = network_->net(drvr_pin);
- auto net_name =
- net ? network_->pathName(net) : network_->pathName(drvr_pin);
- initNodeMap(net_name);
- streamPrint(spice_stream_, "* Net %s\n", net_name);
- auto node = parasitics_->findNode(parasitic, drvr_pin);
- ParasiticNodeSet nodes;
- ParasiticDeviceSet devices;
- findParasiticDevicesNodes(node, parasitics_, nodes, devices);
- ParasiticDeviceSet::Iterator device_iter(devices);
- while (device_iter.hasNext()) {
- auto device = device_iter.next();
- auto resistance = parasitics_->value(device, parasitic_ap);
- if (parasitics_->isResistor(device)) {
- ParasiticNode *node1, *node2;
- parasitics_->resistorNodes(device, node1, node2);
- streamPrint(spice_stream_, "R%d %s %s %.3e\n",
- resistor_index,
- nodeName(node1),
- nodeName(node2),
- resistance);
- resistor_index++;
- }
- else if (parasitics_->isCouplingCap(device)) {
- }
- }
- ParasiticNodeSet::Iterator node_iter(nodes);
- while (node_iter.hasNext()) {
- auto node = node_iter.next();
- auto cap = parasitics_->nodeGndCap(node, parasitic_ap);
- streamPrint(spice_stream_, "C%d %s 0 %.3e\n",
- cap_index,
- nodeName(node),
- cap);
- cap_index++;
- }
- }
- else
- streamPrint(spice_stream_, "R1 %s %s %.3e\n",
- network_->pathName(drvr_pin),
- network_->pathName(load_pin),
- short_ckt_resistance_);
-}
-
-void
-WriteSpice::initNodeMap(const char *net_name)
-{
- stringDelete(net_name_);
- node_map_.clear();
- next_node_index_ = 1;
- net_name_ = stringCopy(net_name);
-}
-
-const char *
-WriteSpice::nodeName(ParasiticNode *node)
-{
- auto pin = parasitics_->connectionPin(node);
- if (pin)
- return parasitics_->name(node);
- else {
- int node_index;
- bool node_index_exists;
- node_map_.findKey(node, node_index, node_index_exists);
- if (!node_index_exists) {
- node_index = next_node_index_++;
- node_map_[node] = node_index;
- }
- return stringPrintTmp(strlen(net_name_) + 10, "%s/%d",
- net_name_, node_index);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-// Copy the subckt definition from lib_subckts_filename for
-// each cell in path to path_subckts_filename.
-void
-WriteSpice::writeSubckts()
-{
- StringSet path_cell_names;
- findPathCellnames(path_cell_names);
-
- ifstream lib_subckts_stream(lib_subckts_filename_);
- if (lib_subckts_stream.is_open()) {
- ofstream subckts_stream(subckts_filename_);
- if (subckts_stream.is_open()) {
- string line;
- while (getline(lib_subckts_stream, line)) {
- // .subckt [args..]
- StringVector tokens;
- split(line, " \t", tokens);
- if (tokens.size() >= 2
- && stringEqual(tokens[0].c_str(), ".subckt")) {
- const char *cell_name = tokens[1].c_str();
- if (path_cell_names.hasKey(cell_name)) {
- subckts_stream << line << "\n";
- bool found_ends = false;
- while (getline(lib_subckts_stream, line)) {
- subckts_stream << line << "\n";
- if (stringEqual(line.c_str(), ".ends")) {
- subckts_stream << "\n";
- found_ends = true;
- break;
- }
- }
- if (!found_ends)
- throw SubcktEndsMissing(cell_name, lib_subckts_filename_);
- path_cell_names.eraseKey(cell_name);
- }
- recordSpicePortNames(cell_name, tokens);
- }
- }
- subckts_stream.close();
- lib_subckts_stream.close();
-
- if (!path_cell_names.empty()) {
- StringSet::Iterator cell_iter(path_cell_names);
- report_->error("The following subkcts are missing from %s\n",
- lib_subckts_filename_);
- while (cell_iter.hasNext()) {
- const char *cell_name = cell_iter.next();
- report_->printError(" %s\n", cell_name);
- }
- }
- }
- else {
- lib_subckts_stream.close();
- throw FileNotWritable(subckts_filename_);
- }
- }
- else
- throw FileNotReadable(lib_subckts_filename_);
-}
-
-void
-WriteSpice::findPathCellnames(// Return values.
- StringSet &path_cell_names)
-{
- for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
- auto arc = stageGateArc(stage);
- if (arc) {
- LibertyCell *cell = arc->set()->libertyCell();
- if (cell) {
- debugPrint1(debug_, "write_spice", 2, "cell %s\n", cell->name());
- path_cell_names.insert(cell->name());
- }
- }
- }
-}
-
-void
-WriteSpice::recordSpicePortNames(const char *cell_name,
- StringVector &tokens)
-{
- auto cell = network_->findLibertyCell(cell_name);
- auto spice_port_names = new StringVector;
- for (int i = 2; i < tokens.size(); i++) {
- const char *port_name = tokens[i].c_str();
- auto port = cell->findLibertyPort(port_name);
- auto pg_port = cell->findPgPort(port_name);
- if (port == NULL && pg_port == NULL)
- report_->error("subckt %s port %s has no corresponding liberty port or pg_port.\n",
- cell_name, port_name);
- spice_port_names->push_back(port_name);
- }
- cell_spice_port_names_[cell_name] = spice_port_names;
-}
-
-////////////////////////////////////////////////////////////////
-
-Stage
-WriteSpice::stageFirst()
-{
- return 1;
-}
-
-Stage
-WriteSpice::stageLast()
-{
- return (path_expanded_.size() + 1) / 2;
-}
-
-string
-WriteSpice::stageName(Stage stage)
-{
- string name;
- stringPrint(name, "stage%d", stage);
- return name;
-}
-
-int
-WriteSpice::stageGateInputPathIndex(Stage stage)
-{
- return stage * 2 - 3;
-}
-
-int
-WriteSpice::stageDrvrPathIndex(Stage stage)
-{
- return stage * 2 - 2;
-}
-
-int
-WriteSpice::stageLoadPathIndex(Stage stage)
-{
- return stage * 2 - 1;
-}
-
-PathRef *
-WriteSpice::stageGateInputPath(Stage stage)
-{
- int path_index = stageGateInputPathIndex(stage);
- return path_expanded_.path(path_index);
-}
-
-PathRef *
-WriteSpice::stageDrvrPath(Stage stage)
-{
- int path_index = stageDrvrPathIndex(stage);
- return path_expanded_.path(path_index);
-}
-
-PathRef *
-WriteSpice::stageLoadPath(Stage stage)
-{
- int path_index = stageLoadPathIndex(stage);
- return path_expanded_.path(path_index);
-}
-
-TimingArc *
-WriteSpice::stageGateArc(Stage stage)
-{
- int path_index = stageDrvrPathIndex(stage);
- if (path_index >= 0)
- return path_expanded_.prevArc(path_index);
- else
- return NULL;
-}
-
-TimingArc *
-WriteSpice::stageWireArc(Stage stage)
-{
- int path_index = stageLoadPathIndex(stage);
- return path_expanded_.prevArc(path_index);
-}
-
-Edge *
-WriteSpice::stageGateEdge(Stage stage)
-{
- PathRef *path = stageGateInputPath(stage);
- TimingArc *arc = stageGateArc(stage);
- return path->prevEdge(arc, this);
-}
-
-Edge *
-WriteSpice::stageWireEdge(Stage stage)
-{
- PathRef *path = stageLoadPath(stage);
- TimingArc *arc = stageWireArc(stage);
- return path->prevEdge(arc, this);
-}
-
-Pin *
-WriteSpice::stageInputPin(Stage stage)
-{
- PathRef *path = stageGateInputPath(stage);
- return path->pin(this);
-}
-
-Pin *
-WriteSpice::stageDrvrPin(Stage stage)
-{
- PathRef *path = stageDrvrPath(stage);
- return path->pin(this);
-}
-
-Pin *
-WriteSpice::stageLoadPin(Stage stage)
-{
- PathRef *path = stageLoadPath(stage);
- return path->pin(this);
-}
-
-const char *
-WriteSpice::stageInputPinName(Stage stage)
-{
- const Pin *pin = stageInputPin(stage);
- return network_->pathName(pin);
-}
-
-const char *
-WriteSpice::stageDrvrPinName(Stage stage)
-{
- Pin *pin = stageDrvrPin(stage);
- return network_->pathName(pin);
-}
-
-const char *
-WriteSpice::stageLoadPinName(Stage stage)
-{
- const Pin *pin = stageLoadPin(stage);
- return network_->pathName(pin);
-}
-
-////////////////////////////////////////////////////////////////
-
-void
-split(const string &text,
- const string &delims,
- // Return values.
- StringVector &tokens)
-{
- auto start = text.find_first_not_of(delims);
- auto end = text.find_first_of(delims, start);
- while (end != string::npos) {
- tokens.push_back(text.substr(start, end - start));
- start = text.find_first_not_of(delims, end);
- end = text.find_first_of(delims, start);
- }
- if (start != string::npos)
- tokens.push_back(text.substr(start));
-}
-
-// fprintf for c++ streams.
-// Yes, I hate formatted output to ostream THAT much.
-void
-streamPrint(ofstream &stream,
- const char *fmt,
- ...)
-{
- va_list args;
- va_start(args, fmt);
- char *result;
- vasprintf(&result, fmt, args);
- stream << result;
- free(result);
- va_end(args);
-}
-
-} // namespace
diff --git a/search/WriteSpice.hh b/search/WriteSpice.hh
deleted file mode 100644
index c6d7465c..00000000
--- a/search/WriteSpice.hh
+++ /dev/null
@@ -1,36 +0,0 @@
-// OpenSTA, Static Timing Analyzer
-// Copyright (c) 2023, Parallax Software, Inc.
-//
-// 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 .
-
-#pragma once
-
-namespace sta {
-
-// Write a spice deck for path.
-// Throws FileNotReadable, FileNotWritable, SubcktEndsMissing
-void
-writeSpice(Path *path,
- // Spice file written for path.
- const char *spice_filename,
- // Subckts used by path included in spice file.
- const char *subckts_filename,
- // File of all cell spice subckt definitions.
- const char *lib_subckts_filename,
- // Device model file included in spice file.
- const char *models_filename,
- StaState *sta);
-
-} // namespace
-#endif