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;
|
auto cursor = sink_wire;
|
||||||
delay_t delay;
|
delay_t delay;
|
||||||
while (driver_wire != cursor) {
|
while (driver_wire != cursor) {
|
||||||
|
#ifdef ARCH_ECP5
|
||||||
|
if (net->is_global)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
auto it = net->wires.find(cursor);
|
auto it = net->wires.find(cursor);
|
||||||
assert(it != net->wires.end());
|
assert(it != net->wires.end());
|
||||||
auto pip = it->second.pip;
|
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
|
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> {
|
auto est_location = [&](WireId w) -> std::pair<int16_t, int16_t> {
|
||||||
if (w.location.x == 0 && w.location.y == 0) {
|
if (w.location.x == 0 && w.location.y == 0) {
|
||||||
// Global wires
|
// 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);
|
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
|
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;
|
return 0;
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
auto driver_loc = getBelLocation(driver.cell->bel);
|
||||||
auto sink_loc = getBelLocation(sink.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 {
|
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) {
|
if (net_info->driver.port == id_FCO && sink.port == id_FCI) {
|
||||||
return true;
|
|
||||||
budget = 0;
|
budget = 0;
|
||||||
|
return true;
|
||||||
} else if (sink.port == id_FXA || sink.port == id_FXB) {
|
} else if (sink.port == id_FXA || sink.port == id_FXB) {
|
||||||
return true;
|
|
||||||
budget = 0;
|
budget = 0;
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -918,7 +918,7 @@ struct Arch : BaseCtx
|
|||||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||||
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const;
|
delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const;
|
||||||
delay_t getDelayEpsilon() const { return 20; }
|
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; }
|
float getDelayNS(delay_t v) const { return v * 0.001; }
|
||||||
DelayInfo getDelayFromNS(float ns) const
|
DelayInfo getDelayFromNS(float ns) const
|
||||||
{
|
{
|
||||||
|
@ -153,7 +153,7 @@ speed_grade_names = ["6", "7", "8", "8_5G"]
|
|||||||
speed_grade_cells = {}
|
speed_grade_cells = {}
|
||||||
speed_grade_pips = {}
|
speed_grade_pips = {}
|
||||||
|
|
||||||
pip_class_to_idx = {"default": 0}
|
pip_class_to_idx = {"default": 0, "zero": 1}
|
||||||
|
|
||||||
timing_port_xform = {
|
timing_port_xform = {
|
||||||
"RAD0": "D0",
|
"RAD0": "D0",
|
||||||
@ -199,7 +199,7 @@ def process_timing_data():
|
|||||||
pip_class_delays = []
|
pip_class_delays = []
|
||||||
for i in range(len(pip_class_to_idx)):
|
for i in range(len(pip_class_to_idx)):
|
||||||
pip_class_delays.append((50, 50, 0, 0))
|
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:
|
with open(timing_dbs.interconnect_db_path("ECP5", grade)) as f:
|
||||||
interconn_data = json.load(f)
|
interconn_data = json.load(f)
|
||||||
for pipclass, pipdata in sorted(interconn_data.items()):
|
for pipclass, pipdata in sorted(interconn_data.items()):
|
||||||
@ -219,6 +219,12 @@ def process_timing_data():
|
|||||||
|
|
||||||
|
|
||||||
def get_pip_class(wire_from, wire_to):
|
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)
|
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:
|
if class_name is None or class_name not in pip_class_to_idx:
|
||||||
class_name = "default"
|
class_name = "default"
|
||||||
|
Loading…
Reference in New Issue
Block a user