From 9eb0bc482e171037095dd156d13a286b3b1c6d59 Mon Sep 17 00:00:00 2001 From: gatecat Date: Fri, 7 May 2021 21:11:34 +0100 Subject: cyclonev: More validity checking thoughts Signed-off-by: gatecat --- cyclonev/arch.cc | 13 +++++++++++++ cyclonev/arch.h | 5 +++++ cyclonev/archdefs.h | 14 ++++++++++++-- cyclonev/constids.inc | 1 + cyclonev/lab.cc | 23 ++++++++++++++++++----- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc index 9aee5a59..fd2f345d 100644 --- a/cyclonev/arch.cc +++ b/cyclonev/arch.cc @@ -308,6 +308,19 @@ void Arch::add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire) wires[wire].bel_pins.push_back(bel_pin); } +void Arch::assign_default_pinmap(CellInfo *cell) +{ + for (auto &port : cell->ports) { + auto &pinmap = cell->pin_data[port.first].bel_pins; + if (!pinmap.empty()) + continue; // already mapped + if (is_comb_cell(cell->type) && comb_pinmap.count(port.first)) + pinmap.push_back(comb_pinmap.at(port.first)); // default comb mapping for placer purposes + else + pinmap.push_back(port.first); // default: assume bel pin named the same as cell pin + } +} + #ifdef WITH_HEAP const std::string Arch::defaultPlacer = "heap"; #else diff --git a/cyclonev/arch.h b/cyclonev/arch.h index 301f19d8..ff006881 100644 --- a/cyclonev/arch.h +++ b/cyclonev/arch.h @@ -393,6 +393,11 @@ struct Arch : BaseArch BelInfo &bel_data(BelId bel) { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); } const BelInfo &bel_data(BelId bel) const { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); } + + // ------------------------------------------------- + + void assign_default_pinmap(CellInfo *cell); + static const std::unordered_map comb_pinmap; }; NEXTPNR_NAMESPACE_END diff --git a/cyclonev/archdefs.h b/cyclonev/archdefs.h index 5afdd783..31f64a6a 100644 --- a/cyclonev/archdefs.h +++ b/cyclonev/archdefs.h @@ -124,10 +124,19 @@ struct ArchNetInfo { }; +enum CellPinState +{ + PIN_SIG = 0, + PIN_0 = 1, + PIN_1 = 2, + PIN_INV = 3, +}; + struct ArchPinInfo { - // An inverter (INV) has been pushed onto this signal - bool inverted; + // Used to represent signals that are either tied to implicit constants (rather than explicitly routed constants); + // or are inverted + CellPinState state = PIN_SIG; // The physical bel pins that this logical pin maps to std::vector bel_pins; }; @@ -167,6 +176,7 @@ struct ArchCellInfo const NetInfo *comb_out; int lut_input_count; + int used_lut_input_count; // excluding those null/constant int lut_bits_count; bool is_carry, is_shared, is_extended; diff --git a/cyclonev/constids.inc b/cyclonev/constids.inc index fcc723f8..c4af45e6 100644 --- a/cyclonev/constids.inc +++ b/cyclonev/constids.inc @@ -55,6 +55,7 @@ X(MISTRAL_ALUT4) X(MISTRAL_ALUT3) X(MISTRAL_ALUT2) X(MISTRAL_NOT) +X(MISTRAL_BUF) X(MISTRAL_CONST) X(MISTRAL_ALUT_ARITH) diff --git a/cyclonev/lab.cc b/cyclonev/lab.cc index 6f7c5e6d..1f117106 100644 --- a/cyclonev/lab.cc +++ b/cyclonev/lab.cc @@ -195,7 +195,7 @@ ControlSig get_ctrlsig(const CellInfo *cell, IdString port) ControlSig result; result.net = get_net_or_empty(cell, port); if (cell->pin_data.count(port)) - result.inverted = cell->pin_data.at(port).inverted; + result.inverted = cell->pin_data.at(port).state == PIN_INV; else result.inverted = false; return result; @@ -259,7 +259,8 @@ void Arch::assign_comb_info(CellInfo *cell) const ++cell->combInfo.lut_input_count; cell->combInfo.lut_in[1] = get_net_or_empty(cell, id_B); [[fallthrough]]; - case ID_MISTRAL_NOT: + case ID_MISTRAL_BUF: // used to route through to FFs etc + case ID_MISTRAL_NOT: // used for inverters that map to LUTs ++cell->combInfo.lut_input_count; cell->combInfo.lut_in[0] = get_net_or_empty(cell, id_A); [[fallthrough]]; @@ -272,6 +273,10 @@ void Arch::assign_comb_info(CellInfo *cell) const // Note that this relationship won't hold for extended mode, when that is supported cell->combInfo.lut_bits_count = (1 << cell->combInfo.lut_input_count); } + cell->combInfo.used_lut_input_count = 0; + for (int i = 0; i < cell->combInfo.lut_input_count; i++) + if (cell->combInfo.lut_in[i]) + ++cell->combInfo.used_lut_input_count; } void Arch::assign_ff_info(CellInfo *cell) const @@ -336,9 +341,9 @@ bool Arch::is_alm_legal(uint32_t lab, uint8_t alm) const // There are two ways to route from the fabric into FF data - either routing through a LUT or using the E/F // signals and SLOAD=1 (*PKREF*) bool route_thru_lut_avail = !luts[i] && (total_lut_inputs < 8) && (used_lut_bits < 64); - // E/F is available if the LUT is using less than 6 inputs - TODO: is this correct considering all possible LUT - // sharing - bool ef_available = (!luts[i] || luts[i]->combInfo.lut_input_count < 6); + // E/F is available if this LUT is using 3 or fewer inputs - this is conservative and sharing can probably + // improve this situation + bool ef_available = (!luts[i] || luts[i]->combInfo.used_lut_input_count <= 3); // Control set checking bool found_ff = false; @@ -383,4 +388,12 @@ bool Arch::is_lab_ctrlset_legal(uint32_t lab) const return true; } +// This default cell-bel pin mapping is used to provide estimates during placement only. It will have errors and +// overlaps and a correct mapping will be resolved twixt placement and routing +const std::unordered_map Arch::comb_pinmap = { + {id_A, id_F0}, // fastest input first + {id_B, id_E0}, {id_C, id_D}, {id_D, id_C}, {id_D0, id_C}, {id_D1, id_B}, + {id_E, id_B}, {id_F, id_A}, {id_Q, id_COMBOUT}, {id_SO, id_COMBOUT}, +}; + NEXTPNR_NAMESPACE_END \ No newline at end of file -- cgit v1.2.3