generic: New Property interface

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2019-08-05 17:28:54 +01:00
parent ec48f8f464
commit ebcdfc1ae8
6 changed files with 21 additions and 22 deletions

View File

@ -497,7 +497,7 @@ bool Arch::place()
// FIXME: No HeAP because it needs a list of IO buffers // FIXME: No HeAP because it needs a list of IO buffers
if (placer == "sa") { if (placer == "sa") {
bool retVal = placer1(getCtx(), Placer1Cfg(getCtx())); bool retVal = placer1(getCtx(), Placer1Cfg(getCtx()));
getCtx()->settings[getCtx()->id("place")] = "1"; getCtx()->settings[getCtx()->id("place")] = 1;
archInfoToAttributes(); archInfoToAttributes();
return retVal; return retVal;
} else { } else {
@ -508,7 +508,7 @@ bool Arch::place()
bool Arch::route() bool Arch::route()
{ {
bool retVal = router1(getCtx(), Router1Cfg(getCtx())); bool retVal = router1(getCtx(), Router1Cfg(getCtx()));
getCtx()->settings[getCtx()->id("route")] = "1"; getCtx()->settings[getCtx()->id("route")] = 1;
archInfoToAttributes(); archInfoToAttributes();
return retVal; return retVal;
} }

View File

@ -43,8 +43,8 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
new_cell->type = type; new_cell->type = type;
if (type == ctx->id("GENERIC_SLICE")) { if (type == ctx->id("GENERIC_SLICE")) {
new_cell->params[ctx->id("K")] = std::to_string(ctx->args.K); new_cell->params[ctx->id("K")] = std::to_string(ctx->args.K);
new_cell->params[ctx->id("INIT")] = "0"; new_cell->params[ctx->id("INIT")] = 0;
new_cell->params[ctx->id("FF_USED")] = "0"; new_cell->params[ctx->id("FF_USED")] = 0;
for (int i = 0; i < ctx->args.K; i++) for (int i = 0; i < ctx->args.K; i++)
add_port(ctx, new_cell.get(), "I[" + std::to_string(i) + "]", PORT_IN); add_port(ctx, new_cell.get(), "I[" + std::to_string(i) + "]", PORT_IN);
@ -53,9 +53,9 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
add_port(ctx, new_cell.get(), "Q", PORT_OUT); add_port(ctx, new_cell.get(), "Q", PORT_OUT);
} else if (type == ctx->id("GENERIC_IOB")) { } else if (type == ctx->id("GENERIC_IOB")) {
new_cell->params[ctx->id("INPUT_USED")] = "0"; new_cell->params[ctx->id("INPUT_USED")] = 0;
new_cell->params[ctx->id("OUTPUT_USED")] = "0"; new_cell->params[ctx->id("OUTPUT_USED")] = 0;
new_cell->params[ctx->id("ENABLE_USED")] = "0"; new_cell->params[ctx->id("ENABLE_USED")] = 0;
add_port(ctx, new_cell.get(), "PAD", PORT_INOUT); add_port(ctx, new_cell.get(), "PAD", PORT_INOUT);
add_port(ctx, new_cell.get(), "I", PORT_IN); add_port(ctx, new_cell.get(), "I", PORT_IN);
@ -81,17 +81,17 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
if (no_dff) { if (no_dff) {
replace_port(lut, ctx->id("Q"), lc, ctx->id("Q")); replace_port(lut, ctx->id("Q"), lc, ctx->id("Q"));
lc->params[ctx->id("FF_USED")] = "0"; lc->params[ctx->id("FF_USED")] = 0;
} }
} }
void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut) void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
{ {
lc->params[ctx->id("FF_USED")] = "1"; lc->params[ctx->id("FF_USED")] = 1;
replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK")); replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK"));
if (pass_thru_lut) { if (pass_thru_lut) {
lc->params[ctx->id("INIT")] = "2"; lc->params[ctx->id("INIT")] = 2;
replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]")); replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]"));
} }
@ -101,15 +101,15 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set<IdString> &todelete_cells) void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set<IdString> &todelete_cells)
{ {
if (nxio->type == ctx->id("$nextpnr_ibuf")) { if (nxio->type == ctx->id("$nextpnr_ibuf")) {
iob->params[ctx->id("INPUT_USED")] = "1"; iob->params[ctx->id("INPUT_USED")] = 1;
replace_port(nxio, ctx->id("O"), iob, ctx->id("O")); replace_port(nxio, ctx->id("O"), iob, ctx->id("O"));
} else if (nxio->type == ctx->id("$nextpnr_obuf")) { } else if (nxio->type == ctx->id("$nextpnr_obuf")) {
iob->params[ctx->id("OUTPUT_USED")] = "1"; iob->params[ctx->id("OUTPUT_USED")] = 1;
replace_port(nxio, ctx->id("I"), iob, ctx->id("I")); replace_port(nxio, ctx->id("I"), iob, ctx->id("I"));
} else if (nxio->type == ctx->id("$nextpnr_iobuf")) { } else if (nxio->type == ctx->id("$nextpnr_iobuf")) {
// N.B. tristate will be dealt with below // N.B. tristate will be dealt with below
iob->params[ctx->id("INPUT_USED")] = "1"; iob->params[ctx->id("INPUT_USED")] = 1;
iob->params[ctx->id("OUTPUT_USED")] = "1"; iob->params[ctx->id("OUTPUT_USED")] = 1;
replace_port(nxio, ctx->id("I"), iob, ctx->id("I")); replace_port(nxio, ctx->id("I"), iob, ctx->id("I"));
replace_port(nxio, ctx->id("O"), iob, ctx->id("O")); replace_port(nxio, ctx->id("O"), iob, ctx->id("O"));
} else { } else {
@ -120,7 +120,7 @@ void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set
ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); }, ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); },
ctx->id("Y")); ctx->id("Y"));
if (tbuf) { if (tbuf) {
iob->params[ctx->id("ENABLE_USED")] = "1"; iob->params[ctx->id("ENABLE_USED")] = 1;
replace_port(tbuf, ctx->id("A"), iob, ctx->id("I")); replace_port(tbuf, ctx->id("A"), iob, ctx->id("I"));
replace_port(tbuf, ctx->id("E"), iob, ctx->id("EN")); replace_port(tbuf, ctx->id("E"), iob, ctx->id("EN"));

View File

@ -4,7 +4,7 @@ for cname, cell in ctx.cells:
if cname in ("$PACKER_GND", "$PACKER_VCC"): if cname in ("$PACKER_GND", "$PACKER_VCC"):
continue continue
K = int(cell.params["K"]) K = int(cell.params["K"])
if cell.params["FF_USED"] == "1": if int(cell.params["FF_USED"], 2) == 1:
ctx.addCellTimingClock(cell=cname, port="CLK") ctx.addCellTimingClock(cell=cname, port="CLK")
for i in range(K): for i in range(K):
ctx.addCellTimingSetupHold(cell=cname, port="I[%d]" % i, clock="CLK", ctx.addCellTimingSetupHold(cell=cname, port="I[%d]" % i, clock="CLK",

View File

@ -45,8 +45,7 @@ def write_fasm(ctx, paramCfg, f):
print("%s.%s" % (cell.bel, fasm_name), file=f) print("%s.%s" % (cell.bel, fasm_name), file=f)
else: else:
# Parameters with width >32 are direct binary, otherwise denary # Parameters with width >32 are direct binary, otherwise denary
binval = val if cfg.width > 32 else "{:0{}b}".format(int(val), cfg.width) print("%s.%s[%d:0] = %d'b%s" % (cell.bel, fasm_name, cfg.width-1, cfg.width, val), file=f)
print("%s.%s[%d:0] = %d'b%s" % (cell.bel, fasm_name, cfg.width-1, cfg.width, binval), file=f)
else: else:
print("%s.%s.%s" % (cell.bel, fasm_name, val), file=f) print("%s.%s.%s" % (cell.bel, fasm_name, val), file=f)
print("", file=f) print("", file=f)

View File

@ -55,7 +55,7 @@ std::unique_ptr<Context> GenericCommandHandler::createContext(std::unordered_map
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
if (values.find("arch.name") != values.end()) { if (values.find("arch.name") != values.end()) {
std::string arch_name = values["arch.name"].str; std::string arch_name = values["arch.name"].as_string();
if (arch_name != "generic") if (arch_name != "generic")
log_error("Unsuported architecture '%s'.\n", arch_name.c_str()); log_error("Unsuported architecture '%s'.\n", arch_name.c_str());
} }

View File

@ -150,7 +150,7 @@ static void pack_constants(Context *ctx)
log_info("Packing constants..\n"); log_info("Packing constants..\n");
std::unique_ptr<CellInfo> gnd_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_GND"); std::unique_ptr<CellInfo> gnd_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_GND");
gnd_cell->params[ctx->id("INIT")] = "0"; gnd_cell->params[ctx->id("INIT")] = 0;
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo); std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
gnd_net->name = ctx->id("$PACKER_GND_NET"); gnd_net->name = ctx->id("$PACKER_GND_NET");
gnd_net->driver.cell = gnd_cell.get(); gnd_net->driver.cell = gnd_cell.get();
@ -158,7 +158,7 @@ static void pack_constants(Context *ctx)
gnd_cell->ports.at(ctx->id("Q")).net = gnd_net.get(); gnd_cell->ports.at(ctx->id("Q")).net = gnd_net.get();
std::unique_ptr<CellInfo> vcc_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_VCC"); std::unique_ptr<CellInfo> vcc_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_VCC");
vcc_cell->params[ctx->id("INIT")] = "1"; vcc_cell->params[ctx->id("INIT")] = 1;
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo); std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
vcc_net->name = ctx->id("$PACKER_VCC_NET"); vcc_net->name = ctx->id("$PACKER_VCC_NET");
vcc_net->driver.cell = vcc_cell.get(); vcc_net->driver.cell = vcc_cell.get();
@ -282,7 +282,7 @@ bool Arch::pack()
pack_io(ctx); pack_io(ctx);
pack_lut_lutffs(ctx); pack_lut_lutffs(ctx);
pack_nonlut_ffs(ctx); pack_nonlut_ffs(ctx);
ctx->settings[ctx->id("pack")] = "1"; ctx->settings[ctx->id("pack")] = 1;
ctx->assignArchInfo(); ctx->assignArchInfo();
log_info("Checksum: 0x%08x\n", ctx->checksum()); log_info("Checksum: 0x%08x\n", ctx->checksum());
return true; return true;