mistral: Add stub pack/place/route functions
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
879ac39e53
commit
e5e2f7bc62
@ -75,7 +75,7 @@ typename std::enable_if<std::is_same<Tret, Tc>::value, Tret>::type return_if_mat
|
||||
}
|
||||
|
||||
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 "
|
||||
"respective range types are 'const std::vector&'");
|
||||
|
@ -21,6 +21,13 @@
|
||||
#include "log.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"
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
@ -244,10 +251,6 @@ BelBucketId Arch::getBelBucketForCellType(IdString cell_type) const
|
||||
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)
|
||||
{
|
||||
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
|
||||
const std::string Arch::defaultPlacer = "heap";
|
||||
#else
|
||||
|
@ -214,6 +214,7 @@ struct ArchRanges : BaseArchRanges
|
||||
using AllBelsRangeT = const std::vector<BelId> &;
|
||||
using TileBelsRangeT = std::vector<BelId>;
|
||||
using BelPinsRangeT = std::vector<IdString>;
|
||||
using CellBelPinRangeT = const std::vector<IdString> &;
|
||||
// Wires
|
||||
using AllWiresRangeT = AllWireRange;
|
||||
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;
|
||||
BelBucketId getBelBucketForCellType(IdString cell_type) const override;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
void assignArchInfo() override;
|
||||
bool pack() override;
|
||||
bool place() override;
|
||||
bool route() override;
|
||||
@ -350,6 +357,10 @@ struct Arch : BaseArch<ArchRanges>
|
||||
void assign_comb_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
|
||||
|
@ -388,6 +388,33 @@ bool Arch::is_lab_ctrlset_legal(uint32_t lab) const
|
||||
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
|
||||
// overlaps and a correct mapping will be resolved twixt placement and routing
|
||||
const std::unordered_map<IdString, IdString> Arch::comb_pinmap = {
|
||||
|
35
mistral/pack.cc
Normal file
35
mistral/pack.cc
Normal 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
|
Loading…
Reference in New Issue
Block a user