aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-08-01 14:28:21 +0100
committerDavid Shah <dave@ds0.me>2019-08-05 14:52:15 +0100
commit1839a3a770a71c928b92bf876e04728d2649e425 (patch)
tree9de012efabb47f066860918b6360f3966b42f4da /ice40/pack.cc
parent1ecf271cb32f9f78ea082788c6534f2523144d01 (diff)
downloadnextpnr-1839a3a770a71c928b92bf876e04728d2649e425.tar.gz
nextpnr-1839a3a770a71c928b92bf876e04728d2649e425.tar.bz2
nextpnr-1839a3a770a71c928b92bf876e04728d2649e425.zip
Major Property improvements for common and iCE40
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ice40/pack.cc')
-rw-r--r--ice40/pack.cc60
1 files changed, 31 insertions, 29 deletions
diff --git a/ice40/pack.cc b/ice40/pack.cc
index d1366c9c..462310cd 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -210,7 +210,7 @@ static void pack_carries(Context *ctx)
}
new_cells.push_back(std::move(created_lc));
}
- carry_lc->params[ctx->id("CARRY_ENABLE")] = "1";
+ 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"));
if (i0_net) {
@@ -230,8 +230,9 @@ static void pack_carries(Context *ctx)
if (carry_lc->ports.at(ctx->id("CIN")).net != nullptr) {
IdString cin_net = carry_lc->ports.at(ctx->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")] = "1";
- carry_lc->params[ctx->id("CIN_SET")] = cin_net == ctx->id("$PACKER_VCC_NET") ? "1" : "0";
+ carry_lc->params[ctx->id("CIN_CONST")] = Property::State::S1;
+ carry_lc->params[ctx->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;
auto &cin_users = ctx->nets.at(cin_net)->users;
cin_users.erase(
@@ -270,9 +271,9 @@ static void pack_ram(Context *ctx)
for (auto param : ci->params)
packed->params[param.first] = param.second;
packed->params[ctx->id("NEG_CLK_W")] =
- std::to_string(ci->type == ctx->id("SB_RAM40_4KNW") || ci->type == ctx->id("SB_RAM40_4KNRNW"));
+ Property(ci->type == ctx->id("SB_RAM40_4KNW") || ci->type == ctx->id("SB_RAM40_4KNRNW"), 1);
packed->params[ctx->id("NEG_CLK_R")] =
- std::to_string(ci->type == ctx->id("SB_RAM40_4KNR") || ci->type == ctx->id("SB_RAM40_4KNRNW"));
+ Property(ci->type == ctx->id("SB_RAM40_4KNR") || ci->type == ctx->id("SB_RAM40_4KNRNW"), 1);
packed->type = ctx->id("ICESTORM_RAM");
for (auto port : ci->ports) {
PortInfo &pi = port.second;
@@ -334,7 +335,7 @@ 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")] = "0";
+ gnd_cell->params[ctx->id("LUT_INIT")] = Property(0, 16);
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
gnd_net->name = ctx->id("$PACKER_GND_NET");
gnd_net->driver.cell = gnd_cell.get();
@@ -347,7 +348,7 @@ static void pack_constants(Context *ctx)
}
std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC");
- vcc_cell->params[ctx->id("LUT_INIT")] = "1";
+ vcc_cell->params[ctx->id("LUT_INIT")] = Property(1, 16);
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
vcc_net->name = ctx->id("$PACKER_VCC_NET");
vcc_net->driver.cell = vcc_cell.get();
@@ -417,13 +418,13 @@ 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
- BelId bel = ctx->getBelByName(ctx->id(cell->attrs[ctx->id("BEL")]));
+ BelId bel = ctx->getBelByName(ctx->id(cell->attrs[ctx->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")] = "1";
+ gb->attrs[ctx->id("FOR_PAD_IN")] = Property::State::S1;
gb->attrs[ctx->id("BEL")] = ctx->getBelName(gb_bel).str(ctx);
// Reconnect the net to that port for easier identification it's a global net
@@ -521,7 +522,7 @@ static void pack_io(Context *ctx)
// Make it a normal SB_IO with global marker
ci->type = ctx->id("SB_IO");
- ci->attrs[ctx->id("GLOBAL")] = "1";
+ ci->attrs[ctx->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;
@@ -636,7 +637,7 @@ static void promote_globals(Context *ctx)
/* And possibly limits what we can promote */
if (cell.second->attrs.find(ctx->id("BEL")) != cell.second->attrs.end()) {
/* If the SB_GB is locked, doesn't matter what it drives */
- BelId bel = ctx->getBelByName(ctx->id(cell.second->attrs[ctx->id("BEL")]));
+ BelId bel = ctx->getBelByName(ctx->id(cell.second->attrs[ctx->id("BEL")].as_string()));
int glb_id = ctx->getDrivenGlobalNetwork(bel);
if ((glb_id % 2) == 0)
resets_available--;
@@ -755,10 +756,10 @@ static void place_plls(Context *ctx)
// If it's constrained already, add to already used list
if (ci->attrs.count(ctx->id("BEL"))) {
- BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->id("BEL")]));
+ BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->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")].c_str());
+ ci->attrs[ctx->id("BEL")].as_string().c_str());
pll_used_bels[bel_constrain] = ci;
}
@@ -790,7 +791,7 @@ static void place_plls(Context *ctx)
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->getBelByName(ctx->id(io_cell->attrs.at(ctx->id("BEL"))));
+ BelId io_bel = ctx->getBelByName(ctx->id(io_cell->attrs.at(ctx->id("BEL")).as_string()));
BelId found_bel;
// Find the PLL BEL that would suit that connection
@@ -815,7 +816,7 @@ static void place_plls(Context *ctx)
// Is it user constrained ?
if (ci->attrs.count(ctx->id("BEL"))) {
// Yes. Check it actually matches !
- BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->id("BEL")]));
+ BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->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",
@@ -845,7 +846,7 @@ static void place_plls(Context *ctx)
continue;
// Check all placed PLL (either forced by user, or forced by PACKAGEPIN)
- BelId io_bel = ctx->getBelByName(ctx->id(io_ci->attrs[ctx->id("BEL")]));
+ BelId io_bel = ctx->getBelByName(ctx->id(io_ci->attrs[ctx->id("BEL")].as_string()));
for (auto placed_pll : pll_used_bels) {
BelPin pll_io_a, pll_io_b;
@@ -879,7 +880,7 @@ static void place_plls(Context *ctx)
continue;
// Check all placed PLL (either forced by user, or forced by PACKAGEPIN)
- BelId gb_bel = ctx->getBelByName(ctx->id(gb_ci->attrs[ctx->id("BEL")]));
+ BelId gb_bel = ctx->getBelByName(ctx->id(gb_ci->attrs[ctx->id("BEL")].as_string()));
for (auto placed_pll : pll_used_bels) {
CellInfo *ci = placed_pll.second;
@@ -938,7 +939,7 @@ static void place_plls(Context *ctx)
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->getBelByName(ctx->id(ni->driver.cell->attrs[ctx->id("BEL")]));
+ pad_bel = ctx->getBelByName(ctx->id(ni->driver.cell->attrs[ctx->id("BEL")].as_string()));
// Find a BEL for it
BelId found_bel;
@@ -989,7 +990,7 @@ static std::unique_ptr<CellInfo> spliceLUT(Context *ctx, CellInfo *ci, IdString
// 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")] = "65280"; // output is always I3
+ pt->params[ctx->id("LUT_INIT")] = Property(65280, 16); // output is always I3
// Create LUT output net.
std::unique_ptr<NetInfo> out_net = std::unique_ptr<NetInfo>(new NetInfo);
@@ -1187,10 +1188,11 @@ static void pack_special(Context *ctx)
{std::make_tuple(id_SB_SPI, "0b0010"), Loc(25, 0, 1)},
{std::make_tuple(id_SB_I2C, "0b0011"), Loc(25, 31, 0)},
};
- if (map_ba74.find(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")])) == map_ba74.end())
+ if (map_ba74.find(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")].as_string())) ==
+ 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));
- Loc bel_loc = map_ba74.at(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")]));
+ Loc bel_loc = map_ba74.at(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")].as_string()));
BelId bel = ctx->getBelByLocation(bel_loc);
if (bel == BelId() || ctx->getBelType(bel) != ci->type)
log_error("Unable to find placement for cell '%s' of type '%s'\n", ci->name.c_str(ctx),
@@ -1230,12 +1232,12 @@ static void pack_special(Context *ctx)
};
for (auto param : ci->params)
if (pos_map_name.find(param.first) != pos_map_name.end()) {
- if (pos_map_val.find(param.second) == pos_map_val.end())
- log_error("Invalid PLL output selection '%s'\n", param.second.c_str());
- packed->params[pos_map_name.at(param.first)] = std::to_string(pos_map_val.at(param.second));
+ if (pos_map_val.find(param.second.as_string()) == pos_map_val.end())
+ log_error("Invalid PLL output selection '%s'\n", param.second.as_string().c_str());
+ packed->params[pos_map_name.at(param.first)] = pos_map_val.at(param.second.as_string());
}
- auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")];
+ auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")].as_string();
std::string fbp_value =
feedback_path == "DELAY"
? "0"
@@ -1247,8 +1249,8 @@ static void pack_special(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")] = fbp_value;
- packed->params[ctx->id("PLLTYPE")] = std::to_string(sb_pll40_type(ctx, ci));
+ packed->params[ctx->id("FEEDBACK_PATH")] = Property(std::stoi(fbp_value), 3);
+ packed->params[ctx->id("PLLTYPE")] = sb_pll40_type(ctx, ci);
NetInfo *pad_packagepin_net = nullptr;
@@ -1304,7 +1306,7 @@ static void pack_special(Context *ctx)
}
// PLL must have been placed already in place_plls()
- BelId pll_bel = ctx->getBelByName(ctx->id(packed->attrs[ctx->id("BEL")]));
+ BelId pll_bel = ctx->getBelByName(ctx->id(packed->attrs[ctx->id("BEL")].as_string()));
NPNR_ASSERT(pll_bel != BelId());
// Deal with PAD PLL peculiarities
@@ -1448,7 +1450,7 @@ bool Arch::pack()
ctx->assignArchInfo();
constrain_chains(ctx);
ctx->assignArchInfo();
- ctx->settings[ctx->id("pack")] = "1";
+ ctx->settings[ctx->id("pack")] = 1;
archInfoToAttributes();
log_info("Checksum: 0x%08x\n", ctx->checksum());
return true;