cyclonev: Outline functions for creating bels/wires/pips

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-05-02 20:40:27 +01:00
parent b1d3eb07c3
commit c671961c18
2 changed files with 104 additions and 3 deletions

View File

@ -261,6 +261,66 @@ bool Arch::pack() { return true; }
bool Arch::place() { return true; } bool Arch::place() { return true; }
bool Arch::route() { return true; } bool Arch::route() { return true; }
BelId Arch::add_bel(int x, int y, IdString name, IdString type, IdString bucket)
{
// TODO: nothing else is using this BelId system yet...
// TODO (tomorrow?): we probably want a belsByTile type arrangement, similar for wires and pips, for better spacial
// locality
int z = 0;
BelId id;
// Determine a unique z-coordinate
while (bels.count(id = BelId(CycloneV::xy2pos(x, y), z)))
z++;
auto &bel = bels[id];
bel.name = name;
bel.type = type;
bel.bucket = bucket;
return id;
}
WireId Arch::add_wire(int x, int y, IdString name, uint64_t flags)
{
std::array<IdString, 4> ids{
id_WIRE,
int2id.at(x),
int2id.at(y),
name,
};
IdStringList full_name(ids);
auto existing = npnr_wirebyname.find(full_name);
if (existing != npnr_wirebyname.end()) {
// Already exists, don't create anything
return existing->second;
} else {
// Determine a unique ID for the wire
int z = 0;
WireId id;
while (wires.count(id = WireId(CycloneV::rnode(CycloneV::rnode_type_t((z >> 10) + 128), x, y, (z & 0x3FF)))))
z++;
wires[id].name_override = name;
wires[id].flags = flags;
return id;
}
}
PipId Arch::add_pip(WireId src, WireId dst)
{
wires[src].wires_downhill.push_back(dst);
wires[dst].wires_uphill.push_back(src);
return PipId(src.node, dst.node);
}
void Arch::add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire)
{
bels[bel].pins[pin].dir = dir;
bels[bel].pins[pin].wire = wire;
BelPin bel_pin;
bel_pin.bel = bel;
bel_pin.pin = pin;
wires[wire].bel_pins.push_back(bel_pin);
}
#ifdef WITH_HEAP #ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap"; const std::string Arch::defaultPlacer = "heap";
#else #else

View File

@ -37,16 +37,45 @@ struct ArchArgs
std::string mistral_root; std::string mistral_root;
}; };
// These structures are used for fast ALM validity checking
struct ALMInfo
{
// Pointers to bels
std::array<BelId, 2> lut_bels;
std::array<BelId, 4> ff_bels;
// TODO: ALM configuration (L5/L6 mode, LUT input permutation, etc)
};
struct LABInfo
{
std::array<ALMInfo, 10> alms;
// TODO: LAB configuration (control set etc)
};
struct PinInfo struct PinInfo
{ {
IdString name;
WireId wire; WireId wire;
PortType type; PortType dir;
}; };
struct BelInfo struct BelInfo
{ {
// TODO IdString name;
IdString type;
IdString bucket;
int z;
std::unordered_map<IdString, PinInfo> pins;
// Info for different kinds of bels
union
{
// This enables fast lookup of the associated ALM, etc
struct
{
uint32_t lab; // index into the list of LABs
uint8_t alm; // ALM index inside LAB
uint8_t idx; // LUT or FF index inside ALM
} labData;
};
}; };
// We maintain our own wire data based on mistral's. This gets us the bidirectional linking that nextpnr needs, // We maintain our own wire data based on mistral's. This gets us the bidirectional linking that nextpnr needs,
@ -272,6 +301,18 @@ struct Arch : BaseArch<ArchRanges>
bool place() override; bool place() override;
bool route() override; bool route() override;
// -------------------------------------------------
// Functions for device setup
BelId add_bel(int x, int y, IdString name, IdString type, IdString bucket);
WireId add_wire(int x, int y, IdString name, uint64_t flags = 0);
PipId add_pip(WireId src, WireId dst);
void add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire);
void create_lab(int x, int y);
void create_gpio(int x, int y);
// ------------------------------------------------- // -------------------------------------------------
static const std::string defaultPlacer; static const std::string defaultPlacer;