write verilog match liberty bus bit order

This commit is contained in:
James Cherry 2019-07-02 07:07:34 -07:00
parent c759feaff6
commit eb9fdd1be0
13 changed files with 225 additions and 110 deletions

View File

@ -170,7 +170,7 @@ public:
Cell *cell() const; Cell *cell() const;
ConcreteLibrary *library() const { return cell_->library(); } ConcreteLibrary *library() const { return cell_->library(); }
PortDirection *direction() const { return direction_; } PortDirection *direction() const { return direction_; }
LibertyPort *libertyPort() { return liberty_port_; } LibertyPort *libertyPort() const { return liberty_port_; }
void setLibertyPort(LibertyPort *port); void setLibertyPort(LibertyPort *port);
void setDirection(PortDirection *dir); void setDirection(PortDirection *dir);
// Bundles are groups of related ports that do not use // Bundles are groups of related ports that do not use

View File

@ -755,9 +755,9 @@ ConcreteNetwork::cell(const Port *port) const
} }
LibertyPort * LibertyPort *
ConcreteNetwork::libertyPort(Port *port) const ConcreteNetwork::libertyPort(const Port *port) const
{ {
ConcretePort *cport = reinterpret_cast<ConcretePort*>(port); const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
return cport->libertyPort(); return cport->libertyPort();
} }

View File

@ -92,7 +92,7 @@ public:
virtual const char *name(const Port *port) const; virtual const char *name(const Port *port) const;
virtual Cell *cell(const Port *port) const; virtual Cell *cell(const Port *port) const;
virtual LibertyPort *libertyPort(Port *port) const; virtual LibertyPort *libertyPort(const Port *port) const;
virtual PortDirection *direction(const Port *port) const; virtual PortDirection *direction(const Port *port) const;
virtual bool isBundle(const Port *port) const; virtual bool isBundle(const Port *port) const;
virtual bool hasMembers(const Port *port) const; virtual bool hasMembers(const Port *port) const;

View File

@ -158,7 +158,7 @@ public:
// Port functions // Port functions
virtual const char *name(const Port *port) const = 0; virtual const char *name(const Port *port) const = 0;
virtual Cell *cell(const Port *port) const = 0; virtual Cell *cell(const Port *port) const = 0;
virtual LibertyPort *libertyPort(Port *port) const = 0; virtual LibertyPort *libertyPort(const Port *port) const = 0;
virtual PortDirection *direction(const Port *port) const = 0; virtual PortDirection *direction(const Port *port) const = 0;
// Bus port functions. // Bus port functions.
virtual bool isBus(const Port *port) const = 0; virtual bool isBus(const Port *port) const = 0;

View File

@ -199,7 +199,7 @@ NetworkNameAdapter::cell(const Port *port) const
} }
LibertyPort * LibertyPort *
NetworkNameAdapter::libertyPort(Port *port) const NetworkNameAdapter::libertyPort(const Port *port) const
{ {
return network_->libertyPort(port); return network_->libertyPort(port);
} }

View File

@ -64,7 +64,7 @@ public:
virtual const char *name(const Port *port) const; virtual const char *name(const Port *port) const;
virtual Cell *cell(const Port *port) const; virtual Cell *cell(const Port *port) const;
virtual LibertyPort *libertyPort(Port *port) const; virtual LibertyPort *libertyPort(const Port *port) const;
virtual PortDirection *direction(const Port *port) const; virtual PortDirection *direction(const Port *port) const;
virtual bool isBundle(const Port *port) const; virtual bool isBundle(const Port *port) const;
virtual bool isBus(const Port *port) const; virtual bool isBus(const Port *port) const;

View File

@ -678,6 +678,8 @@ Power::inferedWhen(FuncExpr *expr,
case FuncExpr::op_zero: case FuncExpr::op_zero:
return nullptr; return nullptr;
} }
// gcc not too smaht
return nullptr;
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////

View File

@ -138,6 +138,12 @@ PropertyValue::PropertyValue(LibertyCell *value) :
{ {
} }
PropertyValue::PropertyValue(LibertyPort *value) :
type_(type_liberty_port),
liberty_port_(value)
{
}
PropertyValue::PropertyValue(Library *value) : PropertyValue::PropertyValue(Library *value) :
type_(type_library), type_(type_library),
library_(value) library_(value)
@ -150,6 +156,12 @@ PropertyValue::PropertyValue(Cell *value) :
{ {
} }
PropertyValue::PropertyValue(Port *value) :
type_(type_port),
port_(value)
{
}
PropertyValue::PropertyValue(Instance *value) : PropertyValue::PropertyValue(Instance *value) :
type_(type_instance), type_(type_instance),
inst_(value) inst_(value)
@ -241,12 +253,18 @@ PropertyValue::PropertyValue(const PropertyValue &value) :
case Type::type_liberty_cell: case Type::type_liberty_cell:
liberty_cell_ = value.liberty_cell_; liberty_cell_ = value.liberty_cell_;
break; break;
case Type::type_cell: case Type::type_liberty_port:
cell_ = value.cell_; liberty_port_ = value.liberty_port_;
break; break;
case Type::type_library: case Type::type_library:
library_ = value.library_; library_ = value.library_;
break; break;
case Type::type_cell:
cell_ = value.cell_;
break;
case Type::type_port:
port_ = value.port_;
break;
case Type::type_instance: case Type::type_instance:
inst_ = value.inst_; inst_ = value.inst_;
break; break;
@ -290,17 +308,23 @@ PropertyValue::PropertyValue(PropertyValue &&value) :
case Type::type_bool: case Type::type_bool:
bool_ = value.bool_; bool_ = value.bool_;
break; break;
case Type::type_library:
library_ = value.library_;
break;
case Type::type_cell:
cell_ = value.cell_;
break;
case Type::type_port:
port_ = value.port_;
break;
case Type::type_liberty_library: case Type::type_liberty_library:
liberty_library_ = value.liberty_library_; liberty_library_ = value.liberty_library_;
break; break;
case Type::type_liberty_cell: case Type::type_liberty_cell:
liberty_cell_ = value.liberty_cell_; liberty_cell_ = value.liberty_cell_;
break; break;
case Type::type_cell: case Type::type_liberty_port:
cell_ = value.cell_; liberty_port_ = value.liberty_port_;
break;
case Type::type_library:
library_ = value.library_;
break; break;
case Type::type_instance: case Type::type_instance:
inst_ = value.inst_; inst_ = value.inst_;
@ -370,17 +394,23 @@ PropertyValue::operator=(const PropertyValue &value)
case Type::type_bool: case Type::type_bool:
bool_ = value.bool_; bool_ = value.bool_;
break; break;
case Type::type_library:
library_ = value.library_;
break;
case Type::type_cell:
cell_ = value.cell_;
break;
case Type::type_port:
port_ = value.port_;
break;
case Type::type_liberty_library: case Type::type_liberty_library:
liberty_library_ = value.liberty_library_; liberty_library_ = value.liberty_library_;
break; break;
case Type::type_liberty_cell: case Type::type_liberty_cell:
liberty_cell_ = value.liberty_cell_; liberty_cell_ = value.liberty_cell_;
break; break;
case Type::type_cell: case Type::type_liberty_port:
cell_ = value.cell_; liberty_port_ = value.liberty_port_;
break;
case Type::type_library:
library_ = value.library_;
break; break;
case Type::type_instance: case Type::type_instance:
inst_ = value.inst_; inst_ = value.inst_;
@ -427,17 +457,23 @@ PropertyValue::operator=(PropertyValue &&value)
case Type::type_bool: case Type::type_bool:
bool_ = value.bool_; bool_ = value.bool_;
break; break;
case Type::type_library:
library_ = value.library_;
break;
case Type::type_cell:
cell_ = value.cell_;
break;
case Type::type_port:
port_ = value.port_;
break;
case Type::type_liberty_library: case Type::type_liberty_library:
liberty_library_ = value.liberty_library_; liberty_library_ = value.liberty_library_;
break; break;
case Type::type_liberty_cell: case Type::type_liberty_cell:
liberty_cell_ = value.liberty_cell_; liberty_cell_ = value.liberty_cell_;
break; break;
case Type::type_cell: case Type::type_liberty_port:
cell_ = value.cell_; liberty_port_ = value.liberty_port_;
break;
case Type::type_library:
library_ = value.library_;
break; break;
case Type::type_instance: case Type::type_instance:
inst_ = value.inst_; inst_ = value.inst_;
@ -576,6 +612,9 @@ getProperty(const Port *port,
return PropertyValue(network->name(port)); return PropertyValue(network->name(port));
else if (stringEqual(property, "direction")) else if (stringEqual(property, "direction"))
return PropertyValue(network->direction(port)->name()); return PropertyValue(network->direction(port)->name());
else if (stringEqual(property, "liberty_port"))
return PropertyValue(network->libertyPort(port));
else if (stringEqual(property, "activity")) { else if (stringEqual(property, "activity")) {
const Instance *top_inst = network->topInstance(); const Instance *top_inst = network->topInstance();
const Pin *pin = network->findPin(top_inst, port); const Pin *pin = network->findPin(top_inst, port);

View File

@ -30,12 +30,22 @@ using std::string;
class Sta; class Sta;
class PwrActivity; class PwrActivity;
// Adding a new property type
// value union
// enum Type
// constructor
// copy constructor switch clause
// move constructor switch clause
// operator= & switch clause
// operator= && switch clause
// StaTcl.i swig %typemap(out) PropertyValue switch clause
class PropertyValue class PropertyValue
{ {
public: public:
enum Type { type_none, type_string, type_float, type_bool, enum Type { type_none, type_string, type_float, type_bool,
type_liberty_library, type_liberty_cell, type_library, type_cell, type_port,
type_library, type_cell, type_liberty_library, type_liberty_cell, type_liberty_port,
type_instance, type_pin, type_pins, type_net, type_instance, type_pin, type_pins, type_net,
type_clk, type_clks, type_path_refs, type_pwr_activity }; type_clk, type_clks, type_path_refs, type_pwr_activity };
PropertyValue(); PropertyValue();
@ -43,10 +53,12 @@ public:
PropertyValue(string &value); PropertyValue(string &value);
PropertyValue(float value); PropertyValue(float value);
PropertyValue(bool value); PropertyValue(bool value);
PropertyValue(Library *value);
PropertyValue(Cell *value);
PropertyValue(Port *value);
PropertyValue(LibertyLibrary *value); PropertyValue(LibertyLibrary *value);
PropertyValue(LibertyCell *value); PropertyValue(LibertyCell *value);
PropertyValue(Cell *value); PropertyValue(LibertyPort *value);
PropertyValue(Library *value);
PropertyValue(Instance *value); PropertyValue(Instance *value);
PropertyValue(Pin *value); PropertyValue(Pin *value);
PropertyValue(PinSeq *value); PropertyValue(PinSeq *value);
@ -68,8 +80,10 @@ public:
bool boolValue() const { return bool_; } bool boolValue() const { return bool_; }
LibertyLibrary *libertyLibrary() const { return liberty_library_; } LibertyLibrary *libertyLibrary() const { return liberty_library_; }
LibertyCell *libertyCell() const { return liberty_cell_; } LibertyCell *libertyCell() const { return liberty_cell_; }
LibertyPort *libertyPort() const { return liberty_port_; }
Library *library() const { return library_; } Library *library() const { return library_; }
Cell *cell() const { return cell_; } Cell *cell() const { return cell_; }
Port *port() const { return port_; }
Instance *instance() const { return inst_; } Instance *instance() const { return inst_; }
Pin *pin() const { return pin_; } Pin *pin() const { return pin_; }
PinSeq *pins() const { return pins_; } PinSeq *pins() const { return pins_; }
@ -89,10 +103,12 @@ private:
const char *string_; const char *string_;
float float_; float float_;
bool bool_; bool bool_;
LibertyLibrary *liberty_library_;
LibertyCell *liberty_cell_;
Library *library_; Library *library_;
Cell *cell_; Cell *cell_;
Port *port_;
LibertyLibrary *liberty_library_;
LibertyCell *liberty_cell_;
LibertyPort *liberty_port_;
Instance *inst_; Instance *inst_;
Pin *pin_; Pin *pin_;
PinSeq *pins_; PinSeq *pins_;

View File

@ -1759,18 +1759,13 @@ proc parse_disable_inst_ports { inst port_name } {
if { $port_name == "" } { if { $port_name == "" } {
set ports "NULL" set ports "NULL"
} else { } else {
set cell [instance_property $inst liberty_cell] set cell [instance_property $inst cell]
set port [$cell find_liberty_port $port_name] set port [$cell find_port $port_name]
if { $port == "NULL" } { if { $port == "NULL" } {
sta_error "pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found." sta_error "pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found."
} else { } else {
set ports [port_members $port] set lib_port [get_property $port liberty_port]
foreach port $ports { set ports [port_members $lib_port]
set member_name [get_full_name $port]
if { [$inst find_pin $member_name] == "NULL" } {
sta_error "pin '[get_full_name $inst]]${hierarchy_separator}${member_name}' not found."
}
}
} }
} }
return $ports return $ports

View File

@ -1401,6 +1401,42 @@ using namespace sta;
Tcl_SetResult(interp, const_cast<char*>(bool_string), TCL_STATIC); Tcl_SetResult(interp, const_cast<char*>(bool_string), TCL_STATIC);
} }
break; break;
case PropertyValue::Type::type_library: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.library(),
SWIGTYPE_p_Library, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_cell: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.cell(),
SWIGTYPE_p_Cell, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_port: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.port(),
SWIGTYPE_p_Port, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_liberty_library: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyLibrary(),
SWIGTYPE_p_LibertyLibrary, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_liberty_cell: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyCell(),
SWIGTYPE_p_LibertyCell, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_liberty_port: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyPort(),
SWIGTYPE_p_LibertyPort, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_instance: { case PropertyValue::Type::type_instance: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.instance(), Tcl_Obj *obj = SWIG_NewInstanceObj(value.instance(),
SWIGTYPE_p_Instance, false); SWIGTYPE_p_Instance, false);
@ -1430,30 +1466,6 @@ using namespace sta;
Tcl_SetObjResult(interp, obj); Tcl_SetObjResult(interp, obj);
} }
break; break;
case PropertyValue::Type::type_liberty_cell: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyCell(),
SWIGTYPE_p_LibertyCell, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_liberty_library: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyLibrary(),
SWIGTYPE_p_LibertyLibrary, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_library: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.library(),
SWIGTYPE_p_Library, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_cell: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.cell(),
SWIGTYPE_p_Cell, false);
Tcl_SetObjResult(interp, obj);
}
break;
case PropertyValue::Type::type_clk: { case PropertyValue::Type::type_clk: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.clock(), Tcl_Obj *obj = SWIG_NewInstanceObj(value.clock(),
SWIGTYPE_p_Clock, false); SWIGTYPE_p_Clock, false);

View File

@ -1755,8 +1755,7 @@ VerilogReader::linkNetwork(const char *top_cell_name,
return top_instance; return top_instance;
} }
else { else {
report->error("%s is not a verilog module.\n", report->error("%s is not a verilog module.\n", top_cell_name);
network_->name(top_cell));
return nullptr; return nullptr;
} }
} }

View File

@ -18,6 +18,7 @@
#include "Machine.hh" #include "Machine.hh"
#include "Error.hh" #include "Error.hh"
#include "PortDirection.hh" #include "PortDirection.hh"
#include "Liberty.hh"
#include "Network.hh" #include "Network.hh"
#include "NetworkCmp.hh" #include "NetworkCmp.hh"
#include "VerilogNamespace.hh" #include "VerilogNamespace.hh"
@ -40,6 +41,15 @@ protected:
const char *verilogPortDir(PortDirection *dir); const char *verilogPortDir(PortDirection *dir);
void writeChildren(Instance *inst); void writeChildren(Instance *inst);
void writeChild(Instance *child); void writeChild(Instance *child);
void writeInstPin(Instance *inst,
Port *port,
bool &first_port);
void writeInstBusPin(Instance *inst,
Port *port,
bool &first_port);
void writeInstBusPinBit(Instance *inst,
Port *port,
bool &first_member);
const char *filename_; const char *filename_;
bool sort_; bool sort_;
@ -194,17 +204,82 @@ VerilogWriter::writeChild(Instance *child)
CellPortIterator *port_iter = network_->portIterator(child_cell); CellPortIterator *port_iter = network_->portIterator(child_cell);
while (port_iter->hasNext()) { while (port_iter->hasNext()) {
Port *port = port_iter->next(); Port *port = port_iter->next();
const char *port_name = network_->name(port); if (network_->hasMembers(port))
if (network_->hasMembers(port)) { writeInstBusPin(child, port, first_port);
else
writeInstPin(child, port, first_port);
}
delete port_iter;
fprintf(stream_, ");\n");
}
void
VerilogWriter::writeInstPin(Instance *inst,
Port *port,
bool &first_port)
{
Pin *pin = network_->findPin(inst, port);
if (pin) {
Net *net = network_->net(pin);
if (net) {
const char *net_name = network_->name(net);
const char *net_vname = netVerilogName(net_name, network_->pathEscape());
if (!first_port) if (!first_port)
fprintf(stream_, ",\n "); fprintf(stream_, ",\n ");
const char *port_name = network_->name(port);
fprintf(stream_, ".%s(%s)",
port_name,
net_vname);
first_port = false;
}
}
}
void
VerilogWriter::writeInstBusPin(Instance *inst,
Port *port,
bool &first_port)
{
if (!first_port)
fprintf(stream_, ",\n ");
const char *port_name = network_->name(port);
fprintf(stream_, ".%s({", port_name); fprintf(stream_, ".%s({", port_name);
first_port = false; first_port = false;
bool first_member = true; bool first_member = true;
PortSeq members;
PortMemberIterator *member_iter = network_->memberIterator(port); PortMemberIterator *member_iter = network_->memberIterator(port);
while (member_iter->hasNext()) { while (member_iter->hasNext()) {
Port *member = member_iter->next(); Port *member = member_iter->next();
Pin *pin = network_->findPin(child, member); members.push_back(member);
}
delete member_iter;
// Match the bit_from/bit_to order of the liberty cell if it exists.
LibertyPort *lib_port = network_->libertyPort(port);
if (lib_port
&& (network_->fromIndex(port) > network_->toIndex(port))
!= (lib_port->fromIndex() > lib_port->toIndex())) {
for (int i = members.size() - 1; i >= 0; i--) {
Port *member = members[i];
writeInstBusPinBit(inst, member, first_member);
}
}
else {
for (int i = 0; i < members.size(); i++) {
Port *member = members[i];
writeInstBusPinBit(inst, member, first_member);
}
}
fprintf(stream_, "})");
}
void
VerilogWriter::writeInstBusPinBit(Instance *inst,
Port *port,
bool &first_member)
{
Pin *pin = network_->findPin(inst, port);
const char *net_name = nullptr; const char *net_name = nullptr;
if (pin) { if (pin) {
Net *net = network_->net(pin); Net *net = network_->net(pin);
@ -220,28 +295,5 @@ VerilogWriter::writeChild(Instance *child)
fprintf(stream_, "%s", net_vname); fprintf(stream_, "%s", net_vname);
first_member = false; first_member = false;
} }
delete member_iter;
fprintf(stream_, "})");
}
else {
Pin *pin = network_->findPin(child, port);
if (pin) {
Net *net = network_->net(pin);
if (net) {
const char *net_name = network_->name(net);
const char *net_vname = netVerilogName(net_name, network_->pathEscape());
if (!first_port)
fprintf(stream_, ",\n ");
fprintf(stream_, ".%s(%s)",
port_name,
net_vname);
first_port = false;
}
}
}
}
delete port_iter;
fprintf(stream_, ");\n");
}
} // namespace } // namespace