diff options
| author | David Shah <dave@ds0.me> | 2019-08-01 14:28:21 +0100 | 
|---|---|---|
| committer | David Shah <dave@ds0.me> | 2019-08-05 14:52:15 +0100 | 
| commit | 1839a3a770a71c928b92bf876e04728d2649e425 (patch) | |
| tree | 9de012efabb47f066860918b6360f3966b42f4da /ice40/pack.cc | |
| parent | 1ecf271cb32f9f78ea082788c6534f2523144d01 (diff) | |
| download | nextpnr-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.cc | 60 | 
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; | 
