Merge branch 'master' into remove-legacy-gowin
This commit is contained in:
commit
53791a92c6
2
.github/workflows/arch_ci.yml
vendored
2
.github/workflows/arch_ci.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
DEPS_PATH: ${{ github.workspace }}/deps
|
DEPS_PATH: ${{ github.workspace }}/deps
|
||||||
YOSYS_REVISION: bd7ee79486d4e8788f36de8c25a3fb2df451d682
|
YOSYS_REVISION: 7045cf509e1d95cbc973746674cf2d7c73c02e50
|
||||||
ICESTORM_REVISION: 9f66f9ce16941c6417813cb87653c735a78b53ae
|
ICESTORM_REVISION: 9f66f9ce16941c6417813cb87653c735a78b53ae
|
||||||
TRELLIS_REVISION: 36c615d1740473cc3574464c7f0bed44da20e5b6
|
TRELLIS_REVISION: 36c615d1740473cc3574464c7f0bed44da20e5b6
|
||||||
PRJOXIDE_REVISION: c3fb1526cf4a2165e15b74f4a994d153c7695fe4
|
PRJOXIDE_REVISION: c3fb1526cf4a2165e15b74f4a994d153c7695fe4
|
||||||
|
@ -197,7 +197,7 @@ void init_share_dirname()
|
|||||||
npnr_share_dirname = proc_share_path;
|
npnr_share_dirname = proc_share_path;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc_share_path = proc_self_path + "..\\share\\";
|
proc_share_path = proc_self_path + "..\\share\\" + "nextpnr\\";
|
||||||
if (check_file_exists(proc_share_path, true)) {
|
if (check_file_exists(proc_share_path, true)) {
|
||||||
npnr_share_dirname = proc_share_path;
|
npnr_share_dirname = proc_share_path;
|
||||||
return;
|
return;
|
||||||
@ -389,6 +389,9 @@ po::options_description CommandHandler::getGeneralOptions()
|
|||||||
"allow placer to attempt up to max(10000, total cells^2 / N) iterations to place a cell (int "
|
"allow placer to attempt up to max(10000, total cells^2 / N) iterations to place a cell (int "
|
||||||
"N, default: 8, 0 for no timeout)");
|
"N, default: 8, 0 for no timeout)");
|
||||||
|
|
||||||
|
general.add_options()("static-dump-density", "write density csv files during placer-static flow");
|
||||||
|
|
||||||
|
|
||||||
#if !defined(NPNR_DISABLE_THREADS)
|
#if !defined(NPNR_DISABLE_THREADS)
|
||||||
general.add_options()("parallel-refine", "use new experimental parallelised engine for placement refinement");
|
general.add_options()("parallel-refine", "use new experimental parallelised engine for placement refinement");
|
||||||
#endif
|
#endif
|
||||||
@ -543,6 +546,10 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
if (vm.count("router2-alt-weights"))
|
if (vm.count("router2-alt-weights"))
|
||||||
ctx->settings[ctx->id("router2/alt-weights")] = true;
|
ctx->settings[ctx->id("router2/alt-weights")] = true;
|
||||||
|
|
||||||
|
if (vm.count("static-dump-density"))
|
||||||
|
ctx->settings[ctx->id("static/dump_density")] = true;
|
||||||
|
|
||||||
|
|
||||||
// Setting default values
|
// Setting default values
|
||||||
if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())
|
if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())
|
||||||
ctx->settings[ctx->id("target_freq")] = std::to_string(12e6);
|
ctx->settings[ctx->id("target_freq")] = std::to_string(12e6);
|
||||||
|
@ -44,7 +44,7 @@ void print_utilisation(const Context *ctx)
|
|||||||
for (auto type : available_types) {
|
for (auto type : available_types) {
|
||||||
IdString type_id = type.first;
|
IdString type_id = type.first;
|
||||||
int used_bels = get_or_default(used_types, type.first, 0);
|
int used_bels = get_or_default(used_types, type.first, 0);
|
||||||
log_info("\t%20s: %5d/%5d %5d%%\n", type_id.c_str(ctx), used_bels, type.second, 100 * used_bels / type.second);
|
log_info("\t%20s: %7d/%7d %5d%%\n", type_id.c_str(ctx), used_bels, type.second, 100 * used_bels / type.second);
|
||||||
}
|
}
|
||||||
log_break();
|
log_break();
|
||||||
}
|
}
|
||||||
|
@ -254,6 +254,7 @@ class StaticPlacer
|
|||||||
int width, height;
|
int width, height;
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
bool fft_debug = false;
|
bool fft_debug = false;
|
||||||
|
bool dump_density = false;
|
||||||
|
|
||||||
// legalisation queue
|
// legalisation queue
|
||||||
std::priority_queue<std::pair<int, IdString>> to_legalise;
|
std::priority_queue<std::pair<int, IdString>> to_legalise;
|
||||||
@ -586,8 +587,8 @@ class StaticPlacer
|
|||||||
height = bin_h;
|
height = bin_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
double x0 = pos.x - (width / 2), x1 = pos.x + (width / 2);
|
double x0 = pos.x, x1 = pos.x + width;
|
||||||
double y0 = pos.y - (height / 2), y1 = pos.y + (height / 2);
|
double y0 = pos.y, y1 = pos.y + height;
|
||||||
for (int y = int(y0 / bin_h); y <= int(y1 / bin_h); y++) {
|
for (int y = int(y0 / bin_h); y <= int(y1 / bin_h); y++) {
|
||||||
for (int x = int(x0 / bin_w); x <= int(x1 / bin_w); x++) {
|
for (int x = int(x0 / bin_w); x <= int(x1 / bin_w); x++) {
|
||||||
int xb = std::max(0, std::min(x, m - 1));
|
int xb = std::max(0, std::min(x, m - 1));
|
||||||
@ -658,7 +659,8 @@ class StaticPlacer
|
|||||||
if (!overlap_str.empty())
|
if (!overlap_str.empty())
|
||||||
overlap_str += ", ";
|
overlap_str += ", ";
|
||||||
overlap_str += stringf("%s=%.1f%%", cfg.cell_groups.at(idx).name.c_str(ctx), g.overlap * 100);
|
overlap_str += stringf("%s=%.1f%%", cfg.cell_groups.at(idx).name.c_str(ctx), g.overlap * 100);
|
||||||
g.conc_density.write_csv(stringf("out_conc_density_%d_%d.csv", iter, idx));
|
if (dump_density)
|
||||||
|
g.conc_density.write_csv(stringf("out_conc_density_%d_%d.csv", iter, idx));
|
||||||
}
|
}
|
||||||
log_info("overlap: %s\n", overlap_str.c_str());
|
log_info("overlap: %s\n", overlap_str.c_str());
|
||||||
}
|
}
|
||||||
@ -792,15 +794,15 @@ class StaticPlacer
|
|||||||
auto &pd = nd.ports.at(port.second.type == PORT_OUT ? (nd.ports.size() - 1) : port.second.user_idx.idx());
|
auto &pd = nd.ports.at(port.second.type == PORT_OUT ? (nd.ports.size() - 1) : port.second.user_idx.idx());
|
||||||
// From Replace
|
// From Replace
|
||||||
// TODO: check these derivatives on paper
|
// TODO: check these derivatives on paper
|
||||||
float d_min = 0, d_max = 0;
|
double d_min = 0, d_max = 0;
|
||||||
if (pd.has_min_exp(axis)) {
|
if (pd.has_min_exp(axis)) {
|
||||||
float min_sum = nd.min_exp.at(axis), x_min_sum = nd.x_min_exp.at(axis);
|
double min_sum = nd.min_exp.at(axis), x_min_sum = nd.x_min_exp.at(axis);
|
||||||
d_min = (min_sum * (pd.min_exp.at(axis) * (1.0f - wl_coeff.at(axis) * loc.at(axis))) +
|
d_min = (min_sum * (pd.min_exp.at(axis) * (1.0f - wl_coeff.at(axis) * loc.at(axis))) +
|
||||||
wl_coeff.at(axis) * pd.min_exp.at(axis) * x_min_sum) /
|
wl_coeff.at(axis) * pd.min_exp.at(axis) * x_min_sum) /
|
||||||
(min_sum * min_sum);
|
(min_sum * min_sum);
|
||||||
}
|
}
|
||||||
if (pd.has_max_exp(axis)) {
|
if (pd.has_max_exp(axis)) {
|
||||||
float max_sum = nd.max_exp.at(axis), x_max_sum = nd.x_max_exp.at(axis);
|
double max_sum = nd.max_exp.at(axis), x_max_sum = nd.x_max_exp.at(axis);
|
||||||
d_max = (max_sum * (pd.max_exp.at(axis) * (1.0f + wl_coeff.at(axis) * loc.at(axis))) -
|
d_max = (max_sum * (pd.max_exp.at(axis) * (1.0f + wl_coeff.at(axis) * loc.at(axis))) -
|
||||||
wl_coeff.at(axis) * pd.max_exp.at(axis) * x_max_sum) /
|
wl_coeff.at(axis) * pd.max_exp.at(axis) * x_max_sum) /
|
||||||
(max_sum * max_sum);
|
(max_sum * max_sum);
|
||||||
@ -917,16 +919,20 @@ class StaticPlacer
|
|||||||
{
|
{
|
||||||
float coord_dist = 0;
|
float coord_dist = 0;
|
||||||
float grad_dist = 0;
|
float grad_dist = 0;
|
||||||
|
int n = 0;
|
||||||
for (auto &cell : mcells) {
|
for (auto &cell : mcells) {
|
||||||
|
if (cell.is_fixed || cell.is_dark)
|
||||||
|
continue;
|
||||||
coord_dist += (cell.ref_pos.x - cell.last_ref_pos.x) * (cell.ref_pos.x - cell.last_ref_pos.x);
|
coord_dist += (cell.ref_pos.x - cell.last_ref_pos.x) * (cell.ref_pos.x - cell.last_ref_pos.x);
|
||||||
coord_dist += (cell.ref_pos.y - cell.last_ref_pos.y) * (cell.ref_pos.y - cell.last_ref_pos.y);
|
coord_dist += (cell.ref_pos.y - cell.last_ref_pos.y) * (cell.ref_pos.y - cell.last_ref_pos.y);
|
||||||
grad_dist +=
|
grad_dist +=
|
||||||
(cell.ref_total_grad.x - cell.last_total_grad.x) * (cell.ref_total_grad.x - cell.last_total_grad.x);
|
(cell.ref_total_grad.x - cell.last_total_grad.x) * (cell.ref_total_grad.x - cell.last_total_grad.x);
|
||||||
grad_dist +=
|
grad_dist +=
|
||||||
(cell.ref_total_grad.y - cell.last_total_grad.y) * (cell.ref_total_grad.y - cell.last_total_grad.y);
|
(cell.ref_total_grad.y - cell.last_total_grad.y) * (cell.ref_total_grad.y - cell.last_total_grad.y);
|
||||||
|
n++;
|
||||||
}
|
}
|
||||||
coord_dist = std::sqrt(coord_dist / (2 * float(mcells.size())));
|
coord_dist = std::sqrt(coord_dist / (2 * float(n)));
|
||||||
grad_dist = std::sqrt(grad_dist / (2 * float(mcells.size())));
|
grad_dist = std::sqrt(grad_dist / (2 * float(n)));
|
||||||
log_info("coord_dist: %f grad_dist: %f\n", coord_dist, grad_dist);
|
log_info("coord_dist: %f grad_dist: %f\n", coord_dist, grad_dist);
|
||||||
return coord_dist / grad_dist;
|
return coord_dist / grad_dist;
|
||||||
// return 0.1;
|
// return 0.1;
|
||||||
@ -969,7 +975,7 @@ class StaticPlacer
|
|||||||
update_gradients(true, true, /* init_penalty */ true);
|
update_gradients(true, true, /* init_penalty */ true);
|
||||||
// compute a "fake" previous position based on an arbitrary steplength and said gradients for nesterov
|
// compute a "fake" previous position based on an arbitrary steplength and said gradients for nesterov
|
||||||
for (auto &cell : mcells) {
|
for (auto &cell : mcells) {
|
||||||
if (cell.is_fixed)
|
if (cell.is_fixed || cell.is_dark)
|
||||||
continue;
|
continue;
|
||||||
// save current position in last_pos
|
// save current position in last_pos
|
||||||
cell.last_pos = cell.pos;
|
cell.last_pos = cell.pos;
|
||||||
@ -981,6 +987,8 @@ class StaticPlacer
|
|||||||
update_gradients(true);
|
update_gradients(true);
|
||||||
// Now we have the fake previous state in the current state
|
// Now we have the fake previous state in the current state
|
||||||
for (auto &cell : mcells) {
|
for (auto &cell : mcells) {
|
||||||
|
if (cell.is_fixed || cell.is_dark)
|
||||||
|
continue;
|
||||||
std::swap(cell.last_ref_pos, cell.ref_pos);
|
std::swap(cell.last_ref_pos, cell.ref_pos);
|
||||||
std::swap(cell.ref_total_grad, cell.last_total_grad);
|
std::swap(cell.ref_total_grad, cell.last_total_grad);
|
||||||
std::swap(cell.ref_wl_grad, cell.last_wl_grad);
|
std::swap(cell.ref_wl_grad, cell.last_wl_grad);
|
||||||
@ -1035,7 +1043,11 @@ class StaticPlacer
|
|||||||
{
|
{
|
||||||
// TODO: update penalties; wirelength factor; etc
|
// TODO: update penalties; wirelength factor; etc
|
||||||
steplen = get_steplen();
|
steplen = get_steplen();
|
||||||
log_info("iter=%d steplen=%f a=%f\n", iter, steplen, nesterov_a);
|
std::string penalty_str = "";
|
||||||
|
for (auto p : dens_penalty) {
|
||||||
|
penalty_str += stringf("%s%.2f", penalty_str.empty() ? "" : ", ", p);
|
||||||
|
}
|
||||||
|
log_info("iter=%d steplen=%f a=%f penalty=[%s]\n", iter, steplen, nesterov_a, penalty_str.c_str());
|
||||||
float a_next = (1.0f + std::sqrt(4.0f * nesterov_a * nesterov_a + 1)) / 2.0f;
|
float a_next = (1.0f + std::sqrt(4.0f * nesterov_a * nesterov_a + 1)) / 2.0f;
|
||||||
// Update positions using Nesterov's
|
// Update positions using Nesterov's
|
||||||
for (auto &cell : mcells) {
|
for (auto &cell : mcells) {
|
||||||
@ -1381,6 +1393,7 @@ class StaticPlacer
|
|||||||
groups.resize(cfg.cell_groups.size());
|
groups.resize(cfg.cell_groups.size());
|
||||||
tmg.setup_only = true;
|
tmg.setup_only = true;
|
||||||
tmg.setup();
|
tmg.setup();
|
||||||
|
dump_density = ctx->setting<bool>("static/dump_density", false);
|
||||||
};
|
};
|
||||||
void place()
|
void place()
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "chipdb.h"
|
#include "chipdb.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
@ -62,8 +63,10 @@ void Arch::load_chipdb(const std::string &path)
|
|||||||
db_path = args.chipdb_override;
|
db_path = args.chipdb_override;
|
||||||
} else {
|
} else {
|
||||||
db_path = proc_share_dirname();
|
db_path = proc_share_dirname();
|
||||||
db_path += "/himbaechel/";
|
db_path += "himbaechel/";
|
||||||
db_path += path;
|
db_path += path;
|
||||||
|
boost::filesystem::path p(db_path);
|
||||||
|
db_path = p.make_preferred().string();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
blob_file.open(db_path);
|
blob_file.open(db_path);
|
||||||
|
@ -916,19 +916,47 @@ struct NexusPacker
|
|||||||
{
|
{
|
||||||
// Keep running until we reach a fixed point
|
// Keep running until we reach a fixed point
|
||||||
log_info("Placing globals...\n");
|
log_info("Placing globals...\n");
|
||||||
bool did_something = true;
|
TopoSort<IdString> sorter;
|
||||||
while (did_something) {
|
auto is_glb_cell = [&](const CellInfo *cell) {
|
||||||
did_something = false;
|
return cell->type.in(id_OSC_CORE, id_DCC, id_PLL_CORE, id_DCS);
|
||||||
for (auto &cell : ctx->cells) {
|
};
|
||||||
CellInfo *ci = cell.second.get();
|
|
||||||
if (ci->type == id_OSC_CORE)
|
for (auto &cell : ctx->cells) {
|
||||||
did_something |= preplace_singleton(ci);
|
CellInfo *ci = cell.second.get();
|
||||||
else if (ci->type == id_DCC)
|
if (is_glb_cell(ci)) {
|
||||||
did_something |= preplace_prim(ci, id_CLKI, false);
|
sorter.node(ci->name);
|
||||||
else if (ci->type == id_PLL_CORE)
|
|
||||||
did_something |= preplace_prim(ci, id_REFCK, false);
|
auto do_pin = [&](IdString pin) {
|
||||||
|
NetInfo *net = ci->getPort(pin);
|
||||||
|
if (!net || !net->driver.cell || !is_glb_cell(net->driver.cell))
|
||||||
|
return;
|
||||||
|
sorter.edge(net->driver.cell->name, ci->name);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ci->type == id_PLL_CORE) {
|
||||||
|
do_pin(id_REFCK);
|
||||||
|
} else if (ci->type == id_DCC) {
|
||||||
|
do_pin(id_CLKI);
|
||||||
|
} else if (ci->type == id_DCS) {
|
||||||
|
do_pin(id_CLK0);
|
||||||
|
do_pin(id_CLK1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sorter.sort();
|
||||||
|
|
||||||
|
for (IdString cell_name : sorter.sorted) {
|
||||||
|
CellInfo *ci = ctx->cells.at(cell_name).get();
|
||||||
|
if (ci->type == id_OSC_CORE)
|
||||||
|
preplace_singleton(ci);
|
||||||
|
else if (ci->type == id_DCC)
|
||||||
|
preplace_prim(ci, id_CLKI, false);
|
||||||
|
else if (ci->type == id_PLL_CORE)
|
||||||
|
preplace_prim(ci, id_REFCK, false);
|
||||||
|
else if (ci->type == id_DCS)
|
||||||
|
preplace_prim(ci, id_CLK0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a bus port name
|
// Get a bus port name
|
||||||
|
Loading…
Reference in New Issue
Block a user