From db890d3a81bfe6760e9f4ea981798269abb60a20 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 25 Jun 2018 21:33:48 +0200 Subject: nets and cells are unique_ptr's --- common/design_utils.cc | 4 +- common/nextpnr.cc | 2 +- common/nextpnr.h | 11 ++--- common/place_sa.cc | 22 ++++----- common/route.cc | 8 +-- common/rulecheck.cc | 8 +-- common/timing.cc | 8 +-- common/util.h | 7 ++- ice40/arch_place.cc | 6 +-- ice40/bitstream.cc | 34 ++++++------- ice40/cells.cc | 92 +++++++++++++++++----------------- ice40/cells.h | 2 +- ice40/pack.cc | 132 ++++++++++++++++++++++++------------------------- json/jsonparse.cc | 84 +++++++++++++++---------------- 14 files changed, 207 insertions(+), 213 deletions(-) diff --git a/common/design_utils.cc b/common/design_utils.cc index 640a18a2..74310ab4 100644 --- a/common/design_utils.cc +++ b/common/design_utils.cc @@ -56,8 +56,8 @@ void print_utilisation(const Context *ctx) { // Sort by Bel type std::map used_types; - for (auto cell : ctx->cells) { - used_types[ctx->belTypeFromId(cell.second->type)]++; + for (auto& cell : ctx->cells) { + used_types[ctx->belTypeFromId(cell.second.get()->type)]++; } std::map available_types; for (auto bel : ctx->getBels()) { diff --git a/common/nextpnr.cc b/common/nextpnr.cc index 2dc3bacb..a7a3268e 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -163,7 +163,7 @@ uint32_t Context::checksum() const void Context::check() const { for (auto &n : nets) { - auto ni = n.second; + auto ni = n.second.get(); assert(n.first == ni->name); for (auto &w : ni->wires) { assert(n.first == getBoundWireNet(w.first)); diff --git a/common/nextpnr.h b/common/nextpnr.h index 71a52758..af1ed733 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -24,6 +24,7 @@ #include #include #include +#include #ifndef NEXTPNR_H #define NEXTPNR_H @@ -194,8 +195,8 @@ struct BaseCtx // -------------------------------------------------------------- - std::unordered_map nets; - std::unordered_map cells; + std::unordered_map> nets; + std::unordered_map> cells; BaseCtx() { @@ -210,12 +211,6 @@ struct BaseCtx ~BaseCtx() { - for (auto &item : nets) { - delete item.second; - } - for (auto &item : cells) { - delete item.second; - } delete idstring_str_to_idx; delete idstring_idx_to_str; } diff --git a/common/place_sa.cc b/common/place_sa.cc index 55496f07..56d92633 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -79,8 +79,8 @@ class SAPlacer size_t placed_cells = 0; // Initial constraints placer - for (auto cell_entry : ctx->cells) { - CellInfo *cell = cell_entry.second; + for (auto& cell_entry : ctx->cells) { + CellInfo *cell = cell_entry.second.get(); auto loc = cell->attrs.find(ctx->id("BEL")); if (loc != cell->attrs.end()) { std::string loc_name = loc->second; @@ -109,10 +109,10 @@ class SAPlacer // Sort to-place cells for deterministic initial placement std::vector autoplaced; - for (auto cell : ctx->cells) { - CellInfo *ci = cell.second; + for (auto& cell : ctx->cells) { + CellInfo *ci = cell.second.get(); if (ci->bel == BelId()) { - autoplaced.push_back(cell.second); + autoplaced.push_back(cell.second.get()); } } std::sort(autoplaced.begin(), autoplaced.end(), [](CellInfo *a, CellInfo *b) { return a->name < b->name; }); @@ -137,8 +137,8 @@ class SAPlacer // Calculate wirelength after initial placement curr_wirelength = 0; curr_tns = 0; - for (auto net : ctx->nets) { - wirelen_t wl = get_wirelength(net.second, curr_tns); + for (auto& net : ctx->nets) { + wirelen_t wl = get_wirelength(net.second.get(), curr_tns); wirelengths[net.first] = wl; curr_wirelength += wl; } @@ -211,8 +211,8 @@ class SAPlacer // accumulating over time curr_wirelength = 0; curr_tns = 0; - for (auto net : ctx->nets) { - wirelen_t wl = get_wirelength(net.second, curr_tns); + for (auto& net : ctx->nets) { + wirelen_t wl = get_wirelength(net.second.get(), curr_tns); wirelengths[net.first] = wl; curr_wirelength += wl; } @@ -266,7 +266,7 @@ class SAPlacer uint64_t score = ctx->rng64(); if (score <= best_ripup_score) { best_ripup_score = score; - ripup_target = ctx->cells.at(ctx->getBoundBelCell(bel)); + ripup_target = ctx->cells.at(ctx->getBoundBelCell(bel)).get(); ripup_bel = bel; } } @@ -354,7 +354,7 @@ class SAPlacer wirelen_t new_wirelength = 0, delta; ctx->unbindBel(oldBel); if (other != IdString()) { - other_cell = ctx->cells[other]; + other_cell = ctx->cells[other].get(); ctx->unbindBel(newBel); } diff --git a/common/route.cc b/common/route.cc index a7f8f53f..60965f84 100644 --- a/common/route.cc +++ b/common/route.cc @@ -75,7 +75,7 @@ struct RipupScoreboard void ripup_net(Context *ctx, IdString net_name) { - auto net_info = ctx->nets.at(net_name); + auto net_info = ctx->nets.at(net_name).get(); std::vector pips; std::vector wires; @@ -249,7 +249,7 @@ struct Router Router(Context *ctx, RipupScoreboard &scores, IdString net_name, bool ripup = false, delay_t ripup_penalty = 0) : ctx(ctx), scores(scores), net_name(net_name), ripup(ripup), ripup_penalty(ripup_penalty) { - auto net_info = ctx->nets.at(net_name); + auto net_info = ctx->nets.at(net_name).get(); if (ctx->debug) log("Routing net %s.\n", net_name.c_str(ctx)); @@ -416,7 +416,7 @@ bool route_design(Context *ctx) for (auto &net_it : ctx->nets) { auto net_name = net_it.first; - auto net_info = net_it.second; + auto net_info = net_it.second.get(); if (net_info->driver.cell == nullptr) continue; @@ -438,7 +438,7 @@ bool route_design(Context *ctx) int estimatedTotalDelayCnt = 0; for (auto net_name : netsQueue) { - auto net_info = ctx->nets.at(net_name); + auto net_info = ctx->nets.at(net_name).get(); auto src_bel = net_info->driver.cell->bel; diff --git a/common/rulecheck.cc b/common/rulecheck.cc index c27d33ea..d406178a 100644 --- a/common/rulecheck.cc +++ b/common/rulecheck.cc @@ -11,8 +11,8 @@ bool check_all_nets_driven(Context *ctx) log_info("Rule checker, Verifying pre-placed design\n"); - for (auto cell_entry : ctx->cells) { - CellInfo *cell = cell_entry.second; + for (auto& cell_entry : ctx->cells) { + CellInfo *cell = cell_entry.second.get(); if (debug) log_info(" Examining cell \'%s\', of type \'%s\'\n", cell->name.c_str(ctx), cell->type.c_str(ctx)); @@ -39,8 +39,8 @@ bool check_all_nets_driven(Context *ctx) } } - for (auto net_entry : ctx->nets) { - NetInfo *net = net_entry.second; + for (auto& net_entry : ctx->nets) { + NetInfo *net = net_entry.second.get(); assert(net->name == net_entry.first); if ((net->driver.cell != NULL) && (net->driver.cell->type != ctx->id("GND")) && diff --git a/common/timing.cc b/common/timing.cc index 0684c543..5b929c4c 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -76,16 +76,16 @@ void assign_budget(Context *ctx, float default_clock) log_info("Annotating ports with timing budgets\n"); // Clear delays to a very high value first delay_t default_slack = delay_t(1.0e12 / default_clock); - for (auto net : ctx->nets) { + for (auto& net : ctx->nets) { for (auto &usr : net.second->users) { usr.budget = default_slack; } } // Go through all clocked drivers and set up paths - for (auto cell : ctx->cells) { + for (auto& cell : ctx->cells) { for (auto port : cell.second->ports) { if (port.second.type == PORT_OUT) { - IdString clock_domain = ctx->getPortClock(cell.second, port.first); + IdString clock_domain = ctx->getPortClock(cell.second.get(), port.first); if (clock_domain != IdString()) { delay_t slack = delay_t(1.0e12 / default_clock); // TODO: clock constraints if (port.second.net) @@ -96,7 +96,7 @@ void assign_budget(Context *ctx, float default_clock) } // Post-allocation check - for (auto net : ctx->nets) { + for (auto& net : ctx->nets) { for (auto user : net.second->users) { if (user.budget < 0) log_warning("port %s.%s, connected to net '%s', has negative " diff --git a/common/util.h b/common/util.h index 5e938635..b1cab650 100644 --- a/common/util.h +++ b/common/util.h @@ -57,9 +57,12 @@ bool bool_or_default(const Container &ct, const KeyType &key, bool def = false) }; // Wrap an unordered_map, and allow it to be iterated over sorted by key -template std::map sorted(const std::unordered_map &orig) +template std::map sorted(const std::unordered_map> &orig) { - return std::map(orig.begin(), orig.end()); + std::map retVal; + for(auto& item : orig) + retVal.emplace(std::make_pair(item.first,item.second.get())); + return retVal; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 129ebe18..4160a644 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -91,7 +91,7 @@ bool Arch::isBelLocationValid(BelId bel) const for (auto bel_other : getBelsAtSameTile(bel)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString()) { - const CellInfo *ci_other = cells.at(cell_other); + const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } @@ -101,7 +101,7 @@ bool Arch::isBelLocationValid(BelId bel) const if (cellId == IdString()) return true; else - return isValidBelForCell(cells.at(cellId), bel); + return isValidBelForCell(cells.at(cellId).get(), bel); } } @@ -115,7 +115,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const for (auto bel_other : getBelsAtSameTile(bel)) { IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString() && bel_other != bel) { - const CellInfo *ci_other = cells.at(cell_other); + const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 0e387c72..609741fe 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -140,8 +140,8 @@ void write_asc(const Context *ctx, std::ostream &out) } } // Set logic cell config - for (auto cell : ctx->cells) { - BelId bel = cell.second->bel; + for (auto& cell : ctx->cells) { + BelId bel = cell.second.get()->bel; if (bel == BelId()) { std::cout << "Found unplaced cell " << cell.first.str(ctx) << " while generating bitstream!" << std::endl; continue; @@ -150,12 +150,12 @@ void write_asc(const Context *ctx, std::ostream &out) int x = beli.x, y = beli.y, z = beli.z; if (cell.second->type == ctx->id("ICESTORM_LC")) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC]; - unsigned lut_init = get_param_or_def(cell.second, ctx->id("LUT_INIT")); - bool neg_clk = get_param_or_def(cell.second, ctx->id("NEG_CLK")); - bool dff_enable = get_param_or_def(cell.second, ctx->id("DFF_ENABLE")); - bool async_sr = get_param_or_def(cell.second, ctx->id("ASYNC_SR")); - bool set_noreset = get_param_or_def(cell.second, ctx->id("SET_NORESET")); - bool carry_enable = get_param_or_def(cell.second, ctx->id("CARRY_ENABLE")); + unsigned lut_init = get_param_or_def(cell.second.get(), ctx->id("LUT_INIT")); + bool neg_clk = get_param_or_def(cell.second.get(), ctx->id("NEG_CLK")); + bool dff_enable = get_param_or_def(cell.second.get(), ctx->id("DFF_ENABLE")); + bool async_sr = get_param_or_def(cell.second.get(), ctx->id("ASYNC_SR")); + bool set_noreset = get_param_or_def(cell.second.get(), ctx->id("SET_NORESET")); + bool carry_enable = get_param_or_def(cell.second.get(), ctx->id("CARRY_ENABLE")); std::vector lc(20, false); // From arachne-pnr static std::vector lut_perm = { @@ -176,9 +176,9 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(y).at(x), "NegClk", neg_clk); } else if (cell.second->type == ctx->id("SB_IO")) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; - unsigned pin_type = get_param_or_def(cell.second, ctx->id("PIN_TYPE")); - bool neg_trigger = get_param_or_def(cell.second, ctx->id("NEG_TRIGGER")); - bool pullup = get_param_or_def(cell.second, ctx->id("PULLUP")); + unsigned pin_type = get_param_or_def(cell.second.get(), ctx->id("PIN_TYPE")); + bool neg_trigger = get_param_or_def(cell.second.get(), ctx->id("NEG_TRIGGER")); + bool pullup = get_param_or_def(cell.second.get(), ctx->id("PULLUP")); for (int i = 0; i < 6; i++) { bool val = (pin_type >> i) & 0x01; set_config(ti, config.at(y).at(x), "IOB_" + std::to_string(z) + ".PINTYPE_" + std::to_string(i), val); @@ -220,10 +220,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(cell.second, ctx->id("NEG_CLK_R")); - bool negclk_w = get_param_or_def(cell.second, ctx->id("NEG_CLK_W")); - int write_mode = get_param_or_def(cell.second, ctx->id("WRITE_MODE")); - int read_mode = get_param_or_def(cell.second, ctx->id("READ_MODE")); + bool negclk_r = get_param_or_def(cell.second.get(), ctx->id("NEG_CLK_R")); + bool negclk_w = get_param_or_def(cell.second.get(), ctx->id("NEG_CLK_W")); + int write_mode = get_param_or_def(cell.second.get(), ctx->id("WRITE_MODE")); + int read_mode = get_param_or_def(cell.second.get(), ctx->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); @@ -371,7 +371,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Write RAM init data - for (auto cell : ctx->cells) { + for (auto& cell : ctx->cells) { if (cell.second->bel != BelId()) { if (cell.second->type == ctx->id("ICESTORM_RAM")) { const BelInfoPOD &beli = ci.bel_data[cell.second->bel.index]; @@ -380,7 +380,7 @@ void write_asc(const Context *ctx, std::ostream &out) for (int w = 0; w < 16; w++) { std::vector bits(256); std::string init = - get_param_str_or_def(cell.second, ctx->id(std::string("INIT_") + get_hexdigit(w))); + get_param_str_or_def(cell.second.get(), ctx->id(std::string("INIT_") + get_hexdigit(w))); assert(init != ""); for (size_t i = 0; i < init.size(); i++) { bool val = (init.at((init.size() - 1) - i) == '1'); diff --git a/ice40/cells.cc b/ice40/cells.cc index e9c75649..4ca579f6 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -30,10 +30,10 @@ void add_port(const Context *ctx, CellInfo *cell, std::string name, PortType dir cell->ports[id] = PortInfo{id, nullptr, dir}; } -CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name) +std::unique_ptr create_ice_cell(Context *ctx, IdString type, std::string name) { static int auto_idx = 0; - CellInfo *new_cell = new CellInfo(); + std::unique_ptr new_cell = std::unique_ptr(new CellInfo()); if (name.empty()) { new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++)); } else { @@ -50,84 +50,84 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name) new_cell->params[ctx->id("CIN_CONST")] = "0"; new_cell->params[ctx->id("CIN_SET")] = "0"; - add_port(ctx, new_cell, "I0", PORT_IN); - add_port(ctx, new_cell, "I1", PORT_IN); - add_port(ctx, new_cell, "I2", PORT_IN); - add_port(ctx, new_cell, "I3", PORT_IN); - add_port(ctx, new_cell, "CIN", PORT_IN); + add_port(ctx, new_cell.get(), "I0", PORT_IN); + add_port(ctx, new_cell.get(), "I1", PORT_IN); + add_port(ctx, new_cell.get(), "I2", PORT_IN); + add_port(ctx, new_cell.get(), "I3", PORT_IN); + add_port(ctx, new_cell.get(), "CIN", PORT_IN); - add_port(ctx, new_cell, "CLK", PORT_IN); - add_port(ctx, new_cell, "CEN", PORT_IN); - add_port(ctx, new_cell, "SR", PORT_IN); + add_port(ctx, new_cell.get(), "CLK", PORT_IN); + add_port(ctx, new_cell.get(), "CEN", PORT_IN); + add_port(ctx, new_cell.get(), "SR", PORT_IN); - add_port(ctx, new_cell, "LO", PORT_OUT); - add_port(ctx, new_cell, "O", PORT_OUT); - add_port(ctx, new_cell, "OUT", PORT_OUT); + add_port(ctx, new_cell.get(), "LO", PORT_OUT); + add_port(ctx, new_cell.get(), "O", PORT_OUT); + add_port(ctx, new_cell.get(), "OUT", PORT_OUT); } else if (type == ctx->id("SB_IO")) { new_cell->params[ctx->id("PIN_TYPE")] = "0"; new_cell->params[ctx->id("PULLUP")] = "0"; new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; new_cell->params[ctx->id("IOSTANDARD")] = "SB_LVCMOS"; - add_port(ctx, new_cell, "PACKAGE_PIN", PORT_INOUT); + add_port(ctx, new_cell.get(), "PACKAGE_PIN", PORT_INOUT); - add_port(ctx, new_cell, "LATCH_INPUT_VALUE", PORT_IN); - add_port(ctx, new_cell, "CLOCK_ENABLE", PORT_IN); - add_port(ctx, new_cell, "INPUT_CLK", PORT_IN); - add_port(ctx, new_cell, "OUTPUT_CLK", PORT_IN); + add_port(ctx, new_cell.get(), "LATCH_INPUT_VALUE", PORT_IN); + add_port(ctx, new_cell.get(), "CLOCK_ENABLE", PORT_IN); + add_port(ctx, new_cell.get(), "INPUT_CLK", PORT_IN); + add_port(ctx, new_cell.get(), "OUTPUT_CLK", PORT_IN); - add_port(ctx, new_cell, "OUTPUT_ENABLE", PORT_IN); - add_port(ctx, new_cell, "D_OUT_0", PORT_IN); - add_port(ctx, new_cell, "D_OUT_1", PORT_IN); + add_port(ctx, new_cell.get(), "OUTPUT_ENABLE", PORT_IN); + add_port(ctx, new_cell.get(), "D_OUT_0", PORT_IN); + add_port(ctx, new_cell.get(), "D_OUT_1", PORT_IN); - add_port(ctx, new_cell, "D_IN_0", PORT_OUT); - add_port(ctx, new_cell, "D_IN_1", PORT_OUT); + add_port(ctx, new_cell.get(), "D_IN_0", PORT_OUT); + add_port(ctx, new_cell.get(), "D_IN_1", PORT_OUT); } else if (type == ctx->id("ICESTORM_RAM")) { new_cell->params[ctx->id("NEG_CLK_W")] = "0"; new_cell->params[ctx->id("NEG_CLK_R")] = "0"; new_cell->params[ctx->id("WRITE_MODE")] = "0"; new_cell->params[ctx->id("READ_MODE")] = "0"; - add_port(ctx, new_cell, "RCLK", PORT_IN); - add_port(ctx, new_cell, "RCLKE", PORT_IN); - add_port(ctx, new_cell, "RE", PORT_IN); + add_port(ctx, new_cell.get(), "RCLK", PORT_IN); + add_port(ctx, new_cell.get(), "RCLKE", PORT_IN); + add_port(ctx, new_cell.get(), "RE", PORT_IN); - add_port(ctx, new_cell, "WCLK", PORT_IN); - add_port(ctx, new_cell, "WCLKE", PORT_IN); - add_port(ctx, new_cell, "WE", PORT_IN); + add_port(ctx, new_cell.get(), "WCLK", PORT_IN); + add_port(ctx, new_cell.get(), "WCLKE", PORT_IN); + add_port(ctx, new_cell.get(), "WE", PORT_IN); for (int i = 0; i < 16; i++) { - add_port(ctx, new_cell, "WDATA_" + std::to_string(i), PORT_IN); - add_port(ctx, new_cell, "MASK_" + std::to_string(i), PORT_IN); - add_port(ctx, new_cell, "RDATA_" + std::to_string(i), PORT_OUT); + add_port(ctx, new_cell.get(), "WDATA_" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "MASK_" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "RDATA_" + std::to_string(i), PORT_OUT); } for (int i = 0; i < 11; i++) { - add_port(ctx, new_cell, "RADDR_" + std::to_string(i), PORT_IN); - add_port(ctx, new_cell, "WADDR_" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "RADDR_" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "WADDR_" + std::to_string(i), PORT_IN); } } else if (type == ctx->id("ICESTORM_LFOSC")) { - add_port(ctx, new_cell, "CLKLFEN", PORT_IN); - add_port(ctx, new_cell, "CLKLFPU", PORT_IN); - add_port(ctx, new_cell, "CLKLF", PORT_OUT); - add_port(ctx, new_cell, "CLKLF_FABRIC", PORT_OUT); + add_port(ctx, new_cell.get(), "CLKLFEN", PORT_IN); + add_port(ctx, new_cell.get(), "CLKLFPU", PORT_IN); + add_port(ctx, new_cell.get(), "CLKLF", PORT_OUT); + add_port(ctx, new_cell.get(), "CLKLF_FABRIC", PORT_OUT); } else if (type == ctx->id("ICESTORM_HFOSC")) { new_cell->params[ctx->id("CLKHF_DIV")] = "0"; new_cell->params[ctx->id("TRIM_EN")] = "0"; - add_port(ctx, new_cell, "CLKHFEN", PORT_IN); - add_port(ctx, new_cell, "CLKHFPU", PORT_IN); - add_port(ctx, new_cell, "CLKHF", PORT_OUT); - add_port(ctx, new_cell, "CLKHF_FABRIC", PORT_OUT); + add_port(ctx, new_cell.get(), "CLKHFEN", PORT_IN); + add_port(ctx, new_cell.get(), "CLKHFPU", PORT_IN); + add_port(ctx, new_cell.get(), "CLKHF", PORT_OUT); + add_port(ctx, new_cell.get(), "CLKHF_FABRIC", PORT_OUT); for (int i = 0; i < 10; i++) - add_port(ctx, new_cell, "TRIM" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "TRIM" + std::to_string(i), PORT_IN); } else if (type == ctx->id("SB_GB")) { - add_port(ctx, new_cell, "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN); - add_port(ctx, new_cell, "GLOBAL_BUFFER_OUTPUT", PORT_OUT); + add_port(ctx, new_cell.get(), "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN); + add_port(ctx, new_cell.get(), "GLOBAL_BUFFER_OUTPUT", PORT_OUT); } else { log_error("unable to create iCE40 cell of type %s", type.c_str(ctx)); } - return new_cell; + return std::move(new_cell); } void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff) diff --git a/ice40/cells.h b/ice40/cells.h index a8891598..eb0007aa 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -27,7 +27,7 @@ NEXTPNR_NAMESPACE_BEGIN // Create a standard iCE40 cell and return it // Name will be automatically assigned if not specified -CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name = ""); +std::unique_ptr 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"); } diff --git a/ice40/pack.cc b/ice40/pack.cc index d0419098..43960d9f 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -34,16 +34,15 @@ static void pack_lut_lutffs(Context *ctx) log_info("Packing LUT-FFs..\n"); std::unordered_set packed_cells; - std::vector new_cells; + std::vector> new_cells; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; 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)) { - CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_LC"); + std::unique_ptr packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_LC"); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin())); packed_cells.insert(ci->name); - new_cells.push_back(packed); if (ctx->verbose) 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 @@ -59,8 +58,8 @@ static void pack_lut_lutffs(Context *ctx) 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 { - lut_to_lc(ctx, ci, packed, false); - dff_to_lc(ctx, dff, packed, false); + lut_to_lc(ctx, ci, packed.get(), false); + dff_to_lc(ctx, dff, packed.get(), false); ctx->nets.erase(o->name); if (dff_bel != dff->attrs.end()) packed->attrs[ctx->id("BEL")] = dff_bel->second; @@ -71,15 +70,16 @@ static void pack_lut_lutffs(Context *ctx) } } if (!packed_dff) { - lut_to_lc(ctx, ci, packed, true); + lut_to_lc(ctx, ci, packed.get(), true); } + new_cells.push_back(std::move(packed)); } } for (auto pcell : packed_cells) { ctx->cells.erase(pcell); } - for (auto ncell : new_cells) { - ctx->cells[ncell->name] = ncell; + for (auto& ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); } } @@ -89,25 +89,25 @@ static void pack_nonlut_ffs(Context *ctx) log_info("Packing non-LUT FFs..\n"); std::unordered_set packed_cells; - std::vector new_cells; + std::vector> new_cells; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_ff(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_DFFLC"); + std::unique_ptr packed = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "_DFFLC"); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin())); if (ctx->verbose) log_info("packed cell %s into %s\n", ci->name.c_str(ctx), packed->name.c_str(ctx)); packed_cells.insert(ci->name); - new_cells.push_back(packed); - dff_to_lc(ctx, ci, packed, true); + dff_to_lc(ctx, ci, packed.get(), true); + new_cells.push_back(std::move(packed)); } } for (auto pcell : packed_cells) { ctx->cells.erase(pcell); } - for (auto ncell : new_cells) { - ctx->cells[ncell->name] = ncell; + for (auto& ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); } } @@ -122,7 +122,7 @@ static void pack_carries(Context *ctx) CellInfo *ci = cell.second; if (is_carry(ctx, ci)) { packed_cells.insert(cell.first); - CellInfo *carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, ctx->id("I3"), false); + CellInfo * carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, ctx->id("I3"), false); if (!ci->ports.at(ctx->id("I0")).net) log_error("SB_CARRY '%s' has disconnected port I0\n", cell.first.c_str(ctx)); if (!ci->ports.at(ctx->id("I1")).net) @@ -156,7 +156,7 @@ static void pack_carries(Context *ctx) log_error("SB_CARRY '%s' cannot be packed into any logic " "cell (no logic cell connects to both I0 and I1)\n", cell.first.c_str(ctx)); - carry_lc = ctx->cells.at(*carry_lcs.begin()); + carry_lc = ctx->cells.at(*carry_lcs.begin()).get(); } carry_lc->attrs[ctx->id("CARRY_ENABLE")] = "1"; replace_port(ci, ctx->id("CI"), carry_lc, ctx->id("CIN")); @@ -182,14 +182,13 @@ static void pack_ram(Context *ctx) log_info("Packing RAMs..\n"); std::unordered_set packed_cells; - std::vector new_cells; + std::vector> new_cells; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_ram(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_RAM"), ci->name.str(ctx) + "_RAM"); + std::unique_ptr packed = create_ice_cell(ctx, ctx->id("ICESTORM_RAM"), ci->name.str(ctx) + "_RAM"); packed_cells.insert(ci->name); - new_cells.push_back(packed); for (auto param : ci->params) packed->params[param.first] = param.second; packed->params[ctx->id("NEG_CLK_W")] = @@ -204,16 +203,17 @@ static void pack_ram(Context *ctx) if (bpos != std::string::npos) { newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2); } - replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed, ctx->id(newname)); + replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed.get(), ctx->id(newname)); } + new_cells.push_back(std::move(packed)); } } for (auto pcell : packed_cells) { ctx->cells.erase(pcell); } - for (auto ncell : new_cells) { - ctx->cells[ncell->name] = ncell; + for (auto& ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); } } @@ -242,18 +242,18 @@ static void pack_constants(Context *ctx) { log_info("Packing constants..\n"); - CellInfo *gnd_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); + std::unique_ptr gnd_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_GND"); gnd_cell->params[ctx->id("LUT_INIT")] = "0"; - NetInfo *gnd_net = new NetInfo; + std::unique_ptr gnd_net = std::unique_ptr(new NetInfo); gnd_net->name = ctx->id("$PACKER_GND_NET"); - gnd_net->driver.cell = gnd_cell; + gnd_net->driver.cell = gnd_cell.get(); gnd_net->driver.port = ctx->id("O"); - CellInfo *vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); + std::unique_ptr vcc_cell = create_ice_cell(ctx, ctx->id("ICESTORM_LC"), "$PACKER_VCC"); vcc_cell->params[ctx->id("LUT_INIT")] = "1"; - NetInfo *vcc_net = new NetInfo; + std::unique_ptr vcc_net = std::unique_ptr(new NetInfo); vcc_net->name = ctx->id("$PACKER_VCC_NET"); - vcc_net->driver.cell = vcc_cell; + vcc_net->driver.cell = vcc_cell.get(); vcc_net->driver.port = ctx->id("O"); std::vector dead_nets; @@ -264,29 +264,26 @@ static void pack_constants(Context *ctx) NetInfo *ni = net.second; if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) { IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, gnd_net, false); + set_net_constant(ctx, ni, gnd_net.get(), 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")) { IdString drv_cell = ni->driver.cell->name; - set_net_constant(ctx, ni, vcc_net, true); + set_net_constant(ctx, ni, vcc_net.get(), true); dead_nets.push_back(net.first); ctx->cells.erase(drv_cell); } } if (gnd_used) { - ctx->cells[gnd_cell->name] = gnd_cell; - ctx->nets[gnd_net->name] = gnd_net; - } else { - delete gnd_net; - delete gnd_cell; + ctx->cells[gnd_cell->name] = std::move(gnd_cell); + ctx->nets[gnd_net->name] = std::move(gnd_net); } // Vcc cell always inserted for now, as it may be needed during carry legalisation (TODO: trim later if actually // never used?) - ctx->cells[vcc_cell->name] = vcc_cell; - ctx->nets[vcc_net->name] = vcc_net; + ctx->cells[vcc_cell->name] = std::move(vcc_cell); + ctx->nets[vcc_net->name] = std::move(vcc_net); for (auto dn : dead_nets) { ctx->nets.erase(dn); @@ -303,7 +300,7 @@ static bool is_nextpnr_iob(Context *ctx, CellInfo *cell) static void pack_io(Context *ctx) { std::unordered_set packed_cells; - std::vector new_cells; + std::vector> new_cells; log_info("Packing IOs..\n"); @@ -329,9 +326,10 @@ static void pack_io(Context *ctx) } } else { // Create a SB_IO buffer - sb = create_ice_cell(ctx, ctx->id("SB_IO"), ci->name.str(ctx) + "$sb_io"); - nxio_to_sb(ctx, ci, sb); - new_cells.push_back(sb); + std::unique_ptr ice_cell = create_ice_cell(ctx, ctx->id("SB_IO"), ci->name.str(ctx) + "$sb_io"); + nxio_to_sb(ctx, ci, ice_cell.get()); + new_cells.push_back(std::move(ice_cell)); + sb = new_cells.back().get(); } packed_cells.insert(ci->name); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(sb->attrs, sb->attrs.begin())); @@ -340,40 +338,40 @@ static void pack_io(Context *ctx) for (auto pcell : packed_cells) { ctx->cells.erase(pcell); } - for (auto ncell : new_cells) { - ctx->cells[ncell->name] = ncell; + for (auto& ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); } } static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen) { std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk")); - CellInfo *gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name); + std::unique_ptr gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name); gb->ports[ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER")].net = net; PortRef pr; - pr.cell = gb; + pr.cell = gb.get(); pr.port = ctx->id("USER_SIGNAL_TO_GLOBAL_BUFFER"); net->users.push_back(pr); - pr.cell = gb; + pr.cell = gb.get(); pr.port = ctx->id("GLOBAL_BUFFER_OUTPUT"); - NetInfo *glbnet = new NetInfo(); + std::unique_ptr glbnet = std::unique_ptr(new NetInfo()); glbnet->name = ctx->id(glb_name); - glbnet->driver = pr; - ctx->nets[glbnet->name] = glbnet; - gb->ports[ctx->id("GLOBAL_BUFFER_OUTPUT")].net = glbnet; + glbnet->driver = pr; + gb->ports[ctx->id("GLOBAL_BUFFER_OUTPUT")].net = glbnet.get(); std::vector keep_users; for (auto user : net->users) { if (is_clock_port(ctx, user) || (is_reset && is_reset_port(ctx, user)) || (is_cen && is_enable_port(ctx, user))) { - user.cell->ports[user.port].net = glbnet; + user.cell->ports[user.port].net = glbnet.get(); glbnet->users.push_back(user); } else { keep_users.push_back(user); } } net->users = keep_users; - ctx->cells[gb->name] = gb; + ctx->nets[glbnet->name] = std::move(glbnet); + ctx->cells[gb->name] = std::move(gb); } // Simple global promoter (clock only) @@ -401,8 +399,8 @@ static void promote_globals(Context *ctx) } int prom_globals = 0, prom_resets = 0, prom_cens = 0; int gbs_available = 8; - for (auto cell : ctx->cells) - if (is_gbuf(ctx, cell.second)) + for (auto& cell : ctx->cells) + if (is_gbuf(ctx, cell.second.get())) --gbs_available; while (prom_globals < gbs_available) { auto global_clock = std::max_element(clock_count.begin(), clock_count.end(), @@ -419,7 +417,7 @@ static void promote_globals(Context *ctx) return a.second < b.second; }); if (global_reset->second > global_clock->second && prom_resets < 4) { - NetInfo *rstnet = ctx->nets[global_reset->first]; + NetInfo *rstnet = ctx->nets[global_reset->first].get(); insert_global(ctx, rstnet, true, false); ++prom_globals; ++prom_resets; @@ -427,7 +425,7 @@ static void promote_globals(Context *ctx) reset_count.erase(rstnet->name); cen_count.erase(rstnet->name); } else if (global_cen->second > global_clock->second && prom_cens < 4) { - NetInfo *cennet = ctx->nets[global_cen->first]; + NetInfo *cennet = ctx->nets[global_cen->first].get(); insert_global(ctx, cennet, false, true); ++prom_globals; ++prom_cens; @@ -435,7 +433,7 @@ static void promote_globals(Context *ctx) reset_count.erase(cennet->name); cen_count.erase(cennet->name); } else if (global_clock->second != 0) { - NetInfo *clknet = ctx->nets[global_clock->first]; + NetInfo *clknet = ctx->nets[global_clock->first].get(); insert_global(ctx, clknet, false, false); ++prom_globals; clock_count.erase(clknet->name); @@ -453,29 +451,29 @@ static void pack_intosc(Context *ctx) log_info("Packing oscillators..\n"); std::unordered_set packed_cells; - std::vector new_cells; + std::vector> new_cells; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_sb_lfosc(ctx, ci)) { - CellInfo *packed = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"), ci->name.str(ctx) + "_OSC"); - packed_cells.insert(ci->name); - new_cells.push_back(packed); - replace_port(ci, ctx->id("CLKLFEN"), packed, ctx->id("CLKLFEN")); - replace_port(ci, ctx->id("CLKLFPU"), packed, ctx->id("CLKLFPU")); + std::unique_ptr packed = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"), ci->name.str(ctx) + "_OSC"); + packed_cells.insert(ci->name); + 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, ctx->id("CLKLF_FABRIC")); + replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF_FABRIC")); } else { - replace_port(ci, ctx->id("CLKLF"), packed, ctx->id("CLKLF")); + replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF")); } + new_cells.push_back(std::move(packed)); } } for (auto pcell : packed_cells) { ctx->cells.erase(pcell); } - for (auto ncell : new_cells) { - ctx->cells[ncell->name] = ncell; + for (auto& ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); } } diff --git a/json/jsonparse.cc b/json/jsonparse.cc index 824ce15e..36c4f91b 100644 --- a/json/jsonparse.cc +++ b/json/jsonparse.cc @@ -216,9 +216,9 @@ struct JsonNode } }; -NetInfo *ground_net(Context *ctx, NetInfo *net) +void ground_net(Context *ctx, NetInfo *net) { - CellInfo *cell = new CellInfo; + std::unique_ptr cell = std::unique_ptr(new CellInfo); PortInfo port_info; PortRef port_ref; @@ -229,20 +229,19 @@ NetInfo *ground_net(Context *ctx, NetInfo *net) port_info.net = net; port_info.type = PORT_OUT; - port_ref.cell = cell; + port_ref.cell = cell.get(); port_ref.port = port_info.name; net->driver = port_ref; cell->ports[port_info.name] = port_info; - ctx->cells[cell->name] = cell; - return net; + ctx->cells[cell->name] = std::move(cell); } -NetInfo *vcc_net(Context *ctx, NetInfo *net) +void vcc_net(Context *ctx, NetInfo *net) { - CellInfo *cell = new CellInfo; + std::unique_ptr cell = std::unique_ptr(new CellInfo); PortInfo port_info; PortRef port_ref; @@ -253,18 +252,17 @@ NetInfo *vcc_net(Context *ctx, NetInfo *net) port_info.net = net; port_info.type = PORT_OUT; - port_ref.cell = cell; + port_ref.cell = cell.get(); port_ref.port = port_info.name; net->driver = port_ref; cell->ports[port_info.name] = port_info; - ctx->cells[cell->name] = cell; - return net; + ctx->cells[cell->name] = std::move(cell); } -NetInfo *floating_net(Context *ctx, NetInfo *net) +void floating_net(Context *ctx, NetInfo *net) { PortInfo port_info; PortRef port_ref; @@ -277,8 +275,6 @@ NetInfo *floating_net(Context *ctx, NetInfo *net) port_ref.port = port_info.name; net->driver = port_ref; - - return net; } // @@ -433,17 +429,19 @@ void json_import_ports(Context *ctx, const string &modname, const std::vectorname = net_id; - this_net->driver.cell = NULL; - this_net->driver.port = IdString(); - ctx->nets[net_id] = this_net; + std::unique_ptr net = std::unique_ptr(new NetInfo()); + net->name = net_id; + net->driver.cell = NULL; + net->driver.port = IdString(); + ctx->nets[net_id] = std::move(net); + + this_net = ctx->nets[net_id].get(); } else { // // The net already exists within the design. // We'll connect to it // - this_net = ctx->nets[net_id]; + this_net = ctx->nets[net_id].get(); if (json_debug) log_info(" Reusing net \'%s\', id \'%s\', " "with driver \'%s\'\n", @@ -457,26 +455,26 @@ void json_import_ports(Context *ctx, const string &modname, const std::vectorname = ctx->id("$const_" + std::to_string(const_net_idx++)); + std::unique_ptr net = std::unique_ptr(new NetInfo()); + net->name = ctx->id("$const_" + std::to_string(const_net_idx++)); if (wire_node->data_string.compare(string("0")) == 0) { if (json_debug) log_info(" Generating a constant " "zero net\n"); - this_net = ground_net(ctx, this_net); + ground_net(ctx, net.get()); } else if (wire_node->data_string.compare(string("1")) == 0) { if (json_debug) log_info(" Generating a constant " "one net\n"); - this_net = vcc_net(ctx, this_net); + vcc_net(ctx, net.get()); } else if (wire_node->data_string.compare(string("x")) == 0) { - this_net = floating_net(ctx, this_net); + floating_net(ctx, net.get()); log_warning(" Floating wire node value, " "\'%s\' of port \'%s\' " "in cell \'%s\' of module \'%s\'\n", @@ -486,14 +484,14 @@ void json_import_ports(Context *ctx, const string &modname, const std::vectordata_string.c_str()); + IdString n = net->name; + ctx->nets[net->name] = std::move(net); + this_net = ctx->nets[n].get(); } if (json_debug) log_info(" Inserting port \'%s\' into cell \'%s\'\n", this_port.name.c_str(ctx), obj_name.c_str()); visitor(this_port.type, this_port.name.str(ctx), this_net); - - if (ctx->nets.count(this_net->name) == 0) - ctx->nets[this_net->name] = this_net; } } @@ -506,7 +504,7 @@ void json_import_cell(Context *ctx, string modname, const std::vector if (cell_type == NULL) return; - CellInfo *cell = new CellInfo; + std::unique_ptr cell = std::unique_ptr(new CellInfo); cell->name = ctx->id(cell_name); assert(cell_type->type == 'S'); @@ -526,7 +524,7 @@ void json_import_cell(Context *ctx, string modname, const std::vector // for (int paramid = 0; paramid < GetSize(param_node->data_dict_keys); paramid++) { - json_import_cell_params(ctx, modname, cell, param_node, &cell->params, paramid); + json_import_cell_params(ctx, modname, cell.get(), param_node, &cell->params, paramid); } attr_node = cell_node->data_dict.at("attributes"); @@ -539,7 +537,7 @@ void json_import_cell(Context *ctx, string modname, const std::vector // for (int attrid = 0; attrid < GetSize(attr_node->data_dict_keys); attrid++) { - json_import_cell_params(ctx, modname, cell, attr_node, &cell->attrs, attrid); + json_import_cell_params(ctx, modname, cell.get(), attr_node, &cell->attrs, attrid); } // @@ -594,10 +592,10 @@ void json_import_cell(Context *ctx, string modname, const std::vector wire_group_node = connections->data_dict.at(port_name); json_import_ports(ctx, modname, netnames, cell->name.str(ctx), port_name, dir_node, wire_group_node, - [cell, ctx](PortType type, const std::string &name, NetInfo *net) { + [&cell, ctx](PortType type, const std::string &name, NetInfo *net) { cell->ports[ctx->id(name)] = PortInfo{ctx->id(name), net, type}; PortRef pr; - pr.cell = cell; + pr.cell = cell.get(); pr.port = ctx->id(name); if (net != nullptr) { if (type == PORT_IN || type == PORT_INOUT) { @@ -610,7 +608,7 @@ void json_import_cell(Context *ctx, string modname, const std::vector }); } - ctx->cells[cell->name] = cell; + ctx->cells[cell->name] = std::move(cell); // check_all_nets_driven(ctx); } @@ -622,7 +620,7 @@ static void insert_iobuf(Context *ctx, NetInfo *net, PortType type, const string // During packing, this generic IO buffer will be converted to an // architecure primitive. // - CellInfo *iobuf = new CellInfo(); + std::unique_ptr iobuf = std::unique_ptr(new CellInfo()); iobuf->name = ctx->id(name); std::copy(net->attrs.begin(), net->attrs.end(), std::inserter(iobuf->attrs, iobuf->attrs.begin())); if (type == PORT_IN) { @@ -637,14 +635,14 @@ static void insert_iobuf(Context *ctx, NetInfo *net, PortType type, const string } assert(net->driver.cell == nullptr); net->driver.port = ctx->id("O"); - net->driver.cell = iobuf; + net->driver.cell = iobuf.get(); } else if (type == PORT_OUT) { if (ctx->verbose) log_info("processing output port %s\n", name.c_str()); iobuf->type = ctx->id("$nextpnr_obuf"); iobuf->ports[ctx->id("I")] = PortInfo{ctx->id("I"), net, PORT_IN}; PortRef ref; - ref.cell = iobuf; + ref.cell = iobuf.get(); ref.port = ctx->id("I"); net->users.push_back(ref); } else if (type == PORT_INOUT) { @@ -654,28 +652,28 @@ static void insert_iobuf(Context *ctx, NetInfo *net, PortType type, const string iobuf->ports[ctx->id("I")] = PortInfo{ctx->id("I"), nullptr, PORT_IN}; // Split the input and output nets for bidir ports - NetInfo *net2 = new NetInfo(); + std::unique_ptr net2 = std::unique_ptr(new NetInfo()); net2->name = ctx->id("$" + net->name.str(ctx) + "$iobuf_i"); net2->driver = net->driver; if (net->driver.cell != nullptr) { - net2->driver.cell->ports[net2->driver.port].net = net2; + net2->driver.cell->ports[net2->driver.port].net = net2.get(); net->driver.cell = nullptr; } - ctx->nets[net2->name] = net2; - iobuf->ports[ctx->id("I")].net = net2; + iobuf->ports[ctx->id("I")].net = net2.get(); PortRef ref; - ref.cell = iobuf; + ref.cell = iobuf.get(); ref.port = ctx->id("I"); net2->users.push_back(ref); + ctx->nets[net2->name] = std::move(net2); iobuf->ports[ctx->id("O")] = PortInfo{ctx->id("O"), net, PORT_OUT}; assert(net->driver.cell == nullptr); net->driver.port = ctx->id("O"); - net->driver.cell = iobuf; + net->driver.cell = iobuf.get(); } else { assert(false); } - ctx->cells[iobuf->name] = iobuf; + ctx->cells[iobuf->name] = std::move(iobuf); } void json_import_toplevel_port(Context *ctx, const string &modname, const std::vector &netnames, -- cgit v1.2.3