write liberty bus port
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
d84051d76f
commit
170e6b7a40
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue