cyclonev: Outline functions for creating bels/wires/pips
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
b1d3eb07c3
commit
c671961c18
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user