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 <stdlib.h>
#include <algorithm>
#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

View File

@ -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);
}
}
}