nexus: Add FASM export for comb logic and FFs
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
2c49f812d9
commit
689922bc21
@ -96,3 +96,8 @@ X(LSRMODE)
|
|||||||
|
|
||||||
X(MODE)
|
X(MODE)
|
||||||
X(INJECT)
|
X(INJECT)
|
||||||
|
|
||||||
|
X(PLC)
|
||||||
|
X(CIB)
|
||||||
|
X(CIB_T)
|
||||||
|
X(CIB_LR)
|
||||||
|
@ -80,6 +80,17 @@ struct NexusFasmWriter
|
|||||||
write_vector(name, bits, invert);
|
write_vector(name, bits, invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_enum(const CellInfo *cell, const std::string &name, const std::string &defval = "")
|
||||||
|
{
|
||||||
|
auto fnd = cell->params.find(ctx->id(name));
|
||||||
|
if (fnd == cell->params.end()) {
|
||||||
|
if (!defval.empty())
|
||||||
|
write_bit(stringf("%s.%s", name.c_str(), defval.c_str()));
|
||||||
|
} else {
|
||||||
|
write_bit(stringf("%s.%s", name.c_str(), fnd->second.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NexusFasmWriter(const Context *ctx, std::ostream &out) : ctx(ctx), out(out) {}
|
NexusFasmWriter(const Context *ctx, std::ostream &out) : ctx(ctx), out(out) {}
|
||||||
std::string tile_name(int loc, const PhysicalTileInfoPOD &tile)
|
std::string tile_name(int loc, const PhysicalTileInfoPOD &tile)
|
||||||
{
|
{
|
||||||
@ -108,6 +119,7 @@ struct NexusFasmWriter
|
|||||||
}
|
}
|
||||||
return escaped;
|
return escaped;
|
||||||
}
|
}
|
||||||
|
void push_tile(int loc, IdString tile_type) { push(tile_name(loc, tile_by_type_and_loc(loc, tile_type))); }
|
||||||
void write_pip(PipId pip)
|
void write_pip(PipId pip)
|
||||||
{
|
{
|
||||||
auto &pd = ctx->pip_data(pip);
|
auto &pd = ctx->pip_data(pip);
|
||||||
@ -128,12 +140,60 @@ struct NexusFasmWriter
|
|||||||
write_pip(p);
|
write_pip(p);
|
||||||
blank();
|
blank();
|
||||||
}
|
}
|
||||||
|
void write_comb(const CellInfo *cell)
|
||||||
|
{
|
||||||
|
BelId bel = cell->bel;
|
||||||
|
int z = ctx->bel_data(bel).z;
|
||||||
|
int k = z & 0x1;
|
||||||
|
char slice = 'A' + (z >> 8);
|
||||||
|
push_tile(bel.tile, id_PLC);
|
||||||
|
push(stringf("SLICE%c", slice));
|
||||||
|
if (cell->params.count(id_INIT))
|
||||||
|
write_int_vector(stringf("K%d.INIT", k), int_or_default(cell->params, id_INIT, 0), 16);
|
||||||
|
if (cell->lutInfo.is_carry) {
|
||||||
|
write_bit("MODE.CCU2");
|
||||||
|
write_enum(cell, "INJECT", "NO");
|
||||||
|
}
|
||||||
|
pop(2);
|
||||||
|
}
|
||||||
|
void write_ff(const CellInfo *cell)
|
||||||
|
{
|
||||||
|
BelId bel = cell->bel;
|
||||||
|
int z = ctx->bel_data(bel).z;
|
||||||
|
int k = z & 0x1;
|
||||||
|
char slice = 'A' + (z >> 8);
|
||||||
|
push_tile(bel.tile, id_PLC);
|
||||||
|
push(stringf("SLICE%c", slice));
|
||||||
|
push(stringf("FF%d", k));
|
||||||
|
write_bit("USED.YES");
|
||||||
|
write_enum(cell, "REGSET", "RESET");
|
||||||
|
write_enum(cell, "LSRMODE", "LSR");
|
||||||
|
write_enum(cell, "SEL", "DF");
|
||||||
|
pop();
|
||||||
|
write_enum(cell, "REGDDR");
|
||||||
|
write_enum(cell, "SRMODE");
|
||||||
|
write_enum(cell, "CLKMUX");
|
||||||
|
write_enum(cell, "CEMUX");
|
||||||
|
write_enum(cell, "LSRMUX");
|
||||||
|
write_enum(cell, "GSR");
|
||||||
|
pop(2);
|
||||||
|
}
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
// Write routing
|
// Write routing
|
||||||
for (auto n : sorted(ctx->nets)) {
|
for (auto n : sorted(ctx->nets)) {
|
||||||
write_net(n.second);
|
write_net(n.second);
|
||||||
}
|
}
|
||||||
|
// Write cell config
|
||||||
|
for (auto c : sorted(ctx->cells)) {
|
||||||
|
const CellInfo *ci = c.second;
|
||||||
|
write_comment(stringf("# Cell %s", ctx->nameOf(ci)));
|
||||||
|
if (ci->type == id_OXIDE_COMB)
|
||||||
|
write_comb(ci);
|
||||||
|
else if (ci->type == id_OXIDE_FF)
|
||||||
|
write_ff(ci);
|
||||||
|
blank();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user