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;
ConcreteLibrary *library() const { return cell_->library(); }
PortDirection *direction() const { return direction_; }
LibertyPort *libertyPort() { return liberty_port_; }
LibertyPort *libertyPort() const { return liberty_port_; }
void setLibertyPort(LibertyPort *port);
void setDirection(PortDirection *dir);
// Bundles are groups of related ports that do not use

View File

@ -755,9 +755,9 @@ ConcreteNetwork::cell(const Port *port) const
}
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();
}

View File

@ -92,7 +92,7 @@ public:
virtual const char *name(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 bool isBundle(const Port *port) const;
virtual bool hasMembers(const Port *port) const;

View File

@ -158,7 +158,7 @@ public:
// Port functions
virtual const char *name(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;
// Bus port functions.
virtual bool isBus(const Port *port) const = 0;

View File

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

View File

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

View File

@ -30,12 +30,22 @@ using std::string;
class Sta;
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
{
public:
enum Type { type_none, type_string, type_float, type_bool,
type_liberty_library, type_liberty_cell,
type_library, type_cell,
type_library, type_cell, type_port,
type_liberty_library, type_liberty_cell, type_liberty_port,
type_instance, type_pin, type_pins, type_net,
type_clk, type_clks, type_path_refs, type_pwr_activity };
PropertyValue();
@ -43,10 +53,12 @@ public:
PropertyValue(string &value);
PropertyValue(float value);
PropertyValue(bool value);
PropertyValue(Library *value);
PropertyValue(Cell *value);
PropertyValue(Port *value);
PropertyValue(LibertyLibrary *value);
PropertyValue(LibertyCell *value);
PropertyValue(Cell *value);
PropertyValue(Library *value);
PropertyValue(LibertyPort *value);
PropertyValue(Instance *value);
PropertyValue(Pin *value);
PropertyValue(PinSeq *value);
@ -68,8 +80,10 @@ public:
bool boolValue() const { return bool_; }
LibertyLibrary *libertyLibrary() const { return liberty_library_; }
LibertyCell *libertyCell() const { return liberty_cell_; }
LibertyPort *libertyPort() const { return liberty_port_; }
Library *library() const { return library_; }
Cell *cell() const { return cell_; }
Port *port() const { return port_; }
Instance *instance() const { return inst_; }
Pin *pin() const { return pin_; }
PinSeq *pins() const { return pins_; }
@ -89,10 +103,12 @@ private:
const char *string_;
float float_;
bool bool_;
LibertyLibrary *liberty_library_;
LibertyCell *liberty_cell_;
Library *library_;
Cell *cell_;
Port *port_;
LibertyLibrary *liberty_library_;
LibertyCell *liberty_cell_;
LibertyPort *liberty_port_;
Instance *inst_;
Pin *pin_;
PinSeq *pins_;

View File

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

View File

@ -1401,6 +1401,42 @@ using namespace sta;
Tcl_SetResult(interp, const_cast<char*>(bool_string), TCL_STATIC);
}
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: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.instance(),
SWIGTYPE_p_Instance, false);
@ -1430,30 +1466,6 @@ using namespace sta;
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_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: {
Tcl_Obj *obj = SWIG_NewInstanceObj(value.clock(),
SWIGTYPE_p_Clock, false);

View File

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

View File

@ -18,6 +18,7 @@
#include "Machine.hh"
#include "Error.hh"
#include "PortDirection.hh"
#include "Liberty.hh"
#include "Network.hh"
#include "NetworkCmp.hh"
#include "VerilogNamespace.hh"
@ -40,6 +41,15 @@ protected:
const char *verilogPortDir(PortDirection *dir);
void writeChildren(Instance *inst);
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_;
bool sort_;
@ -194,54 +204,96 @@ VerilogWriter::writeChild(Instance *child)
CellPortIterator *port_iter = network_->portIterator(child_cell);
while (port_iter->hasNext()) {
Port *port = port_iter->next();
const char *port_name = network_->name(port);
if (network_->hasMembers(port)) {
if (!first_port)
fprintf(stream_, ",\n ");
fprintf(stream_, ".%s({", port_name);
first_port = false;
bool first_member = true;
PortMemberIterator *member_iter = network_->memberIterator(port);
while (member_iter->hasNext()) {
Port *member = member_iter->next();
Pin *pin = network_->findPin(child, member);
const char *net_name = nullptr;
if (pin) {
Net *net = network_->net(pin);
if (net)
net_name = network_->name(net);
}
if (net_name == nullptr)
// There is no verilog syntax to "skip" a bit in the concatentation.
net_name = stringPrintTmp("_NC%d", unconnected_net_index_++);
const char *net_vname = netVerilogName(net_name, network_->pathEscape());
if (!first_member)
fprintf(stream_, ",\n ");
fprintf(stream_, "%s", net_vname);
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;
}
}
}
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)
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);
first_port = false;
bool first_member = true;
PortSeq members;
PortMemberIterator *member_iter = network_->memberIterator(port);
while (member_iter->hasNext()) {
Port *member = member_iter->next();
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;
if (pin) {
Net *net = network_->net(pin);
if (net)
net_name = network_->name(net);
}
if (net_name == nullptr)
// There is no verilog syntax to "skip" a bit in the concatentation.
net_name = stringPrintTmp("_NC%d", unconnected_net_index_++);
const char *net_vname = netVerilogName(net_name, network_->pathEscape());
if (!first_member)
fprintf(stream_, ",\n ");
fprintf(stream_, "%s", net_vname);
first_member = false;
}
} // namespace