diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index e14b5792..87833b1a 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -17,6 +17,7 @@ #include "LibertyWriter.hh" #include +#include #include "Units.hh" #include "FuncExpr.hh" @@ -30,6 +31,8 @@ namespace sta { +using std::abs; + class LibertyWriter { public: @@ -44,9 +47,12 @@ protected: void writeFooter(); void writeTableTemplates(); void writeTableTemplate(TableTemplate *tbl_template); + void writeBusDcls(); void writeCells(); void writeCell(const LibertyCell *cell); void writePort(const LibertyPort *port); + void writeBusPort(const LibertyPort *port); + void writePortAttrs(const LibertyPort *port); void writeTimingArcSet(const TimingArcSet *arc_set); void writeTimingModels(const TimingArc *arc, RiseFall *rf); @@ -103,6 +109,7 @@ LibertyWriter::writeLibrary() writeHeader(); fprintf(stream_, "\n"); writeTableTemplates(); + writeBusDcls(); fprintf(stream_, "\n"); writeCells(); writeFooter(); @@ -237,6 +244,21 @@ LibertyWriter::writeTableAxis(TableAxis *axis, fprintf(stream_, "\");\n"); } +void +LibertyWriter::writeBusDcls() +{ + BusDclSeq dcls = library_->busDcls(); + for (BusDcl *dcl : dcls) { + fprintf(stream_, " type (\"%s\") {\n", dcl->name()); + fprintf(stream_, " base_type : array;\n"); + fprintf(stream_, " data_type : bit;\n"); + fprintf(stream_, " bit_width : %d;\n", abs(dcl->from() - dcl->to() + 1)); + fprintf(stream_, " bit_from : %d;\n", dcl->from()); + fprintf(stream_, " bit_to : %d;\n", dcl->to()); + fprintf(stream_, " }\n"); + } +} + void LibertyWriter::writeCells() { @@ -257,20 +279,50 @@ LibertyWriter::writeCell(const LibertyCell *cell) if (cell->isMacro()) fprintf(stream_, " is_macro : true;\n"); - LibertyCellPortBitIterator port_iter(cell); + LibertyCellPortIterator port_iter(cell); while (port_iter.hasNext()) { const LibertyPort *port = port_iter.next(); - writePort(port); + if (port->isBus()) + writeBusPort(port); + else if (port->isBundle()) + report_->error(704, "%s/%s bundled ports not supported.", + library_->name(), + cell->name()); + else + writePort(port); } fprintf(stream_, " }\n"); fprintf(stream_, "\n"); } +void +LibertyWriter::writeBusPort(const LibertyPort *port) +{ + fprintf(stream_, " bus(\"%s\") {\n", port->name()); + if (port->busDcl()) + fprintf(stream_, " bus_type : %s;\n", port->busDcl()->name()); + writePortAttrs(port); + + LibertyPortMemberIterator member_iter(port); + while (member_iter.hasNext()) { + LibertyPort *member = member_iter.next(); + writePort(member); + } + fprintf(stream_, " }\n"); +} + void LibertyWriter::writePort(const LibertyPort *port) { fprintf(stream_, " pin(\"%s\") {\n", port->name()); + writePortAttrs(port); + fprintf(stream_, " }\n"); +} + +void +LibertyWriter::writePortAttrs(const LibertyPort *port) +{ fprintf(stream_, " direction : %s;\n" , asString(port->direction())); auto func = port->function(); if (func) @@ -308,8 +360,6 @@ LibertyWriter::writePort(const LibertyPort *port) const TimingArcSet *arc_set = set_iter.next(); writeTimingArcSet(arc_set); } - - fprintf(stream_, " }\n"); } void diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 8c3c9eff..f2c73411 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -61,9 +61,10 @@ MakeTimingModel::makeTimingModel(const char *cell_name, for (Clock *clk : *sdc_->clocks()) sta_->setPropagatedClock(clk); - findInputToOutputPaths(); + //findInputToOutputPaths(); findInputSetupHolds(); findClkedOutputPaths(); + cell_->finish(false, report_, debug_); return library_; } @@ -106,16 +107,39 @@ void MakeTimingModel::makePorts() { const DcalcAnalysisPt *dcalc_ap = corner_->findDcalcAnalysisPt(min_max_); - InstancePinIterator *pin_iter = network_->pinIterator(network_->topInstance()); - while (pin_iter->hasNext()) { - Pin *pin = pin_iter->next(); - Port *port = network_->port(pin); - LibertyPort *lib_port = lib_builder_->makePort(cell_, network_->name(port)); - lib_port->setDirection(network_->direction(port)); - float load_cap = graph_delay_calc_->loadCap(pin, dcalc_ap); - lib_port->setCapacitance(load_cap); + Instance *top_inst = network_->topInstance(); + Cell *top_cell = network_->cell(top_inst); + CellPortIterator *port_iter = network_->portIterator(top_cell); + while (port_iter->hasNext()) { + Port *port = port_iter->next(); + const char *port_name = network_->name(port); + if (network_->isBus(port)) { + int from_index = network_->fromIndex(port); + int to_index = network_->toIndex(port); + BusDcl *bus_dcl = new BusDcl(port_name, from_index, to_index); + library_->addBusDcl(bus_dcl); + LibertyPort *lib_port = lib_builder_->makeBusPort(cell_, port_name, + from_index, to_index, + bus_dcl); + lib_port->setDirection(network_->direction(port)); + PortMemberIterator *member_iter = network_->memberIterator(port); + while (member_iter->hasNext()) { + Port *bit_port = member_iter->next(); + Pin *pin = network_->findPin(top_inst, bit_port); + LibertyPort *lib_bit_port = modelPort(pin); + float load_cap = graph_delay_calc_->loadCap(pin, dcalc_ap); + lib_bit_port->setCapacitance(load_cap); + } + } + else { + LibertyPort *lib_port = lib_builder_->makePort(cell_, port_name); + lib_port->setDirection(network_->direction(port)); + Pin *pin = network_->findPin(top_inst, port); + float load_cap = graph_delay_calc_->loadCap(pin, dcalc_ap); + lib_port->setCapacitance(load_cap); + } } - delete pin_iter; + delete port_iter; } // input -> output combinational paths @@ -150,7 +174,8 @@ MakeTimingModel::findInputToOutputPaths() network_->pathName(input_pin), network_->pathName(output_pin)); PathEnd *end = (*ends)[0]; - sta_->reportPathEnd(end); + if (debug_->check("make_timing_model", 2)) + sta_->reportPathEnd(end); } } }