write liberty bus port

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-06-09 19:19:05 -07:00
parent d84051d76f
commit 170e6b7a40
2 changed files with 90 additions and 15 deletions

View File

@ -17,6 +17,7 @@
#include "LibertyWriter.hh" #include "LibertyWriter.hh"
#include <stdlib.h> #include <stdlib.h>
#include <algorithm>
#include "Units.hh" #include "Units.hh"
#include "FuncExpr.hh" #include "FuncExpr.hh"
@ -30,6 +31,8 @@
namespace sta { namespace sta {
using std::abs;
class LibertyWriter class LibertyWriter
{ {
public: public:
@ -44,9 +47,12 @@ protected:
void writeFooter(); void writeFooter();
void writeTableTemplates(); void writeTableTemplates();
void writeTableTemplate(TableTemplate *tbl_template); void writeTableTemplate(TableTemplate *tbl_template);
void writeBusDcls();
void writeCells(); void writeCells();
void writeCell(const LibertyCell *cell); void writeCell(const LibertyCell *cell);
void writePort(const LibertyPort *port); void writePort(const LibertyPort *port);
void writeBusPort(const LibertyPort *port);
void writePortAttrs(const LibertyPort *port);
void writeTimingArcSet(const TimingArcSet *arc_set); void writeTimingArcSet(const TimingArcSet *arc_set);
void writeTimingModels(const TimingArc *arc, void writeTimingModels(const TimingArc *arc,
RiseFall *rf); RiseFall *rf);
@ -103,6 +109,7 @@ LibertyWriter::writeLibrary()
writeHeader(); writeHeader();
fprintf(stream_, "\n"); fprintf(stream_, "\n");
writeTableTemplates(); writeTableTemplates();
writeBusDcls();
fprintf(stream_, "\n"); fprintf(stream_, "\n");
writeCells(); writeCells();
writeFooter(); writeFooter();
@ -237,6 +244,21 @@ LibertyWriter::writeTableAxis(TableAxis *axis,
fprintf(stream_, "\");\n"); 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 void
LibertyWriter::writeCells() LibertyWriter::writeCells()
{ {
@ -257,20 +279,50 @@ LibertyWriter::writeCell(const LibertyCell *cell)
if (cell->isMacro()) if (cell->isMacro())
fprintf(stream_, " is_macro : true;\n"); fprintf(stream_, " is_macro : true;\n");
LibertyCellPortBitIterator port_iter(cell); LibertyCellPortIterator port_iter(cell);
while (port_iter.hasNext()) { while (port_iter.hasNext()) {
const LibertyPort *port = port_iter.next(); 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");
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 void
LibertyWriter::writePort(const LibertyPort *port) LibertyWriter::writePort(const LibertyPort *port)
{ {
fprintf(stream_, " pin(\"%s\") {\n", port->name()); 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())); fprintf(stream_, " direction : %s;\n" , asString(port->direction()));
auto func = port->function(); auto func = port->function();
if (func) if (func)
@ -308,8 +360,6 @@ LibertyWriter::writePort(const LibertyPort *port)
const TimingArcSet *arc_set = set_iter.next(); const TimingArcSet *arc_set = set_iter.next();
writeTimingArcSet(arc_set); writeTimingArcSet(arc_set);
} }
fprintf(stream_, " }\n");
} }
void void

View File

@ -61,9 +61,10 @@ MakeTimingModel::makeTimingModel(const char *cell_name,
for (Clock *clk : *sdc_->clocks()) for (Clock *clk : *sdc_->clocks())
sta_->setPropagatedClock(clk); sta_->setPropagatedClock(clk);
findInputToOutputPaths(); //findInputToOutputPaths();
findInputSetupHolds(); findInputSetupHolds();
findClkedOutputPaths(); findClkedOutputPaths();
cell_->finish(false, report_, debug_); cell_->finish(false, report_, debug_);
return library_; return library_;
} }
@ -106,16 +107,39 @@ void
MakeTimingModel::makePorts() MakeTimingModel::makePorts()
{ {
const DcalcAnalysisPt *dcalc_ap = corner_->findDcalcAnalysisPt(min_max_); const DcalcAnalysisPt *dcalc_ap = corner_->findDcalcAnalysisPt(min_max_);
InstancePinIterator *pin_iter = network_->pinIterator(network_->topInstance()); Instance *top_inst = network_->topInstance();
while (pin_iter->hasNext()) { Cell *top_cell = network_->cell(top_inst);
Pin *pin = pin_iter->next(); CellPortIterator *port_iter = network_->portIterator(top_cell);
Port *port = network_->port(pin); while (port_iter->hasNext()) {
LibertyPort *lib_port = lib_builder_->makePort(cell_, network_->name(port)); Port *port = port_iter->next();
lib_port->setDirection(network_->direction(port)); const char *port_name = network_->name(port);
float load_cap = graph_delay_calc_->loadCap(pin, dcalc_ap); if (network_->isBus(port)) {
lib_port->setCapacitance(load_cap); 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 // input -> output combinational paths
@ -150,7 +174,8 @@ MakeTimingModel::findInputToOutputPaths()
network_->pathName(input_pin), network_->pathName(input_pin),
network_->pathName(output_pin)); network_->pathName(output_pin));
PathEnd *end = (*ends)[0]; PathEnd *end = (*ends)[0];
sta_->reportPathEnd(end); if (debug_->check("make_timing_model", 2))
sta_->reportPathEnd(end);
} }
} }
} }