cyclonev: More validity checking thoughts

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-05-07 21:11:34 +01:00
parent a6ea72fd84
commit 9eb0bc482e
5 changed files with 49 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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