Skip to content

Commit

Permalink
sdc: add_false_path to PathConstraint logic
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanG077 committed Sep 26, 2024
1 parent 7f35139 commit e7f8ca5
Showing 1 changed file with 96 additions and 24 deletions.
120 changes: 96 additions & 24 deletions common/kernel/sdc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@

NEXTPNR_NAMESPACE_BEGIN

bool is_startpoint(Context *ctx, const PortRef &port)
{
int clkInfoCount;
TimingPortClass cls = ctx->getPortTimingClass(port.cell, port.port, clkInfoCount);

return cls == TMG_STARTPOINT || cls == TMG_REGISTER_OUTPUT;
}

bool is_endpoint(Context *ctx, const PortRef &port)
{
int clkInfoCount;
TimingPortClass cls = ctx->getPortTimingClass(port.cell, port.port, clkInfoCount);

return cls == TMG_ENDPOINT || cls == TMG_REGISTER_OUTPUT;
}

struct SdcEntity
{
enum EntityType
Expand Down Expand Up @@ -59,6 +75,23 @@ struct SdcEntity
return &ctx->ports.at(name);
}

PortRef get_pin(Context *ctx) const
{
if (type != ENTITY_PIN)
return PortRef{nullptr, IdString()};

CellInfo *cell = nullptr;
if (ctx->cells.count(name)) {
cell = ctx->cells.at(name).get();
} else {
return PortRef{nullptr, IdString()};
}
if (!cell->ports.count(pin))
return PortRef{nullptr, IdString()};

return PortRef{cell, pin};
}

NetInfo *get_net(Context *ctx) const
{
if (type == ENTITY_PIN) {
Expand Down Expand Up @@ -251,6 +284,60 @@ struct SDCParser
return args;
}

// Parse an argument to -from/to into the path_constraint
void sdc_into_path_constraint(const SdcEntity &ety, bool is_from, PathConstraint &ct)
{
auto &target = is_from ? ct.from : ct.to;
auto test_port = is_from ? is_startpoint : is_endpoint;
std::string tartget_str = is_from ? "startpoint" : "endpoint";

if (ety.type == SdcEntity::ENTITY_PIN) {
auto port_ref = ety.get_pin(ctx);
if (test_port(ctx, port_ref) == false) {
log_error("\"%s.%s\" is not a timing %s (line %d)\n", port_ref.cell->name.c_str(ctx),
port_ref.port.c_str(ctx), tartget_str.c_str(), lineno);
}
target.emplace(CellPortKey(port_ref));
} else if (ety.type == SdcEntity::ENTITY_NET) {
auto net = ety.get_net(ctx);
if (is_from) {
auto port_ref = net->driver;
if (test_port(ctx, port_ref) == false) {
log_error("\"%s.%s\" is not a timing %s (line %d)\n", port_ref.cell->name.c_str(ctx),
port_ref.port.c_str(ctx), tartget_str.c_str(), lineno);
}
target.emplace(CellPortKey(port_ref));
} else {
for (const auto &usr : net->users) {
if (test_port(ctx, usr) == false) {
log_error("\"%s.%s\" is not a timing %s (line %d)\n", usr.cell->name.c_str(ctx),
usr.port.c_str(ctx), tartget_str.c_str(), lineno);
}
target.emplace(CellPortKey(usr));
}
}
} else if (ety.type == SdcEntity::ENTITY_PORT) {
auto ioport_ref = ety.get_port(ctx);
auto net = ioport_ref->net;
if (is_from) {
auto port_ref = net->driver;
if (test_port(ctx, port_ref) == false) {
log_error("\"%s.%s\" is not a timing %s (line %d)\n", port_ref.cell->name.c_str(ctx),
port_ref.port.c_str(ctx), tartget_str.c_str(), lineno);
}
target.emplace(CellPortKey(port_ref));
} else {
for (const auto &usr : net->users) {
if (test_port(ctx, usr) == false) {
log_error("\"%s.%s\" is not a timing %s (line %d)\n", usr.cell->name.c_str(ctx),
usr.port.c_str(ctx), tartget_str.c_str(), lineno);
}
target.emplace(CellPortKey(usr));
}
}
}
}

SdcValue cmd_get_nets(const std::vector<SdcValue> &arguments)
{
std::vector<SdcEntity> nets;
Expand Down Expand Up @@ -318,7 +405,7 @@ struct SDCParser
if (pos == std::string::npos)
log_error("expected / in cell pin name '%s' (line %d)\n", s.c_str(), lineno);
pins.emplace_back(SdcEntity::ENTITY_PIN, ctx->id(s.substr(0, pos)), ctx->id(s.substr(pos + 1)));
if (pins.back().get_net(ctx) == nullptr) {
if (pins.back().get_pin(ctx).cell == nullptr) {
log_warning("cell pin '%s' not found\n", s.c_str());
pins.pop_back();
}
Expand Down Expand Up @@ -369,8 +456,8 @@ struct SDCParser

SdcValue cmd_set_false_path(const std::vector<SdcValue> &arguments)
{
NetInfo *from = nullptr;
NetInfo *to = nullptr;
PathConstraint ct;
ct.exception = FalsePath{};

for (int i = 1; i < int(arguments.size()); i++) {
auto &arg = arguments.at(i);
Expand All @@ -396,32 +483,17 @@ struct SDCParser

auto &ety = val.list.at(0);

NetInfo *net = nullptr;
if (ety.type == SdcEntity::ENTITY_PIN)
net = ety.get_net(ctx);
else if (ety.type == SdcEntity::ENTITY_NET)
net = ctx->nets.at(ety.name).get();
else if (ety.type == SdcEntity::ENTITY_PORT)
net = ctx->ports.at(ety.name).net;
else
log_error("set_false_path applies only to nets, cell pins, or IO ports (line %d)\n", lineno);

if (is_from) {
from = net;
} else {
to = net;
}
sdc_into_path_constraint(ety, is_from, ct);
}
}

if (from == nullptr) {
log_error("-from is required for set_false_path (line %d)\n", lineno);
} else if (to == nullptr) {
log_error("-to is required for set_false_path (line %d)\n", lineno);
if (ct.from.empty()) {
log_error("query specified in -from did not find any pins or ports (line %d)\n", lineno);
} else if (ct.to.empty()) {
log_error("query specified in -to did not find any pins or ports (line %d)\n", lineno);
}

log_warning("set_false_path from: %s, to: %s does not do anything(yet).\n", from->name.c_str(ctx),
to->name.c_str(ctx));
ctx->path_constraints.emplace_back(ct);

return std::string{};
}
Expand Down

0 comments on commit e7f8ca5

Please sign in to comment.