ecp5: Router performance improvements
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
f5b11ce075
commit
55b0b60d9d
@ -837,6 +837,10 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
|
||||
auto cursor = sink_wire;
|
||||
delay_t delay;
|
||||
while (driver_wire != cursor) {
|
||||
#ifdef ARCH_ECP5
|
||||
if (net->is_global)
|
||||
break;
|
||||
#endif
|
||||
auto it = net->wires.find(cursor);
|
||||
assert(it != net->wires.end());
|
||||
auto pip = it->second.pip;
|
||||
|
21
ecp5/arch.cc
21
ecp5/arch.cc
@ -427,6 +427,16 @@ BelId Arch::getBelByLocation(Loc loc) const
|
||||
|
||||
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||
{
|
||||
WireId cursor = dst;
|
||||
|
||||
int num_uh = locInfo(dst)->wire_data[dst.index].num_uphill;
|
||||
if (num_uh < 6) {
|
||||
for (auto uh : getPipsUphill(dst)) {
|
||||
if (getPipSrcWire(uh) == src)
|
||||
return getPipDelay(uh).maxDelay();
|
||||
}
|
||||
}
|
||||
|
||||
auto est_location = [&](WireId w) -> std::pair<int16_t, int16_t> {
|
||||
if (w.location.x == 0 && w.location.y == 0) {
|
||||
// Global wires
|
||||
@ -448,7 +458,8 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||
|
||||
auto src_loc = est_location(src), dst_loc = est_location(dst);
|
||||
|
||||
return (110 - 10 * args.speed) + (200 - 20 * args.speed) * (abs(src_loc.first - dst_loc.first) + abs(src_loc.second - dst_loc.second));
|
||||
int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second);
|
||||
return (130 - 13 * args.speed) * (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
|
||||
}
|
||||
|
||||
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
||||
@ -458,16 +469,18 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
||||
return 0;
|
||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
||||
return (110 - 10 * args.speed) + (200 - 20 * args.speed) * (abs(driver_loc.x - sink_loc.x) + abs(driver_loc.y - sink_loc.y));
|
||||
|
||||
int dx = abs(driver_loc.x - sink_loc.x), dy = abs(driver_loc.y - sink_loc.y);
|
||||
return (130 - 13 * args.speed) * (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
|
||||
}
|
||||
|
||||
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const {
|
||||
if (net_info->driver.port == id_FCO && sink.port == id_FCI) {
|
||||
return true;
|
||||
budget = 0;
|
||||
return true;
|
||||
} else if (sink.port == id_FXA || sink.port == id_FXB) {
|
||||
return true;
|
||||
budget = 0;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -918,7 +918,7 @@ struct Arch : BaseCtx
|
||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const;
|
||||
delay_t getDelayEpsilon() const { return 20; }
|
||||
delay_t getRipupDelayPenalty() const { return 200; }
|
||||
delay_t getRipupDelayPenalty() const { return 500; }
|
||||
float getDelayNS(delay_t v) const { return v * 0.001; }
|
||||
DelayInfo getDelayFromNS(float ns) const
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ speed_grade_names = ["6", "7", "8", "8_5G"]
|
||||
speed_grade_cells = {}
|
||||
speed_grade_pips = {}
|
||||
|
||||
pip_class_to_idx = {"default": 0}
|
||||
pip_class_to_idx = {"default": 0, "zero": 1}
|
||||
|
||||
timing_port_xform = {
|
||||
"RAD0": "D0",
|
||||
@ -199,7 +199,7 @@ def process_timing_data():
|
||||
pip_class_delays = []
|
||||
for i in range(len(pip_class_to_idx)):
|
||||
pip_class_delays.append((50, 50, 0, 0))
|
||||
|
||||
pip_class_delays[pip_class_to_idx["zero"]] = (0, 0, 0, 0)
|
||||
with open(timing_dbs.interconnect_db_path("ECP5", grade)) as f:
|
||||
interconn_data = json.load(f)
|
||||
for pipclass, pipdata in sorted(interconn_data.items()):
|
||||
@ -219,6 +219,12 @@ def process_timing_data():
|
||||
|
||||
|
||||
def get_pip_class(wire_from, wire_to):
|
||||
|
||||
if "FCO" in wire_from or "FCI" in wire_to:
|
||||
return pip_class_to_idx["zero"]
|
||||
if "F5" in wire_from or "FX" in wire_from or "FXA" in wire_to or "FXB" in wire_to:
|
||||
return pip_class_to_idx["zero"]
|
||||
|
||||
class_name = pip_classes.get_pip_class(wire_from, wire_to)
|
||||
if class_name is None or class_name not in pip_class_to_idx:
|
||||
class_name = "default"
|
||||
|
Loading…
Reference in New Issue
Block a user