diff options
| author | gatecat <gatecat@ds0.me> | 2021-05-07 21:11:34 +0100 | 
|---|---|---|
| committer | gatecat <gatecat@ds0.me> | 2021-05-15 14:54:33 +0100 | 
| commit | 9eb0bc482e171037095dd156d13a286b3b1c6d59 (patch) | |
| tree | 9126d1b4488920431cf6daef8e6416bf86a77127 | |
| parent | a6ea72fd84706de8bdb6fd28005e3c735903ad4c (diff) | |
| download | nextpnr-9eb0bc482e171037095dd156d13a286b3b1c6d59.tar.gz nextpnr-9eb0bc482e171037095dd156d13a286b3b1c6d59.tar.bz2 nextpnr-9eb0bc482e171037095dd156d13a286b3b1c6d59.zip | |
cyclonev: More validity checking thoughts
Signed-off-by: gatecat <gatecat@ds0.me>
| -rw-r--r-- | cyclonev/arch.cc | 13 | ||||
| -rw-r--r-- | cyclonev/arch.h | 5 | ||||
| -rw-r--r-- | cyclonev/archdefs.h | 14 | ||||
| -rw-r--r-- | cyclonev/constids.inc | 1 | ||||
| -rw-r--r-- | 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<ArchRanges>      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<IdString, IdString> 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<IdString> 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<IdString, IdString> 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 | 
