aboutsummaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2023-02-16 11:10:51 +0100
committergatecat <gatecat@ds0.me>2023-02-16 11:56:58 +0100
commit06b675b345ec0685fbef651d17cd0577df642e71 (patch)
tree2180a0e77aea2b81ba48ab6beab60f2c7af0fb8c /generic
parent78dabb7b8f2279090b61447d1ebd04385061fc61 (diff)
downloadnextpnr-06b675b345ec0685fbef651d17cd0577df642e71.tar.gz
nextpnr-06b675b345ec0685fbef651d17cd0577df642e71.tar.bz2
nextpnr-06b675b345ec0685fbef651d17cd0577df642e71.zip
fabulous: Add fake timings
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'generic')
-rw-r--r--generic/arch.h7
-rw-r--r--generic/viaduct/fabulous/fabulous.cc45
2 files changed, 46 insertions, 6 deletions
diff --git a/generic/arch.h b/generic/arch.h
index 2a177be9..19a0a078 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -316,8 +316,8 @@ struct Arch : BaseArch<ArchRanges>
delay_t estimateDelay(WireId src, WireId dst) const override;
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
- delay_t getDelayEpsilon() const override { return 0.001; }
- delay_t getRipupDelayPenalty() const override { return 0.015; }
+ delay_t getDelayEpsilon() const override { return delay_epsilon; }
+ delay_t getRipupDelayPenalty() const override { return ripup_penalty; }
float getDelayNS(delay_t v) const override { return v; }
delay_t getDelayFromNS(float ns) const override { return ns; }
@@ -397,6 +397,9 @@ struct Arch : BaseArch<ArchRanges>
// Internal usage
void assignArchInfo() override;
bool cellsCompatible(const CellInfo **cells, int count) const;
+
+ float delay_epsilon = 0.001;
+ float ripup_penalty = 0.015;
};
NEXTPNR_NAMESPACE_END
diff --git a/generic/viaduct/fabulous/fabulous.cc b/generic/viaduct/fabulous/fabulous.cc
index 7dad0c66..d3bfb4e2 100644
--- a/generic/viaduct/fabulous/fabulous.cc
+++ b/generic/viaduct/fabulous/fabulous.cc
@@ -69,7 +69,35 @@ struct FabulousImpl : ViaductAPI
blk_trk = std::make_unique<BlockTracker>(ctx, cfg);
is_new_fab ? init_bels_v2() : init_bels_v1();
init_pips();
- ctx->setDelayScaling(0.25, 0.5);
+ ctx->setDelayScaling(2.0, 5.0);
+ ctx->delay_epsilon = 0.5;
+ ctx->ripup_penalty = 1.5;
+ }
+
+ void update_cell_timing(Context *ctx)
+ {
+ // These timings are not realistic. They just make sure nextpnr does some timing-driven optimisation...
+ for (auto &cell : ctx->cells) {
+ CellInfo *ci = cell.second.get();
+ if (ci->type == id_FABULOUS_LC) {
+ auto &lct = cell_tags.get(ci);
+ if (lct.ff.ff_used) {
+ ctx->addCellTimingClock(ci->name, id_CLK);
+ for (unsigned i = 0; i < cfg.clb.lut_k; i++)
+ ctx->addCellTimingSetupHold(ci->name, ctx->idf("I%d", i), id_CLK, 2.5, 0.1);
+ ctx->addCellTimingClockToOut(ci->name, id_Q, id_CLK, 1.0);
+ } else {
+ for (unsigned i = 0; i < cfg.clb.lut_k; i++)
+ ctx->addCellTimingDelay(ci->name, ctx->idf("I%d", i), id_O, 3.0);
+ }
+ } else if (ci->type == id_OutPass4_frame_config) {
+ for (unsigned i = 0; i < 4; i++)
+ ctx->addCellTimingSetupHold(ci->name, ctx->idf("I%d", i), id_CLK, 2.5, 0.1);
+ } else if (ci->type == id_InPass4_frame_config) {
+ for (unsigned i = 0; i < 4; i++)
+ ctx->addCellTimingClockToOut(ci->name, ctx->idf("O%d", i), id_CLK, 2.5);
+ }
+ }
}
void pack() override { fabulous_pack(ctx, cfg); }
@@ -80,7 +108,11 @@ struct FabulousImpl : ViaductAPI
fabulous_write_fasm(ctx, cfg, fasm_file);
}
- void prePlace() override { assign_cell_info(); }
+ void prePlace() override
+ {
+ assign_cell_info();
+ update_cell_timing(ctx);
+ }
bool isBelLocationValid(BelId bel, bool explain_invalid) const override
{
return blk_trk->check_validity(bel, cfg, cell_tags);
@@ -122,7 +154,7 @@ struct FabulousImpl : ViaductAPI
{
const auto &src_data = ctx->wire_info(src);
IdStringList pip_name = IdStringList::concat(ctx->getWireName(src), ctx->getWireName(dst));
- ctx->addPip(pip_name, pip_type, src, dst, ctx->getDelayFromNS(0.05), Loc(src_data.x, src_data.y, 0));
+ ctx->addPip(pip_name, pip_type, src, dst, ctx->getDelayFromNS(1.0), Loc(src_data.x, src_data.y, 0));
}
void handle_bel_ports(BelId bel, IdString tile, IdString bel_type, const std::vector<parser_view> &ports)
@@ -138,6 +170,11 @@ struct FabulousImpl : ViaductAPI
ctx->addBelPin(bel, pin, port_wire, pin.in(id_I, id_T) ? PORT_IN : PORT_OUT);
}
} 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()) {
+ add_pseudo_pip(global_clk_wire, clk_wire, id_global_clock);
+ }
+ ctx->addBelInput(bel, id_CLK, clk_wire);
for (parser_view p : ports) {
IdString port_id = p.to_id(ctx);
WireId port_wire = get_wire(tile, port_id, port_id);
@@ -382,7 +419,7 @@ struct FabulousImpl : ViaductAPI
WireId src_wire = get_wire(src_tile, src_port, src_port);
WireId dst_wire = get_wire(dst_tile, dst_port, dst_port);
ctx->addPip(IdStringList::concat(src_tile, pip_name), pip_name, src_wire, dst_wire,
- ctx->getDelayFromNS(0.01 * delay), tile_loc(src_tile));
+ ctx->getDelayFromNS(0.05 * delay), tile_loc(src_tile));
}
}