mistral: Add stub pack/place/route functions

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-05-08 13:38:17 +01:00
parent 879ac39e53
commit e5e2f7bc62
5 changed files with 143 additions and 5 deletions

View File

@ -75,7 +75,7 @@ typename std::enable_if<std::is_same<Tret, Tc>::value, Tret>::type return_if_mat
} }
template <typename Tret, typename Tc> template <typename Tret, typename Tc>
typename std::enable_if<!std::is_same<Tret, Tc>::value, Tret>::type return_if_match(Tret r) typename std::enable_if<!std::is_same<Tret, Tc>::value, Tc>::type return_if_match(Tret r)
{ {
NPNR_ASSERT_FALSE("default implementations of cell type and bel bucket range functions only available when the " NPNR_ASSERT_FALSE("default implementations of cell type and bel bucket range functions only available when the "
"respective range types are 'const std::vector&'"); "respective range types are 'const std::vector&'");

View File

@ -21,6 +21,13 @@
#include "log.h" #include "log.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "placer1.h"
#include "placer_heap.h"
#include "router1.h"
#include "router2.h"
#include "timing.h"
#include "util.h"
#include "cyclonev.h" #include "cyclonev.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -244,10 +251,6 @@ BelBucketId Arch::getBelBucketForCellType(IdString cell_type) const
return cell_type; return cell_type;
} }
bool Arch::pack() { return true; }
bool Arch::place() { return true; }
bool Arch::route() { return true; }
BelId Arch::add_bel(int x, int y, IdString name, IdString type) BelId Arch::add_bel(int x, int y, IdString name, IdString type)
{ {
auto &bels = bels_by_tile.at(pos2idx(x, y)); auto &bels = bels_by_tile.at(pos2idx(x, y));
@ -321,6 +324,68 @@ void Arch::assign_default_pinmap(CellInfo *cell)
} }
} }
void Arch::assignArchInfo()
{
for (auto cell : sorted(cells)) {
CellInfo *ci = cell.second;
if (is_comb_cell(ci->type))
assign_comb_info(ci);
else if (ci->type == id_MISTRAL_FF)
assign_ff_info(ci);
assign_default_pinmap(ci);
}
}
bool Arch::place()
{
std::string placer = str_or_default(settings, id("placer"), defaultPlacer);
if (placer == "heap") {
PlacerHeapCfg cfg(getCtx());
cfg.ioBufTypes.insert(id_MISTRAL_IO);
cfg.ioBufTypes.insert(id_MISTRAL_IB);
cfg.ioBufTypes.insert(id_MISTRAL_OB);
cfg.cellGroups.emplace_back();
cfg.cellGroups.back().insert({id_MISTRAL_COMB});
cfg.cellGroups.back().insert({id_MISTRAL_FF});
cfg.beta = 0.5; // TODO: find a good value of beta for sensible ALM spreading
cfg.criticalityExponent = 7;
if (!placer_heap(getCtx(), cfg))
return false;
} else if (placer == "sa") {
if (!placer1(getCtx(), Placer1Cfg(getCtx())))
return false;
} else {
log_error("Mistral architecture does not support placer '%s'\n", placer.c_str());
}
getCtx()->attrs[getCtx()->id("step")] = std::string("place");
archInfoToAttributes();
return true;
}
bool Arch::route()
{
assign_budget(getCtx(), true);
lab_pre_route();
std::string router = str_or_default(settings, id("router"), defaultRouter);
bool result;
if (router == "router1") {
result = router1(getCtx(), Router1Cfg(getCtx()));
} else if (router == "router2") {
router2(getCtx(), Router2Cfg(getCtx()));
result = true;
} else {
log_error("Mistral architecture does not support router '%s'\n", router.c_str());
}
getCtx()->attrs[getCtx()->id("step")] = std::string("route");
archInfoToAttributes();
return result;
}
#ifdef WITH_HEAP #ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap"; const std::string Arch::defaultPlacer = "heap";
#else #else

View File

@ -214,6 +214,7 @@ struct ArchRanges : BaseArchRanges
using AllBelsRangeT = const std::vector<BelId> &; using AllBelsRangeT = const std::vector<BelId> &;
using TileBelsRangeT = std::vector<BelId>; using TileBelsRangeT = std::vector<BelId>;
using BelPinsRangeT = std::vector<IdString>; using BelPinsRangeT = std::vector<IdString>;
using CellBelPinRangeT = const std::vector<IdString> &;
// Wires // Wires
using AllWiresRangeT = AllWireRange; using AllWiresRangeT = AllWireRange;
using DownhillPipRangeT = UpDownhillPipRange; using DownhillPipRangeT = UpDownhillPipRange;
@ -315,11 +316,17 @@ struct Arch : BaseArch<ArchRanges>
// ------------------------------------------------- // -------------------------------------------------
const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override
{
return cell_info->pin_data.at(pin).bel_pins;
}
bool isValidBelForCellType(IdString cell_type, BelId bel) const override; bool isValidBelForCellType(IdString cell_type, BelId bel) const override;
BelBucketId getBelBucketForCellType(IdString cell_type) const override; BelBucketId getBelBucketForCellType(IdString cell_type) const override;
// ------------------------------------------------- // -------------------------------------------------
void assignArchInfo() override;
bool pack() override; bool pack() override;
bool place() override; bool place() override;
bool route() override; bool route() override;
@ -350,6 +357,10 @@ struct Arch : BaseArch<ArchRanges>
void assign_comb_info(CellInfo *cell) const; // lab.cc void assign_comb_info(CellInfo *cell) const; // lab.cc
void assign_ff_info(CellInfo *cell) const; // lab.cc void assign_ff_info(CellInfo *cell) const; // lab.cc
void lab_pre_route(); // lab.cc
void assign_control_sets(uint32_t lab); // lab.cc
void reassign_alm_inputs(uint32_t lab, uint8_t alm); // lab.cc
// ------------------------------------------------- // -------------------------------------------------
bool is_io_cell(IdString cell_type) const; // io.cc bool is_io_cell(IdString cell_type) const; // io.cc

View File

@ -388,6 +388,33 @@ bool Arch::is_lab_ctrlset_legal(uint32_t lab) const
return true; return true;
} }
void Arch::lab_pre_route()
{
for (uint32_t lab = 0; lab < labs.size(); lab++) {
assign_control_sets(lab);
for (uint8_t alm = 0; alm < 10; alm++) {
reassign_alm_inputs(lab, alm);
}
}
}
void Arch::assign_control_sets(uint32_t lab)
{
// TODO: set up reservations for checkPipAvailForNet for control set signals
// This will be needed because clock and CE are routed together and must be kept together, there isn't free choice
// e.g. CLK0 & ENA0 must be use for one control set, and CLK1 & ENA1 for another, they can't be mixed and matched
}
void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm)
{
// TODO: based on the usage of LUTs inside the ALM, set up cell-bel pin map for the combinational cells in the ALM
// so that each physical bel pin is only used for one net; and the logical functions can be implemented correctly.
// This function should also insert route-through LUTs to legalise flipflop inputs as needed.
// TODO: in the future, as well as the reassignment here we will also have pseudo PIPs in front of the ALM so that
// the router can permute LUTs for routeability; too. Here we will need to lock out some of those PIPs depending on
// the usage of the ALM, as not all inputs are always interchangeable.
}
// This default cell-bel pin mapping is used to provide estimates during placement only. It will have errors and // This default cell-bel pin mapping is used to provide estimates during placement only. It will have errors and
// overlaps and a correct mapping will be resolved twixt placement and routing // overlaps and a correct mapping will be resolved twixt placement and routing
const std::unordered_map<IdString, IdString> Arch::comb_pinmap = { const std::unordered_map<IdString, IdString> Arch::comb_pinmap = {

35
mistral/pack.cc Normal file
View File

@ -0,0 +1,35 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2021 gatecat <gatecat@ds0.me>
*
* 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 "log.h"
#include "nextpnr.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN
bool Arch::pack()
{
// TODO:
// - Insert constant driver LUTs
// - Fold constants and inverters into cell pins
// - Constrain IO
return true;
}
NEXTPNR_NAMESPACE_END