Merge pull request #47 from YosysHQ/settings_propagate
Use settings for placer1 and router1
This commit is contained in:
commit
26be6f9761
@ -144,7 +144,7 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("cstrweight")) {
|
if (vm.count("cstrweight")) {
|
||||||
// ctx->placer_constraintWeight = vm["cstrweight"].as<float>();
|
settings->set("placer1/constraintWeight", vm["cstrweight"].as<float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("freq")) {
|
if (vm.count("freq")) {
|
||||||
@ -261,6 +261,7 @@ int CommandHandler::exec()
|
|||||||
} else {
|
} else {
|
||||||
ctx = createContext();
|
ctx = createContext();
|
||||||
}
|
}
|
||||||
|
settings = std::unique_ptr<Settings>(new Settings(ctx.get()));
|
||||||
setupContext(ctx.get());
|
setupContext(ctx.get());
|
||||||
setupArchContext(ctx.get());
|
setupArchContext(ctx.get());
|
||||||
return executeMain(std::move(ctx));
|
return executeMain(std::move(ctx));
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ class CommandHandler
|
|||||||
protected:
|
protected:
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
ArchArgs chipArgs;
|
ArchArgs chipArgs;
|
||||||
|
std::unique_ptr<Settings> settings;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
po::options_description options;
|
po::options_description options;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -108,14 +109,12 @@ class SAPlacer
|
|||||||
if (bel_type != cell->type) {
|
if (bel_type != cell->type) {
|
||||||
log_error("Bel \'%s\' of type \'%s\' does not match cell "
|
log_error("Bel \'%s\' of type \'%s\' does not match cell "
|
||||||
"\'%s\' of type \'%s\'\n",
|
"\'%s\' of type \'%s\'\n",
|
||||||
loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
|
loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx));
|
||||||
cell->type.c_str(ctx));
|
|
||||||
}
|
}
|
||||||
if (!ctx->isValidBelForCell(cell, bel)) {
|
if (!ctx->isValidBelForCell(cell, bel)) {
|
||||||
log_error("Bel \'%s\' of type \'%s\' is not valid for cell "
|
log_error("Bel \'%s\' of type \'%s\' is not valid for cell "
|
||||||
"\'%s\' of type \'%s\'\n",
|
"\'%s\' of type \'%s\'\n",
|
||||||
loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
|
loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx));
|
||||||
cell->type.c_str(ctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->bindBel(bel, cell, STRENGTH_USER);
|
ctx->bindBel(bel, cell, STRENGTH_USER);
|
||||||
@ -492,6 +491,8 @@ class SAPlacer
|
|||||||
std::vector<decltype(NetInfo::udata)> old_udata;
|
std::vector<decltype(NetInfo::udata)> old_udata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx) { constraintWeight = get<float>("placer1/constraintWeight", 10); }
|
||||||
|
|
||||||
bool placer1(Context *ctx, Placer1Cfg cfg)
|
bool placer1(Context *ctx, Placer1Cfg cfg)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -20,12 +20,14 @@
|
|||||||
#define PLACE_H
|
#define PLACE_H
|
||||||
|
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct Placer1Cfg
|
struct Placer1Cfg : public Settings
|
||||||
{
|
{
|
||||||
float constraintWeight = 10;
|
Placer1Cfg(Context *ctx);
|
||||||
|
float constraintWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool placer1(Context *ctx, Placer1Cfg cfg);
|
extern bool placer1(Context *ctx, Placer1Cfg cfg);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -64,17 +65,36 @@ void ProjectHandler::save(Context *ctx, std::string filename)
|
|||||||
root.put("project.name", boost::filesystem::basename(filename));
|
root.put("project.name", boost::filesystem::basename(filename));
|
||||||
root.put("project.arch.name", ctx->archId().c_str(ctx));
|
root.put("project.arch.name", ctx->archId().c_str(ctx));
|
||||||
root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
|
||||||
std::string fn = ctx->settings[ctx->id("project/input/json")];
|
std::string fn = ctx->settings[ctx->id("input/json")];
|
||||||
root.put("project.input.json", make_relative(fn, proj.parent_path()).string());
|
root.put("project.input.json", make_relative(fn, proj.parent_path()).string());
|
||||||
root.put("project.params.freq", int(ctx->target_freq / 1e6));
|
root.put("project.params.freq", int(ctx->target_freq / 1e6));
|
||||||
root.put("project.params.seed", ctx->rngstate);
|
root.put("project.params.seed", ctx->rngstate);
|
||||||
saveArch(ctx, root, proj.parent_path().string());
|
saveArch(ctx, root, proj.parent_path().string());
|
||||||
|
for (auto const &item : ctx->settings) {
|
||||||
|
std::string path = "project.settings.";
|
||||||
|
path += item.first.c_str(ctx);
|
||||||
|
std::replace(path.begin(), path.end(), '/', '.');
|
||||||
|
root.put(path, item.second);
|
||||||
|
}
|
||||||
pt::write_json(f, root);
|
pt::write_json(f, root);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
log_error("Error saving project file.\n");
|
log_error("Error saving project file.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addSettings(Context *ctx, std::string path, pt::ptree sub)
|
||||||
|
{
|
||||||
|
for (pt::ptree::value_type &v : sub) {
|
||||||
|
const std::string &key = v.first;
|
||||||
|
const boost::property_tree::ptree &subtree = v.second;
|
||||||
|
if (subtree.empty()) {
|
||||||
|
ctx->settings.emplace(ctx->id(path + key), subtree.get_value<std::string>().c_str());
|
||||||
|
} else {
|
||||||
|
addSettings(ctx, path + key + "/", subtree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Context> ProjectHandler::load(std::string filename)
|
std::unique_ptr<Context> ProjectHandler::load(std::string filename)
|
||||||
{
|
{
|
||||||
std::unique_ptr<Context> ctx;
|
std::unique_ptr<Context> ctx;
|
||||||
@ -110,6 +130,10 @@ std::unique_ptr<Context> ProjectHandler::load(std::string filename)
|
|||||||
if (params.count("seed"))
|
if (params.count("seed"))
|
||||||
ctx->rngseed(params.get<uint64_t>("seed"));
|
ctx->rngseed(params.get<uint64_t>("seed"));
|
||||||
}
|
}
|
||||||
|
if (project.count("settings")) {
|
||||||
|
addSettings(ctx.get(), "", project.get_child("settings"));
|
||||||
|
}
|
||||||
|
|
||||||
loadArch(ctx.get(), root, proj.parent_path().string());
|
loadArch(ctx.get(), root, proj.parent_path().string());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
log_error("Error loading project file.\n");
|
log_error("Error loading project file.\n");
|
||||||
|
@ -682,6 +682,14 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg, RipupScoreboard &scores
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
Router1Cfg::Router1Cfg(Context *ctx) : Settings(ctx)
|
||||||
|
{
|
||||||
|
maxIterCnt = get<int>("router1/maxIterCnt", 200);
|
||||||
|
cleanupReroute = get<bool>("router1/cleanupReroute", true);
|
||||||
|
fullCleanupReroute = get<bool>("router1/fullCleanupReroute", true);
|
||||||
|
useEstimate = get<bool>("router1/useEstimate", true);
|
||||||
|
}
|
||||||
|
|
||||||
bool router1(Context *ctx, const Router1Cfg &cfg)
|
bool router1(Context *ctx, const Router1Cfg &cfg)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -953,7 +961,7 @@ bool Context::getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t *del
|
|||||||
std::unordered_map<WireId, PipId> *route, bool useEstimate)
|
std::unordered_map<WireId, PipId> *route, bool useEstimate)
|
||||||
{
|
{
|
||||||
RipupScoreboard scores;
|
RipupScoreboard scores;
|
||||||
Router1Cfg cfg;
|
Router1Cfg cfg(this);
|
||||||
cfg.useEstimate = useEstimate;
|
cfg.useEstimate = useEstimate;
|
||||||
|
|
||||||
Router router(this, cfg, scores, src_wire, dst_wire);
|
Router router(this, cfg, scores, src_wire, dst_wire);
|
||||||
|
@ -21,15 +21,18 @@
|
|||||||
#define ROUTER1_H
|
#define ROUTER1_H
|
||||||
|
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct Router1Cfg
|
struct Router1Cfg : Settings
|
||||||
{
|
{
|
||||||
int maxIterCnt = 200;
|
Router1Cfg(Context *ctx);
|
||||||
bool cleanupReroute = true;
|
|
||||||
bool fullCleanupReroute = true;
|
int maxIterCnt;
|
||||||
bool useEstimate = true;
|
bool cleanupReroute;
|
||||||
|
bool fullCleanupReroute;
|
||||||
|
bool useEstimate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool router1(Context *ctx, const Router1Cfg &cfg);
|
extern bool router1(Context *ctx, const Router1Cfg &cfg);
|
||||||
|
63
common/settings.h
Normal file
63
common/settings.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* nextpnr -- Next Generation Place and Route
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Miodrag Milanovic <miodrag@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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef SETTINGS_H
|
||||||
|
#define SETTINGS_H
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include "log.h"
|
||||||
|
#include "nextpnr.h"
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Settings(Context *ctx) : ctx(ctx) {}
|
||||||
|
|
||||||
|
template <typename T> T get(const char *name, T defaultValue)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
IdString id = ctx->id(name);
|
||||||
|
auto pair = ctx->settings.emplace(id, std::to_string(defaultValue));
|
||||||
|
if (!pair.second) {
|
||||||
|
return boost::lexical_cast<T>(pair.first->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (boost::bad_lexical_cast &) {
|
||||||
|
log_error("Problem reading setting %s, using default value\n", name);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void set(const char *name, T value)
|
||||||
|
{
|
||||||
|
IdString id = ctx->id(name);
|
||||||
|
auto pair = ctx->settings.emplace(id, std::to_string(value));
|
||||||
|
if (!pair.second) {
|
||||||
|
ctx->settings[pair.first->first] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Context *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // SETTINGS_H
|
@ -383,13 +383,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
bool Arch::place() { return placer1(getCtx(), Placer1Cfg()); }
|
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||||
{
|
|
||||||
Router1Cfg cfg;
|
|
||||||
return router1(getCtx(), cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -446,9 +446,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
bool Arch::place() { return placer1(getCtx(), Placer1Cfg()); }
|
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||||
|
|
||||||
bool Arch::route() { return router1(getCtx(), Router1Cfg()); }
|
bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ void BaseMainWindow::disableActions()
|
|||||||
actionNew->setEnabled(true);
|
actionNew->setEnabled(true);
|
||||||
actionOpen->setEnabled(true);
|
actionOpen->setEnabled(true);
|
||||||
|
|
||||||
if (ctx->settings.find(ctx->id("project/input/json")) != ctx->settings.end())
|
if (ctx->settings.find(ctx->id("input/json")) != ctx->settings.end())
|
||||||
actionSave->setEnabled(true);
|
actionSave->setEnabled(true);
|
||||||
else
|
else
|
||||||
actionSave->setEnabled(false);
|
actionSave->setEnabled(false);
|
||||||
|
@ -191,7 +191,7 @@ void MainWindow::onRouteFinished() { actionSaveAsc->setEnabled(true); }
|
|||||||
|
|
||||||
void MainWindow::onProjectLoaded()
|
void MainWindow::onProjectLoaded()
|
||||||
{
|
{
|
||||||
if (ctx->settings.find(ctx->id("project/input/pcf")) != ctx->settings.end())
|
if (ctx->settings.find(ctx->id("input/pcf")) != ctx->settings.end())
|
||||||
actionLoadPCF->setEnabled(false);
|
actionLoadPCF->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,18 +602,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
bool Arch::place()
|
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||||
{
|
|
||||||
Placer1Cfg cfg;
|
|
||||||
cfg.constraintWeight = placer_constraintWeight;
|
|
||||||
return placer1(getCtx(), cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Arch::route()
|
bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||||
{
|
|
||||||
Router1Cfg cfg;
|
|
||||||
return router1(getCtx(), cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -839,8 +839,6 @@ struct Arch : BaseCtx
|
|||||||
}
|
}
|
||||||
NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}");
|
NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}");
|
||||||
}
|
}
|
||||||
|
|
||||||
float placer_constraintWeight = 10;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ice40DelayFuzzerMain(Context *ctx);
|
void ice40DelayFuzzerMain(Context *ctx);
|
||||||
|
@ -66,7 +66,7 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
|
|||||||
log_error("unsupported pcf command '%s'\n", cmd.c_str());
|
log_error("unsupported pcf command '%s'\n", cmd.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->settings.emplace(ctx->id("project/input/pcf"), filename);
|
ctx->settings.emplace(ctx->id("input/pcf"), filename);
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -28,8 +28,8 @@ NEXTPNR_NAMESPACE_BEGIN
|
|||||||
void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path)
|
void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path)
|
||||||
{
|
{
|
||||||
root.put("project.arch.package", ctx->archArgs().package);
|
root.put("project.arch.package", ctx->archArgs().package);
|
||||||
if (ctx->settings.find(ctx->id("project/input/pcf")) != ctx->settings.end()) {
|
if (ctx->settings.find(ctx->id("input/pcf")) != ctx->settings.end()) {
|
||||||
std::string fn = ctx->settings[ctx->id("project/input/pcf")];
|
std::string fn = ctx->settings[ctx->id("input/pcf")];
|
||||||
root.put("project.input.pcf", make_relative(fn, path).string());
|
root.put("project.input.pcf", make_relative(fn, path).string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,7 +768,7 @@ bool parse_json_file(std::istream &f, std::string &filename, Context *ctx)
|
|||||||
|
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
log_break();
|
log_break();
|
||||||
ctx->settings.emplace(ctx->id("project/input/json"), filename);
|
ctx->settings.emplace(ctx->id("input/json"), filename);
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user