write path spice off path pins

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-04-15 14:31:47 -07:00
parent dc4bf88582
commit 79fda841d5
4 changed files with 89 additions and 18 deletions

View File

@ -16,8 +16,16 @@
#pragma once #pragma once
#include <string>
#include <set>
namespace sta { namespace sta {
using std::string;
using std::set;
typedef set<string> StdStringSet;
class Path; class Path;
class StaState; class StaState;
@ -33,6 +41,8 @@ writePathSpice(Path *path,
const char *lib_subckt_filename, const char *lib_subckt_filename,
// Device model file included in spice file. // Device model file included in spice file.
const char *model_filename, const char *model_filename,
// Nets off of path to include in the spice run.
StdStringSet *off_path_pin_names,
const char *power_name, const char *power_name,
const char *gnd_name, const char *gnd_name,
StaState *sta); StaState *sta);

View File

@ -45,11 +45,9 @@
namespace sta { namespace sta {
using std::string;
using std::ofstream; using std::ofstream;
using std::ifstream; using std::ifstream;
using std::max; using std::max;
using std::set;
typedef Map<string, StringVector*> CellSpicePortNames; typedef Map<string, StringVector*> CellSpicePortNames;
typedef int Stage; typedef int Stage;
@ -71,6 +69,7 @@ public:
const char *subckt_filename, const char *subckt_filename,
const char *lib_subckt_filename, const char *lib_subckt_filename,
const char *model_filename, const char *model_filename,
StdStringSet *off_path_pin_names,
const char *power_name, const char *power_name,
const char *gnd_name, const char *gnd_name,
const StaState *sta); const StaState *sta);
@ -100,8 +99,8 @@ private:
DcalcAPIndex dcalc_ap_index); DcalcAPIndex dcalc_ap_index);
void writeStageParasitics(Stage stage); void writeStageParasitics(Stage stage);
void writeSubckts(); void writeSubckts();
set<string> findPathCellnames(); StdStringSet findPathCellnames();
void findPathCellSubckts(set<string> &path_cell_names); void findPathCellSubckts(StdStringSet &path_cell_names);
void recordSpicePortNames(const char *cell_name, void recordSpicePortNames(const char *cell_name,
StringVector &tokens); StringVector &tokens);
float maxTime(); float maxTime();
@ -209,12 +208,14 @@ private:
const char *stageLoadPinName(Stage stage); const char *stageLoadPinName(Stage stage);
LibertyCell *stageLibertyCell(Stage stage); LibertyCell *stageLibertyCell(Stage stage);
Instance *stageInstance(Stage stage); Instance *stageInstance(Stage stage);
StdStringSet stageOffPathPinNames(Stage stage);
Path *path_; Path *path_;
const char *spice_filename_; const char *spice_filename_;
const char *subckt_filename_; const char *subckt_filename_;
const char *lib_subckt_filename_; const char *lib_subckt_filename_;
const char *model_filename_; const char *model_filename_;
StdStringSet *off_path_pin_names_;
const char *power_name_; const char *power_name_;
const char *gnd_name_; const char *gnd_name_;
@ -270,13 +271,14 @@ writePathSpice(Path *path,
const char *subckt_filename, const char *subckt_filename,
const char *lib_subckt_filename, const char *lib_subckt_filename,
const char *model_filename, const char *model_filename,
StdStringSet *off_path_pin_names,
const char *power_name, const char *power_name,
const char *gnd_name, const char *gnd_name,
StaState *sta) StaState *sta)
{ {
WritePathSpice writer(path, spice_filename, subckt_filename, WritePathSpice writer(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename, lib_subckt_filename, model_filename,
power_name, gnd_name, sta); off_path_pin_names, power_name, gnd_name, sta);
writer.writeSpice(); writer.writeSpice();
} }
@ -285,6 +287,7 @@ WritePathSpice::WritePathSpice(Path *path,
const char *subckt_filename, const char *subckt_filename,
const char *lib_subckt_filename, const char *lib_subckt_filename,
const char *model_filename, const char *model_filename,
StdStringSet *off_path_pin_names,
const char *power_name, const char *power_name,
const char *gnd_name, const char *gnd_name,
const StaState *sta) : const StaState *sta) :
@ -294,6 +297,7 @@ WritePathSpice::WritePathSpice(Path *path,
subckt_filename_(subckt_filename), subckt_filename_(subckt_filename),
lib_subckt_filename_(lib_subckt_filename), lib_subckt_filename_(lib_subckt_filename),
model_filename_(model_filename), model_filename_(model_filename),
off_path_pin_names_(off_path_pin_names),
power_name_(power_name), power_name_(power_name),
gnd_name_(gnd_name), gnd_name_(gnd_name),
path_expanded_(sta), path_expanded_(sta),
@ -388,6 +392,9 @@ WritePathSpice::writePrintStmt()
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
streamPrint(spice_stream_, " v(%s)", stageDrvrPinName(stage)); streamPrint(spice_stream_, " v(%s)", stageDrvrPinName(stage));
streamPrint(spice_stream_, " v(%s)", stageLoadPinName(stage)); streamPrint(spice_stream_, " v(%s)", stageLoadPinName(stage));
StdStringSet off_path_names = stageOffPathPinNames(stage);
for (const string &off_path_name : off_path_names)
streamPrint(spice_stream_, " v(%s)", off_path_name.c_str());
} }
streamPrint(spice_stream_, "\n\n"); streamPrint(spice_stream_, "\n\n");
} }
@ -441,13 +448,17 @@ WritePathSpice::writeStageInstances()
stageDrvrPinName(stage), stageDrvrPinName(stage),
stageLoadPinName(stage), stageLoadPinName(stage),
stage_cname); stage_cname);
else else {
streamPrint(spice_stream_, "x%s %s %s %s %s\n", streamPrint(spice_stream_, "x%s %s %s %s",
stage_cname, stage_cname,
stageGateInputPinName(stage), stageGateInputPinName(stage),
stageDrvrPinName(stage), stageDrvrPinName(stage),
stageLoadPinName(stage), stageLoadPinName(stage));
stage_cname); StdStringSet off_path_names = stageOffPathPinNames(stage);
for (const string &off_path_name : off_path_names)
streamPrint(spice_stream_, " %s", off_path_name.c_str());
streamPrint(spice_stream_, " %s\n", stage_cname);
}
} }
streamPrint(spice_stream_, "\n"); streamPrint(spice_stream_, "\n");
} }
@ -855,11 +866,16 @@ WritePathSpice::writeGateStage(Stage stage)
const char *drvr_pin_name = stageDrvrPinName(stage); const char *drvr_pin_name = stageDrvrPinName(stage);
const Pin *load_pin = stageLoadPin(stage); const Pin *load_pin = stageLoadPin(stage);
const char *load_pin_name = stageLoadPinName(stage); const char *load_pin_name = stageLoadPinName(stage);
streamPrint(spice_stream_, ".subckt stage%d %s %s %s\n", streamPrint(spice_stream_, ".subckt stage%d %s %s %s",
stage, stage,
input_pin_name, input_pin_name,
drvr_pin_name, drvr_pin_name,
load_pin_name); load_pin_name);
StdStringSet off_path_names = stageOffPathPinNames(stage);
for (const string &off_path_name : off_path_names)
streamPrint(spice_stream_, " %s", off_path_name.c_str());
streamPrint(spice_stream_, "\n");
// Driver subckt call. // Driver subckt call.
Instance *inst = stageInstance(stage); Instance *inst = stageInstance(stage);
LibertyPort *input_port = stageGateInputPort(stage); LibertyPort *input_port = stageGateInputPort(stage);
@ -1433,7 +1449,7 @@ WritePathSpice::nodeName(ParasiticNode *node)
void void
WritePathSpice::writeSubckts() WritePathSpice::writeSubckts()
{ {
set<string> path_cell_names = findPathCellnames(); StdStringSet path_cell_names = findPathCellnames();
findPathCellSubckts(path_cell_names); findPathCellSubckts(path_cell_names);
ifstream lib_subckts_stream(lib_subckt_filename_); ifstream lib_subckts_stream(lib_subckt_filename_);
@ -1489,10 +1505,10 @@ WritePathSpice::writeSubckts()
throw FileNotReadable(lib_subckt_filename_); throw FileNotReadable(lib_subckt_filename_);
} }
set<string> StdStringSet
WritePathSpice::findPathCellnames() WritePathSpice::findPathCellnames()
{ {
set<string> path_cell_names; StdStringSet path_cell_names;
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
TimingArc *arc = stageGateArc(stage); TimingArc *arc = stageGateArc(stage);
if (arc) { if (arc) {
@ -1520,7 +1536,7 @@ WritePathSpice::findPathCellnames()
// Subckts can call subckts (asap7). // Subckts can call subckts (asap7).
void void
WritePathSpice::findPathCellSubckts(set<string> &path_cell_names) WritePathSpice::findPathCellSubckts(StdStringSet &path_cell_names)
{ {
ifstream lib_subckts_stream(lib_subckt_filename_); ifstream lib_subckts_stream(lib_subckt_filename_);
if (lib_subckts_stream.is_open()) { if (lib_subckts_stream.is_open()) {
@ -1731,6 +1747,26 @@ WritePathSpice::stageLoadPinName(Stage stage)
return network_->pathName(pin); return network_->pathName(pin);
} }
StdStringSet
WritePathSpice::stageOffPathPinNames(Stage stage)
{
StdStringSet pin_names;
if (off_path_pin_names_) {
const PathRef *path = stageDrvrPath(stage);
Vertex *drvr = path->vertex(this);
VertexOutEdgeIterator edge_iter(drvr, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
Vertex *load = edge->to(graph_);
const Pin *load_pin = load->pin();
string load_pin_name = network_->pathName(load_pin);
if (off_path_pin_names_->find(load_pin_name) != off_path_pin_names_->end())
pin_names.insert(load_pin_name);
}
}
return pin_names;
}
Instance * Instance *
WritePathSpice::stageInstance(Stage stage) WritePathSpice::stageInstance(Stage stage)
{ {

View File

@ -254,6 +254,26 @@ tclListSeqConstChar(Tcl_Obj *const source,
return nullptr; return nullptr;
} }
StdStringSet *
tclListSetStdString(Tcl_Obj *const source,
Tcl_Interp *interp)
{
int argc;
Tcl_Obj **argv;
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
StdStringSet *set = new StdStringSet;
for (int i = 0; i < argc; i++) {
int length;
const char *str = Tcl_GetStringFromObj(argv[i], &length);
set->insert(str);
}
return set;
}
else
return nullptr;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Sequence out to tcl list. // Sequence out to tcl list.
@ -425,6 +445,10 @@ using namespace sta;
$1 = tclListSeqConstChar($input, interp); $1 = tclListSeqConstChar($input, interp);
} }
%typemap(in) StdStringSet* {
$1 = tclListSetStdString($input, interp);
}
%typemap(out) StringSeq* { %typemap(out) StringSeq* {
StringSeq *strs = $1; StringSeq *strs = $1;
Tcl_Obj *list = Tcl_NewListObj(0, nullptr); Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
@ -4865,12 +4889,13 @@ write_path_spice_cmd(PathRef *path,
const char *subckt_filename, const char *subckt_filename,
const char *lib_subckt_filename, const char *lib_subckt_filename,
const char *model_filename, const char *model_filename,
StdStringSet *off_path_pins,
const char *power_name, const char *power_name,
const char *gnd_name) const char *gnd_name)
{ {
Sta *sta = Sta::sta(); Sta *sta = Sta::sta();
writePathSpice(path, spice_filename, subckt_filename, writePathSpice(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename, lib_subckt_filename, model_filename, off_path_pins,
power_name, gnd_name, sta); power_name, gnd_name, sta);
} }

View File

@ -89,7 +89,7 @@ proc write_path_spice { args } {
set spice_file [file join $spice_dir "$path_name.sp"] set spice_file [file join $spice_dir "$path_name.sp"]
set subckt_file [file join $spice_dir "$path_name.subckt"] set subckt_file [file join $spice_dir "$path_name.subckt"]
write_path_spice_cmd $path $spice_file $subckt_file \ write_path_spice_cmd $path $spice_file $subckt_file \
$lib_subckt_file $model_file $power $ground $lib_subckt_file $model_file {} $power $ground
incr path_index incr path_index
} }
} }