or20190411 write_path_spice with no voltage_map, pg_pins

This commit is contained in:
James Cherry 2019-04-13 15:01:14 -07:00
parent 2d519b4740
commit 4fc8801e76
4 changed files with 85 additions and 69 deletions

View File

@ -2473,9 +2473,9 @@ LibertyReader::visitClockGatingIntegratedCell(LibertyAttr *attr)
if (cell_) { if (cell_) {
const char *clock_gate_type = getAttrString(attr); const char *clock_gate_type = getAttrString(attr);
if (clock_gate_type) { if (clock_gate_type) {
if (stringBeginEq(clock_gate_type, "latch_posedge")) if (stringBeginEqual(clock_gate_type, "latch_posedge"))
cell_->setClockGateType(ClockGateType::latch_posedge); cell_->setClockGateType(ClockGateType::latch_posedge);
else if (stringBeginEq(clock_gate_type, "latch_negedge")) else if (stringBeginEqual(clock_gate_type, "latch_negedge"))
cell_->setClockGateType(ClockGateType::latch_negedge); cell_->setClockGateType(ClockGateType::latch_negedge);
else else
cell_->setClockGateType(ClockGateType::other); cell_->setClockGateType(ClockGateType::other);

View File

@ -108,9 +108,6 @@ private:
StringSet &path_cell_names); StringSet &path_cell_names);
void recordSpicePortNames(const char *cell_name, void recordSpicePortNames(const char *cell_name,
StringVector &tokens); StringVector &tokens);
float pgPortVoltage(const char *pg_port_name,
LibertyCell *cell);
float pgPortVoltage(LibertyPgPort *pg_port);
float maxTime(); float maxTime();
const char *nodeName(ParasiticNode *node); const char *nodeName(ParasiticNode *node);
void initNodeMap(const char *net_name); void initNodeMap(const char *net_name);
@ -159,12 +156,18 @@ private:
TimingArc *next_arc, TimingArc *next_arc,
DcalcAPIndex dcalc_ap_index); DcalcAPIndex dcalc_ap_index);
LibertyPort *onePort(FuncExpr *expr); LibertyPort *onePort(FuncExpr *expr);
void writeVoltageSource(const char *inst_name,
const char *port_name,
float voltage,
int &volt_index);
void writeVoltageSource(LibertyCell *cell, void writeVoltageSource(LibertyCell *cell,
const char *inst_name, const char *inst_name,
const char *subckt_port_name, const char *subckt_port_name,
const char *pg_port_name, const char *pg_port_name,
float voltage,
int &volt_index); int &volt_index);
float slewAxisMinValue(TimingArc *arc); float slewAxisMinValue(TimingArc *arc);
float pgPortVoltage(LibertyPgPort *pg_port);
// Stage "accessors". // Stage "accessors".
// //
@ -296,11 +299,16 @@ WritePathSpice::WritePathSpice(Path *path,
{ {
bool exists; bool exists;
default_library_->supplyVoltage(power_name_, power_voltage_, exists); default_library_->supplyVoltage(power_name_, power_voltage_, exists);
if (!exists) if (!exists) {
report_->error("supply %s voltage not found,\n", power_name_); auto dcalc_ap = path_->dcalcAnalysisPt(this);
auto op_cond = dcalc_ap->operatingConditions();
if (op_cond == nullptr)
op_cond = network_->defaultLibertyLibrary()->defaultOperatingConditions();
power_voltage_ = op_cond->voltage();
}
default_library_->supplyVoltage(gnd_name_, gnd_voltage_, exists); default_library_->supplyVoltage(gnd_name_, gnd_voltage_, exists);
if (!exists) if (!exists)
report_->error("supply %s voltage not found,\n", gnd_name_); gnd_voltage_ = 0.0;
} }
WritePathSpice::~WritePathSpice() WritePathSpice::~WritePathSpice()
@ -403,26 +411,31 @@ WritePathSpice::writeStageInstances()
streamPrint(spice_stream_, "\n"); streamPrint(spice_stream_, "\n");
} }
float
WritePathSpice::pgPortVoltage(const char *pg_port_name,
LibertyCell *cell)
{
auto pg_port = cell->findPgPort(pg_port_name);
return pgPortVoltage(pg_port);
}
float float
WritePathSpice::pgPortVoltage(LibertyPgPort *pg_port) WritePathSpice::pgPortVoltage(LibertyPgPort *pg_port)
{ {
auto cell = pg_port->cell(); LibertyLibrary *liberty = pg_port->cell()->libertyLibrary();
auto voltage_name = pg_port->voltageName(); float voltage = 0.0;
auto lib = cell->libertyLibrary();
float voltage;
bool exists; bool exists;
lib->supplyVoltage(voltage_name, voltage, exists); auto voltage_name = pg_port->voltageName();
if (!exists) if (voltage_name) {
report_->error("pg_port %s voltage %s not found,\n", liberty->supplyVoltage(voltage_name, voltage, exists);
pg_port->name(), voltage_name); if (!exists) {
if (stringEqual(voltage_name, power_name_))
voltage = power_voltage_;
else if (stringEqual(voltage_name, gnd_name_))
voltage = gnd_voltage_;
else
report_->error("pg_pin %s/%s voltage %s not found,\n",
pg_port->cell()->name(),
pg_port->name(),
voltage_name);
}
}
else
report_->error("Liberty pg_port %s/%s missing voltage_name attribute,\n",
pg_port->cell()->name(),
pg_port->name());
return voltage; return voltage;
} }
@ -818,6 +831,9 @@ WritePathSpice::writeSubcktInst(const Pin *input_pin)
} }
else if (pg_port) else if (pg_port)
streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname); streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname);
else if (stringEq(subckt_port_cname, power_name_)
|| stringEq(subckt_port_cname, gnd_name_))
streamPrint(spice_stream_, " %s/%s", inst_name, subckt_port_cname);
} }
streamPrint(spice_stream_, " %s\n", cell_name); streamPrint(spice_stream_, " %s\n", cell_name);
} }
@ -851,14 +867,16 @@ WritePathSpice::writeSubcktInstVoltSrcs(Stage stage,
debugPrint2(debug_, "write_spice", 2, " port %s%s\n", debugPrint2(debug_, "write_spice", 2, " port %s%s\n",
subckt_port_name, subckt_port_name,
pg_port ? " pwr/gnd" : ""); pg_port ? " pwr/gnd" : "");
if (pg_port) { if (pg_port)
auto voltage = pgPortVoltage(pg_port); writeVoltageSource(inst_name, subckt_port_name,
streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n", pgPortVoltage(pg_port), volt_index);
volt_index, else if (stringEq(subckt_port_name, power_name_))
inst_name, subckt_port_name, writeVoltageSource(inst_name, subckt_port_name,
voltage); power_voltage_, volt_index);
volt_index++; else if (stringEq(subckt_port_name, gnd_name_))
} else if (!(stringEq(subckt_port_name, input_port_name) writeVoltageSource(inst_name, subckt_port_name,
gnd_voltage_, volt_index);
else if (!(stringEq(subckt_port_name, input_port_name)
|| stringEq(subckt_port_name, drvr_port_name))) { || stringEq(subckt_port_name, drvr_port_name))) {
// Input voltage to sensitize path from gate input to output. // Input voltage to sensitize path from gate input to output.
auto port = cell->findLibertyPort(subckt_port_name); auto port = cell->findLibertyPort(subckt_port_name);
@ -879,11 +897,13 @@ WritePathSpice::writeSubcktInstVoltSrcs(Stage stage,
case LogicValue::unknown: case LogicValue::unknown:
writeVoltageSource(cell, inst_name, subckt_port_name, writeVoltageSource(cell, inst_name, subckt_port_name,
port->relatedGroundPin(), port->relatedGroundPin(),
gnd_voltage_,
volt_index); volt_index);
break; break;
case LogicValue::one: case LogicValue::one:
writeVoltageSource(cell, inst_name, subckt_port_name, writeVoltageSource(cell, inst_name, subckt_port_name,
port->relatedPowerPin(), port->relatedPowerPin(),
power_voltage_,
volt_index); volt_index);
break; break;
case LogicValue::rise: case LogicValue::rise:
@ -914,39 +934,38 @@ WritePathSpice::writeClkedStepSource(const Pin *pin,
writeStepVoltSource(pin, tr, slew, time, volt_index); writeStepVoltSource(pin, tr, slew, time, volt_index);
} }
void
WritePathSpice::writeVoltageSource(const char *inst_name,
const char *port_name,
float voltage,
int &volt_index)
{
streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n",
volt_index,
inst_name, port_name,
voltage);
volt_index++;
}
void void
WritePathSpice::writeVoltageSource(LibertyCell *cell, WritePathSpice::writeVoltageSource(LibertyCell *cell,
const char *inst_name, const char *inst_name,
const char *subckt_port_name, const char *subckt_port_name,
const char *pg_port_name, const char *pg_port_name,
float voltage,
int &volt_index) int &volt_index)
{ {
auto pg_port = cell->findPgPort(pg_port_name); if (pg_port_name) {
if (pg_port) { auto pg_port = cell->findPgPort(pg_port_name);
auto voltage_name = pg_port->voltageName(); if (pg_port)
if (voltage_name) { voltage = pgPortVoltage(pg_port);
float voltage;
bool exists;
cell->libertyLibrary()->supplyVoltage(voltage_name, voltage, exists);
if (!exists)
report_->error("pg_port %s voltage %s not found,\n",
pg_port_name, voltage_name);
streamPrint(spice_stream_, "v%d %s/%s 0 %.3f\n",
volt_index,
inst_name, subckt_port_name,
voltage);
volt_index++;
}
else else
report_->error("port %s %s voltage %s not found,\n", report_->error("%s pg_port %s not found,\n",
subckt_port_name, cell->name(),
pg_port_name, pg_port_name);
voltage_name);
} }
else writeVoltageSource(inst_name, subckt_port_name, voltage, volt_index);
report_->error("port %s %s not found,\n",
subckt_port_name,
pg_port_name);
} }
void void
@ -1345,7 +1364,7 @@ WritePathSpice::writeSubckts()
bool found_ends = false; bool found_ends = false;
while (getline(lib_subckts_stream, line)) { while (getline(lib_subckts_stream, line)) {
subckts_stream << line << "\n"; subckts_stream << line << "\n";
if (stringEqual(line.c_str(), ".ends")) { if (stringBeginEqual(line.c_str(), ".ends")) {
subckts_stream << "\n"; subckts_stream << "\n";
found_ends = true; found_ends = true;
break; break;
@ -1416,8 +1435,11 @@ WritePathSpice::recordSpicePortNames(const char *cell_name,
auto port_name = tokens[i].c_str(); auto port_name = tokens[i].c_str();
auto port = cell->findLibertyPort(port_name); auto port = cell->findLibertyPort(port_name);
auto pg_port = cell->findPgPort(port_name); auto pg_port = cell->findPgPort(port_name);
if (port == nullptr && pg_port == nullptr) if (port == nullptr
report_->error("subckt %s port %s has no corresponding liberty port or pg_port.\n", && pg_port == nullptr
&& !stringEqual(port_name, power_name_)
&& !stringEqual(port_name, gnd_name_))
report_->error("subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground.\n",
cell_name, port_name); cell_name, port_name);
spice_port_names->push_back(port_name); spice_port_names->push_back(port_name);
} }

View File

@ -1942,18 +1942,12 @@ proc write_path_spice { args } {
if { [info exists keys(-power)] } { if { [info exists keys(-power)] } {
set power $keys(-power) set power $keys(-power)
if { ![liberty_supply_exists $power] } {
sta_error "liberty $power not found.\n"
}
} else { } else {
sta_error "No -power specified.\n" sta_error "No -power specified.\n"
} }
if { [info exists keys(-ground)] } { if { [info exists keys(-ground)] } {
set ground $keys(-ground) set ground $keys(-ground)
if { ![liberty_supply_exists $ground] } {
sta_error "liberty $ground not found.\n"
}
} else { } else {
sta_error "No -ground specified.\n" sta_error "No -ground specified.\n"
} }

View File

@ -49,12 +49,12 @@ stringEqIf(const char *str1,
|| (str1 && str2 && strcmp(str1, str2) == 0); || (str1 && str2 && strcmp(str1, str2) == 0);
} }
// Compare the beginning of str1 to str2. // Case insensitive compare the beginning of str1 to str2.
inline bool inline bool
stringBeginEq(const char *str1, stringBeginEqual(const char *str1,
const char *str2) const char *str2)
{ {
return strncasecmp(str1, str2, strlen(str2)) == 9; return strncasecmp(str1, str2, strlen(str2)) == 0;
} }
// Case insensitive compare. // Case insensitive compare.