From f6b3333a7d34c865e0e371b5585e1ee8151a58b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 4 Aug 2018 19:50:49 +0200 Subject: Add new iCE40 delay estimator and delay predictor Signed-off-by: Clifford Wolf --- ice40/delay.cc | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 4 deletions(-) (limited to 'ice40/delay.cc') diff --git a/ice40/delay.cc b/ice40/delay.cc index d63af5d1..342b7f0b 100644 --- a/ice40/delay.cc +++ b/ice40/delay.cc @@ -23,7 +23,7 @@ NEXTPNR_NAMESPACE_BEGIN -#define NUM_FUZZ_ROUTES 100000 +#define NUM_FUZZ_ROUTES 1000 void ice40DelayFuzzerMain(Context *ctx) { @@ -101,20 +101,145 @@ void ice40DelayFuzzerMain(Context *ctx) } } +namespace { + +struct model_params_t { + int neighbourhood; + + int model0_offset; + int model0_norm1; + + int model1_offset; + int model1_norm1; + int model1_norm2; + int model1_norm3; + + int model2_offset; + int model2_linear; + int model2_sqrt; + + int delta_local; + int delta_lutffin; + int delta_sp4; + int delta_sp12; + + static const model_params_t &get(ArchArgs args) + { + static const model_params_t model_hx8k = { + 588, 129253, 8658, + 118333, 23915, -73105, 57696, + -86797, 89, 3706, + -316, -575, -158, -296 + }; + + static const model_params_t model_lp8k = { + 867, 206236, 11043, + 191910, 31074, -95972, 75739, + -309793, 30, 11056, + -474, -856, -363, -536 + }; + + static const model_params_t model_up5k = { + 1761, 305798, 16705, + 296830, 24430, -40369, 33038, + -162662, 94, 4705, + -1099, -1761, -418, -838 + }; + + if (args.type == ArchArgs::HX1K || args.type == ArchArgs::HX8K) + return model_hx8k; + + if (args.type == ArchArgs::LP384 || args.type == ArchArgs::LP1K || args.type == ArchArgs::LP8K) + return model_lp8k; + + if (args.type == ArchArgs::UP5K) + return model_up5k; + + NPNR_ASSERT(0); + } +}; + +} // namespace + delay_t Arch::estimateDelay(WireId src, WireId dst) const { NPNR_ASSERT(src != WireId()); int x1 = chip_info->wire_data[src.index].x; int y1 = chip_info->wire_data[src.index].y; + int z1 = chip_info->wire_data[src.index].z; + int type = chip_info->wire_data[src.index].type; NPNR_ASSERT(dst != WireId()); int x2 = chip_info->wire_data[dst.index].x; int y2 = chip_info->wire_data[dst.index].y; + int z2 = chip_info->wire_data[dst.index].z; + + int dx = abs(x2 - x1); + int dy = abs(y2 - y1); + + const model_params_t &p = model_params_t::get(args); + delay_t v = p.neighbourhood; + + if (dx > 1 || dy > 1) + v = (p.model0_offset + p.model0_norm1 * (dx + dy)) / 128; + + if (type == WireInfoPOD::WIRE_TYPE_LOCAL) + v += p.delta_local; + + if (type == WireInfoPOD::WIRE_TYPE_LUTFF_IN || type == WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT) + v += (z1 == z2) ? p.delta_lutffin : 1000; + + if (type == WireInfoPOD::WIRE_TYPE_SP4_V || type == WireInfoPOD::WIRE_TYPE_SP4_H) + v += p.delta_sp4; + + if (type == WireInfoPOD::WIRE_TYPE_SP12_V || type == WireInfoPOD::WIRE_TYPE_SP12_H) + v += p.delta_sp12; + + return v; +} + +delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const +{ + const auto &driver = net_info->driver; + auto driver_loc = getBelLocation(driver.cell->bel); + auto sink_loc = getBelLocation(sink.cell->bel); + + if (driver.port == id_cout) { + if (driver_loc.y == sink_loc.y) + return 0; + return 250; + } + + int dx = abs(sink_loc.x - driver_loc.x); + int dy = abs(sink_loc.y - driver_loc.y); + + const model_params_t &p = model_params_t::get(args); + + if (dx <= 1 && dy <= 1) + return p.neighbourhood; + + float norm1 = dx + dy; + + float dx2 = dx * dx; + float dy2 = dy * dy; + float norm2 = sqrtf(dx2 + dy2); + + float dx3 = dx2 * dx; + float dy3 = dy2 * dy; + float norm3 = powf(dx3 + dy3, 1.0/3.0); + + // Model #1 + float v = p.model1_offset; + v += p.model1_norm1 * norm1; + v += p.model1_norm2 * norm2; + v += p.model1_norm3 * norm3; + v /= 128; - int xd = x2 - x1, yd = y2 - y1; - int xscale = 120, yscale = 120, offset = 0; + // Model #2 + v = p.model2_offset + p.model2_linear * v + p.model2_sqrt * sqrtf(v); + v /= 128; - return xscale * abs(xd) + yscale * abs(yd) + offset; + return v; } NEXTPNR_NAMESPACE_END -- cgit v1.2.3