aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2022-02-16 17:09:54 +0000
committergatecat <gatecat@ds0.me>2022-02-16 17:09:54 +0000
commit76683a1e3c123d28deff750c38467c6377936879 (patch)
tree379b38c06745919df0e87c1be1410e16793b0925 /ice40
parent9ef0bc3d3ad667d937ed803eba7b216a604d5624 (diff)
downloadnextpnr-76683a1e3c123d28deff750c38467c6377936879.tar.gz
nextpnr-76683a1e3c123d28deff750c38467c6377936879.tar.bz2
nextpnr-76683a1e3c123d28deff750c38467c6377936879.zip
refactor: Use constids instead of id("..")
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc90
-rw-r--r--ice40/arch_place.cc2
-rw-r--r--ice40/bitstream.cc90
-rw-r--r--ice40/cells.cc588
-rw-r--r--ice40/cells.h80
-rw-r--r--ice40/chains.cc55
-rw-r--r--ice40/constids.inc166
-rw-r--r--ice40/main.cc8
-rw-r--r--ice40/pack.cc363
-rw-r--r--ice40/pcf.cc16
10 files changed, 798 insertions, 660 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 0f0246ef..cf7e99a5 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -169,29 +169,29 @@ std::string Arch::getChipName() const
IdString Arch::archArgsToId(ArchArgs args) const
{
if (args.type == ArchArgs::LP384)
- return id("lp384");
+ return id_lp384;
if (args.type == ArchArgs::LP1K)
- return id("lp1k");
+ return id_lp1k;
if (args.type == ArchArgs::HX1K)
- return id("hx1k");
+ return id_hx1k;
if (args.type == ArchArgs::UP3K)
- return id("up3k");
+ return id_up3k;
if (args.type == ArchArgs::UP5K)
- return id("up5k");
+ return id_up5k;
if (args.type == ArchArgs::U1K)
- return id("u1k");
+ return id_u1k;
if (args.type == ArchArgs::U2K)
- return id("u2k");
+ return id_u2k;
if (args.type == ArchArgs::U4K)
- return id("u4k");
+ return id_u4k;
if (args.type == ArchArgs::LP4K)
- return id("lp4k");
+ return id_lp4k;
if (args.type == ArchArgs::LP8K)
- return id("lp8k");
+ return id_lp8k;
if (args.type == ArchArgs::HX4K)
- return id("hx4k");
+ return id_hx4k;
if (args.type == ArchArgs::HX8K)
- return id("hx8k");
+ return id_hx8k;
return IdString();
}
@@ -289,7 +289,7 @@ std::vector<std::pair<IdString, std::string>> Arch::getBelAttrs(BelId bel) const
{
std::vector<std::pair<IdString, std::string>> ret;
- ret.push_back(std::make_pair(id("INDEX"), stringf("%d", bel.index)));
+ ret.push_back(std::make_pair(id_INDEX, stringf("%d", bel.index)));
return ret;
}
@@ -387,33 +387,33 @@ IdString Arch::getWireType(WireId wire) const
case WireInfoPOD::WIRE_TYPE_NONE:
return IdString();
case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
- return id("GLB2LOCAL");
+ return id_GLB2LOCAL;
case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
- return id("GLB_NETWK");
+ return id_GLB_NETWK;
case WireInfoPOD::WIRE_TYPE_LOCAL:
- return id("LOCAL");
+ return id_LOCAL;
case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
- return id("LUTFF_IN");
+ return id_LUTFF_IN;
case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
- return id("LUTFF_IN_LUT");
+ return id_LUTFF_IN_LUT;
case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
- return id("LUTFF_LOUT");
+ return id_LUTFF_LOUT;
case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
- return id("LUTFF_OUT");
+ return id_LUTFF_OUT;
case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
- return id("LUTFF_COUT");
+ return id_LUTFF_COUT;
case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
- return id("LUTFF_GLOBAL");
+ return id_LUTFF_GLOBAL;
case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
- return id("CARRY_IN_MUX");
+ return id_CARRY_IN_MUX;
case WireInfoPOD::WIRE_TYPE_SP4_V:
- return id("SP4_V");
+ return id_SP4_V;
case WireInfoPOD::WIRE_TYPE_SP4_H:
- return id("SP4_H");
+ return id_SP4_H;
case WireInfoPOD::WIRE_TYPE_SP12_V:
- return id("SP12_V");
+ return id_SP12_V;
case WireInfoPOD::WIRE_TYPE_SP12_H:
- return id("SP12_H");
+ return id_SP12_H;
}
return IdString();
}
@@ -423,11 +423,11 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co
std::vector<std::pair<IdString, std::string>> ret;
auto &wi = chip_info->wire_data[wire.index];
- ret.push_back(std::make_pair(id("INDEX"), stringf("%d", wire.index)));
+ ret.push_back(std::make_pair(id_INDEX, stringf("%d", wire.index)));
- ret.push_back(std::make_pair(id("GRID_X"), stringf("%d", wi.x)));
- ret.push_back(std::make_pair(id("GRID_Y"), stringf("%d", wi.y)));
- ret.push_back(std::make_pair(id("GRID_Z"), stringf("%d", wi.z)));
+ ret.push_back(std::make_pair(id_GRID_X, stringf("%d", wi.x)));
+ ret.push_back(std::make_pair(id_GRID_Y, stringf("%d", wi.y)));
+ ret.push_back(std::make_pair(id_GRID_Z, stringf("%d", wi.z)));
return ret;
}
@@ -476,7 +476,7 @@ std::vector<std::pair<IdString, std::string>> Arch::getPipAttrs(PipId pip) const
{
std::vector<std::pair<IdString, std::string>> ret;
- ret.push_back(std::make_pair(id("INDEX"), stringf("%d", pip.index)));
+ ret.push_back(std::make_pair(id_INDEX, stringf("%d", pip.index)));
return ret;
}
@@ -682,7 +682,7 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
bool Arch::place()
{
- std::string placer = str_or_default(settings, id("placer"), defaultPlacer);
+ std::string placer = str_or_default(settings, id_placer, defaultPlacer);
if (placer == "heap") {
PlacerHeapCfg cfg(getCtx());
cfg.ioBufTypes.insert(id_SB_IO);
@@ -695,19 +695,19 @@ bool Arch::place()
log_error("iCE40 architecture does not support placer '%s'\n", placer.c_str());
}
bool retVal = true;
- if (bool_or_default(settings, id("opt_timing"), false)) {
+ if (bool_or_default(settings, id_opt_timing, false)) {
TimingOptCfg tocfg(getCtx());
tocfg.cellTypes.insert(id_ICESTORM_LC);
retVal = timing_opt(getCtx(), tocfg);
}
- getCtx()->settings[getCtx()->id("place")] = 1;
+ getCtx()->settings[id_place] = 1;
archInfoToAttributes();
return retVal;
}
bool Arch::route()
{
- std::string router = str_or_default(settings, id("router"), defaultRouter);
+ std::string router = str_or_default(settings, id_router, defaultRouter);
bool result;
if (router == "router1") {
result = router1(getCtx(), Router1Cfg(getCtx()));
@@ -717,7 +717,7 @@ bool Arch::route()
} else {
log_error("iCE40 architecture does not support router '%s'\n", router.c_str());
}
- getCtx()->settings[getCtx()->id("route")] = 1;
+ getCtx()->settings[id_route] = 1;
archInfoToAttributes();
return result;
}
@@ -1064,7 +1064,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_CLOCK_INPUT;
return TMG_IGNORE;
} else if (cell->type == id_SB_I2C || cell->type == id_SB_SPI) {
- if (port == this->id("SBCLKI"))
+ if (port == id_SBCLKI)
return TMG_CLOCK_INPUT;
clockInfoCount = 1;
@@ -1108,10 +1108,10 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
} else if (cell->type == id_ICESTORM_RAM) {
if (port.str(this)[0] == 'R') {
info.clock_port = id_RCLK;
- info.edge = bool_or_default(cell->params, id("NEG_CLK_R")) ? FALLING_EDGE : RISING_EDGE;
+ info.edge = bool_or_default(cell->params, id_NEG_CLK_R) ? FALLING_EDGE : RISING_EDGE;
} else {
info.clock_port = id_WCLK;
- info.edge = bool_or_default(cell->params, id("NEG_CLK_W")) ? FALLING_EDGE : RISING_EDGE;
+ info.edge = bool_or_default(cell->params, id_NEG_CLK_W) ? FALLING_EDGE : RISING_EDGE;
}
if (cell->ports.at(port).type == PORT_OUT) {
bool has_clktoq = get_cell_delay_internal(cell, info.clock_port, port, info.clockToQ);
@@ -1168,7 +1168,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.hold = DelayPair(0);
}
} else if (cell->type == id_SB_I2C || cell->type == id_SB_SPI) {
- info.clock_port = this->id("SBCLKI");
+ info.clock_port = id_SBCLKI;
info.edge = RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
/* Dummy number */
@@ -1233,12 +1233,12 @@ void Arch::assignCellInfo(CellInfo *cell)
cell->lcInfo.inputCount++;
} else if (cell->type == id_SB_IO) {
cell->ioInfo.lvds = str_or_default(cell->params, id_IO_STANDARD, "SB_LVCMOS") == "SB_LVDS_INPUT";
- cell->ioInfo.global = bool_or_default(cell->attrs, this->id("GLOBAL"));
- cell->ioInfo.pintype = int_or_default(cell->params, this->id("PIN_TYPE"));
- cell->ioInfo.negtrig = bool_or_default(cell->params, this->id("NEG_TRIGGER"));
+ cell->ioInfo.global = bool_or_default(cell->attrs, id_GLOBAL);
+ cell->ioInfo.pintype = int_or_default(cell->params, id_PIN_TYPE);
+ cell->ioInfo.negtrig = bool_or_default(cell->params, id_NEG_TRIGGER);
} else if (cell->type == id_SB_GB) {
- cell->gbInfo.forPadIn = bool_or_default(cell->attrs, this->id("FOR_PAD_IN"));
+ cell->gbInfo.forPadIn = bool_or_default(cell->attrs, id_FOR_PAD_IN);
}
}
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index f01afdff..3b024d81 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -120,7 +120,7 @@ bool Arch::isBelLocationValid(BelId bel) const
break;
// Are we perhaps a PAD INPUT Bel that can be placed here?
- if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(getCtx()))
+ if (pll_cell->attrs[id_BEL_PAD_INPUT] == getBelName(bel).str(getCtx()))
return true;
// Conflict
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 8caa9dc6..89f84262 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -391,7 +391,7 @@ void write_asc(const Context *ctx, std::ostream &out)
pool<Loc> sb_io_used_by_pll_pad;
for (auto &cell : ctx->cells) {
- if (cell.second->type != ctx->id("ICESTORM_PLL"))
+ if (cell.second->type != id_ICESTORM_PLL)
continue;
// Collect all locations matching an PLL output port
@@ -434,16 +434,16 @@ void write_asc(const Context *ctx, std::ostream &out)
std::cout << "Found unplaced cell " << cell.first.str(ctx) << " while generating bitstream!" << std::endl;
continue;
}
- if (cell.second->type == ctx->id("ICESTORM_LC")) {
+ if (cell.second->type == id_ICESTORM_LC) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC];
- unsigned lut_init = get_param_or_def(ctx, cell.second.get(), ctx->id("LUT_INIT"));
- bool neg_clk = get_param_or_def(ctx, cell.second.get(), ctx->id("NEG_CLK"));
- bool dff_enable = get_param_or_def(ctx, cell.second.get(), ctx->id("DFF_ENABLE"));
- bool async_sr = get_param_or_def(ctx, cell.second.get(), ctx->id("ASYNC_SR"));
- bool set_noreset = get_param_or_def(ctx, cell.second.get(), ctx->id("SET_NORESET"));
- bool carry_enable = get_param_or_def(ctx, cell.second.get(), ctx->id("CARRY_ENABLE"));
+ unsigned lut_init = get_param_or_def(ctx, cell.second.get(), id_LUT_INIT);
+ bool neg_clk = get_param_or_def(ctx, cell.second.get(), id_NEG_CLK);
+ bool dff_enable = get_param_or_def(ctx, cell.second.get(), id_DFF_ENABLE);
+ bool async_sr = get_param_or_def(ctx, cell.second.get(), id_ASYNC_SR);
+ bool set_noreset = get_param_or_def(ctx, cell.second.get(), id_SET_NORESET);
+ bool carry_enable = get_param_or_def(ctx, cell.second.get(), id_CARRY_ENABLE);
std::vector<bool> lc(20, false);
// Discover permutation
@@ -502,20 +502,20 @@ void write_asc(const Context *ctx, std::ostream &out)
if (dff_enable)
set_config(ti, config.at(y).at(x), "NegClk", neg_clk);
- bool carry_const = get_param_or_def(ctx, cell.second.get(), ctx->id("CIN_CONST"));
- bool carry_set = get_param_or_def(ctx, cell.second.get(), ctx->id("CIN_SET"));
+ bool carry_const = get_param_or_def(ctx, cell.second.get(), id_CIN_CONST);
+ bool carry_set = get_param_or_def(ctx, cell.second.get(), id_CIN_SET);
if (carry_const) {
if (!ctx->force)
NPNR_ASSERT(z == 0);
set_config(ti, config.at(y).at(x), "CarryInSet", carry_set);
}
- } else if (cell.second->type == ctx->id("SB_IO")) {
+ } else if (cell.second->type == id_SB_IO) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
- unsigned pin_type = get_param_or_def(ctx, cell.second.get(), ctx->id("PIN_TYPE"));
- bool neg_trigger = get_param_or_def(ctx, cell.second.get(), ctx->id("NEG_TRIGGER"));
- bool pullup = get_param_or_def(ctx, cell.second.get(), ctx->id("PULLUP"));
+ unsigned pin_type = get_param_or_def(ctx, cell.second.get(), id_PIN_TYPE);
+ bool neg_trigger = get_param_or_def(ctx, cell.second.get(), id_NEG_TRIGGER);
+ bool pullup = get_param_or_def(ctx, cell.second.get(), id_PULLUP);
bool lvds = cell.second->ioInfo.lvds;
bool used_by_pll_out = sb_io_used_by_pll_out.count(Loc(x, y, z)) > 0;
bool used_by_pll_pad = sb_io_used_by_pll_pad.count(Loc(x, y, z)) > 0;
@@ -550,8 +550,8 @@ void write_asc(const Context *ctx, std::ostream &out)
if (ctx->args.type == ArchArgs::UP5K || ctx->args.type == ArchArgs::UP3K) {
std::string pullup_resistor = "100K";
- if (cell.second->attrs.count(ctx->id("PULLUP_RESISTOR")))
- pullup_resistor = cell.second->attrs.at(ctx->id("PULLUP_RESISTOR")).as_string();
+ if (cell.second->attrs.count(id_PULLUP_RESISTOR))
+ pullup_resistor = cell.second->attrs.at(id_PULLUP_RESISTOR).as_string();
NPNR_ASSERT(pullup_resistor == "100K" || pullup_resistor == "10K" || pullup_resistor == "6P8K" ||
pullup_resistor == "3P3K");
if (iez == 0) {
@@ -599,7 +599,7 @@ void write_asc(const Context *ctx, std::ostream &out)
}
}
}
- } else if (cell.second->type == ctx->id("SB_GB")) {
+ } else if (cell.second->type == id_SB_GB) {
if (cell.second->gbInfo.forPadIn) {
Loc gb_loc = ctx->getBelLocation(bel);
for (auto &glb : ci.global_network_info) {
@@ -608,7 +608,7 @@ void write_asc(const Context *ctx, std::ostream &out)
}
}
}
- } else if (cell.second->type == ctx->id("ICESTORM_RAM")) {
+ } else if (cell.second->type == id_ICESTORM_RAM) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y;
const TileInfoPOD &ti_ramt = bi.tiles_nonrouting[TILE_RAMT];
@@ -616,10 +616,10 @@ void write_asc(const Context *ctx, std::ostream &out)
if (!(ctx->args.type == ArchArgs::LP1K || ctx->args.type == ArchArgs::HX1K)) {
set_config(ti_ramb, config.at(y).at(x), "RamConfig.PowerUp", true);
}
- bool negclk_r = get_param_or_def(ctx, cell.second.get(), ctx->id("NEG_CLK_R"));
- bool negclk_w = get_param_or_def(ctx, cell.second.get(), ctx->id("NEG_CLK_W"));
- int write_mode = get_param_or_def(ctx, cell.second.get(), ctx->id("WRITE_MODE"));
- int read_mode = get_param_or_def(ctx, cell.second.get(), ctx->id("READ_MODE"));
+ bool negclk_r = get_param_or_def(ctx, cell.second.get(), id_NEG_CLK_R);
+ bool negclk_w = get_param_or_def(ctx, cell.second.get(), id_NEG_CLK_W);
+ int write_mode = get_param_or_def(ctx, cell.second.get(), id_WRITE_MODE);
+ int read_mode = get_param_or_def(ctx, cell.second.get(), id_READ_MODE);
set_config(ti_ramb, config.at(y).at(x), "NegClk", negclk_w);
set_config(ti_ramt, config.at(y + 1).at(x), "NegClk", negclk_r);
@@ -627,27 +627,27 @@ void write_asc(const Context *ctx, std::ostream &out)
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_1", write_mode & 0x2);
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_2", read_mode & 0x1);
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_3", read_mode & 0x2);
- } else if (cell.second->type == ctx->id("SB_LED_DRV_CUR")) {
+ } else if (cell.second->type == id_SB_LED_DRV_CUR) {
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "LED_DRV_CUR_EN", true,
"IpConfig.");
- } else if (cell.second->type == ctx->id("SB_RGB_DRV")) {
+ } else if (cell.second->type == id_SB_RGB_DRV) {
const std::vector<std::pair<std::string, int>> rgb_params = {
{"RGB0_CURRENT", 6}, {"RGB1_CURRENT", 6}, {"RGB2_CURRENT", 6}};
configure_extra_cell(config, ctx, cell.second.get(), rgb_params, true, std::string("IpConfig."));
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "RGB_DRV_EN", true, "IpConfig.");
- } else if (cell.second->type == ctx->id("SB_RGBA_DRV")) {
+ } else if (cell.second->type == id_SB_RGBA_DRV) {
const std::vector<std::pair<std::string, int>> rgba_params = {
{"CURRENT_MODE", 1}, {"RGB0_CURRENT", 6}, {"RGB1_CURRENT", 6}, {"RGB2_CURRENT", 6}};
configure_extra_cell(config, ctx, cell.second.get(), rgba_params, true, std::string("IpConfig."));
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "RGBA_DRV_EN", true, "IpConfig.");
- } else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC") ||
- cell.second->type == ctx->id("SB_LEDDA_IP")) {
+ } else if (cell.second->type == id_SB_WARMBOOT || cell.second->type == id_ICESTORM_LFOSC ||
+ cell.second->type == id_SB_LEDDA_IP) {
// No config needed
- } else if (cell.second->type == ctx->id("SB_I2C")) {
- bool sda_in_dly = !cell.second->attrs.count(ctx->id("SDA_INPUT_DELAYED")) ||
- cell.second->attrs[ctx->id("SDA_INPUT_DELAYED")].as_bool();
- bool sda_out_dly = !cell.second->attrs.count(ctx->id("SDA_OUTPUT_DELAYED")) ||
- cell.second->attrs[ctx->id("SDA_OUTPUT_DELAYED")].as_bool();
+ } else if (cell.second->type == id_SB_I2C) {
+ bool sda_in_dly = !cell.second->attrs.count(id_SDA_INPUT_DELAYED) ||
+ cell.second->attrs[id_SDA_INPUT_DELAYED].as_bool();
+ bool sda_out_dly = !cell.second->attrs.count(id_SDA_OUTPUT_DELAYED) ||
+ cell.second->attrs[id_SDA_OUTPUT_DELAYED].as_bool();
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SDA_INPUT_DELAYED", sda_in_dly,
"IpConfig.");
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SDA_OUTPUT_DELAYED", sda_out_dly,
@@ -656,7 +656,7 @@ void write_asc(const Context *ctx, std::ostream &out)
"IpConfig.");
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "I2C_ENABLE_1", true,
"IpConfig.");
- } else if (cell.second->type == ctx->id("SB_SPI")) {
+ } else if (cell.second->type == id_SB_SPI) {
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_0", true,
"IpConfig.");
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_1", true,
@@ -665,7 +665,7 @@ void write_asc(const Context *ctx, std::ostream &out)
"IpConfig.");
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "SPI_ENABLE_3", true,
"IpConfig.");
- } else if (cell.second->type == ctx->id("ICESTORM_SPRAM")) {
+ } else if (cell.second->type == id_ICESTORM_SPRAM) {
const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z;
NPNR_ASSERT(ctx->args.type == ArchArgs::UP5K || ctx->args.type == ArchArgs::UP3K);
@@ -688,7 +688,7 @@ void write_asc(const Context *ctx, std::ostream &out)
NPNR_ASSERT(false);
}
}
- } else if (cell.second->type == ctx->id("ICESTORM_DSP")) {
+ } else if (cell.second->type == id_ICESTORM_DSP) {
const std::vector<std::pair<std::string, int>> mac16_params = {{"C_REG", 1},
{"A_REG", 1},
{"B_REG", 1},
@@ -709,13 +709,13 @@ void write_asc(const Context *ctx, std::ostream &out)
{"A_SIGNED", 1},
{"B_SIGNED", 1}};
configure_extra_cell(config, ctx, cell.second.get(), mac16_params, false, std::string("IpConfig."));
- } else if (cell.second->type == ctx->id("ICESTORM_HFOSC")) {
+ } else if (cell.second->type == id_ICESTORM_HFOSC) {
std::vector<std::pair<std::string, int>> hfosc_params = {{"CLKHF_DIV", 2}};
if (ctx->args.type != ArchArgs::U4K && ctx->args.type != ArchArgs::U1K && ctx->args.type != ArchArgs::U2K)
hfosc_params.push_back(std::pair<std::string, int>("TRIM_EN", 1));
configure_extra_cell(config, ctx, cell.second.get(), hfosc_params, true, std::string("IpConfig."));
- } else if (cell.second->type == ctx->id("ICESTORM_PLL")) {
+ } else if (cell.second->type == id_ICESTORM_PLL) {
const std::vector<std::pair<std::string, int>> pll_params = {{"DELAY_ADJMODE_FB", 1},
{"DELAY_ADJMODE_REL", 1},
{"DIVF", 7},
@@ -874,7 +874,7 @@ void write_asc(const Context *ctx, std::ostream &out)
// Write RAM init data
for (auto &cell : ctx->cells) {
if (cell.second->bel != BelId()) {
- if (cell.second->type == ctx->id("ICESTORM_RAM")) {
+ if (cell.second->type == id_ICESTORM_RAM) {
const BelInfoPOD &beli = ci.bel_data[cell.second->bel.index];
int x = beli.x, y = beli.y;
out << ".ram_data " << x << " " << y << std::endl;
@@ -1054,7 +1054,7 @@ bool read_asc(Context *ctx, std::istream &in)
isUsed |= carry_set;
if (isUsed) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LC"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_ICESTORM_LC);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(bel, ctx->cells[name].get(), STRENGTH_WEAK);
@@ -1074,7 +1074,7 @@ bool read_asc(Context *ctx, std::istream &in)
isUsed |= neg_trigger;
if (isUsed) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_IO"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_SB_IO);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(bel, ctx->cells[name].get(), STRENGTH_WEAK);
@@ -1091,35 +1091,35 @@ bool read_asc(Context *ctx, std::istream &in)
if (ctx->checkBelAvail(belpin.bel)) {
if (ctx->getBelType(belpin.bel) == id_ICESTORM_LC) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LC"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_ICESTORM_LC);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets
}
if (ctx->getBelType(belpin.bel) == id_SB_IO) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_IO"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_SB_IO);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets
}
if (ctx->getBelType(belpin.bel) == id_SB_GB) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_GB"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_SB_GB);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets
}
if (ctx->getBelType(belpin.bel) == id_SB_WARMBOOT) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_WARMBOOT"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_SB_WARMBOOT);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets
}
if (ctx->getBelType(belpin.bel) == id_ICESTORM_LFOSC) {
- std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"));
+ std::unique_ptr<CellInfo> created = create_ice_cell(ctx, id_ICESTORM_LFOSC);
IdString name = created->name;
ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
diff --git a/ice40/cells.cc b/ice40/cells.cc
index b97131a6..a8d30347 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -33,61 +33,61 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
name.empty() ? ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++)) : ctx->id(name);
auto new_cell = std::make_unique<CellInfo>(ctx, name_id, type);
- if (type == ctx->id("ICESTORM_LC")) {
- new_cell->params[ctx->id("LUT_INIT")] = Property(0, 16);
- new_cell->params[ctx->id("NEG_CLK")] = Property::State::S0;
- new_cell->params[ctx->id("CARRY_ENABLE")] = Property::State::S0;
- new_cell->params[ctx->id("DFF_ENABLE")] = Property::State::S0;
- new_cell->params[ctx->id("SET_NORESET")] = Property::State::S0;
- new_cell->params[ctx->id("ASYNC_SR")] = Property::State::S0;
- new_cell->params[ctx->id("CIN_CONST")] = Property::State::S0;
- new_cell->params[ctx->id("CIN_SET")] = Property::State::S0;
-
- new_cell->addInput(ctx->id("I0"));
- new_cell->addInput(ctx->id("I1"));
- new_cell->addInput(ctx->id("I2"));
- new_cell->addInput(ctx->id("I3"));
- new_cell->addInput(ctx->id("CIN"));
-
- new_cell->addInput(ctx->id("CLK"));
- new_cell->addInput(ctx->id("CEN"));
- new_cell->addInput(ctx->id("SR"));
-
- new_cell->addOutput(ctx->id("LO"));
- new_cell->addOutput(ctx->id("O"));
- new_cell->addOutput(ctx->id("COUT"));
- } else if (type == ctx->id("SB_IO")) {
- new_cell->params[ctx->id("PIN_TYPE")] = Property(0, 6);
- new_cell->params[ctx->id("PULLUP")] = Property::State::S0;
- new_cell->params[ctx->id("NEG_TRIGGER")] = Property::State::S0;
- new_cell->params[ctx->id("IO_STANDARD")] = Property("SB_LVCMOS");
-
- new_cell->addInout(ctx->id("PACKAGE_PIN"));
-
- new_cell->addInput(ctx->id("LATCH_INPUT_VALUE"));
- new_cell->addInput(ctx->id("CLOCK_ENABLE"));
- new_cell->addInput(ctx->id("INPUT_CLK"));
- new_cell->addInput(ctx->id("OUTPUT_CLK"));
-
- new_cell->addInput(ctx->id("OUTPUT_ENABLE"));
- new_cell->addInput(ctx->id("D_OUT_0"));
- new_cell->addInput(ctx->id("D_OUT_1"));
-
- new_cell->addOutput(ctx->id("D_IN_0"));
- new_cell->addOutput(ctx->id("D_IN_1"));
- } else if (type == ctx->id("ICESTORM_RAM")) {
- new_cell->params[ctx->id("NEG_CLK_W")] = Property::State::S0;
- new_cell->params[ctx->id("NEG_CLK_R")] = Property::State::S0;
- new_cell->params[ctx->id("WRITE_MODE")] = Property::State::S0;
- new_cell->params[ctx->id("READ_MODE")] = Property::State::S0;
-
- new_cell->addInput(ctx->id("RCLK"));
- new_cell->addInput(ctx->id("RCLKE"));
- new_cell->addInput(ctx->id("RE"));
-
- new_cell->addInput(ctx->id("WCLK"));
- new_cell->addInput(ctx->id("WCLKE"));
- new_cell->addInput(ctx->id("WE"));
+ if (type == id_ICESTORM_LC) {
+ new_cell->params[id_LUT_INIT] = Property(0, 16);
+ new_cell->params[id_NEG_CLK] = Property::State::S0;
+ new_cell->params[id_CARRY_ENABLE] = Property::State::S0;
+ new_cell->params[id_DFF_ENABLE] = Property::State::S0;
+ new_cell->params[id_SET_NORESET] = Property::State::S0;
+ new_cell->params[id_ASYNC_SR] = Property::State::S0;
+ new_cell->params[id_CIN_CONST] = Property::State::S0;
+ new_cell->params[id_CIN_SET] = Property::State::S0;
+
+ new_cell->addInput(id_I0);
+ new_cell->addInput(id_I1);
+ new_cell->addInput(id_I2);
+ new_cell->addInput(id_I3);
+ new_cell->addInput(id_CIN);
+
+ new_cell->addInput(id_CLK);
+ new_cell->addInput(id_CEN);
+ new_cell->addInput(id_SR);
+
+ new_cell->addOutput(id_LO);
+ new_cell->addOutput(id_O);
+ new_cell->addOutput(id_COUT);
+ } else if (type == id_SB_IO) {
+ new_cell->params[id_PIN_TYPE] = Property(0, 6);
+ new_cell->params[id_PULLUP] = Property::State::S0;
+ new_cell->params[id_NEG_TRIGGER] = Property::State::S0;
+ new_cell->params[id_IO_STANDARD] = Property("SB_LVCMOS");
+
+ new_cell->addInout(id_PACKAGE_PIN);
+
+ new_cell->addInput(id_LATCH_INPUT_VALUE);
+ new_cell->addInput(id_CLOCK_ENABLE);
+ new_cell->addInput(id_INPUT_CLK);
+ new_cell->addInput(id_OUTPUT_CLK);
+
+ new_cell->addInput(id_OUTPUT_ENABLE);
+ new_cell->addInput(id_D_OUT_0);
+ new_cell->addInput(id_D_OUT_1);
+
+ new_cell->addOutput(id_D_IN_0);
+ new_cell->addOutput(id_D_IN_1);
+ } else if (type == id_ICESTORM_RAM) {
+ new_cell->params[id_NEG_CLK_W] = Property::State::S0;
+ new_cell->params[id_NEG_CLK_R] = Property::State::S0;
+ new_cell->params[id_WRITE_MODE] = Property::State::S0;
+ new_cell->params[id_READ_MODE] = Property::State::S0;
+
+ new_cell->addInput(id_RCLK);
+ new_cell->addInput(id_RCLKE);
+ new_cell->addInput(id_RE);
+
+ new_cell->addInput(id_WCLK);
+ new_cell->addInput(id_WCLKE);
+ new_cell->addInput(id_WE);
for (int i = 0; i < 16; i++) {
new_cell->addInput(ctx->id("WDATA_" + std::to_string(i)));
@@ -99,31 +99,31 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
new_cell->addInput(ctx->id("RADDR_" + std::to_string(i)));
new_cell->addInput(ctx->id("WADDR_" + std::to_string(i)));
}
- } else if (type == ctx->id("ICESTORM_LFOSC")) {
- new_cell->addInput(ctx->id("CLKLFEN"));
- new_cell->addInput(ctx->id("CLKLFPU"));
- new_cell->addOutput(ctx->id("CLKLF"));
- new_cell->addOutput(ctx->id("CLKLF_FABRIC"));
- } else if (type == ctx->id("ICESTORM_HFOSC")) {
- new_cell->params[ctx->id("CLKHF_DIV")] = Property("0b00");
- new_cell->params[ctx->id("TRIM_EN")] = Property("0b0");
-
- new_cell->addInput(ctx->id("CLKHFEN"));
- new_cell->addInput(ctx->id("CLKHFPU"));
- new_cell->addOutput(ctx->id("CLKHF"));
- new_cell->addOutput(ctx->id("CLKHF_FABRIC"));
+ } else if (type == id_ICESTORM_LFOSC) {
+ new_cell->addInput(id_CLKLFEN);
+ new_cell->addInput(id_CLKLFPU);
+ new_cell->addOutput(id_CLKLF);
+ new_cell->addOutput(id_CLKLF_FABRIC);
+ } else if (type == id_ICESTORM_HFOSC) {
+ new_cell->params[id_CLKHF_DIV] = Property("0b00");
+ new_cell->params[id_TRIM_EN] = Property("0b0");
+
+ new_cell->addInput(id_CLKHFEN);
+ new_cell->addInput(id_CLKHFPU);
+ new_cell->addOutput(id_CLKHF);
+ new_cell->addOutput(id_CLKHF_FABRIC);
for (int i = 0; i < 10; i++)
new_cell->addInput(ctx->id("TRIM" + std::to_string(i)));
- } else if (type == ctx->id("SB_GB")) {
- new_cell->addInput(ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER"));
- new_cell->addOutput(ctx->id("GLOBAL_BUFFER_OUTPUT"));
- } else if (type == ctx->id("ICESTORM_SPRAM")) {
- new_cell->addInput(ctx->id("WREN"));
- new_cell->addInput(ctx->id("CHIPSELECT"));
- new_cell->addInput(ctx->id("CLOCK"));
- new_cell->addInput(ctx->id("STANDBY"));
- new_cell->addInput(ctx->id("SLEEP"));
- new_cell->addInput(ctx->id("POWEROFF"));
+ } else if (type == id_SB_GB) {
+ new_cell->addInput(id_USER_SIGNAL_TO_GLOBAL_BUFFER);
+ new_cell->addOutput(id_GLOBAL_BUFFER_OUTPUT);
+ } else if (type == id_ICESTORM_SPRAM) {
+ new_cell->addInput(id_WREN);
+ new_cell->addInput(id_CHIPSELECT);
+ new_cell->addInput(id_CLOCK);
+ new_cell->addInput(id_STANDBY);
+ new_cell->addInput(id_SLEEP);
+ new_cell->addInput(id_POWEROFF);
for (int i = 0; i < 16; i++) {
new_cell->addInput(ctx->id("DATAIN_" + std::to_string(i)));
@@ -135,196 +135,196 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
for (int i = 0; i < 4; i++) {
new_cell->addInput(ctx->id("MASKWREN_" + std::to_string(i)));
}
- } else if (type == ctx->id("ICESTORM_DSP")) {
- new_cell->params[ctx->id("NEG_TRIGGER")] = Property::State::S0;
-
- new_cell->params[ctx->id("C_REG")] = Property::State::S0;
- new_cell->params[ctx->id("A_REG")] = Property::State::S0;
- new_cell->params[ctx->id("B_REG")] = Property::State::S0;
- new_cell->params[ctx->id("D_REG")] = Property::State::S0;
- new_cell->params[ctx->id("TOP_8x8_MULT_REG")] = Property::State::S0;
- new_cell->params[ctx->id("BOT_8x8_MULT_REG")] = Property::State::S0;
- new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG1")] = Property::State::S0;
- new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG2")] = Property::State::S0;
-
- new_cell->params[ctx->id("TOPOUTPUT_SELECT")] = Property(0, 2);
- new_cell->params[ctx->id("TOPADDSUB_LOWERINPUT")] = Property(0, 2);
- new_cell->params[ctx->id("TOPADDSUB_UPPERINPUT")] = Property::State::S0;
- new_cell->params[ctx->id("TOPADDSUB_CARRYSELECT")] = Property(0, 2);
-
- new_cell->params[ctx->id("BOTOUTPUT_SELECT")] = Property(0, 2);
- new_cell->params[ctx->id("BOTADDSUB_LOWERINPUT")] = Property(0, 2);
- new_cell->params[ctx->id("BOTADDSUB_UPPERINPUT")] = Property::State::S0;
- new_cell->params[ctx->id("BOTADDSUB_CARRYSELECT")] = Property(0, 2);
-
- new_cell->params[ctx->id("MODE_8x8")] = Property::State::S0;
- new_cell->params[ctx->id("A_SIGNED")] = Property::State::S0;
- new_cell->params[ctx->id("B_SIGNED")] = Property::State::S0;
-
- new_cell->addInput(ctx->id("CLK"));
- new_cell->addInput(ctx->id("CE"));
+ } else if (type == id_ICESTORM_DSP) {
+ new_cell->params[id_NEG_TRIGGER] = Property::State::S0;
+
+ new_cell->params[id_C_REG] = Property::State::S0;
+ new_cell->params[id_A_REG] = Property::State::S0;
+ new_cell->params[id_B_REG] = Property::State::S0;
+ new_cell->params[id_D_REG] = Property::State::S0;
+ new_cell->params[id_TOP_8x8_MULT_REG] = Property::State::S0;
+ new_cell->params[id_BOT_8x8_MULT_REG] = Property::State::S0;
+ new_cell->params[id_PIPELINE_16x16_MULT_REG1] = Property::State::S0;
+ new_cell->params[id_PIPELINE_16x16_MULT_REG2] = Property::State::S0;
+
+ new_cell->params[id_TOPOUTPUT_SELECT] = Property(0, 2);
+ new_cell->params[id_TOPADDSUB_LOWERINPUT] = Property(0, 2);
+ new_cell->params[id_TOPADDSUB_UPPERINPUT] = Property::State::S0;
+ new_cell->params[id_TOPADDSUB_CARRYSELECT] = Property(0, 2);
+
+ new_cell->params[id_BOTOUTPUT_SELECT] = Property(0, 2);
+ new_cell->params[id_BOTADDSUB_LOWERINPUT] = Property(0, 2);
+ new_cell->params[id_BOTADDSUB_UPPERINPUT] = Property::State::S0;
+ new_cell->params[id_BOTADDSUB_CARRYSELECT] = Property(0, 2);
+
+ new_cell->params[id_MODE_8x8] = Property::State::S0;
+ new_cell->params[id_A_SIGNED] = Property::State::S0;
+ new_cell->params[id_B_SIGNED] = Property::State::S0;
+
+ new_cell->addInput(id_CLK);
+ new_cell->addInput(id_CE);
for (int i = 0; i < 16; i++) {
new_cell->addInput(ctx->id("C_" + std::to_string(i)));
new_cell->addInput(ctx->id("A_" + std::to_string(i)));
new_cell->addInput(ctx->id("B_" + std::to_string(i)));
new_cell->addInput(ctx->id("D_" + std::to_string(i)));
}
- new_cell->addInput(ctx->id("AHOLD"));
- new_cell->addInput(ctx->id("BHOLD"));
- new_cell->addInput(ctx->id("CHOLD"));
- new_cell->addInput(ctx->id("DHOLD"));
+ new_cell->addInput(id_AHOLD);
+ new_cell->addInput(id_BHOLD);
+ new_cell->addInput(id_CHOLD);
+ new_cell->addInput(id_DHOLD);
- new_cell->addInput(ctx->id("IRSTTOP"));
- new_cell->addInput(ctx->id("IRSTBOT"));
- new_cell->addInput(ctx->id("ORSTTOP"));
- new_cell->addInput(ctx->id("ORSTBOT"));
+ new_cell->addInput(id_IRSTTOP);
+ new_cell->addInput(id_IRSTBOT);
+ new_cell->addInput(id_ORSTTOP);
+ new_cell->addInput(id_ORSTBOT);
- new_cell->addInput(ctx->id("OLOADTOP"));
- new_cell->addInput(ctx->id("OLOADBOT"));
+ new_cell->addInput(id_OLOADTOP);
+ new_cell->addInput(id_OLOADBOT);
- new_cell->addInput(ctx->id("ADDSUBTOP"));
- new_cell->addInput(ctx->id("ADDSUBBOT"));
+ new_cell->addInput(id_ADDSUBTOP);
+ new_cell->addInput(id_ADDSUBBOT);
- new_cell->addInput(ctx->id("OHOLDTOP"));
- new_cell->addInput(ctx->id("OHOLDBOT"));
+ new_cell->addInput(id_OHOLDTOP);
+ new_cell->addInput(id_OHOLDBOT);
- new_cell->addInput(ctx->id("CI"));
- new_cell->addInput(ctx->id("ACCUMCI"));
- new_cell->addInput(ctx->id("SIGNEXTIN"));
+ new_cell->addInput(id_CI);
+ new_cell->addInput(id_ACCUMCI);
+ new_cell->addInput(id_SIGNEXTIN);
for (int i = 0; i < 32; i++) {
new_cell->addOutput(ctx->id("O_" + std::to_string(i)));
}
- new_cell->addOutput(ctx->id("CO"));
- new_cell->addOutput(ctx->id("ACCUMCO"));
- new_cell->addOutput(ctx->id("SIGNEXTOUT"));
+ new_cell->addOutput(id_CO);
+ new_cell->addOutput(id_ACCUMCO);
+ new_cell->addOutput(id_SIGNEXTOUT);
- } else if (type == ctx->id("ICESTORM_PLL")) {
- new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = Property::State::S0;
- new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = Property::State::S0;
+ } else if (type == id_ICESTORM_PLL) {
+ new_cell->params[id_DELAY_ADJMODE_FB] = Property::State::S0;
+ new_cell->params[id_DELAY_ADJMODE_REL] = Property::State::S0;
- new_cell->params[ctx->id("DIVF")] = Property(0, 7);
- new_cell->params[ctx->id("DIVQ")] = Property(0, 3);
- new_cell->params[ctx->id("DIVR")] = Property(0, 4);
+ new_cell->params[id_DIVF] = Property(0, 7);
+ new_cell->params[id_DIVQ] = Property(0, 3);
+ new_cell->params[id_DIVR] = Property(0, 4);
- new_cell->params[ctx->id("FDA_FEEDBACK")] = Property(0, 4);
- new_cell->params[ctx->id("FDA_RELATIVE")] = Property(0, 4);
- new_cell->params[ctx->id("FEEDBACK_PATH")] = Property(1, 3);
- new_cell->params[ctx->id("FILTER_RANGE")] = Property(0, 3);
+ new_cell->params[id_FDA_FEEDBACK] = Property(0, 4);
+ new_cell->params[id_FDA_RELATIVE] = Property(0, 4);
+ new_cell->params[id_FEEDBACK_PATH] = Property(1, 3);
+ new_cell->params[id_FILTER_RANGE] = Property(0, 3);
- new_cell->params[ctx->id("PLLOUT_SELECT_A")] = Property(0, 2);
- new_cell->params[ctx->id("PLLOUT_SELECT_B")] = Property(0, 2);
+ new_cell->params[id_PLLOUT_SELECT_A] = Property(0, 2);
+ new_cell->params[id_PLLOUT_SELECT_B] = Property(0, 2);
- new_cell->params[ctx->id("PLLTYPE")] = Property(0, 3);
- new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = Property::State::S0;
- new_cell->params[ctx->id("TEST_MODE")] = Property::State::S0;
+ new_cell->params[id_PLLTYPE] = Property(0, 3);
+ new_cell->params[id_SHIFTREG_DIVMODE] = Property::State::S0;
+ new_cell->params[id_TEST_MODE] = Property::State::S0;
- new_cell->addInput(ctx->id("BYPASS"));
+ new_cell->addInput(id_BYPASS);
for (int i = 0; i < 8; i++)
new_cell->addInput(ctx->id("DYNAMICDELAY_" + std::to_string(i)));
- new_cell->addInput(ctx->id("EXTFEEDBACK"));
- new_cell->addInput(ctx->id("LATCHINPUTVALUE"));
- new_cell->addInput(ctx->id("REFERENCECLK"));
- new_cell->addInput(ctx->id("RESETB"));
-
- new_cell->addInput(ctx->id("SCLK"));
- new_cell->addInput(ctx->id("SDI"));
- new_cell->addOutput(ctx->id("SDO"));
-
- new_cell->addOutput(ctx->id("LOCK"));
- new_cell->addOutput(ctx->id("PLLOUT_A"));
- new_cell->addOutput(ctx->id("PLLOUT_B"));
- new_cell->addOutput(ctx->id("PLLOUT_A_GLOBAL"));
- new_cell->addOutput(ctx->id("PLLOUT_B_GLOBAL"));
- } else if (type == ctx->id("SB_RGBA_DRV")) {
- new_cell->params[ctx->id("CURRENT_MODE")] = std::string("0b0");
- new_cell->params[ctx->id("RGB0_CURRENT")] = std::string("0b000000");
- new_cell->params[ctx->id("RGB1_CURRENT")] = std::string("0b000000");
- new_cell->params[ctx->id("RGB2_CURRENT")] = std::string("0b000000");
-
- new_cell->addInput(ctx->id("CURREN"));
- new_cell->addInput(ctx->id("RGBLEDEN"));
- new_cell->addInput(ctx->id("RGB0PWM"));
- new_cell->addInput(ctx->id("RGB1PWM"));
- new_cell->addInput(ctx->id("RGB2PWM"));
- new_cell->addOutput(ctx->id("RGB0"));
- new_cell->addOutput(ctx->id("RGB1"));
- new_cell->addOutput(ctx->id("RGB2"));
- } else if (type == ctx->id("SB_LED_DRV_CUR")) {
- new_cell->addInput(ctx->id("EN"));
- new_cell->addOutput(ctx->id("LEDPU"));
- } else if (type == ctx->id("SB_RGB_DRV")) {
- new_cell->params[ctx->id("RGB0_CURRENT")] = std::string("0b000000");
- new_cell->params[ctx->id("RGB1_CURRENT")] = std::string("0b000000");
- new_cell->params[ctx->id("RGB2_CURRENT")] = std::string("0b000000");
-
- new_cell->addInput(ctx->id("RGBPU"));
- new_cell->addInput(ctx->id("RGBLEDEN"));
- new_cell->addInput(ctx->id("RGB0PWM"));
- new_cell->addInput(ctx->id("RGB1PWM"));
- new_cell->addInput(ctx->id("RGB2PWM"));
- new_cell->addOutput(ctx->id("RGB0"));
- new_cell->addOutput(ctx->id("RGB1"));
- new_cell->addOutput(ctx->id("RGB2"));
- } else if (type == ctx->id("SB_LEDDA_IP")) {
- new_cell->addInput(ctx->id("LEDDCS"));
- new_cell->addInput(ctx->id("LEDDCLK"));
+ new_cell->addInput(id_EXTFEEDBACK);
+ new_cell->addInput(id_LATCHINPUTVALUE);
+ new_cell->addInput(id_REFERENCECLK);
+ new_cell->addInput(id_RESETB);
+
+ new_cell->addInput(id_SCLK);
+ new_cell->addInput(id_SDI);
+ new_cell->addOutput(id_SDO);
+
+ new_cell->addOutput(id_LOCK);
+ new_cell->addOutput(id_PLLOUT_A);
+ new_cell->addOutput(id_PLLOUT_B);
+ new_cell->addOutput(id_PLLOUT_A_GLOBAL);
+ new_cell->addOutput(id_PLLOUT_B_GLOBAL);
+ } else if (type == id_SB_RGBA_DRV) {
+ new_cell->params[id_CURRENT_MODE] = std::string("0b0");
+ new_cell->params[id_RGB0_CURRENT] = std::string("0b000000");
+ new_cell->params[id_RGB1_CURRENT] = std::string("0b000000");
+ new_cell->params[id_RGB2_CURRENT] = std::string("0b000000");
+
+ new_cell->addInput(id_CURREN);
+ new_cell->addInput(id_RGBLEDEN);
+ new_cell->addInput(id_RGB0PWM);
+ new_cell->addInput(id_RGB1PWM);
+ new_cell->addInput(id_RGB2PWM);
+ new_cell->addOutput(id_RGB0);
+ new_cell->addOutput(id_RGB1);
+ new_cell->addOutput(id_RGB2);
+ } else if (type == id_SB_LED_DRV_CUR) {
+ new_cell->addInput(id_EN);
+ new_cell->addOutput(id_LEDPU);
+ } else if (type == id_SB_RGB_DRV) {
+ new_cell->params[id_RGB0_CURRENT] = std::string("0b000000");
+ new_cell->params[id_RGB1_CURRENT] = std::string("0b000000");
+ new_cell->params[id_RGB2_CURRENT] = std::string("0b000000");
+
+ new_cell->addInput(id_RGBPU);
+ new_cell->addInput(id_RGBLEDEN);
+ new_cell->addInput(id_RGB0PWM);
+ new_cell->addInput(id_RGB1PWM);
+ new_cell->addInput(id_RGB2PWM);
+ new_cell->addOutput(id_RGB0);
+ new_cell->addOutput(id_RGB1);
+ new_cell->addOutput(id_RGB2);
+ } else if (type == id_SB_LEDDA_IP) {
+ new_cell->addInput(id_LEDDCS);
+ new_cell->addInput(id_LEDDCLK);
for (int i = 0; i < 8; i++)
new_cell->addInput(ctx->id("LEDDDAT" + std::to_string(i)));
for (int i = 0; i < 3; i++)
new_cell->addInput(ctx->id("LEDDADDR" + std::to_string(i)));
- new_cell->addInput(ctx->id("LEDDDEN"));
- new_cell->addInput(ctx->id("LEDDEXE"));
- new_cell->addInput(ctx->id("LEDDRST")); // doesn't actually exist, for icecube code compatibility
- // only
- new_cell->addOutput(ctx->id("PWMOUT0"));
- new_cell->addOutput(ctx->id("PWMOUT1"));
- new_cell->addOutput(ctx->id("PWMOUT2"));
- new_cell->addOutput(ctx->id("LEDDON"));
- } else if (type == ctx->id("SB_I2C")) {
- new_cell->params[ctx->id("I2C_SLAVE_INIT_ADDR")] = std::string("0b1111100001");
- new_cell->params[ctx->id("BUS_ADDR74")] = std::string("0b0001");
+ new_cell->addInput(id_LEDDDEN);
+ new_cell->addInput(id_LEDDEXE);
+ new_cell->addInput(id_LEDDRST); // doesn't actually exist, for icecube code compatibility
+ // only
+ new_cell->addOutput(id_PWMOUT0);
+ new_cell->addOutput(id_PWMOUT1);
+ new_cell->addOutput(id_PWMOUT2);
+ new_cell->addOutput(id_LEDDON);
+ } else if (type == id_SB_I2C) {
+ new_cell->params[id_I2C_SLAVE_INIT_ADDR] = std::string("0b1111100001");
+ new_cell->params[id_BUS_ADDR74] = std::string("0b0001");
for (int i = 0; i < 8; i++) {
new_cell->addInput(ctx->id("SBADRI" + std::to_string(i)));
new_cell->addInput(ctx->id("SBDATI" + std::to_string(i)));
new_cell->addOutput(ctx->id("SBDATO" + std::to_string(i)));
}
- new_cell->addInput(ctx->id("SBCLKI"));
- new_cell->addInput(ctx->id("SBRWI"));
- new_cell->addInput(ctx->id("SBSTBI"));
- new_cell->addInput(ctx->id("SCLI"));
- new_cell->addInput(ctx->id("SDAI"));
- new_cell->addOutput(ctx->id("SBACKO"));
- new_cell->addOutput(ctx->id("I2CIRQ"));
- new_cell->addOutput(ctx->id("I2CWKUP"));
- new_cell->addOutput(ctx->id("SCLO"));
- new_cell->addOutput(ctx->id("SCLOE"));
- new_cell->addOutput(ctx->id("SDAO"));
- new_cell->addOutput(ctx->id("SDAOE"));
- } else if (type == ctx->id("SB_SPI")) {
- new_cell->params[ctx->id("BUS_ADDR74")] = std::string("0b0000");
+ new_cell->addInput(id_SBCLKI);
+ new_cell->addInput(id_SBRWI);
+ new_cell->addInput(id_SBSTBI);
+ new_cell->addInput(id_SCLI);
+ new_cell->addInput(id_SDAI);
+ new_cell->addOutput(id_SBACKO);
+ new_cell->addOutput(id_I2CIRQ);
+ new_cell->addOutput(id_I2CWKUP);
+ new_cell->addOutput(id_SCLO);
+ new_cell->addOutput(id_SCLOE);
+ new_cell->addOutput(id_SDAO);
+ new_cell->addOutput(id_SDAOE);
+ } else if (type == id_SB_SPI) {
+ new_cell->params[id_BUS_ADDR74] = std::string("0b0000");
for (int i = 0; i < 8; i++) {
new_cell->addInput(ctx->id("SBADRI" + std::to_string(i)));
new_cell->addInput(ctx->id("SBDATI" + std::to_string(i)));
new_cell->addOutput(ctx->id("SBDATO" + std::to_string(i)));
}
- new_cell->addInput(ctx->id("SBCLKI"));
- new_cell->addInput(ctx->id("SBRWI"));
- new_cell->addInput(ctx->id("SBSTBI"));
- new_cell->addInput(ctx->id("MI"));
- new_cell->addInput(ctx->id("SI"));
- new_cell->addInput(ctx->id("SCKI"));
- new_cell->addInput(ctx->id("SCSNI"));
- new_cell->addOutput(ctx->id("SBACKO"));
- new_cell->addOutput(ctx->id("SPIIRQ"));
- new_cell->addOutput(ctx->id("SPIWKUP"));
- new_cell->addOutput(ctx->id("SO"));
- new_cell->addOutput(ctx->id("SOE"));
- new_cell->addOutput(ctx->id("MO"));
- new_cell->addOutput(ctx->id("MOE"));
- new_cell->addOutput(ctx->id("SCKO"));
- new_cell->addOutput(ctx->id("SCKOE"));
+ new_cell->addInput(id_SBCLKI);
+ new_cell->addInput(id_SBRWI);
+ new_cell->addInput(id_SBSTBI);
+ new_cell->addInput(id_MI);
+ new_cell->addInput(id_SI);
+ new_cell->addInput(id_SCKI);
+ new_cell->addInput(id_SCSNI);
+ new_cell->addOutput(id_SBACKO);
+ new_cell->addOutput(id_SPIIRQ);
+ new_cell->addOutput(id_SPIWKUP);
+ new_cell->addOutput(id_SO);
+ new_cell->addOutput(id_SOE);
+ new_cell->addOutput(id_MO);
+ new_cell->addOutput(id_MOE);
+ new_cell->addOutput(id_SCKO);
+ new_cell->addOutput(id_SCKOE);
for (int i = 0; i < 4; i++) {
new_cell->addOutput(ctx->id("MCSNO" + std::to_string(i)));
new_cell->addOutput(ctx->id("MCSNOE" + std::to_string(i)));
@@ -339,14 +339,14 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
{
if (lc->hierpath == IdString())
lc->hierpath = lut->hierpath;
- lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")].extract(0, 16, Property::State::S0);
- replace_port(lut, ctx->id("I0"), lc, ctx->id("I0"));
- replace_port(lut, ctx->id("I1"), lc, ctx->id("I1"));
- replace_port(lut, ctx->id("I2"), lc, ctx->id("I2"));
- replace_port(lut, ctx->id("I3"), lc, ctx->id("I3"));
+ lc->params[id_LUT_INIT] = lut->params[id_LUT_INIT].extract(0, 16, Property::State::S0);
+ replace_port(lut, id_I0, lc, id_I0);
+ replace_port(lut, id_I1, lc, id_I1);
+ replace_port(lut, id_I2, lc, id_I2);
+ replace_port(lut, id_I3, lc, id_I3);
if (no_dff) {
- replace_port(lut, ctx->id("O"), lc, ctx->id("O"));
- lc->params[ctx->id("DFF_ENABLE")] = Property::State::S0;
+ replace_port(lut, id_O, lc, id_O);
+ lc->params[id_DFF_ENABLE] = Property::State::S0;
}
}
@@ -354,20 +354,20 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
{
if (lc->hierpath == IdString())
lc->hierpath = dff->hierpath;
- lc->params[ctx->id("DFF_ENABLE")] = Property::State::S1;
+ lc->params[id_DFF_ENABLE] = Property::State::S1;
std::string config = dff->type.str(ctx).substr(6);
auto citer = config.begin();
- replace_port(dff, ctx->id("C"), lc, ctx->id("CLK"));
+ replace_port(dff, id_C, lc, id_CLK);
if (citer != config.end() && *citer == 'N') {
- lc->params[ctx->id("NEG_CLK")] = Property::State::S1;
+ lc->params[id_NEG_CLK] = Property::State::S1;
++citer;
} else {
- lc->params[ctx->id("NEG_CLK")] = Property::State::S0;
+ lc->params[id_NEG_CLK] = Property::State::S0;
}
if (citer != config.end() && *citer == 'E') {
- replace_port(dff, ctx->id("E"), lc, ctx->id("CEN"));
+ replace_port(dff, id_E, lc, id_CEN);
++citer;
}
@@ -375,60 +375,60 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
if ((config.end() - citer) >= 2) {
char c = *(citer++);
NPNR_ASSERT(c == 'S');
- lc->params[ctx->id("ASYNC_SR")] = Property::State::S0;
+ lc->params[id_ASYNC_SR] = Property::State::S0;
} else {
- lc->params[ctx->id("ASYNC_SR")] = Property::State::S1;
+ lc->params[id_ASYNC_SR] = Property::State::S1;
}
if (*citer == 'S') {
citer++;
- replace_port(dff, ctx->id("S"), lc, ctx->id("SR"));
- lc->params[ctx->id("SET_NORESET")] = Property::State::S1;
+ replace_port(dff, id_S, lc, id_SR);
+ lc->params[id_SET_NORESET] = Property::State::S1;
} else {
NPNR_ASSERT(*citer == 'R');
citer++;
- replace_port(dff, ctx->id("R"), lc, ctx->id("SR"));
- lc->params[ctx->id("SET_NORESET")] = Property::State::S0;
+ replace_port(dff, id_R, lc, id_SR);
+ lc->params[id_SET_NORESET] = Property::State::S0;
}
}
NPNR_ASSERT(citer == config.end());
if (pass_thru_lut) {
- lc->params[ctx->id("LUT_INIT")] = Property(2, 16);
- replace_port(dff, ctx->id("D"), lc, ctx->id("I0"));
+ lc->params[id_LUT_INIT] = Property(2, 16);
+ replace_port(dff, id_D, lc, id_I0);
}
- replace_port(dff, ctx->id("Q"), lc, ctx->id("O"));
+ replace_port(dff, id_Q, lc, id_O);
}
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &todelete_cells)
{
if (nxio->type == ctx->id("$nextpnr_ibuf")) {
- sbio->params[ctx->id("PIN_TYPE")] = 1;
- auto pu_attr = nxio->attrs.find(ctx->id("PULLUP"));
+ sbio->params[id_PIN_TYPE] = 1;
+ auto pu_attr = nxio->attrs.find(id_PULLUP);
if (pu_attr != nxio->attrs.end())
- sbio->params[ctx->id("PULLUP")] = pu_attr->second;
- replace_port(nxio, ctx->id("O"), sbio, ctx->id("D_IN_0"));
+ sbio->params[id_PULLUP] = pu_attr->second;
+ replace_port(nxio, id_O, sbio, id_D_IN_0);
} else if (nxio->type == ctx->id("$nextpnr_obuf")) {
- sbio->params[ctx->id("PIN_TYPE")] = 25;
- replace_port(nxio, ctx->id("I"), sbio, ctx->id("D_OUT_0"));
+ sbio->params[id_PIN_TYPE] = 25;
+ replace_port(nxio, id_I, sbio, id_D_OUT_0);
} else if (nxio->type == ctx->id("$nextpnr_iobuf")) {
// N.B. tristate will be dealt with below
- NetInfo *i = get_net_or_empty(nxio, ctx->id("I"));
+ NetInfo *i = get_net_or_empty(nxio, id_I);
if (i == nullptr || i->driver.cell == nullptr)
- sbio->params[ctx->id("PIN_TYPE")] = 1;
+ sbio->params[id_PIN_TYPE] = 1;
else
- sbio->params[ctx->id("PIN_TYPE")] = 25;
- auto pu_attr = nxio->attrs.find(ctx->id("PULLUP"));
+ sbio->params[id_PIN_TYPE] = 25;
+ auto pu_attr = nxio->attrs.find(id_PULLUP);
if (pu_attr != nxio->attrs.end())
- sbio->params[ctx->id("PULLUP")] = pu_attr->second;
- replace_port(nxio, ctx->id("I"), sbio, ctx->id("D_OUT_0"));
- replace_port(nxio, ctx->id("O"), sbio, ctx->id("D_IN_0"));
+ sbio->params[id_PULLUP] = pu_attr->second;
+ replace_port(nxio, id_I, sbio, id_D_OUT_0);
+ replace_port(nxio, id_O, sbio, id_D_IN_0);
} else {
NPNR_ASSERT(false);
}
- NetInfo *donet = sbio->ports.at(ctx->id("D_OUT_0")).net, *dinet = sbio->ports.at(ctx->id("D_IN_0")).net;
+ NetInfo *donet = sbio->ports.at(id_D_OUT_0).net, *dinet = sbio->ports.at(id_D_IN_0).net;
// Rename I/O nets to avoid conflicts
if (donet != nullptr && donet->name == nxio->name)
@@ -451,17 +451,17 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &to
NPNR_ASSERT(!ctx->nets.count(tn_netname));
ctx->net_aliases.erase(tn_netname);
NetInfo *toplevel_net = ctx->createNet(tn_netname);
- connect_port(ctx, toplevel_net, sbio, ctx->id("PACKAGE_PIN"));
+ connect_port(ctx, toplevel_net, sbio, id_PACKAGE_PIN);
ctx->ports[nxio->name].net = toplevel_net;
}
CellInfo *tbuf = net_driven_by(
ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); },
- ctx->id("Y"));
+ id_Y);
if (tbuf) {
- sbio->params[ctx->id("PIN_TYPE")] = 41;
- replace_port(tbuf, ctx->id("A"), sbio, ctx->id("D_OUT_0"));
- replace_port(tbuf, ctx->id("E"), sbio, ctx->id("OUTPUT_ENABLE"));
+ sbio->params[id_PIN_TYPE] = 41;
+ replace_port(tbuf, id_A, sbio, id_D_OUT_0);
+ replace_port(tbuf, id_E, sbio, id_OUTPUT_ENABLE);
if (donet->users.size() > 1) {
for (auto user : donet->users)
@@ -477,15 +477,15 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, pool<IdString> &to
uint8_t sb_pll40_type(const BaseCtx *ctx, const CellInfo *cell)
{
- if (cell->type == ctx->id("SB_PLL40_PAD"))
+ if (cell->type == id_SB_PLL40_PAD)
return 2;
- if (cell->type == ctx->id("SB_PLL40_2_PAD"))
+ if (cell->type == id_SB_PLL40_2_PAD)
return 4;
- if (cell->type == ctx->id("SB_PLL40_2F_PAD"))
+ if (cell->type == id_SB_PLL40_2F_PAD)
return 6;
- if (cell->type == ctx->id("SB_PLL40_CORE"))
+ if (cell->type == id_SB_PLL40_CORE)
return 3;
- if (cell->type == ctx->id("SB_PLL40_2F_CORE"))
+ if (cell->type == id_SB_PLL40_2F_CORE)
return 7;
NPNR_ASSERT(0);
}
@@ -495,15 +495,14 @@ bool is_clock_port(const BaseCtx *ctx, const PortRef &port)
if (port.cell == nullptr)
return false;
if (is_ff(ctx, port.cell))
- return port.port == ctx->id("C");
- if (port.cell->type == ctx->id("ICESTORM_LC"))
- return port.port == ctx->id("CLK");
- if (is_ram(ctx, port.cell) || port.cell->type == ctx->id("ICESTORM_RAM"))
- return port.port == ctx->id("RCLK") || port.port == ctx->id("WCLK") || port.port == ctx->id("RCLKN") ||
- port.port == ctx->id("WCLKN");
- if (is_sb_mac16(ctx, port.cell) || port.cell->type == ctx->id("ICESTORM_DSP"))
- return port.port == ctx->id("CLK");
- if (is_sb_spram(ctx, port.cell) || port.cell->type == ctx->id("ICESTORM_SPRAM"))
+ return port.port == id_C;
+ if (port.cell->type == id_ICESTORM_LC)
+ return port.port == id_CLK;
+ if (is_ram(ctx, port.cell) || port.cell->type == id_ICESTORM_RAM)
+ return port.port == id_RCLK || port.port == id_WCLK || port.port == id_RCLKN || port.port == id_WCLKN;
+ if (is_sb_mac16(ctx, port.cell) || port.cell->type == id_ICESTORM_DSP)
+ return port.port == id_CLK;
+ if (is_sb_spram(ctx, port.cell) || port.cell->type == id_ICESTORM_SPRAM)
return port.port == id_CLOCK;
if (is_sb_io(ctx, port.cell))
return port.port == id_INPUT_CLK || port.port == id_OUTPUT_CLK;
@@ -515,12 +514,11 @@ bool is_reset_port(const BaseCtx *ctx, const PortRef &port)
if (port.cell == nullptr)
return false;
if (is_ff(ctx, port.cell))
- return port.port == ctx->id("R") || port.port == ctx->id("S");
- if (port.cell->type == ctx->id("ICESTORM_LC"))
- return port.port == ctx->id("SR");
- if (is_sb_mac16(ctx, port.cell) || port.cell->type == ctx->id("ICESTORM_DSP"))
- return port.port == ctx->id("IRSTTOP") || port.port == ctx->id("IRSTBOT") || port.port == ctx->id("ORSTTOP") ||
- port.port == ctx->id("ORSTBOT");
+ return port.port == id_R || port.port == id_S;
+ if (port.cell->type == id_ICESTORM_LC)
+ return port.port == id_SR;
+ if (is_sb_mac16(ctx, port.cell) || port.cell->type == id_ICESTORM_DSP)
+ return port.port == id_IRSTTOP || port.port == id_IRSTBOT || port.port == id_ORSTTOP || port.port == id_ORSTBOT;
return false;
}
@@ -529,12 +527,12 @@ bool is_enable_port(const BaseCtx *ctx, const PortRef &port)
if (port.cell == nullptr)
return false;
if (is_ff(ctx, port.cell))
- return port.port == ctx->id("E");
- if (port.cell->type == ctx->id("ICESTORM_LC"))
- return port.port == ctx->id("CEN");
+ return port.port == id_E;
+ if (port.cell->type == id_ICESTORM_LC)
+ return port.port == id_CEN;
// FIXME
- // if (is_sb_mac16(ctx, port.cell) || port.cell->type == ctx->id("ICESTORM_DSP"))
- // return port.port == ctx->id("CE");
+ // if (is_sb_mac16(ctx, port.cell) || port.cell->type == id_ICESTORM_DSP)
+ // return port.port == id_CE;
return false;
}
diff --git a/ice40/cells.h b/ice40/cells.h
index 30fdd631..724500d6 100644
--- a/ice40/cells.h
+++ b/ice40/cells.h
@@ -30,90 +30,80 @@ NEXTPNR_NAMESPACE_BEGIN
std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::string name = "");
// Return true if a cell is a LUT
-inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_LUT4"); }
+inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_LUT4; }
// Return true if a cell is a flipflop
inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == ctx->id("SB_DFF") || cell->type == ctx->id("SB_DFFE") || cell->type == ctx->id("SB_DFFSR") ||
- cell->type == ctx->id("SB_DFFR") || cell->type == ctx->id("SB_DFFSS") || cell->type == ctx->id("SB_DFFS") ||
- cell->type == ctx->id("SB_DFFESR") || cell->type == ctx->id("SB_DFFER") ||
- cell->type == ctx->id("SB_DFFESS") || cell->type == ctx->id("SB_DFFES") ||
- cell->type == ctx->id("SB_DFFN") || cell->type == ctx->id("SB_DFFNE") ||
- cell->type == ctx->id("SB_DFFNSR") || cell->type == ctx->id("SB_DFFNR") ||
- cell->type == ctx->id("SB_DFFNSS") || cell->type == ctx->id("SB_DFFNS") ||
- cell->type == ctx->id("SB_DFFNESR") || cell->type == ctx->id("SB_DFFNER") ||
- cell->type == ctx->id("SB_DFFNESS") || cell->type == ctx->id("SB_DFFNES");
+ return cell->type == id_SB_DFF || cell->type == id_SB_DFFE || cell->type == id_SB_DFFSR ||
+ cell->type == id_SB_DFFR || cell->type == id_SB_DFFSS || cell->type == id_SB_DFFS ||
+ cell->type == id_SB_DFFESR || cell->type == id_SB_DFFER || cell->type == id_SB_DFFESS ||
+ cell->type == id_SB_DFFES || cell->type == id_SB_DFFN || cell->type == id_SB_DFFNE ||
+ cell->type == id_SB_DFFNSR || cell->type == id_SB_DFFNR || cell->type == id_SB_DFFNSS ||
+ cell->type == id_SB_DFFNS || cell->type == id_SB_DFFNESR || cell->type == id_SB_DFFNER ||
+ cell->type == id_SB_DFFNESS || cell->type == id_SB_DFFNES;
}
-inline bool is_carry(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_CARRY"); }
+inline bool is_carry(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_CARRY; }
-inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("ICESTORM_LC"); }
+inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_ICESTORM_LC; }
// Return true if a cell is a SB_IO
-inline bool is_sb_io(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_IO"); }
+inline bool is_sb_io(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_IO; }
// Return true if a cell is a SB_GB_IO
-inline bool is_sb_gb_io(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_GB_IO"); }
+inline bool is_sb_gb_io(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_GB_IO; }
// Return true if a cell is a global buffer
-inline bool is_gbuf(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_GB"); }
+inline bool is_gbuf(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_GB; }
// Return true if a cell is a RAM
inline bool is_ram(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == ctx->id("SB_RAM40_4K") || cell->type == ctx->id("SB_RAM40_4KNR") ||
- cell->type == ctx->id("SB_RAM40_4KNW") || cell->type == ctx->id("SB_RAM40_4KNRNW");
+ return cell->type == id_SB_RAM40_4K || cell->type == id_SB_RAM40_4KNR || cell->type == id_SB_RAM40_4KNW ||
+ cell->type == id_SB_RAM40_4KNRNW;
}
-inline bool is_sb_lfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_LFOSC"); }
+inline bool is_sb_lfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_LFOSC; }
-inline bool is_sb_hfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_HFOSC"); }
+inline bool is_sb_hfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_HFOSC; }
-inline bool is_sb_spram(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_SPRAM256KA"); }
+inline bool is_sb_spram(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_SPRAM256KA; }
-inline bool is_sb_mac16(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_MAC16"); }
+inline bool is_sb_mac16(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_MAC16; }
-inline bool is_sb_rgba_drv(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_RGBA_DRV"); }
+inline bool is_sb_rgba_drv(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_RGBA_DRV; }
-inline bool is_sb_rgb_drv(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_RGB_DRV"); }
+inline bool is_sb_rgb_drv(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_RGB_DRV; }
-inline bool is_sb_led_drv_cur(const BaseCtx *ctx, const CellInfo *cell)
-{
- return cell->type == ctx->id("SB_LED_DRV_CUR");
-}
+inline bool is_sb_led_drv_cur(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_LED_DRV_CUR; }
-inline bool is_sb_ledda_ip(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_LEDDA_IP"); }
+inline bool is_sb_ledda_ip(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_LEDDA_IP; }
-inline bool is_sb_i2c(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_I2C"); }
+inline bool is_sb_i2c(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_I2C; }
-inline bool is_sb_spi(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_SPI"); }
+inline bool is_sb_spi(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_SPI; }
inline bool is_sb_pll40(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == ctx->id("SB_PLL40_PAD") || cell->type == ctx->id("SB_PLL40_2_PAD") ||
- cell->type == ctx->id("SB_PLL40_2F_PAD") || cell->type == ctx->id("SB_PLL40_CORE") ||
- cell->type == ctx->id("SB_PLL40_2F_CORE");
+ return cell->type == id_SB_PLL40_PAD || cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD ||
+ cell->type == id_SB_PLL40_CORE || cell->type == id_SB_PLL40_2F_CORE;
}
inline bool is_sb_pll40_pad(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == ctx->id("SB_PLL40_PAD") || cell->type == ctx->id("SB_PLL40_2_PAD") ||
- cell->type == ctx->id("SB_PLL40_2F_PAD") ||
- (cell->type == ctx->id("ICESTORM_PLL") &&
- (cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_PAD" ||
- cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_2_PAD" ||
- cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_2F_PAD"));
+ return cell->type == id_SB_PLL40_PAD || cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD ||
+ (cell->type == id_ICESTORM_PLL && (cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_PAD" ||
+ cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2_PAD" ||
+ cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_PAD"));
}
inline bool is_sb_pll40_dual(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == ctx->id("SB_PLL40_2_PAD") || cell->type == ctx->id("SB_PLL40_2F_PAD") ||
- cell->type == ctx->id("SB_PLL40_2F_CORE") ||
- (cell->type == ctx->id("ICESTORM_PLL") &&
- (cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_2_PAD" ||
- cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_2F_PAD" ||
- cell->attrs.at(ctx->id("TYPE")).as_string() == "SB_PLL40_2F_CORE"));
+ return cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD || cell->type == id_SB_PLL40_2F_CORE ||
+ (cell->type == id_ICESTORM_PLL && (cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2_PAD" ||
+ cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_PAD" ||
+ cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_CORE"));
}
uint8_t sb_pll40_type(const BaseCtx *ctx, const CellInfo *cell);
diff --git a/ice40/chains.cc b/ice40/chains.cc
index fa4ce413..e6a37044 100644
--- a/ice40/chains.cc
+++ b/ice40/chains.cc
@@ -53,9 +53,9 @@ class ChainConstrainer
tile.clear();
chains.emplace_back();
start_of_chain = false;
- if (cell->ports.at(ctx->id("CIN")).net) {
+ if (cell->ports.at(id_CIN).net) {
// CIN is not constant and not part of a chain. Must feed in from fabric
- CellInfo *feedin = make_carry_feed_in(cell, cell->ports.at(ctx->id("CIN")));
+ CellInfo *feedin = make_carry_feed_in(cell, cell->ports.at(id_CIN));
chains.back().cells.push_back(feedin);
tile.push_back(feedin);
++feedio_lcs;
@@ -66,18 +66,18 @@ class ChainConstrainer
bool split_chain = (!ctx->logic_cells_compatible(tile.data(), tile.size())) ||
(int(chains.back().cells.size()) > max_length);
if (split_chain) {
- CellInfo *passout = make_carry_pass_out((*(curr_cell - 1))->ports.at(ctx->id("COUT")));
+ CellInfo *passout = make_carry_pass_out((*(curr_cell - 1))->ports.at(id_COUT));
tile.pop_back();
chains.back().cells.back() = passout;
start_of_chain = true;
} else {
- NetInfo *carry_net = cell->ports.at(ctx->id("COUT")).net;
+ NetInfo *carry_net = cell->ports.at(id_COUT).net;
bool at_end = (curr_cell == carryc.cells.end() - 1);
if (carry_net != nullptr && (carry_net->users.size() > 1 || at_end)) {
if (carry_net->users.size() > 2 ||
- (net_only_drives(ctx, carry_net, is_lc, ctx->id("I3"), false) !=
- net_only_drives(ctx, carry_net, is_lc, ctx->id("CIN"), false)) ||
- (at_end && !net_only_drives(ctx, carry_net, is_lc, ctx->id("I3"), true))) {
+ (net_only_drives(ctx, carry_net, is_lc, id_I3, false) !=
+ net_only_drives(ctx, carry_net, is_lc, id_CIN, false)) ||
+ (at_end && !net_only_drives(ctx, carry_net, is_lc, id_I3, true))) {
if (ctx->debug)
log_info(" inserting feed-%s\n", at_end ? "out" : "out-in");
CellInfo *passout;
@@ -89,10 +89,10 @@ class ChainConstrainer
tile.pop_back();
if (split_chain_next)
start_of_chain = true;
- passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT")),
+ passout = make_carry_pass_out(cell->ports.at(id_COUT),
split_chain_next ? nullptr : *(curr_cell + 1));
} else {
- passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT")), nullptr);
+ passout = make_carry_pass_out(cell->ports.at(id_COUT), nullptr);
}
chains.back().cells.push_back(passout);
@@ -110,9 +110,9 @@ class ChainConstrainer
CellInfo *make_carry_pass_out(PortInfo &cout_port, CellInfo *cin_cell = nullptr)
{
NPNR_ASSERT(cout_port.net != nullptr);
- std::unique_ptr<CellInfo> lc = create_ice_cell(ctx, ctx->id("ICESTORM_LC"));
- lc->params[ctx->id("LUT_INIT")] = Property(65280, 16); // 0xff00: O = I3
- lc->params[ctx->id("CARRY_ENABLE")] = Property::State::S1;
+ std::unique_ptr<CellInfo> lc = create_ice_cell(ctx, id_ICESTORM_LC);
+ lc->params[id_LUT_INIT] = Property(65280, 16); // 0xff00: O = I3
+ lc->params[id_CARRY_ENABLE] = Property::State::S1;
lc->ports.at(id_O).net = cout_port.net;
NetInfo *co_i3_net = ctx->createNet(ctx->id(lc->name.str(ctx) + "$I3"));
co_i3_net->driver = cout_port.net->driver;
@@ -177,11 +177,11 @@ class ChainConstrainer
CellInfo *make_carry_feed_in(CellInfo *cin_cell, PortInfo &cin_port)
{
NPNR_ASSERT(cin_port.net != nullptr);
- std::unique_ptr<CellInfo> lc = create_ice_cell(ctx, ctx->id("ICESTORM_LC"));
- lc->params[ctx->id("CARRY_ENABLE")] = Property::State::S1;
- lc->params[ctx->id("CIN_CONST")] = Property::State::S1;
- lc->params[ctx->id("CIN_SET")] = Property::State::S1;
- lc->ports.at(ctx->id("I1")).net = cin_port.net;
+ std::unique_ptr<CellInfo> lc = create_ice_cell(ctx, id_ICESTORM_LC);
+ lc->params[id_CARRY_ENABLE] = Property::State::S1;
+ lc->params[id_CIN_CONST] = Property::State::S1;
+ lc->params[id_CIN_SET] = Property::State::S1;
+ lc->ports.at(id_I1).net = cin_port.net;
cin_port.net->users.erase(std::remove_if(cin_port.net->users.begin(), cin_port.net->users.end(),
[cin_cell, cin_port](const PortRef &usr) {
return usr.cell == cin_cell && usr.port == cin_port.name;
@@ -189,16 +189,16 @@ class ChainConstrainer
PortRef i1_ref;
i1_ref.cell = lc.get();
- i1_ref.port = ctx->id("I1");
- lc->ports.at(ctx->id("I1")).net->users.push_back(i1_ref);
+ i1_ref.port = id_I1;
+ lc->ports.at(id_I1).net->users.push_back(i1_ref);
NetInfo *out_net = ctx->createNet(ctx->id(lc->name.str(ctx) + "$O"));
PortRef drv_ref;
- drv_ref.port = ctx->id("COUT");
+ drv_ref.port = id_COUT;
drv_ref.cell = lc.get();
out_net->driver = drv_ref;
- lc->ports.at(ctx->id("COUT")).net = out_net;
+ lc->ports.at(id_COUT).net = out_net;
PortRef usr_ref;
usr_ref.port = cin_port.name;
@@ -219,22 +219,19 @@ class ChainConstrainer
[](const Context *ctx, const
CellInfo *cell) {
- CellInfo *carry_prev =
- net_driven_by(ctx, cell->ports.at(ctx->id("CIN")).net, is_lc, ctx->id("COUT"));
+ CellInfo *carry_prev = net_driven_by(ctx, cell->ports.at(id_CIN).net, is_lc, id_COUT);
if (carry_prev != nullptr)
return carry_prev;
- CellInfo *i3_prev = net_driven_by(ctx, cell->ports.at(ctx->id("I3")).net, is_lc, ctx->id("COUT"));
+ CellInfo *i3_prev = net_driven_by(ctx, cell->ports.at(id_I3).net, is_lc, id_COUT);
if (i3_prev != nullptr)
return i3_prev;
return (CellInfo *)nullptr;
},
[](const Context *ctx, const CellInfo *cell) {
- CellInfo *carry_next =
- net_only_drives(ctx, cell->ports.at(ctx->id("COUT")).net, is_lc, ctx->id("CIN"), false);
+ CellInfo *carry_next = net_only_drives(ctx, cell->ports.at(id_COUT).net, is_lc, id_CIN, false);
if (carry_next != nullptr)
return carry_next;
- CellInfo *i3_next =
- net_only_drives(ctx, cell->ports.at(ctx->id("COUT")).net, is_lc, ctx->id("I3"), false);
+ CellInfo *i3_next = net_only_drives(ctx, cell->ports.at(id_COUT).net, is_lc, id_I3, false);
if (i3_next != nullptr)
return i3_next;
return (CellInfo *)nullptr;
@@ -249,7 +246,7 @@ class ChainConstrainer
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
if (chained.find(cell.first) == chained.end() && is_lc(ctx, ci) &&
- bool_or_default(ci->params, ctx->id("CARRY_ENABLE"))) {
+ bool_or_default(ci->params, id_CARRY_ENABLE)) {
CellChain sChain;
sChain.cells.push_back(ci);
chained.insert(cell.first);
diff --git a/ice40/constids.inc b/ice40/constids.inc
index 6aa5c4c0..8bad9e25 100644
--- a/ice40/constids.inc
+++ b/ice40/constids.inc
@@ -448,4 +448,168 @@ X(SB_RGB_DRV)
X(DFF_ENABLE)
X(CARRY_ENABLE)
X(NEG_CLK)
-X(IO_STANDARD) \ No newline at end of file
+X(IO_STANDARD)
+X(A)
+X(ASYNC_SR)
+X(A_REG)
+X(A_SIGNED)
+X(BEL)
+X(BEL_PAD_INPUT)
+X(BOTADDSUB_CARRYSELECT)
+X(BOTADDSUB_LOWERINPUT)
+X(BOTADDSUB_UPPERINPUT)
+X(BOTOUTPUT_SELECT)
+X(BOT_8x8_MULT_REG)
+X(BUS_ADDR74)
+X(B_REG)
+X(B_SIGNED)
+X(C)
+X(CARRY_IN_MUX)
+X(CIN_CONST)
+X(CIN_SET)
+X(CLKHF_DIV)
+X(CURRENT_MODE)
+X(C_REG)
+X(D)
+X(DELAY_ADJMODE_FB)
+X(DELAY_ADJMODE_REL)
+X(DELAY_ADJUSTMENT_MODE_FEEDBACK)
+X(DELAY_ADJUSTMENT_MODE_RELATIVE)
+X(DIVF)
+X(DIVQ)
+X(DIVR)
+X(D_REG)
+X(E)
+X(FDA_FEEDBACK)
+X(FDA_RELATIVE)
+X(FEEDBACK_PATH)
+X(FILTER_RANGE)
+X(FOR_PAD_IN)
+X(GLB2LOCAL)
+X(GLB_NETWK)
+X(GLOBAL)
+X(GND)
+X(GRID_X)
+X(GRID_Y)
+X(GRID_Z)
+X(I)
+X(I2C_SLAVE_INIT_ADDR)
+X(INDEX)
+X(LEDDRST)
+X(LOCAL)
+X(LUTFF_COUT)
+X(LUTFF_GLOBAL)
+X(LUTFF_IN)
+X(LUTFF_IN_LUT)
+X(LUTFF_LOUT)
+X(LUTFF_OUT)
+X(LUT_INIT)
+X(MODE_8x8)
+X(NEG_CLK_R)
+X(NEG_CLK_W)
+X(NEG_TRIGGER)
+X(PACKAGEPIN)
+X(PIN_TYPE)
+X(PIPELINE_16x16_MULT_REG1)
+X(PIPELINE_16x16_MULT_REG2)
+X(PLLOUTCORE)
+X(PLLOUTCOREA)
+X(PLLOUTCOREB)
+X(PLLOUTGLOBAL)
+X(PLLOUTGLOBALA)
+X(PLLOUTGLOBALB)
+X(PLLOUT_SELECT)
+X(PLLOUT_SELECT_A)
+X(PLLOUT_SELECT_B)
+X(PLLOUT_SELECT_PORTA)
+X(PLLOUT_SELECT_PORTB)
+X(PLLTYPE)
+X(PULLUP)
+X(PULLUP_RESISTOR)
+X(Q)
+X(R)
+X(RCLKN)
+X(READ_MODE)
+X(RGB0_CURRENT)
+X(RGB1_CURRENT)
+X(RGB2_CURRENT)
+X(ROUTE_THROUGH_FABRIC)
+X(S)
+X(SB_CARRY)
+X(SB_DFF)
+X(SB_DFFE)
+X(SB_DFFER)
+X(SB_DFFES)
+X(SB_DFFESR)
+X(SB_DFFESS)
+X(SB_DFFN)
+X(SB_DFFNE)
+X(SB_DFFNER)
+X(SB_DFFNES)
+X(SB_DFFNESR)
+X(SB_DFFNESS)
+X(SB_DFFNR)
+X(SB_DFFNS)
+X(SB_DFFNSR)
+X(SB_DFFNSS)
+X(SB_DFFR)
+X(SB_DFFS)
+X(SB_DFFSR)
+X(SB_DFFSS)
+X(SB_GB_IO)
+X(SB_HFOSC)
+X(SB_LFOSC)
+X(SB_LUT4)
+X(SB_MAC16)
+X(SB_PLL40_2F_CORE)
+X(SB_PLL40_2F_PAD)
+X(SB_PLL40_2_PAD)
+X(SB_PLL40_CORE)
+X(SB_PLL40_PAD)
+X(SB_RAM40_4K)
+X(SB_RAM40_4KNR)
+X(SB_RAM40_4KNRNW)
+X(SB_RAM40_4KNW)
+X(SB_SPRAM256KA)
+X(SDA_INPUT_DELAYED)
+X(SDA_OUTPUT_DELAYED)
+X(SET_NORESET)
+X(SHIFTREG_DIVMODE)
+X(SHIFTREG_DIV_MODE)
+X(SP12_H)
+X(SP12_V)
+X(SP4_H)
+X(SP4_V)
+X(TEST_MODE)
+X(TOPADDSUB_CARRYSELECT)
+X(TOPADDSUB_LOWERINPUT)
+X(TOPADDSUB_UPPERINPUT)
+X(TOPOUTPUT_SELECT)
+X(TOP_8x8_MULT_REG)
+X(TRIM_EN)
+X(TYPE)
+X(VCC)
+X(WCLKN)
+X(WRITE_MODE)
+X(Y)
+X(hx1k)
+X(hx4k)
+X(hx8k)
+X(lp1k)
+X(lp384)
+X(lp4k)
+X(lp8k)
+X(no_promote_globals)
+X(opt_timing)
+X(pack)
+X(pcf_allow_unconstrained)
+X(place)
+X(placer)
+X(promote_logic)
+X(route)
+X(router)
+X(u1k)
+X(u2k)
+X(u4k)
+X(up3k)
+X(up5k)
diff --git a/ice40/main.cc b/ice40/main.cc
index e480a6ce..224b0275 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -265,13 +265,13 @@ std::unique_ptr<Context> Ice40CommandHandler::createContext(dict<std::string, Pr
ctx->settings[ctx->id("arch.package")] = ctx->archArgs().package;
if (vm.count("promote-logic"))
- ctx->settings[ctx->id("promote_logic")] = Property::State::S1;
+ ctx->settings[id_promote_logic] = Property::State::S1;
if (vm.count("no-promote-globals"))
- ctx->settings[ctx->id("no_promote_globals")] = Property::State::S1;
+ ctx->settings[id_no_promote_globals] = Property::State::S1;
if (vm.count("opt-timing"))
- ctx->settings[ctx->id("opt_timing")] = Property::State::S1;
+ ctx->settings[id_opt_timing] = Property::State::S1;
if (vm.count("pcf-allow-unconstrained"))
- ctx->settings[ctx->id("pcf_allow_unconstrained")] = Property::State::S1;
+ ctx->settings[id_pcf_allow_unconstrained] = Property::State::S1;
return ctx;
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index fcbdf2bd..0220d4fe 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -41,7 +41,7 @@ static void pack_lut_lutffs(Context *ctx)
if (ctx->verbose)
log_info("cell '%s' is of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx));
if (is_lut(ctx, ci)) {
- std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_LC");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_LC, ci->name.str(ctx) + "_LC");
for (auto &attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
packed_cells.insert(ci->name);
@@ -49,14 +49,14 @@ static void pack_lut_lutffs(Context *ctx)
log_info("packed cell %s into %s\n", ci->name.c_str(ctx), packed->name.c_str(ctx));
// See if we can pack into a DFF
// TODO: LUT cascade
- NetInfo *o = ci->ports.at(ctx->id("O")).net;
- CellInfo *dff = net_only_drives(ctx, o, is_ff, ctx->id("D"), true);
- auto lut_bel = ci->attrs.find(ctx->id("BEL"));
+ NetInfo *o = ci->ports.at(id_O).net;
+ CellInfo *dff = net_only_drives(ctx, o, is_ff, id_D, true);
+ auto lut_bel = ci->attrs.find(id_BEL);
bool packed_dff = false;
if (dff) {
if (ctx->verbose)
log_info("found attached dff %s\n", dff->name.c_str(ctx));
- auto dff_bel = dff->attrs.find(ctx->id("BEL"));
+ auto dff_bel = dff->attrs.find(id_BEL);
if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() && lut_bel->second != dff_bel->second) {
// Locations don't match, can't pack
} else {
@@ -65,10 +65,10 @@ static void pack_lut_lutffs(Context *ctx)
++lut_and_ff;
ctx->nets.erase(o->name);
if (dff_bel != dff->attrs.end())
- packed->attrs[ctx->id("BEL")] = dff_bel->second;
+ packed->attrs[id_BEL] = dff_bel->second;
for (const auto &attr : dff->attrs) {
// BEL is dealt with specially
- if (attr.first != ctx->id("BEL"))
+ if (attr.first != id_BEL)
packed->attrs[attr.first] = attr.second;
}
packed_cells.insert(dff->name);
@@ -106,8 +106,7 @@ static void pack_nonlut_ffs(Context *ctx)
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
if (is_ff(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_DFFLC");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_LC, ci->name.str(ctx) + "_DFFLC");
for (auto &attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
if (ctx->verbose)
@@ -155,25 +154,25 @@ static void pack_carries(Context *ctx)
CellInfo *carry_ci_lc;
bool ci_value;
- bool ci_const = net_is_constant(ctx, ci->ports.at(ctx->id("CI")).net, ci_value);
+ bool ci_const = net_is_constant(ctx, ci->ports.at(id_CI).net, ci_value);
if (ci_const) {
carry_ci_lc = nullptr;
} else {
- carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, ctx->id("I3"), false);
+ carry_ci_lc = net_only_drives(ctx, ci->ports.at(id_CI).net, is_lc, id_I3, false);
}
std::set<IdString> i0_matches, i1_matches;
- NetInfo *i0_net = ci->ports.at(ctx->id("I0")).net;
- NetInfo *i1_net = ci->ports.at(ctx->id("I1")).net;
+ NetInfo *i0_net = ci->ports.at(id_I0).net;
+ NetInfo *i1_net = ci->ports.at(id_I1).net;
// Find logic cells connected to both I0 and I1
if (i0_net) {
for (auto usr : i0_net->users) {
- if (is_lc(ctx, usr.cell) && usr.port == ctx->id("I1")) {
+ if (is_lc(ctx, usr.cell) && usr.port == id_I1) {
if (ctx->cells.find(usr.cell->name) != ctx->cells.end() &&
exhausted_cells.find(usr.cell->name) == exhausted_cells.end()) {
// This clause stops us double-packing cells
i0_matches.insert(usr.cell->name);
- if (!i1_net && !usr.cell->ports.at(ctx->id("I2")).net) {
+ if (!i1_net && !usr.cell->ports.at(id_I2).net) {
// I1 is don't care when disconnected, duplicate I0
i1_matches.insert(usr.cell->name);
}
@@ -183,12 +182,12 @@ static void pack_carries(Context *ctx)
}
if (i1_net) {
for (auto usr : i1_net->users) {
- if (is_lc(ctx, usr.cell) && usr.port == ctx->id("I2")) {
+ if (is_lc(ctx, usr.cell) && usr.port == id_I2) {
if (ctx->cells.find(usr.cell->name) != ctx->cells.end() &&
exhausted_cells.find(usr.cell->name) == exhausted_cells.end()) {
// This clause stops us double-packing cells
i1_matches.insert(usr.cell->name);
- if (!i0_net && !usr.cell->ports.at(ctx->id("I1")).net) {
+ if (!i0_net && !usr.cell->ports.at(id_I1).net) {
// I0 is don't care when disconnected, duplicate I1
i0_matches.insert(usr.cell->name);
}
@@ -208,53 +207,53 @@ static void pack_carries(Context *ctx)
} else {
// No LC to pack into matching I0/I1, insert a new one
std::unique_ptr<CellInfo> created_lc =
- create_ice_cell(ctx, ctx->id("ICESTORM_LC"), cell.first.str(ctx) + "$CARRY");
+ create_ice_cell(ctx, id_ICESTORM_LC, cell.first.str(ctx) + "$CARRY");
carry_lc = created_lc.get();
- created_lc->ports.at(ctx->id("I1")).net = i0_net;
+ created_lc->ports.at(id_I1).net = i0_net;
if (i0_net) {
PortRef pr;
pr.cell = created_lc.get();
- pr.port = ctx->id("I1");
+ pr.port = id_I1;
i0_net->users.push_back(pr);
}
- created_lc->ports.at(ctx->id("I2")).net = i1_net;
+ created_lc->ports.at(id_I2).net = i1_net;
if (i1_net) {
PortRef pr;
pr.cell = created_lc.get();
- pr.port = ctx->id("I2");
+ pr.port = id_I2;
i1_net->users.push_back(pr);
}
new_cells.push_back(std::move(created_lc));
++carry_only;
}
- carry_lc->params[ctx->id("CARRY_ENABLE")] = Property::State::S1;
- replace_port(ci, ctx->id("CI"), carry_lc, ctx->id("CIN"));
- replace_port(ci, ctx->id("CO"), carry_lc, ctx->id("COUT"));
+ carry_lc->params[id_CARRY_ENABLE] = Property::State::S1;
+ replace_port(ci, id_CI, carry_lc, id_CIN);
+ replace_port(ci, id_CO, carry_lc, id_COUT);
if (i0_net) {
auto &i0_usrs = i0_net->users;
i0_usrs.erase(std::remove_if(i0_usrs.begin(), i0_usrs.end(), [ci, ctx](const PortRef &pr) {
- return pr.cell == ci && pr.port == ctx->id("I0");
+ return pr.cell == ci && pr.port == id_I0;
}));
}
if (i1_net) {
auto &i1_usrs = i1_net->users;
i1_usrs.erase(std::remove_if(i1_usrs.begin(), i1_usrs.end(), [ci, ctx](const PortRef &pr) {
- return pr.cell == ci && pr.port == ctx->id("I1");
+ return pr.cell == ci && pr.port == id_I1;
}));
}
// Check for constant driver on CIN
- if (carry_lc->ports.at(ctx->id("CIN")).net != nullptr) {
- IdString cin_net = carry_lc->ports.at(ctx->id("CIN")).net->name;
+ if (carry_lc->ports.at(id_CIN).net != nullptr) {
+ IdString cin_net = carry_lc->ports.at(id_CIN).net->name;
if (cin_net == ctx->id("$PACKER_GND_NET") || cin_net == ctx->id("$PACKER_VCC_NET")) {
- carry_lc->params[ctx->id("CIN_CONST")] = Property::State::S1;
- carry_lc->params[ctx->id("CIN_SET")] =
+ carry_lc->params[id_CIN_CONST] = Property::State::S1;
+ carry_lc->params[id_CIN_SET] =
cin_net == ctx->id("$PACKER_VCC_NET") ? Property::State::S1 : Property::State::S0;
- carry_lc->ports.at(ctx->id("CIN")).net = nullptr;
+ carry_lc->ports.at(id_CIN).net = nullptr;
auto &cin_users = ctx->nets.at(cin_net)->users;
cin_users.erase(
std::remove_if(cin_users.begin(), cin_users.end(), [carry_lc, ctx](const PortRef &pr) {
- return pr.cell == carry_lc && pr.port == ctx->id("CIN");
+ return pr.cell == carry_lc && pr.port == id_CIN;
}));
}
}
@@ -281,18 +280,15 @@ static void pack_ram(Context *ctx)
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
if (is_ram(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_RAM"), ci->name.str(ctx) + "_RAM");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_RAM, ci->name.str(ctx) + "_RAM");
packed_cells.insert(ci->name);
for (auto attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
for (auto param : ci->params)
packed->params[param.first] = param.second;
- packed->params[ctx->id("NEG_CLK_W")] =
- Property(ci->type == ctx->id("SB_RAM40_4KNW") || ci->type == ctx->id("SB_RAM40_4KNRNW"), 1);
- packed->params[ctx->id("NEG_CLK_R")] =
- Property(ci->type == ctx->id("SB_RAM40_4KNR") || ci->type == ctx->id("SB_RAM40_4KNRNW"), 1);
- packed->type = ctx->id("ICESTORM_RAM");
+ packed->params[id_NEG_CLK_W] = Property(ci->type == id_SB_RAM40_4KNW || ci->type == id_SB_RAM40_4KNRNW, 1);
+ packed->params[id_NEG_CLK_R] = Property(ci->type == id_SB_RAM40_4KNR || ci->type == id_SB_RAM40_4KNRNW, 1);
+ packed->type = id_ICESTORM_RAM;
for (auto port : ci->ports) {
PortInfo &pi = port.second;
std::string newname = pi.name.str(ctx);
@@ -300,9 +296,9 @@ static void pack_ram(Context *ctx)
if (bpos != std::string::npos) {
newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2);
}
- if (pi.name == ctx->id("RCLKN"))
+ if (pi.name == id_RCLKN)
newname = "RCLK";
- else if (pi.name == ctx->id("WCLKN"))
+ else if (pi.name == id_WCLKN)
newname = "WCLK";
replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed.get(), ctx->id(newname));
}
@@ -330,13 +326,13 @@ static void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constne
if ((is_lut(ctx, uc) || is_lc(ctx, uc) || is_carry(ctx, uc)) && (user.port.str(ctx).at(0) == 'I') &&
!constval) {
uc->ports[user.port].net = nullptr;
- } else if ((is_sb_mac16(ctx, uc) || uc->type == ctx->id("ICESTORM_DSP")) &&
- (user.port != ctx->id("CLK") &&
- ((constval && user.port == ctx->id("CE")) || (!constval && user.port != ctx->id("CE"))))) {
+ } else if ((is_sb_mac16(ctx, uc) || uc->type == id_ICESTORM_DSP) &&
+ (user.port != id_CLK &&
+ ((constval && user.port == id_CE) || (!constval && user.port != id_CE)))) {
uc->ports[user.port].net = nullptr;
- } else if (is_ram(ctx, uc) && !constval && user.port != ctx->id("RCLK") && user.port != ctx->id("RCLKN") &&
- user.port != ctx->id("WCLK") && user.port != ctx->id("WCLKN") && user.port != ctx->id("RCLKE") &&
- user.port != ctx->id("WCLKE")) {
+ } else if (is_ram(ctx, uc) && !constval && user.port != id_RCLK && user.port != id_RCLKN &&
+ user.port != id_WCLK && user.port != id_WCLKN && user.port != id_RCLKE &&
+ user.port != id_WCLKE) {
uc->ports[user.port].net = nullptr;
} else {
uc->ports[user.port].net = constnet;
@@ -352,24 +348,24 @@ static void pack_constants(Context *ctx)
{
log_info("Packing constants..\n");
- std::unique_ptr<CellInfo> gnd_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND");
- gnd_cell->params[ctx->id("LUT_INIT")] = Property(0, 16);
+ std::unique_ptr<CellInfo> gnd_cell = create_ice_cell(ctx, id_ICESTORM_LC, "$PACKER_GND");
+ gnd_cell->params[id_LUT_INIT] = Property(0, 16);
auto gnd_net = std::make_unique<NetInfo>(ctx->id("$PACKER_GND_NET"));
gnd_net->driver.cell = gnd_cell.get();
- gnd_net->driver.port = ctx->id("O");
- gnd_cell->ports.at(ctx->id("O")).net = gnd_net.get();
+ gnd_net->driver.port = id_O;
+ gnd_cell->ports.at(id_O).net = gnd_net.get();
NetInfo *gnd_net_info = gnd_net.get();
if (ctx->nets.find(ctx->id("$PACKER_GND_NET")) != ctx->nets.end()) {
gnd_net_info = ctx->nets.find(ctx->id("$PACKER_GND_NET"))->second.get();
}
- std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC");
- vcc_cell->params[ctx->id("LUT_INIT")] = Property(1, 16);
+ std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, id_ICESTORM_LC, "$PACKER_VCC");
+ vcc_cell->params[id_LUT_INIT] = Property(1, 16);
auto vcc_net = std::make_unique<NetInfo>(ctx->id("$PACKER_VCC_NET"));
vcc_net->driver.cell = vcc_cell.get();
- vcc_net->driver.port = ctx->id("O");
- vcc_cell->ports.at(ctx->id("O")).net = vcc_net.get();
+ vcc_net->driver.port = id_O;
+ vcc_cell->ports.at(id_O).net = vcc_net.get();
NetInfo *vcc_net_info = vcc_net.get();
if (ctx->nets.find(ctx->id("$PACKER_VCC_NET")) != ctx->nets.end()) {
@@ -382,13 +378,13 @@ static void pack_constants(Context *ctx)
for (auto &net : ctx->nets) {
NetInfo *ni = net.second.get();
- if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) {
+ if (ni->driver.cell != nullptr && ni->driver.cell->type == id_GND) {
IdString drv_cell = ni->driver.cell->name;
set_net_constant(ctx, ni, gnd_net_info, false);
gnd_used = true;
dead_nets.push_back(net.first);
ctx->cells.erase(drv_cell);
- } else if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("VCC")) {
+ } else if (ni->driver.cell != nullptr && ni->driver.cell->type == id_VCC) {
IdString drv_cell = ni->driver.cell->name;
set_net_constant(ctx, ni, vcc_net_info, true);
dead_nets.push_back(net.first);
@@ -434,16 +430,16 @@ static std::unique_ptr<CellInfo> create_padin_gbuf(Context *ctx, CellInfo *cell,
std::string gbuf_name)
{
// Find the matching SB_GB BEL connected to the same global network
- if (!cell->attrs.count(ctx->id("BEL")))
+ if (!cell->attrs.count(id_BEL))
log_error("Unconstrained SB_GB_IO %s is not supported.\n", ctx->nameOf(cell));
- BelId bel = ctx->getBelByNameStr(cell->attrs[ctx->id("BEL")].as_string());
+ BelId bel = ctx->getBelByNameStr(cell->attrs[id_BEL].as_string());
BelId gb_bel = find_padin_gbuf(ctx, bel, port_name);
NPNR_ASSERT(gb_bel != BelId());
// Create a SB_GB Cell and lock it there
- std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, ctx->id("SB_GB"), gbuf_name);
- gb->attrs[ctx->id("FOR_PAD_IN")] = Property::State::S1;
- gb->attrs[ctx->id("BEL")] = ctx->getBelName(gb_bel).str(ctx);
+ std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, id_SB_GB, gbuf_name);
+ gb->attrs[id_FOR_PAD_IN] = Property::State::S1;
+ gb->attrs[id_BEL] = ctx->getBelName(gb_bel).str(ctx);
// Reconnect the net to that port for easier identification it's a global net
replace_port(cell, port_name, gb.get(), id_GLOBAL_BUFFER_OUTPUT);
@@ -475,11 +471,11 @@ static void pack_io(Context *ctx)
if (is_nextpnr_iob(ctx, ci)) {
CellInfo *sb = nullptr, *rgb = nullptr;
if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) {
- sb = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, is_ice_iob, ctx->id("PACKAGE_PIN"), true, ci);
+ sb = net_only_drives(ctx, ci->ports.at(id_O).net, is_ice_iob, id_PACKAGE_PIN, true, ci);
} else if (ci->type == ctx->id("$nextpnr_obuf")) {
- NetInfo *net = ci->ports.at(ctx->id("I")).net;
- sb = net_only_drives(ctx, net, is_ice_iob, ctx->id("PACKAGE_PIN"), true, ci);
+ NetInfo *net = ci->ports.at(id_I).net;
+ sb = net_only_drives(ctx, net, is_ice_iob, id_PACKAGE_PIN, true, ci);
if (net && net->driver.cell &&
(is_sb_rgba_drv(ctx, net->driver.cell) || is_sb_rgb_drv(ctx, net->driver.cell)))
rgb = net->driver.cell;
@@ -488,7 +484,7 @@ static void pack_io(Context *ctx)
// Trivial case, SB_IO used. Just destroy the iobuf
log_info("%s feeds SB_IO %s, removing %s %s.\n", ci->name.c_str(ctx), sb->name.c_str(ctx),
ci->type.c_str(ctx), ci->name.c_str(ctx));
- NetInfo *net = sb->ports.at(ctx->id("PACKAGE_PIN")).net;
+ NetInfo *net = sb->ports.at(id_PACKAGE_PIN).net;
if (((ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) &&
net->users.size() > 1) ||
(ci->type == ctx->id("$nextpnr_obuf") && (net->users.size() > 2 || net->driver.cell != nullptr)))
@@ -518,13 +514,12 @@ static void pack_io(Context *ctx)
} else if (rgb != nullptr) {
log_info("%s use by SB_RGBA_DRV/SB_RGB_DRV %s, not creating SB_IO\n", ci->name.c_str(ctx),
rgb->name.c_str(ctx));
- disconnect_port(ctx, ci, ctx->id("I"));
+ disconnect_port(ctx, ci, id_I);
packed_cells.insert(ci->name);
continue;
} else {
// Create a SB_IO buffer
- std::unique_ptr<CellInfo> ice_cell =
- create_ice_cell(ctx, ctx->id("SB_IO"), ci->name.str(ctx) + "$sb_io");
+ std::unique_ptr<CellInfo> ice_cell = create_ice_cell(ctx, id_SB_IO, ci->name.str(ctx) + "$sb_io");
nxio_to_sb(ctx, ci, ice_cell.get(), packed_cells);
new_cells.push_back(std::move(ice_cell));
sb = new_cells.back().get();
@@ -535,7 +530,7 @@ static void pack_io(Context *ctx)
for (auto &attr : ci->attrs)
sb->attrs[attr.first] = attr.second;
} else if (is_sb_io(ctx, ci) || is_sb_gb_io(ctx, ci)) {
- NetInfo *net = ci->ports.at(ctx->id("PACKAGE_PIN")).net;
+ NetInfo *net = ci->ports.at(id_PACKAGE_PIN).net;
if ((net != nullptr) && ((net->users.size() > 2) ||
(net->driver.cell != nullptr &&
net->driver.cell->type == ctx->id("$nextpnr_obuf") && net->users.size() > 1)))
@@ -552,8 +547,8 @@ static void pack_io(Context *ctx)
new_cells.push_back(std::move(gb));
// Make it a normal SB_IO with global marker
- ci->type = ctx->id("SB_IO");
- ci->attrs[ctx->id("GLOBAL")] = Property::State::S1;
+ ci->type = id_SB_IO;
+ ci->attrs[id_GLOBAL] = Property::State::S1;
} else if (is_sb_io(ctx, ci)) {
// Disconnect unused inputs
NetInfo *net_in0 = ci->ports.count(id_D_IN_0) ? ci->ports[id_D_IN_0].net : nullptr;
@@ -595,18 +590,18 @@ static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen
is_cen ? " [cen]" : "", is_logic ? " [logic]" : "", fanout);
std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
- std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name);
- gb->ports[ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER")].net = net;
+ std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, id_SB_GB, "$gbuf_" + glb_name);
+ gb->ports[id_USER_SIGNAL_TO_GLOBAL_BUFFER].net = net;
PortRef pr;
pr.cell = gb.get();
- pr.port = ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER");
+ pr.port = id_USER_SIGNAL_TO_GLOBAL_BUFFER;
net->users.push_back(pr);
pr.cell = gb.get();
- pr.port = ctx->id("GLOBAL_BUFFER_OUTPUT");
+ pr.port = id_GLOBAL_BUFFER_OUTPUT;
NetInfo *glbnet = ctx->createNet(ctx->id(glb_name));
glbnet->driver = pr;
- gb->ports[ctx->id("GLOBAL_BUFFER_OUTPUT")].net = glbnet;
+ gb->ports[id_GLOBAL_BUFFER_OUTPUT].net = glbnet;
std::vector<PortRef> keep_users;
for (auto user : net->users) {
if (is_clock_port(ctx, user) || (is_reset && is_reset_port(ctx, user)) ||
@@ -664,9 +659,9 @@ static void promote_globals(Context *ctx)
--gbs_available;
/* And possibly limits what we can promote */
- if (cell.second->attrs.find(ctx->id("BEL")) != cell.second->attrs.end()) {
+ if (cell.second->attrs.find(id_BEL) != cell.second->attrs.end()) {
/* If the SB_GB is locked, doesn't matter what it drives */
- BelId bel = ctx->getBelByNameStr(cell.second->attrs[ctx->id("BEL")].as_string());
+ BelId bel = ctx->getBelByNameStr(cell.second->attrs[id_BEL].as_string());
int glb_id = ctx->get_driven_glb_netwk(bel);
if ((glb_id % 2) == 0)
resets_available--;
@@ -708,7 +703,7 @@ static void promote_globals(Context *ctx)
if (global_clock->second == 0 && prom_logics < 4 && global_logic->second > logic_fanout_thresh &&
(global_logic->second > global_cen->second || prom_cens >= cens_available) &&
(global_logic->second > global_reset->second || prom_resets >= resets_available) &&
- bool_or_default(ctx->settings, ctx->id("promote_logic"), false)) {
+ bool_or_default(ctx->settings, id_promote_logic, false)) {
NetInfo *logicnet = ctx->nets[global_logic->first].get();
insert_global(ctx, logicnet, false, false, true, global_logic->second);
++prom_globals;
@@ -784,11 +779,11 @@ static void place_plls(Context *ctx)
continue;
// If it's constrained already, add to already used list
- if (ci->attrs.count(ctx->id("BEL"))) {
- BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[ctx->id("BEL")].as_string());
+ if (ci->attrs.count(id_BEL)) {
+ BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[id_BEL].as_string());
if (pll_all_bels.count(bel_constrain) == 0)
log_error("PLL '%s' is constrained to invalid BEL '%s'\n", ci->name.c_str(ctx),
- ci->attrs[ctx->id("BEL")].as_string().c_str());
+ ci->attrs[id_BEL].as_string().c_str());
pll_used_bels[bel_constrain] = ci;
}
@@ -802,10 +797,10 @@ static void place_plls(Context *ctx)
continue;
// Check PACKAGEPIN connection
- if (!ci->ports.count(ctx->id("PACKAGEPIN")))
+ if (!ci->ports.count(id_PACKAGEPIN))
log_error("PLL '%s' is of PAD type but doesn't have a PACKAGEPIN port\n", ci->name.c_str(ctx));
- NetInfo *ni = ci->ports.at(ctx->id("PACKAGEPIN")).net;
+ NetInfo *ni = ci->ports.at(id_PACKAGEPIN).net;
if (ni == nullptr || ni->driver.cell == nullptr)
log_error("PLL '%s' is of PAD type but doesn't have a valid PACKAGEPIN connection\n", ci->name.c_str(ctx));
@@ -816,11 +811,11 @@ static void place_plls(Context *ctx)
ci->name.c_str(ctx), io_cell->type.c_str(ctx));
if (ni->users.size() != 1)
log_error("PLL '%s' clock input '%s' can only drive PLL\n", ci->name.c_str(ctx), ni->name.c_str(ctx));
- if (!io_cell->attrs.count(ctx->id("BEL")))
+ if (!io_cell->attrs.count(id_BEL))
log_error("PLL '%s' PACKAGEPIN SB_IO '%s' is unconstrained\n", ci->name.c_str(ctx),
io_cell->name.c_str(ctx));
- BelId io_bel = ctx->getBelByNameStr(io_cell->attrs.at(ctx->id("BEL")).as_string());
+ BelId io_bel = ctx->getBelByNameStr(io_cell->attrs.at(id_BEL).as_string());
BelId found_bel;
// Find the PLL BEL that would suit that connection
@@ -843,16 +838,16 @@ static void place_plls(Context *ctx)
}
// Is it user constrained ?
- if (ci->attrs.count(ctx->id("BEL"))) {
+ if (ci->attrs.count(id_BEL)) {
// Yes. Check it actually matches !
- BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[ctx->id("BEL")].as_string());
+ BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[id_BEL].as_string());
if (bel_constrain != found_bel)
log_error("PLL '%s' is user constrained to %s but can only be placed in %s based on its PACKAGEPIN "
"connection\n",
ci->name.c_str(ctx), ctx->nameOfBel(bel_constrain), ctx->nameOfBel(found_bel));
} else {
// No, we can constrain it ourselves
- ci->attrs[ctx->id("BEL")] = ctx->getBelName(found_bel).str(ctx);
+ ci->attrs[id_BEL] = ctx->getBelName(found_bel).str(ctx);
pll_used_bels[found_bel] = ci;
}
@@ -867,15 +862,15 @@ static void place_plls(Context *ctx)
continue;
// Only consider bound IO that are used as inputs
- if (!io_ci->attrs.count(ctx->id("BEL")))
+ if (!io_ci->attrs.count(id_BEL))
continue;
if ((!io_ci->ports.count(id_D_IN_0) || (io_ci->ports[id_D_IN_0].net == nullptr)) &&
(!io_ci->ports.count(id_D_IN_1) || (io_ci->ports[id_D_IN_1].net == nullptr)) &&
- !bool_or_default(io_ci->attrs, ctx->id("GLOBAL")))
+ !bool_or_default(io_ci->attrs, id_GLOBAL))
continue;
// Check all placed PLL (either forced by user, or forced by PACKAGEPIN)
- BelId io_bel = ctx->getBelByNameStr(io_ci->attrs[ctx->id("BEL")].as_string());
+ BelId io_bel = ctx->getBelByNameStr(io_ci->attrs[id_BEL].as_string());
for (auto placed_pll : pll_used_bels) {
BelPin pll_io_a, pll_io_b;
@@ -905,11 +900,11 @@ static void place_plls(Context *ctx)
continue;
// Only consider the bound ones
- if (!gb_ci->attrs.count(ctx->id("BEL")))
+ if (!gb_ci->attrs.count(id_BEL))
continue;
// Check all placed PLL (either forced by user, or forced by PACKAGEPIN)
- BelId gb_bel = ctx->getBelByNameStr(gb_ci->attrs[ctx->id("BEL")].as_string());
+ BelId gb_bel = ctx->getBelByNameStr(gb_ci->attrs[id_BEL].as_string());
for (auto placed_pll : pll_used_bels) {
CellInfo *ci = placed_pll.second;
@@ -967,8 +962,8 @@ static void place_plls(Context *ctx)
// Could this be a PAD PLL ?
bool could_be_pad = false;
BelId pad_bel;
- if (ni->users.size() == 1 && is_sb_io(ctx, ni->driver.cell) && ni->driver.cell->attrs.count(ctx->id("BEL")))
- pad_bel = ctx->getBelByNameStr(ni->driver.cell->attrs[ctx->id("BEL")].as_string());
+ if (ni->users.size() == 1 && is_sb_io(ctx, ni->driver.cell) && ni->driver.cell->attrs.count(id_BEL))
+ pad_bel = ctx->getBelByNameStr(ni->driver.cell->attrs[id_BEL].as_string());
// Find a BEL for it
BelId found_bel;
@@ -1002,7 +997,7 @@ static void place_plls(Context *ctx)
if (could_be_pad)
log_info(" (given its connections, this PLL could have been a PAD PLL)\n");
- ci->attrs[ctx->id("BEL")] = ctx->getBelName(found_bel).str(ctx);
+ ci->attrs[id_BEL] = ctx->getBelName(found_bel).str(ctx);
pll_used_bels[found_bel] = ci;
}
}
@@ -1017,20 +1012,20 @@ static std::unique_ptr<CellInfo> spliceLUT(Context *ctx, CellInfo *ci, IdString
NPNR_ASSERT(port.net != nullptr);
// Create pass-through LUT.
- std::unique_ptr<CellInfo> pt = create_ice_cell(ctx, ctx->id("ICESTORM_LC"),
- ci->name.str(ctx) + "$nextpnr_" + portId.str(ctx) + "_lut_through");
- pt->params[ctx->id("LUT_INIT")] = Property(65280, 16); // output is always I3
+ std::unique_ptr<CellInfo> pt =
+ create_ice_cell(ctx, id_ICESTORM_LC, ci->name.str(ctx) + "$nextpnr_" + portId.str(ctx) + "_lut_through");
+ pt->params[id_LUT_INIT] = Property(65280, 16); // output is always I3
// Create LUT output net.
NetInfo *out_net = ctx->createNet(ctx->id(ci->name.str(ctx) + "$nextnr_" + portId.str(ctx) + "_lut_through_net"));
out_net->driver.cell = pt.get();
- out_net->driver.port = ctx->id("O");
- pt->ports.at(ctx->id("O")).net = out_net;
+ out_net->driver.port = id_O;
+ pt->ports.at(id_O).net = out_net;
// New users of the original cell's port
std::vector<PortRef> new_users;
for (const auto &user : port.net->users) {
- if (onlyNonLUTs && user.cell->type == ctx->id("ICESTORM_LC")) {
+ if (onlyNonLUTs && user.cell->type == id_ICESTORM_LC) {
new_users.push_back(user);
continue;
}
@@ -1046,9 +1041,9 @@ static std::unique_ptr<CellInfo> spliceLUT(Context *ctx, CellInfo *ci, IdString
// Add LUT to new users.
PortRef pr;
pr.cell = pt.get();
- pr.port = ctx->id("I3");
+ pr.port = id_I3;
new_users.push_back(pr);
- pt->ports.at(ctx->id("I3")).net = port.net;
+ pt->ports.at(id_I3).net = port.net;
// Replace users of the original net.
port.net->users = new_users;
@@ -1065,7 +1060,7 @@ static BelId cell_place_unique(Context *ctx, CellInfo *ci)
if (ctx->is_bel_locked(bel))
continue;
IdStringList bel_name = ctx->getBelName(bel);
- ci->attrs[ctx->id("BEL")] = bel_name.str(ctx);
+ ci->attrs[id_BEL] = bel_name.str(ctx);
log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), ctx->nameOfBel(bel));
return bel;
}
@@ -1124,7 +1119,7 @@ static void pack_special(Context *ctx)
/* Force placement (no choices anyway) */
cell_place_unique(ctx, ci);
- NetInfo *ledpu_net = ci->ports.at(ctx->id("LEDPU")).net;
+ NetInfo *ledpu_net = ci->ports.at(id_LEDPU).net;
for (auto &user : ledpu_net->users) {
if (!is_sb_rgb_drv(ctx, user.cell)) {
log_error("SB_LED_DRV_CUR LEDPU port can only be connected to SB_RGB_DRV!\n");
@@ -1133,44 +1128,42 @@ static void pack_special(Context *ctx)
user.cell->ports.at(user.port).net = nullptr;
}
}
- ci->ports.erase(ctx->id("LEDPU"));
+ ci->ports.erase(id_LEDPU);
ctx->nets.erase(ledpu_net->name);
}
}
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
if (is_sb_lfosc(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"), ci->name.str(ctx) + "_OSC");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_LFOSC, ci->name.str(ctx) + "_OSC");
packed_cells.insert(ci->name);
cell_place_unique(ctx, packed.get());
- replace_port(ci, ctx->id("CLKLFEN"), packed.get(), ctx->id("CLKLFEN"));
- replace_port(ci, ctx->id("CLKLFPU"), packed.get(), ctx->id("CLKLFPU"));
- if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) {
- replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF_FABRIC"));
- set_period(ctx, packed.get(), ctx->id("CLKLF_FABRIC"), 100000000); // 10kHz
+ replace_port(ci, id_CLKLFEN, packed.get(), id_CLKLFEN);
+ replace_port(ci, id_CLKLFPU, packed.get(), id_CLKLFPU);
+ if (bool_or_default(ci->attrs, id_ROUTE_THROUGH_FABRIC)) {
+ replace_port(ci, id_CLKLF, packed.get(), id_CLKLF_FABRIC);
+ set_period(ctx, packed.get(), id_CLKLF_FABRIC, 100000000); // 10kHz
} else {
- replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF"));
+ replace_port(ci, id_CLKLF, packed.get(), id_CLKLF);
std::unique_ptr<CellInfo> gb =
- create_padin_gbuf(ctx, packed.get(), ctx->id("CLKLF"), "$gbuf_" + ci->name.str(ctx) + "_lfosc");
+ create_padin_gbuf(ctx, packed.get(), id_CLKLF, "$gbuf_" + ci->name.str(ctx) + "_lfosc");
set_period(ctx, gb.get(), id_GLOBAL_BUFFER_OUTPUT, 100000000); // 10kHz
new_cells.push_back(std::move(gb));
}
new_cells.push_back(std::move(packed));
} else if (is_sb_hfosc(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_HFOSC"), ci->name.str(ctx) + "_OSC");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_HFOSC, ci->name.str(ctx) + "_OSC");
packed_cells.insert(ci->name);
cell_place_unique(ctx, packed.get());
- packed->params[ctx->id("TRIM_EN")] = str_or_default(ci->params, ctx->id("TRIM_EN"), "0b0");
- packed->params[ctx->id("CLKHF_DIV")] = str_or_default(ci->params, ctx->id("CLKHF_DIV"), "0b00");
- replace_port(ci, ctx->id("CLKHFEN"), packed.get(), ctx->id("CLKHFEN"));
- replace_port(ci, ctx->id("CLKHFPU"), packed.get(), ctx->id("CLKHFPU"));
+ packed->params[id_TRIM_EN] = str_or_default(ci->params, id_TRIM_EN, "0b0");
+ packed->params[id_CLKHF_DIV] = str_or_default(ci->params, id_CLKHF_DIV, "0b00");
+ replace_port(ci, id_CLKHFEN, packed.get(), id_CLKHFEN);
+ replace_port(ci, id_CLKHFPU, packed.get(), id_CLKHFPU);
for (int i = 0; i < 10; i++) {
auto port = ctx->id("TRIM" + std::to_string(i));
replace_port(ci, port, packed.get(), port);
}
- std::string div = packed->params[ctx->id("CLKHF_DIV")].as_string();
+ std::string div = packed->params[id_CLKHF_DIV].as_string();
int frequency;
if (div == "0b00")
frequency = 48;
@@ -1182,20 +1175,19 @@ static void pack_special(Context *ctx)
frequency = 6;
else
log_error("Invalid HFOSC divider value '%s' - expecting 0b00, 0b01, 0b10 or 0b11\n", div.c_str());
- if (bool_or_default(ci->attrs, ctx->id("ROUTE_THROUGH_FABRIC"))) {
- replace_port(ci, ctx->id("CLKHF"), packed.get(), ctx->id("CLKHF_FABRIC"));
- set_period(ctx, packed.get(), ctx->id("CLKHF_FABRIC"), 1000000 / frequency);
+ if (bool_or_default(ci->attrs, id_ROUTE_THROUGH_FABRIC)) {
+ replace_port(ci, id_CLKHF, packed.get(), id_CLKHF_FABRIC);
+ set_period(ctx, packed.get(), id_CLKHF_FABRIC, 1000000 / frequency);
} else {
- replace_port(ci, ctx->id("CLKHF"), packed.get(), ctx->id("CLKHF"));
+ replace_port(ci, id_CLKHF, packed.get(), id_CLKHF);
std::unique_ptr<CellInfo> gb =
- create_padin_gbuf(ctx, packed.get(), ctx->id("CLKHF"), "$gbuf_" + ci->name.str(ctx) + "_hfosc");
+ create_padin_gbuf(ctx, packed.get(), id_CLKHF, "$gbuf_" + ci->name.str(ctx) + "_hfosc");
set_period(ctx, gb.get(), id_GLOBAL_BUFFER_OUTPUT, 1000000 / frequency);
new_cells.push_back(std::move(gb));
}
new_cells.push_back(std::move(packed));
} else if (is_sb_spram(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_SPRAM"), ci->name.str(ctx) + "_RAM");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_SPRAM, ci->name.str(ctx) + "_RAM");
packed_cells.insert(ci->name);
for (auto attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
@@ -1210,8 +1202,7 @@ static void pack_special(Context *ctx)
}
new_cells.push_back(std::move(packed));
} else if (is_sb_mac16(ctx, ci)) {
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_DSP"), ci->name.str(ctx) + "_DSP");
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_DSP, ci->name.str(ctx) + "_DSP");
packed_cells.insert(ci->name);
for (auto attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
@@ -1241,7 +1232,7 @@ static void pack_special(Context *ctx)
if (net == nullptr)
continue;
- if ((pi.name != ctx->id("RGB0")) && (pi.name != ctx->id("RGB1")) && (pi.name != ctx->id("RGB2")))
+ if ((pi.name != id_RGB0) && (pi.name != id_RGB1) && (pi.name != id_RGB2))
continue;
if (net->users.size() > 0)
@@ -1253,10 +1244,10 @@ static void pack_special(Context *ctx)
if (is_sb_rgb_drv(ctx, ci) && !ci->ledInfo.ledCurConnected)
log_error("Port RGBPU of SB_RGB_DRV should be driven by port LEDPU of SB_LED_DRV_CUR!\n");
- ci->ports.erase(ctx->id("RGBPU"));
- ci->ports.erase(ctx->id("RGB0"));
- ci->ports.erase(ctx->id("RGB1"));
- ci->ports.erase(ctx->id("RGB2"));
+ ci->ports.erase(id_RGBPU);
+ ci->ports.erase(id_RGB0);
+ ci->ports.erase(id_RGB1);
+ ci->ports.erase(id_RGB2);
} else if (is_sb_ledda_ip(ctx, ci)) {
/* Force placement (no choices anyway) */
cell_place_unique(ctx, ci);
@@ -1268,7 +1259,7 @@ static void pack_special(Context *ctx)
{std::make_tuple(id_SB_I2C, "0b0011"), Loc(25, 31, 0)},
};
std::string bus_addr74 =
- str_or_default(ci->params, ctx->id("BUS_ADDR74"), is_sb_i2c(ctx, ci) ? "0b0001" : "0b0000");
+ str_or_default(ci->params, id_BUS_ADDR74, is_sb_i2c(ctx, ci) ? "0b0001" : "0b0000");
if (map_ba74.find(std::make_tuple(ci->type, bus_addr74)) == map_ba74.end())
log_error("Invalid value for BUS_ADDR74 for cell '%s' of type '%s'\n", ci->name.c_str(ctx),
ci->type.c_str(ctx));
@@ -1278,7 +1269,7 @@ static void pack_special(Context *ctx)
log_error("Unable to find placement for cell '%s' of type '%s'\n", ci->name.c_str(ctx),
ci->type.c_str(ctx));
IdStringList bel_name = ctx->getBelName(bel);
- ci->attrs[ctx->id("BEL")] = bel_name.str(ctx);
+ ci->attrs[id_BEL] = bel_name.str(ctx);
log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), ctx->nameOfBel(bel));
}
}
@@ -1303,15 +1294,14 @@ void pack_plls(Context *ctx)
bool is_pad = is_sb_pll40_pad(ctx, ci);
bool is_core = !is_pad;
- std::unique_ptr<CellInfo> packed =
- create_ice_cell(ctx, ctx->id("ICESTORM_PLL"), ci->name.str(ctx) + "_PLL");
- packed->attrs[ctx->id("TYPE")] = ci->type.str(ctx);
+ std::unique_ptr<CellInfo> packed = create_ice_cell(ctx, id_ICESTORM_PLL, ci->name.str(ctx) + "_PLL");
+ packed->attrs[id_TYPE] = ci->type.str(ctx);
packed_cells.insert(ci->name);
if (!is_sb_pll40_dual(ctx, ci)) {
// Remove second output, so a buffer isn't created for it, for these
// cell types with only one output
- packed->ports.erase(ctx->id("PLLOUT_B"));
- packed->ports.erase(ctx->id("PLLOUT_B_GLOBAL"));
+ packed->ports.erase(id_PLLOUT_B);
+ packed->ports.erase(id_PLLOUT_B_GLOBAL);
}
for (auto attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
@@ -1319,9 +1309,9 @@ void pack_plls(Context *ctx)
packed->params[param.first] = param.second;
const std::map<IdString, IdString> pos_map_name = {
- {ctx->id("PLLOUT_SELECT"), ctx->id("PLLOUT_SELECT_A")},
- {ctx->id("PLLOUT_SELECT_PORTA"), ctx->id("PLLOUT_SELECT_A")},
- {ctx->id("PLLOUT_SELECT_PORTB"), ctx->id("PLLOUT_SELECT_B")},
+ {id_PLLOUT_SELECT, id_PLLOUT_SELECT_A},
+ {id_PLLOUT_SELECT_PORTA, id_PLLOUT_SELECT_A},
+ {id_PLLOUT_SELECT_PORTB, id_PLLOUT_SELECT_B},
};
const std::map<std::string, int> pos_map_val = {
{"GENCLK", 0},
@@ -1336,9 +1326,8 @@ void pack_plls(Context *ctx)
packed->params[pos_map_name.at(param.first)] = pos_map_val.at(param.second.as_string());
}
const std::map<IdString, std::pair<IdString, IdString>> delmodes = {
- {ctx->id("DELAY_ADJUSTMENT_MODE_FEEDBACK"), {ctx->id("DELAY_ADJMODE_FB"), ctx->id("FDA_FEEDBACK")}},
- {ctx->id("DELAY_ADJUSTMENT_MODE_RELATIVE"),
- {ctx->id("DELAY_ADJMODE_REL"), ctx->id("FDA_RELATIVE")}},
+ {id_DELAY_ADJUSTMENT_MODE_FEEDBACK, {id_DELAY_ADJMODE_FB, id_FDA_FEEDBACK}},
+ {id_DELAY_ADJUSTMENT_MODE_RELATIVE, {id_DELAY_ADJMODE_REL, id_FDA_RELATIVE}},
};
for (auto delmode : delmodes) {
if (ci->params.count(delmode.first)) {
@@ -1352,9 +1341,9 @@ void pack_plls(Context *ctx)
log_error("Invalid PLL %s selection '%s'\n", delmode.first.c_str(ctx), value.c_str());
}
}
- auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")].is_string
- ? packed->params[ctx->id("FEEDBACK_PATH")].as_string()
- : std::to_string(packed->params[ctx->id("FEEDBACK_PATH")].as_int64());
+ auto feedback_path = packed->params[id_FEEDBACK_PATH].is_string
+ ? packed->params[id_FEEDBACK_PATH].as_string()
+ : std::to_string(packed->params[id_FEEDBACK_PATH].as_int64());
std::string fbp_value = feedback_path == "DELAY" ? "0"
: feedback_path == "SIMPLE" ? "1"
: feedback_path == "PHASE_AND_DELAY" ? "2"
@@ -1363,8 +1352,8 @@ void pack_plls(Context *ctx)
if (!std::all_of(fbp_value.begin(), fbp_value.end(), isdigit))
log_error("PLL '%s' has unsupported FEEDBACK_PATH value '%s'\n", ci->name.c_str(ctx),
feedback_path.c_str());
- packed->params[ctx->id("FEEDBACK_PATH")] = Property(std::stoi(fbp_value), 3);
- packed->params[ctx->id("PLLTYPE")] = sb_pll40_type(ctx, ci);
+ packed->params[id_FEEDBACK_PATH] = Property(std::stoi(fbp_value), 3);
+ packed->params[id_PLLTYPE] = sb_pll40_type(ctx, ci);
NetInfo *pad_packagepin_net = nullptr;
@@ -1379,16 +1368,16 @@ void pack_plls(Context *ctx)
newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2);
}
- if (pi.name == ctx->id("PLLOUTCOREA") || pi.name == ctx->id("PLLOUTCORE"))
+ if (pi.name == id_PLLOUTCOREA || pi.name == id_PLLOUTCORE)
newname = "PLLOUT_A";
- if (pi.name == ctx->id("PLLOUTCOREB"))
+ if (pi.name == id_PLLOUTCOREB)
newname = "PLLOUT_B";
- if (pi.name == ctx->id("PLLOUTGLOBALA") || pi.name == ctx->id("PLLOUTGLOBAL"))
+ if (pi.name == id_PLLOUTGLOBALA || pi.name == id_PLLOUTGLOBAL)
newname = "PLLOUT_A_GLOBAL";
- if (pi.name == ctx->id("PLLOUTGLOBALB"))
+ if (pi.name == id_PLLOUTGLOBALB)
newname = "PLLOUT_B_GLOBAL";
- if (pi.name == ctx->id("PACKAGEPIN")) {
+ if (pi.name == id_PACKAGEPIN) {
if (!is_pad) {
log_error("PLL '%s' has a PACKAGEPIN but is not a PAD PLL\n", ci->name.c_str(ctx));
} else {
@@ -1399,7 +1388,7 @@ void pack_plls(Context *ctx)
continue;
}
}
- if (pi.name == ctx->id("REFERENCECLK")) {
+ if (pi.name == id_REFERENCECLK) {
if (!is_core)
log_error("PLL '%s' has a REFERENCECLK but is not a CORE PLL\n", ci->name.c_str(ctx));
got_input_constr = get_period(ctx, ci, pi.name, input_constr);
@@ -1429,7 +1418,7 @@ void pack_plls(Context *ctx)
log_info(" Input frequency of PLL '%s' is constrained to %.1f MHz\n", ctx->nameOf(ci),
MHz(ctx, input_constr));
// Input divider (DIVR)
- input_constr *= (int_or_default(packed->params, ctx->id("DIVR"), 0) + 1);
+ input_constr *= (int_or_default(packed->params, id_DIVR, 0) + 1);
delay_t vco_constr = 0;
delay_t outa_constr = 0, outb_constr = 0;
int sr_div = 4;
@@ -1452,7 +1441,7 @@ void pack_plls(Context *ctx)
};
// Lookup shiftreg divider
- int sr_div_mode = int_or_default(packed->params, ctx->id("SHIFTREG_DIV_MODE"), 0);
+ int sr_div_mode = int_or_default(packed->params, id_SHIFTREG_DIV_MODE, 0);
switch (sr_div_mode) {
case 0:
sr_div = 4;
@@ -1470,8 +1459,8 @@ void pack_plls(Context *ctx)
}
}
// Determine dividers in VCO path
- vco_constr = input_constr / (int_or_default(packed->params, ctx->id("DIVF"), 0) + 1);
- divq = 1 << (int_or_default(packed->params, ctx->id("DIVQ"), 0));
+ vco_constr = input_constr / (int_or_default(packed->params, id_DIVF, 0) + 1);
+ divq = 1 << (int_or_default(packed->params, id_DIVQ, 0));
if (fbp_value != "1") // anything other than SIMPLE - feedback after DIVQ
vco_constr /= divq;
if (fbp_value == "6") { // EXTERNAL
@@ -1484,19 +1473,19 @@ void pack_plls(Context *ctx)
}
log_info(" VCO frequency of PLL '%s' is constrained to %.1f MHz\n", ctx->nameOf(ci),
MHz(ctx, vco_constr));
- if (ci->type == ctx->id("SB_PLL40_2_PAD"))
+ if (ci->type == id_SB_PLL40_2_PAD)
outa_constr = input_constr; // 2_PAD variant passes through input to OUTPUT A
else
- outa_constr = process_output(ctx->id("PLLOUT_SELECT_A"));
- outb_constr = process_output(ctx->id("PLLOUT_SELECT_B"));
- set_period(ctx, packed.get(), ctx->id("PLLOUT_A"), outa_constr);
- set_period(ctx, packed.get(), ctx->id("PLLOUT_A_GLOBAL"), outa_constr);
- set_period(ctx, packed.get(), ctx->id("PLLOUT_B"), outb_constr);
- set_period(ctx, packed.get(), ctx->id("PLLOUT_B_GLOBAL"), outb_constr);
+ outa_constr = process_output(id_PLLOUT_SELECT_A);
+ outb_constr = process_output(id_PLLOUT_SELECT_B);
+ set_period(ctx, packed.get(), id_PLLOUT_A, outa_constr);
+ set_period(ctx, packed.get(), id_PLLOUT_A_GLOBAL, outa_constr);
+ set_period(ctx, packed.get(), id_PLLOUT_B, outb_constr);
+ set_period(ctx, packed.get(), id_PLLOUT_B_GLOBAL, outb_constr);
}
constr_fail:
// PLL must have been placed already in place_plls()
- BelId pll_bel = ctx->getBelByNameStr(packed->attrs[ctx->id("BEL")].as_string());
+ BelId pll_bel = ctx->getBelByNameStr(packed->attrs[id_BEL].as_string());
NPNR_ASSERT(pll_bel != BelId());
// Deal with PAD PLL peculiarities
@@ -1505,10 +1494,10 @@ void pack_plls(Context *ctx)
auto pll_packagepin_driver = pad_packagepin_net->driver;
NPNR_ASSERT(pll_packagepin_driver.cell != nullptr);
auto packagepin_cell = pll_packagepin_driver.cell;
- auto packagepin_bel_name = packagepin_cell->attrs.find(ctx->id("BEL"));
+ auto packagepin_bel_name = packagepin_cell->attrs.find(id_BEL);
// Set an attribute about this PLL's PAD SB_IO.
- packed->attrs[ctx->id("BEL_PAD_INPUT")] = packagepin_bel_name->second;
+ packed->attrs[id_BEL_PAD_INPUT] = packagepin_bel_name->second;
// Disconnect PACKAGEPIN (it's a physical HW link)
for (auto user : pad_packagepin_net->users)
@@ -1522,7 +1511,7 @@ void pack_plls(Context *ctx)
// In practice, this means the LOCK signal can only directly reach LUT
// inputs.
// If we have a net connected to LOCK, make sure it only drives LUTs.
- auto port = packed->ports[ctx->id("LOCK")];
+ auto port = packed->ports[id_LOCK];
if (port.net != nullptr) {
log_info(" PLL '%s' has LOCK output, need to pass all outputs via LUT\n", ci->name.c_str(ctx));
bool found_lut = false;
@@ -1531,8 +1520,8 @@ void pack_plls(Context *ctx)
unsigned int lut_count = 0;
for (const auto &user : port.net->users) {
NPNR_ASSERT(user.cell != nullptr);
- if (user.cell->type == ctx->id("ICESTORM_LC")) {
- if (bool_or_default(user.cell->params, ctx->id("CARRY_ENABLE"), false)) {
+ if (user.cell->type == id_ICESTORM_LC) {
+ if (bool_or_default(user.cell->params, id_CARRY_ENABLE, false)) {
found_carry = true;
all_luts = false;
} else {
@@ -1569,14 +1558,14 @@ void pack_plls(Context *ctx)
int z = 0;
for (const auto &user : port.net->users) {
NPNR_ASSERT(user.cell != nullptr);
- NPNR_ASSERT(user.cell->type == ctx->id("ICESTORM_LC"));
+ NPNR_ASSERT(user.cell->type == id_ICESTORM_LC);
// TODO(q3k): handle when the Bel might be already the
// target of another constraint.
NPNR_ASSERT(z < 8);
auto target_bel = ctx->getBelByLocation(Loc(x, y, z++));
auto target_bel_name = ctx->getBelName(target_bel).str(ctx);
- user.cell->attrs[ctx->id("BEL")] = target_bel_name;
+ user.cell->attrs[id_BEL] = target_bel_name;
log_info(" constrained '%s' to %s\n", user.cell->name.c_str(ctx), target_bel_name.c_str());
}
}
@@ -1586,9 +1575,9 @@ void pack_plls(Context *ctx)
PortInfo &pi = port.second;
bool is_b_port;
- if (pi.name == ctx->id("PLLOUT_A_GLOBAL"))
+ if (pi.name == id_PLLOUT_A_GLOBAL)
is_b_port = false;
- else if (pi.name == ctx->id("PLLOUT_B_GLOBAL"))
+ else if (pi.name == id_PLLOUT_B_GLOBAL)
is_b_port = true;
else
continue;
@@ -1635,13 +1624,13 @@ bool Arch::pack()
place_plls(ctx);
pack_special(ctx);
pack_plls(ctx);
- if (!bool_or_default(ctx->settings, ctx->id("no_promote_globals"), false))
+ if (!bool_or_default(ctx->settings, id_no_promote_globals, false))
promote_globals(ctx);
ctx->assignArchInfo();
constrain_chains(ctx);
ctx->fixupHierarchy();
ctx->assignArchInfo();
- ctx->settings[ctx->id("pack")] = 1;
+ ctx->settings[id_pack] = 1;
archInfoToAttributes();
log_info("Checksum: 0x%08x\n", ctx->checksum());
return true;
diff --git a/ice40/pcf.cc b/ice40/pcf.cc
index 1003c037..d03820da 100644
--- a/ice40/pcf.cc
+++ b/ice40/pcf.cc
@@ -57,9 +57,9 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
if (setting == "-pullup") {
const auto &value = words.at(++args_end);
if (value == "yes" || value == "1")
- extra_attrs.emplace_back(std::make_pair(ctx->id("PULLUP"), Property::State::S1));
+ extra_attrs.emplace_back(std::make_pair(id_PULLUP, Property::State::S1));
else if (value == "no" || value == "0")
- extra_attrs.emplace_back(std::make_pair(ctx->id("PULLUP"), Property::State::S0));
+ extra_attrs.emplace_back(std::make_pair(id_PULLUP, Property::State::S0));
else
log_error("Invalid value '%s' for -pullup (on line %d)\n", value.c_str(), lineno);
} else if (setting == "-pullup_resistor") {
@@ -68,7 +68,7 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
log_error("Pullup resistance can only be set on UP5K/UP3K (on line %d)\n", lineno);
if (value != "3P3K" && value != "6P8K" && value != "10K" && value != "100K")
log_error("Invalid value '%s' for -pullup_resistor (on line %d)\n", value.c_str(), lineno);
- extra_attrs.emplace_back(std::make_pair(ctx->id("PULLUP_RESISTOR"), value));
+ extra_attrs.emplace_back(std::make_pair(id_PULLUP_RESISTOR, value));
} else if (setting == "-nowarn") {
nowarn = true;
} else if (setting == "--warn-no-port") {
@@ -92,11 +92,11 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
BelId pin_bel = ctx->get_package_pin_bel(pin);
if (pin_bel == BelId())
log_error("package does not have a pin named '%s' (on line %d)\n", pin.c_str(), lineno);
- if (fnd_cell->second->attrs.count(ctx->id("BEL")))
+ if (fnd_cell->second->attrs.count(id_BEL))
log_error("duplicate pin constraint on '%s' (on line %d)\n", cell.c_str(), lineno);
- fnd_cell->second->attrs[ctx->id("BEL")] = ctx->getBelName(pin_bel).str(ctx);
+ fnd_cell->second->attrs[id_BEL] = ctx->getBelName(pin_bel).str(ctx);
log_info("constrained '%s' to bel '%s'\n", cell.c_str(),
- fnd_cell->second->attrs[ctx->id("BEL")].as_string().c_str());
+ fnd_cell->second->attrs[id_BEL].as_string().c_str());
for (const auto &attr : extra_attrs)
fnd_cell->second->attrs[attr.first] = attr.second;
}
@@ -112,8 +112,8 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
CellInfo *ci = cell.second.get();
if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_obuf") ||
ci->type == ctx->id("$nextpnr_iobuf")) {
- if (!ci->attrs.count(ctx->id("BEL"))) {
- if (bool_or_default(ctx->settings, ctx->id("pcf_allow_unconstrained")))
+ if (!ci->attrs.count(id_BEL)) {
+ if (bool_or_default(ctx->settings, id_pcf_allow_unconstrained))
log_warning("IO '%s' is unconstrained in PCF and will be automatically placed\n",
cell.first.c_str(ctx));
else