mirror of https://github.com/YosysHQ/nextpnr.git
fabulous: improve pcf implementation, create global clock only if necessary (#1654)
* fabulous: report port as unconstrained unless BEL attr set Signed-off-by: Leo Moser <leomoser99@gmail.com> * fabulous: only create global clock if needed Signed-off-by: Leo Moser <leomoser99@gmail.com> --------- Signed-off-by: Leo Moser <leomoser99@gmail.com>
This commit is contained in:
parent
eba9764645
commit
50c2ca21a3
|
|
@ -163,8 +163,6 @@ struct FabulousImpl : ViaductAPI
|
|||
FabricConfig cfg; // TODO: non-default config
|
||||
ViaductHelpers h;
|
||||
|
||||
WireId global_clk_wire;
|
||||
|
||||
std::string fasm_file;
|
||||
|
||||
std::string pcf_file;
|
||||
|
|
@ -222,6 +220,7 @@ struct FabulousImpl : ViaductAPI
|
|||
} else if (bel_type.in(id_InPass4_frame_config, id_OutPass4_frame_config)) {
|
||||
WireId clk_wire = get_wire(tile, id_CLK, id_REG_CLK);
|
||||
if (ctx->wires.at(clk_wire.index).uphill.empty()) {
|
||||
WireId global_clk_wire = get_wire(ctx->id("X0Y0"), id_CLK, id_CLK);
|
||||
add_pseudo_pip(global_clk_wire, clk_wire, id_global_clock);
|
||||
}
|
||||
ctx->addBelInput(bel, id_CLK, clk_wire);
|
||||
|
|
@ -234,6 +233,7 @@ struct FabulousImpl : ViaductAPI
|
|||
} else if (bel_type == id_RegFile_32x4) {
|
||||
WireId clk_wire = get_wire(tile, id_CLK, id_REG_CLK);
|
||||
ctx->addBelInput(bel, id_CLK, clk_wire);
|
||||
WireId global_clk_wire = get_wire(ctx->id("X0Y0"), id_CLK, id_CLK);
|
||||
add_pseudo_pip(global_clk_wire, clk_wire, id_global_clock);
|
||||
for (parser_view p : ports) {
|
||||
IdString port_id = p.to_id(ctx);
|
||||
|
|
@ -270,6 +270,7 @@ struct FabulousImpl : ViaductAPI
|
|||
// TODO: split LC mode, LUT permutation pseudo-switchbox, LUT thru pseudo-pips
|
||||
WireId clk_wire = get_wire(tile, ctx->idf("L%s_CLK", idx.c_str(ctx)), id_LUT_CLK);
|
||||
ctx->addBelInput(bel, id_CLK, clk_wire);
|
||||
WireId global_clk_wire = get_wire(ctx->id("X0Y0"), id_CLK, id_CLK);
|
||||
add_pseudo_pip(global_clk_wire, clk_wire, id_global_clock);
|
||||
blk_trk->set_bel_type(bel, BelFlags::BLOCK_CLB, BelFlags::FUNC_LC_COMB, loc.z);
|
||||
for (parser_view p : ports) {
|
||||
|
|
@ -303,10 +304,13 @@ struct FabulousImpl : ViaductAPI
|
|||
void init_global_clock()
|
||||
{
|
||||
// TODO: how do we extend this to more complex clocking topologies?
|
||||
BelId global_clk_bel =
|
||||
ctx->addBel(IdStringList::concat(ctx->id("X0Y0"), id_CLK), id_Global_Clock, Loc(0, 0, 0), true, false);
|
||||
global_clk_wire = ctx->addWire(IdStringList::concat(ctx->id("X0Y0"), id_CLK), id_CLK, 0, 0);
|
||||
ctx->addBelOutput(global_clk_bel, id_CLK, global_clk_wire);
|
||||
auto found = ctx->wire_by_name.find(IdStringList::concat(ctx->id("X0Y0"), id_CLK));
|
||||
if (found != ctx->wire_by_name.end()) {
|
||||
BelId global_clk_bel = ctx->addBel(IdStringList::concat(ctx->id("X0Y0"), id_CLK), id_Global_Clock,
|
||||
Loc(0, 0, 0), true, false);
|
||||
WireId global_clk_wire = get_wire(ctx->id("X0Y0"), id_CLK, id_CLK);
|
||||
ctx->addBelOutput(global_clk_bel, id_CLK, global_clk_wire);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this is for legacy fabulous only, the new code path can be a lot simpler
|
||||
|
|
@ -314,7 +318,6 @@ struct FabulousImpl : ViaductAPI
|
|||
{
|
||||
std::ifstream in = open_data_rel("/npnroutput/bel.txt");
|
||||
CsvParser csv(in);
|
||||
init_global_clock();
|
||||
while (csv.fetch_next_line()) {
|
||||
IdString tile = csv.next_field().to_id(ctx);
|
||||
int bel_x = csv.next_field().substr(1).to_int();
|
||||
|
|
@ -345,6 +348,7 @@ struct FabulousImpl : ViaductAPI
|
|||
BelId bel = ctx->addBel(IdStringList::concat(tile, bel_name), bel_type, loc, false, false);
|
||||
handle_bel_ports(bel, tile, bel_type, ports);
|
||||
}
|
||||
init_global_clock();
|
||||
postprocess_bels();
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +356,6 @@ struct FabulousImpl : ViaductAPI
|
|||
{
|
||||
std::ifstream in = open_data_rel("/.FABulous/bel.v2.txt");
|
||||
CsvParser csv(in);
|
||||
init_global_clock();
|
||||
BelId curr_bel;
|
||||
while (csv.fetch_next_line()) {
|
||||
IdString cmd = csv.next_field().to_id(ctx);
|
||||
|
|
@ -386,6 +389,7 @@ struct FabulousImpl : ViaductAPI
|
|||
IdStringList bel_name = ctx->getBelName(curr_bel);
|
||||
WireId clk_wire = get_wire(bel_name[0], ctx->idf("%s_CLK", bel_name[1].c_str(ctx)), id_REG_CLK);
|
||||
ctx->addBelInput(curr_bel, id_CLK, clk_wire);
|
||||
WireId global_clk_wire = get_wire(ctx->id("X0Y0"), id_CLK, id_CLK);
|
||||
add_pseudo_pip(global_clk_wire, clk_wire, id_global_clock);
|
||||
} else if (cmd == id_CFG) {
|
||||
// TODO...
|
||||
|
|
@ -396,6 +400,7 @@ struct FabulousImpl : ViaductAPI
|
|||
curr_bel == BelId() ? "<none>" : ctx->nameOfBel(curr_bel));
|
||||
}
|
||||
}
|
||||
init_global_clock();
|
||||
postprocess_bels();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -334,8 +334,8 @@ struct FabulousPacker
|
|||
auto &ci = *cell.second;
|
||||
if (!ci.type.in(ibuf, obuf, iobuf))
|
||||
continue;
|
||||
log_info("port is unconstrained: %s This pin will be assigned randomly\n", ctx->nameOf(&ci));
|
||||
bool found_pad = false;
|
||||
bool constrained = false;
|
||||
for (auto &port : ci.ports) {
|
||||
NetInfo *net = port.second.net;
|
||||
if (!net)
|
||||
|
|
@ -347,6 +347,8 @@ struct FabulousPacker
|
|||
if (usr.port != id_PAD)
|
||||
log_error("Top-level port '%s' connected to illegal port %s.%s (must be PAD)\n",
|
||||
ctx->nameOf(&ci), ctx->nameOf(usr.cell), ctx->nameOf(usr.port));
|
||||
if (usr.cell->attrs.count(id_BEL))
|
||||
constrained = true;
|
||||
if (found_pad)
|
||||
log_error("Top-level port '%s' connected to multiple PAD ports (at least %s.%s and %s.%s)\n",
|
||||
ctx->nameOf(&ci), ctx->nameOf(usr.cell), ctx->nameOf(usr.port),
|
||||
|
|
@ -362,6 +364,8 @@ struct FabulousPacker
|
|||
if (drv.port != id_PAD)
|
||||
log_error("Top-level port '%s' connected to illegal port %s.%s (must be PAD)\n",
|
||||
ctx->nameOf(&ci), ctx->nameOf(drv.cell), ctx->nameOf(drv.port));
|
||||
if (drv.cell->attrs.count(id_BEL))
|
||||
constrained = true;
|
||||
if (found_pad)
|
||||
log_error("Top-level port '%s' connected to multiple PAD ports (at least %s.%s and %s.%s)\n",
|
||||
ctx->nameOf(&ci), ctx->nameOf(drv.cell), ctx->nameOf(drv.port),
|
||||
|
|
@ -372,6 +376,8 @@ struct FabulousPacker
|
|||
if (!found_pad)
|
||||
log_error("No IO cell found connected to '%s' via PAD port. Was iopadmap run in Yosys?\n",
|
||||
ctx->nameOf(&ci));
|
||||
if (!constrained)
|
||||
log_info("port is unconstrained: %s This pin will be assigned randomly\n", ctx->nameOf(&ci));
|
||||
ci.disconnectPort(id_I);
|
||||
ci.disconnectPort(id_O);
|
||||
to_remove.push_back(ci.name);
|
||||
|
|
|
|||
|
|
@ -619,4 +619,4 @@ void fabulous_pcf(Context *ctx, const std::string &filename)
|
|||
log_info("Finished applying constraints from '%s'\n", filename.c_str());
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
|
|
|||
Loading…
Reference in New Issue