diff --git a/common/kernel/arch_api.h b/common/kernel/arch_api.h index 56c5cf0a..c2de19e6 100644 --- a/common/kernel/arch_api.h +++ b/common/kernel/arch_api.h @@ -119,6 +119,7 @@ template struct ArchAPI : BaseCtx virtual bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const = 0; virtual delay_t estimateDelay(WireId src, WireId dst) const = 0; virtual BoundingBox getRouteBoundingBox(WireId src, WireId dst) const = 0; + virtual bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const = 0; // Decal methods virtual typename R::DecalGfxRangeT getDecalGraphics(DecalId decal) const = 0; virtual DecalXY getBelDecal(BelId bel) const = 0; diff --git a/common/kernel/base_arch.h b/common/kernel/base_arch.h index 609d9378..4da94989 100644 --- a/common/kernel/base_arch.h +++ b/common/kernel/base_arch.h @@ -317,6 +317,10 @@ template struct BaseArch : ArchAPI { return false; } + virtual bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const override + { + return false; + } // Decal methods virtual typename R::DecalGfxRangeT getDecalGraphics(DecalId decal) const override diff --git a/common/kernel/context.cc b/common/kernel/context.cc index 821ad822..7048be59 100644 --- a/common/kernel/context.cc +++ b/common/kernel/context.cc @@ -128,6 +128,12 @@ delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &us if (src_wire == WireId()) return 0; + DelayQuad quad_result; + if (getArcDelayOverride(net_info, user_info, quad_result)) { + // Arch overrides delay + return quad_result.maxDelay(); + } + delay_t max_delay = 0; for (auto dst_wire : getNetinfoSinkWires(net_info, user_info)) { @@ -173,6 +179,11 @@ DelayQuad Context::getNetinfoRouteDelayQuad(const NetInfo *net_info, const PortR DelayQuad result(std::numeric_limits::max(), std::numeric_limits::lowest()); + if (getArcDelayOverride(net_info, user_info, result)) { + // Arch overrides delay + return result; + } + for (auto dst_wire : getNetinfoSinkWires(net_info, user_info)) { WireId cursor = dst_wire; DelayQuad delay{0}; diff --git a/docs/archapi.md b/docs/archapi.md index 3a7994de..062bd946 100644 --- a/docs/archapi.md +++ b/docs/archapi.md @@ -551,6 +551,14 @@ Overwrite or modify (in-place) the timing budget for a given arc. Returns a bool *BaseArch default: returns false* +### bool getArcDelayOverride(const NetInfo \*net_info, const PortRef &sink, DelayQuad &delay) const + +This allows an arch to provide a more precise method for calculating the delay for a routed arc than +summing wire and pip delays; for example a SPICE simulation. If available, `delay` should be set and +`true` returned. + +*BaseArch default: returns false* + Flow Methods ------------ diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index a44c7c21..74473e63 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -709,6 +709,11 @@ struct Arch : ArchAPI uint32_t getDelayChecksum(delay_t v) const final { return v; } bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const final; + bool getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, DelayQuad &delay) const final + { + return false; + } + // ------------------------------------------------- void place_iobufs(WireId pad_wire, NetInfo *net,