ecp5: Add criticality-based LUT permutation
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
f363dd2d3c
commit
a0fa164399
12
ecp5/arch.cc
12
ecp5/arch.cc
@ -486,7 +486,7 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
|||||||
|
|
||||||
int dx = abs(driver_loc.x - sink_loc.x), dy = 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 - 25 * args.speed) *
|
return (130 - 25 * args.speed) *
|
||||||
(4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
|
(6 + 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
|
||||||
@ -504,7 +504,17 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||||
|
=======
|
||||||
|
bool Arch::place()
|
||||||
|
{
|
||||||
|
bool result = placer_heap(getCtx());
|
||||||
|
if (result)
|
||||||
|
permute_luts();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
>>>>>>> 136e030... lut permutation
|
||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route()
|
||||||
{
|
{
|
||||||
|
@ -971,6 +971,8 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
void assignArchInfo();
|
void assignArchInfo();
|
||||||
|
|
||||||
|
void permute_luts();
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> getTilesAtLocation(int row, int col);
|
std::vector<std::pair<std::string, std::string>> getTilesAtLocation(int row, int col);
|
||||||
std::string getTileByTypeAndLocation(int row, int col, std::string type) const
|
std::string getTileByTypeAndLocation(int row, int col, std::string type) const
|
||||||
{
|
{
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cells.h"
|
#include "cells.h"
|
||||||
|
#include "design_utils.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "timing.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -115,4 +117,76 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Arch::permute_luts()
|
||||||
|
{
|
||||||
|
NetCriticalityMap nc;
|
||||||
|
get_criticalities(getCtx(), &nc);
|
||||||
|
|
||||||
|
std::unordered_map<PortInfo *, size_t> port_to_user;
|
||||||
|
for (auto net : sorted(nets)) {
|
||||||
|
NetInfo *ni = net.second;
|
||||||
|
for (size_t i = 0; i < ni->users.size(); i++) {
|
||||||
|
auto &usr = ni->users.at(i);
|
||||||
|
port_to_user[&(usr.cell->ports.at(usr.port))] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto proc_lut = [&](CellInfo *ci, int lut) {
|
||||||
|
std::vector<IdString> port_names;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
port_names.push_back(id(std::string("ABCD").substr(i, 1) + std::to_string(lut)));
|
||||||
|
|
||||||
|
std::vector<std::pair<float, int>> inputs;
|
||||||
|
std::vector<NetInfo *> orig_nets;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
auto &port = ci->ports.at(port_names.at(i));
|
||||||
|
float crit = 0;
|
||||||
|
if (port.net != nullptr && nc.count(port.net->name)) {
|
||||||
|
auto &n = nc.at(port.net->name);
|
||||||
|
size_t usr = port_to_user.at(&port);
|
||||||
|
if (usr < n.criticality.size())
|
||||||
|
crit = n.criticality.at(usr);
|
||||||
|
}
|
||||||
|
orig_nets.push_back(port.net);
|
||||||
|
inputs.emplace_back(crit, i);
|
||||||
|
}
|
||||||
|
// Least critical first (A input is slowest)
|
||||||
|
std::sort(inputs.begin(), inputs.end());
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
IdString p = port_names.at(i);
|
||||||
|
// log_info("%s %s %f\n", p.c_str(ctx), port_names.at(inputs.at(i).second).c_str(ctx), inputs.at(i).first);
|
||||||
|
disconnect_port(getCtx(), ci, p);
|
||||||
|
ci->ports.at(p).net = nullptr;
|
||||||
|
if (orig_nets.at(inputs.at(i).second) != nullptr) {
|
||||||
|
connect_port(getCtx(), orig_nets.at(inputs.at(i).second), ci, p);
|
||||||
|
ci->params[id(p.str(this) + "MUX")] = p.str(this);
|
||||||
|
} else {
|
||||||
|
ci->params[id(p.str(this) + "MUX")] = "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rewrite function
|
||||||
|
int old_init = int_or_default(ci->params, id("LUT" + std::to_string(lut) + "_INITVAL"), 0);
|
||||||
|
int new_init = 0;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
int old_index = 0;
|
||||||
|
for (int k = 0; k < 4; k++) {
|
||||||
|
if (i & (1 << k))
|
||||||
|
old_index |= (1 << inputs.at(k).second);
|
||||||
|
}
|
||||||
|
if (old_init & (1 << old_index))
|
||||||
|
new_init |= (1 << i);
|
||||||
|
}
|
||||||
|
ci->params[id("LUT" + std::to_string(lut) + "_INITVAL")] = std::to_string(new_init);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto cell : sorted(cells)) {
|
||||||
|
CellInfo *ci = cell.second;
|
||||||
|
if (ci->type == id_TRELLIS_SLICE && str_or_default(ci->params, id("MODE"), "LOGIC") == "LOGIC") {
|
||||||
|
proc_lut(ci, 0);
|
||||||
|
proc_lut(ci, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "design_utils.h"
|
#include "design_utils.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "timing.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user