diff --git a/ice40/arch.cc b/ice40/arch.cc index a5c920bb..1825c142 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -707,23 +707,28 @@ void Arch::assignArchArgs() } for (auto &cell : getCtx()->cells) { CellInfo *ci = cell.second.get(); - ci->belType = belTypeFromId(ci->type); - if (ci->type == id_icestorm_lc) { - ci->lcInfo.dffEnable = bool_or_default(ci->params, id_dff_en); - ci->lcInfo.negClk = bool_or_default(ci->params, id_neg_clk); - ci->lcInfo.clk = get_net_or_empty(ci, id_clk); - ci->lcInfo.cen = get_net_or_empty(ci, id_cen); - ci->lcInfo.sr = get_net_or_empty(ci, id_sr); - ci->lcInfo.inputCount = 0; - if (get_net_or_empty(ci, id_i0)) - ci->lcInfo.inputCount++; - if (get_net_or_empty(ci, id_i1)) - ci->lcInfo.inputCount++; - if (get_net_or_empty(ci, id_i2)) - ci->lcInfo.inputCount++; - if (get_net_or_empty(ci, id_i3)) - ci->lcInfo.inputCount++; - } + assignCellArgs(ci); + } +} + +void Arch::assignCellArgs(CellInfo *cell) +{ + cell->belType = belTypeFromId(cell->type); + if (cell->type == id_icestorm_lc) { + cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en); + cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk); + cell->lcInfo.clk = get_net_or_empty(cell, id_clk); + cell->lcInfo.cen = get_net_or_empty(cell, id_cen); + cell->lcInfo.sr = get_net_or_empty(cell, id_sr); + cell->lcInfo.inputCount = 0; + if (get_net_or_empty(cell, id_i0)) + cell->lcInfo.inputCount++; + if (get_net_or_empty(cell, id_i1)) + cell->lcInfo.inputCount++; + if (get_net_or_empty(cell, id_i2)) + cell->lcInfo.inputCount++; + if (get_net_or_empty(cell, id_i3)) + cell->lcInfo.inputCount++; } } diff --git a/ice40/arch.h b/ice40/arch.h index 8821ded2..8c1a3d41 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -709,6 +709,7 @@ struct Arch : BaseCtx // Assign architecure-specific arguments to nets and cells, which must be called between packing or further // netlist modifications, and validity checks void assignArchArgs(); + void assignCellArgs(CellInfo *cell); IdString id_glb_buf_out; IdString id_icestorm_lc, id_sb_io, id_sb_gb; diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index dc1bc3eb..1f2943a0 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -31,45 +31,37 @@ bool Arch::logicCellsCompatible(const std::vector &cells) cons int locals_count = 0; for (auto cell : cells) { - if (bool_or_default(cell->params, id_dff_en)) { + NPNR_ASSERT(cell->belType == TYPE_ICESTORM_LC); + if (cell->lcInfo.dffEnable) { if (!dffs_exist) { dffs_exist = true; - cen = get_net_or_empty(cell, id_cen); - clk = get_net_or_empty(cell, id_clk); - sr = get_net_or_empty(cell, id_sr); + cen = cell->lcInfo.cen; + clk = cell->lcInfo.clk; + sr = cell->lcInfo.sr; - if (!isGlobalNet(cen) && cen != nullptr) + if (cen != nullptr && !cen->is_global) locals_count++; - if (!isGlobalNet(clk) && clk != nullptr) + if (clk != nullptr && !clk->is_global) locals_count++; - if (!isGlobalNet(sr) && sr != nullptr) + if (sr != nullptr && !sr->is_global) locals_count++; - if (bool_or_default(cell->params, id_neg_clk)) { + if (cell->lcInfo.negClk) { dffs_neg = true; } } else { - if (cen != get_net_or_empty(cell, id_cen)) + if (cen != cell->lcInfo.cen) return false; - if (clk != get_net_or_empty(cell, id_clk)) + if (clk != cell->lcInfo.clk) return false; - if (sr != get_net_or_empty(cell, id_sr)) + if (sr != cell->lcInfo.sr) return false; - if (dffs_neg != bool_or_default(cell->params, id_neg_clk)) + if (dffs_neg != cell->lcInfo.negClk) return false; } } - const NetInfo *i0 = get_net_or_empty(cell, id_i0), *i1 = get_net_or_empty(cell, id_i1), - *i2 = get_net_or_empty(cell, id_i2), *i3 = get_net_or_empty(cell, id_i3); - if (i0 != nullptr) - locals_count++; - if (i1 != nullptr) - locals_count++; - if (i2 != nullptr) - locals_count++; - if (i3 != nullptr) - locals_count++; + locals_count += cell->lcInfo.inputCount; } return locals_count <= 32; diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index ebcc0da7..3c82a1bd 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -372,6 +372,7 @@ class PlacementLegaliser NPNR_ASSERT(ctx->nets.find(co_i3_name) == ctx->nets.end()); ctx->nets[co_i3_name] = std::move(co_i3_net); IdString name = lc->name; + ctx->assignCellArgs(lc.get()); ctx->cells[lc->name] = std::move(lc); createdCells.insert(name); return ctx->cells[name].get(); @@ -416,6 +417,7 @@ class PlacementLegaliser ctx->nets[out_net_name] = std::move(out_net); IdString name = lc->name; + ctx->assignCellArgs(lc.get()); ctx->cells[lc->name] = std::move(lc); createdCells.insert(name); return ctx->cells[name].get();