write path spice off path pins
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
dc4bf88582
commit
79fda841d5
|
|
@ -16,8 +16,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::set;
|
||||
|
||||
typedef set<string> StdStringSet;
|
||||
|
||||
class Path;
|
||||
class StaState;
|
||||
|
||||
|
|
@ -33,7 +41,9 @@ writePathSpice(Path *path,
|
|||
const char *lib_subckt_filename,
|
||||
// Device model file included in spice file.
|
||||
const char *model_filename,
|
||||
const char *power_name,
|
||||
// Nets off of path to include in the spice run.
|
||||
StdStringSet *off_path_pin_names,
|
||||
const char *power_name,
|
||||
const char *gnd_name,
|
||||
StaState *sta);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,9 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::ofstream;
|
||||
using std::ifstream;
|
||||
using std::max;
|
||||
using std::set;
|
||||
|
||||
typedef Map<string, StringVector*> CellSpicePortNames;
|
||||
typedef int Stage;
|
||||
|
|
@ -71,6 +69,7 @@ public:
|
|||
const char *subckt_filename,
|
||||
const char *lib_subckt_filename,
|
||||
const char *model_filename,
|
||||
StdStringSet *off_path_pin_names,
|
||||
const char *power_name,
|
||||
const char *gnd_name,
|
||||
const StaState *sta);
|
||||
|
|
@ -100,8 +99,8 @@ private:
|
|||
DcalcAPIndex dcalc_ap_index);
|
||||
void writeStageParasitics(Stage stage);
|
||||
void writeSubckts();
|
||||
set<string> findPathCellnames();
|
||||
void findPathCellSubckts(set<string> &path_cell_names);
|
||||
StdStringSet findPathCellnames();
|
||||
void findPathCellSubckts(StdStringSet &path_cell_names);
|
||||
void recordSpicePortNames(const char *cell_name,
|
||||
StringVector &tokens);
|
||||
float maxTime();
|
||||
|
|
@ -209,12 +208,14 @@ private:
|
|||
const char *stageLoadPinName(Stage stage);
|
||||
LibertyCell *stageLibertyCell(Stage stage);
|
||||
Instance *stageInstance(Stage stage);
|
||||
StdStringSet stageOffPathPinNames(Stage stage);
|
||||
|
||||
Path *path_;
|
||||
const char *spice_filename_;
|
||||
const char *subckt_filename_;
|
||||
const char *lib_subckt_filename_;
|
||||
const char *model_filename_;
|
||||
StdStringSet *off_path_pin_names_;
|
||||
const char *power_name_;
|
||||
const char *gnd_name_;
|
||||
|
||||
|
|
@ -270,13 +271,14 @@ writePathSpice(Path *path,
|
|||
const char *subckt_filename,
|
||||
const char *lib_subckt_filename,
|
||||
const char *model_filename,
|
||||
const char *power_name,
|
||||
StdStringSet *off_path_pin_names,
|
||||
const char *power_name,
|
||||
const char *gnd_name,
|
||||
StaState *sta)
|
||||
{
|
||||
WritePathSpice writer(path, spice_filename, subckt_filename,
|
||||
lib_subckt_filename, model_filename,
|
||||
power_name, gnd_name, sta);
|
||||
off_path_pin_names, power_name, gnd_name, sta);
|
||||
writer.writeSpice();
|
||||
}
|
||||
|
||||
|
|
@ -285,6 +287,7 @@ WritePathSpice::WritePathSpice(Path *path,
|
|||
const char *subckt_filename,
|
||||
const char *lib_subckt_filename,
|
||||
const char *model_filename,
|
||||
StdStringSet *off_path_pin_names,
|
||||
const char *power_name,
|
||||
const char *gnd_name,
|
||||
const StaState *sta) :
|
||||
|
|
@ -294,6 +297,7 @@ WritePathSpice::WritePathSpice(Path *path,
|
|||
subckt_filename_(subckt_filename),
|
||||
lib_subckt_filename_(lib_subckt_filename),
|
||||
model_filename_(model_filename),
|
||||
off_path_pin_names_(off_path_pin_names),
|
||||
power_name_(power_name),
|
||||
gnd_name_(gnd_name),
|
||||
path_expanded_(sta),
|
||||
|
|
@ -388,6 +392,9 @@ WritePathSpice::writePrintStmt()
|
|||
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
|
||||
streamPrint(spice_stream_, " v(%s)", stageDrvrPinName(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");
|
||||
}
|
||||
|
|
@ -441,13 +448,17 @@ WritePathSpice::writeStageInstances()
|
|||
stageDrvrPinName(stage),
|
||||
stageLoadPinName(stage),
|
||||
stage_cname);
|
||||
else
|
||||
streamPrint(spice_stream_, "x%s %s %s %s %s\n",
|
||||
else {
|
||||
streamPrint(spice_stream_, "x%s %s %s %s",
|
||||
stage_cname,
|
||||
stageGateInputPinName(stage),
|
||||
stageDrvrPinName(stage),
|
||||
stageLoadPinName(stage),
|
||||
stage_cname);
|
||||
stageLoadPinName(stage));
|
||||
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");
|
||||
}
|
||||
|
|
@ -855,11 +866,16 @@ WritePathSpice::writeGateStage(Stage stage)
|
|||
const char *drvr_pin_name = stageDrvrPinName(stage);
|
||||
const Pin *load_pin = stageLoadPin(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,
|
||||
input_pin_name,
|
||||
drvr_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.
|
||||
Instance *inst = stageInstance(stage);
|
||||
LibertyPort *input_port = stageGateInputPort(stage);
|
||||
|
|
@ -1433,7 +1449,7 @@ WritePathSpice::nodeName(ParasiticNode *node)
|
|||
void
|
||||
WritePathSpice::writeSubckts()
|
||||
{
|
||||
set<string> path_cell_names = findPathCellnames();
|
||||
StdStringSet path_cell_names = findPathCellnames();
|
||||
findPathCellSubckts(path_cell_names);
|
||||
|
||||
ifstream lib_subckts_stream(lib_subckt_filename_);
|
||||
|
|
@ -1489,10 +1505,10 @@ WritePathSpice::writeSubckts()
|
|||
throw FileNotReadable(lib_subckt_filename_);
|
||||
}
|
||||
|
||||
set<string>
|
||||
StdStringSet
|
||||
WritePathSpice::findPathCellnames()
|
||||
{
|
||||
set<string> path_cell_names;
|
||||
StdStringSet path_cell_names;
|
||||
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
|
||||
TimingArc *arc = stageGateArc(stage);
|
||||
if (arc) {
|
||||
|
|
@ -1520,7 +1536,7 @@ WritePathSpice::findPathCellnames()
|
|||
|
||||
// Subckts can call subckts (asap7).
|
||||
void
|
||||
WritePathSpice::findPathCellSubckts(set<string> &path_cell_names)
|
||||
WritePathSpice::findPathCellSubckts(StdStringSet &path_cell_names)
|
||||
{
|
||||
ifstream lib_subckts_stream(lib_subckt_filename_);
|
||||
if (lib_subckts_stream.is_open()) {
|
||||
|
|
@ -1731,6 +1747,26 @@ WritePathSpice::stageLoadPinName(Stage stage)
|
|||
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 *
|
||||
WritePathSpice::stageInstance(Stage stage)
|
||||
{
|
||||
|
|
|
|||
27
tcl/StaTcl.i
27
tcl/StaTcl.i
|
|
@ -254,6 +254,26 @@ tclListSeqConstChar(Tcl_Obj *const source,
|
|||
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.
|
||||
|
|
@ -425,6 +445,10 @@ using namespace sta;
|
|||
$1 = tclListSeqConstChar($input, interp);
|
||||
}
|
||||
|
||||
%typemap(in) StdStringSet* {
|
||||
$1 = tclListSetStdString($input, interp);
|
||||
}
|
||||
|
||||
%typemap(out) StringSeq* {
|
||||
StringSeq *strs = $1;
|
||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
||||
|
|
@ -4865,12 +4889,13 @@ write_path_spice_cmd(PathRef *path,
|
|||
const char *subckt_filename,
|
||||
const char *lib_subckt_filename,
|
||||
const char *model_filename,
|
||||
StdStringSet *off_path_pins,
|
||||
const char *power_name,
|
||||
const char *gnd_name)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
writePathSpice(path, spice_filename, subckt_filename,
|
||||
lib_subckt_filename, model_filename,
|
||||
lib_subckt_filename, model_filename, off_path_pins,
|
||||
power_name, gnd_name, sta);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ proc write_path_spice { args } {
|
|||
set spice_file [file join $spice_dir "$path_name.sp"]
|
||||
set subckt_file [file join $spice_dir "$path_name.subckt"]
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue