85 lines
3.5 KiB
C++
85 lines
3.5 KiB
C++
/*
|
|
* nextpnr -- Next Generation Place and Route
|
|
*
|
|
* Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
|
|
* Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#include "nextpnr.h"
|
|
#include "router1.h"
|
|
|
|
NEXTPNR_NAMESPACE_BEGIN
|
|
|
|
#define NUM_FUZZ_ROUTES 100000
|
|
|
|
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|
{
|
|
const auto &src_tw = torc_info->wire_to_tilewire[src.index];
|
|
const auto &src_loc = torc_info->tile_to_xy[src_tw.getTileIndex()];
|
|
const auto &dst_tw = torc_info->wire_to_tilewire[dst.index];
|
|
const auto &dst_loc = torc_info->tile_to_xy[dst_tw.getTileIndex()];
|
|
|
|
if (!torc_info->wire_is_global[src.index]) {
|
|
auto abs_delta_x = abs(dst_loc.first - src_loc.first);
|
|
auto abs_delta_y = abs(dst_loc.second - src_loc.second);
|
|
auto div_LH = std::div(abs_delta_x, 12);
|
|
auto div_LV = std::div(abs_delta_y, 18);
|
|
auto div_LVB = std::div(div_LV.rem, 12);
|
|
auto div_H6 = std::div(div_LH.rem, 6);
|
|
auto div_V6 = std::div(div_LVB.rem, 6);
|
|
auto div_H4 = std::div(div_H6.rem, 4);
|
|
auto div_V4 = std::div(div_V6.rem, 4);
|
|
auto div_H2 = std::div(div_H4.rem, 2);
|
|
auto div_V2 = std::div(div_V4.rem, 2);
|
|
auto num_H1 = div_H2.rem;
|
|
auto num_V1 = div_V2.rem;
|
|
return div_LH.quot * 360 + div_LVB.quot * 300 + div_LV.quot * 350 +
|
|
(div_H6.quot + div_H4.quot + div_V6.quot + div_V4.quot) * 210 + (div_H2.quot + div_V2.quot) * 170 +
|
|
(num_H1 + num_V1) * 150;
|
|
} else {
|
|
auto src_y = src_loc.second;
|
|
auto dst_y = dst_loc.second;
|
|
auto div_src_y = std::div(src_y, 52);
|
|
auto div_dst_y = std::div(dst_y, 52);
|
|
return abs(div_dst_y.quot - div_src_y.quot) * 52 + abs(div_dst_y.rem - div_src_y.rem);
|
|
}
|
|
}
|
|
|
|
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);
|
|
auto abs_delta_x = abs(driver_loc.x - sink_loc.x);
|
|
auto abs_delta_y = abs(driver_loc.y - sink_loc.y);
|
|
auto div_LH = std::div(abs_delta_x, 12);
|
|
auto div_LV = std::div(abs_delta_y, 18);
|
|
auto div_LVB = std::div(div_LV.rem, 12);
|
|
auto div_H6 = std::div(div_LH.rem, 6);
|
|
auto div_V6 = std::div(div_LVB.rem, 6);
|
|
auto div_H4 = std::div(div_H6.rem, 4);
|
|
auto div_V4 = std::div(div_V6.rem, 4);
|
|
auto div_H2 = std::div(div_H4.rem, 2);
|
|
auto div_V2 = std::div(div_V4.rem, 2);
|
|
auto num_H1 = div_H2.rem;
|
|
auto num_V1 = div_V2.rem;
|
|
return div_LH.quot * 360 + div_LVB.quot * 300 + div_LV.quot * 350 +
|
|
(div_H6.quot + div_H4.quot + div_V6.quot + div_V4.quot) * 210 + (div_H2.quot + div_V2.quot) * 170 +
|
|
(num_H1 + num_V1) * 150;
|
|
}
|
|
|
|
NEXTPNR_NAMESPACE_END
|