nexus: Working on validity checking
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
887d7c717b
commit
84d5426242
@ -82,6 +82,13 @@ template <typename F1> CellInfo *net_driven_by(const Context *ctx, const NetInfo
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a port is used
|
||||
inline bool port_used(CellInfo *cell, IdString port_name)
|
||||
{
|
||||
auto port_fnd = cell->ports.find(port_name);
|
||||
return port_fnd != cell->ports.end() && port_fnd->second.net != nullptr;
|
||||
}
|
||||
|
||||
// Connect a net to a port
|
||||
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name);
|
||||
|
||||
|
@ -410,12 +410,6 @@ bool Arch::route()
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Arch::assignArchInfo() {}
|
||||
|
||||
void assignCellInfo(CellInfo *cell) {}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#ifdef WITH_HEAP
|
||||
const std::string Arch::defaultPlacer = "heap";
|
||||
#else
|
||||
|
46
nexus/arch.h
46
nexus/arch.h
@ -159,7 +159,7 @@ NPNR_PACKED_STRUCT(struct PhysicalTileInfoPOD {
|
||||
int32_t tiletype; // tile type IdString
|
||||
});
|
||||
|
||||
enum LocFlagsPOD : uint32_t
|
||||
enum LocFlags : uint32_t
|
||||
{
|
||||
LOC_LOGIC = 0x000001,
|
||||
LOC_IO18 = 0x000002,
|
||||
@ -816,12 +816,19 @@ struct Arch : BaseCtx
|
||||
cell->bel = bel;
|
||||
cell->belStrength = strength;
|
||||
refreshUiBel(bel);
|
||||
|
||||
if (tile_is(bel, LOC_LOGIC))
|
||||
update_logic_bel(bel, cell);
|
||||
}
|
||||
|
||||
void unbindBel(BelId bel)
|
||||
{
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
NPNR_ASSERT(tileStatus[bel.tile].boundcells[bel.index] != nullptr);
|
||||
|
||||
if (tile_is(bel, LOC_LOGIC))
|
||||
update_logic_bel(bel, nullptr);
|
||||
|
||||
tileStatus[bel.tile].boundcells[bel.index]->bel = BelId();
|
||||
tileStatus[bel.tile].boundcells[bel.index]->belStrength = STRENGTH_NONE;
|
||||
tileStatus[bel.tile].boundcells[bel.index] = nullptr;
|
||||
@ -1302,6 +1309,43 @@ struct Arch : BaseCtx
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
template <typename TId> uint32_t tile_loc_flags(TId id) const { return chip_info->grid[id.tile].loc_flags; }
|
||||
|
||||
template <typename TId> bool tile_is(TId id, LocFlags lf) const { return tile_loc_flags(id) & lf; }
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
enum LogicBelZ
|
||||
{
|
||||
BEL_LUT0 = 0,
|
||||
BEL_LUT1 = 1,
|
||||
BEL_FF0 = 2,
|
||||
BEL_FF1 = 3,
|
||||
BEL_RAMW = 4,
|
||||
};
|
||||
|
||||
void update_logic_bel(BelId bel, CellInfo *cell)
|
||||
{
|
||||
int z = bel_data(bel).z;
|
||||
NPNR_ASSERT(z < 32);
|
||||
auto &tts = tileStatus[bel.tile];
|
||||
if (tts.lts == nullptr)
|
||||
tts.lts = new LogicTileStatus();
|
||||
auto &ts = *(tts.lts);
|
||||
ts.cells[z] = cell;
|
||||
switch (z & 0x7) {
|
||||
case BEL_FF0:
|
||||
case BEL_FF1:
|
||||
case BEL_RAMW:
|
||||
ts.halfs[(z >> 3) / 2].dirty = true;
|
||||
/* fall-through */
|
||||
case BEL_LUT0:
|
||||
case BEL_LUT1:
|
||||
ts.slices[(z >> 3)].dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool nexus_logic_tile_valid(LogicTileStatus <s) const;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
@ -23,15 +23,6 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
enum LogicBelZ
|
||||
{
|
||||
BEL_LUT0 = 0,
|
||||
BEL_LUT1 = 1,
|
||||
BEL_FF0 = 2,
|
||||
BEL_FF1 = 3,
|
||||
BEL_RAMW = 4,
|
||||
};
|
||||
|
||||
bool Arch::nexus_logic_tile_valid(LogicTileStatus <s) const
|
||||
{
|
||||
for (int s = 0; s < 4; s++) {
|
||||
@ -93,8 +84,23 @@ bool Arch::nexus_logic_tile_valid(LogicTileStatus <s) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; }
|
||||
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
||||
{
|
||||
// FIXME
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Arch::isBelLocationValid(BelId bel) const { return true; }
|
||||
bool Arch::isBelLocationValid(BelId bel) const
|
||||
{
|
||||
if (tile_is(bel, LOC_LOGIC)) {
|
||||
LogicTileStatus *lts = tileStatus[bel.tile].lts;
|
||||
if (lts == nullptr)
|
||||
return true;
|
||||
else
|
||||
return nexus_logic_tile_valid(*lts);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -169,7 +169,6 @@ struct ArchCellInfo
|
||||
struct
|
||||
{
|
||||
bool is_memory, is_carry, mux2_used;
|
||||
int input_count;
|
||||
NetInfo *f, *ofx;
|
||||
} lutInfo;
|
||||
struct
|
||||
|
@ -25,6 +25,10 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
bool is_enabled(CellInfo *ci, IdString prop) { return str_or_default(ci->params, prop, "") == "ENABLED"; }
|
||||
} // namespace
|
||||
|
||||
struct NexusPacker
|
||||
{
|
||||
Context *ctx;
|
||||
@ -182,4 +186,48 @@ bool Arch::pack()
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Arch::assignArchInfo()
|
||||
{
|
||||
for (auto cell : sorted(cells)) {
|
||||
assignCellInfo(cell.second);
|
||||
}
|
||||
}
|
||||
|
||||
void Arch::assignCellInfo(CellInfo *cell)
|
||||
{
|
||||
if (cell->type == id_OXIDE_COMB) {
|
||||
cell->lutInfo.is_memory = str_or_default(cell->params, id_MODE, "LOGIC") == "DPRAM";
|
||||
cell->lutInfo.is_carry = str_or_default(cell->params, id_MODE, "LOGIC") == "CCU2";
|
||||
cell->lutInfo.mux2_used = port_used(cell, id_OFX);
|
||||
cell->lutInfo.f = get_net_or_empty(cell, id_F);
|
||||
cell->lutInfo.ofx = get_net_or_empty(cell, id_OFX);
|
||||
} else if (cell->type == id_OXIDE_FF) {
|
||||
cell->ffInfo.ctrlset.async = str_or_default(cell->params, id_SRMODE, "LSR_OVER_CE") == "ASYNC";
|
||||
cell->ffInfo.ctrlset.regddr_en = is_enabled(cell, id_REGDDR);
|
||||
cell->ffInfo.ctrlset.gsr_en = is_enabled(cell, id_GSR);
|
||||
cell->ffInfo.ctrlset.clkmux = id(str_or_default(cell->params, id_CLKMUX, "CLK")).index;
|
||||
cell->ffInfo.ctrlset.cemux = id(str_or_default(cell->params, id_CEMUX, "CE")).index;
|
||||
cell->ffInfo.ctrlset.lsrmux = id(str_or_default(cell->params, id_LSRMUX, "LSR")).index;
|
||||
cell->ffInfo.ctrlset.clk = get_net_or_empty(cell, id_CLK);
|
||||
cell->ffInfo.ctrlset.ce = get_net_or_empty(cell, id_CE);
|
||||
cell->ffInfo.ctrlset.lsr = get_net_or_empty(cell, id_LSR);
|
||||
cell->ffInfo.di = get_net_or_empty(cell, id_DI);
|
||||
cell->ffInfo.m = get_net_or_empty(cell, id_M);
|
||||
} else if (cell->type == ID_RAMW) {
|
||||
cell->ffInfo.ctrlset.async = false;
|
||||
cell->ffInfo.ctrlset.regddr_en = false;
|
||||
cell->ffInfo.ctrlset.gsr_en = false;
|
||||
cell->ffInfo.ctrlset.clkmux = id(str_or_default(cell->params, id_CLKMUX, "CLK")).index;
|
||||
cell->ffInfo.ctrlset.cemux = ID_CE;
|
||||
cell->ffInfo.ctrlset.lsrmux = id(str_or_default(cell->params, id_LSRMUX, "LSR")).index;
|
||||
cell->ffInfo.ctrlset.clk = get_net_or_empty(cell, id_CLK);
|
||||
cell->ffInfo.ctrlset.ce = nullptr;
|
||||
cell->ffInfo.ctrlset.lsr = get_net_or_empty(cell, id_LSR);
|
||||
cell->ffInfo.di = nullptr;
|
||||
cell->ffInfo.m = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
Loading…
Reference in New Issue
Block a user