ecp5: Update to use const IdStrings in place of PortPin/BelType

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-08-08 19:08:43 +02:00
parent abf5ea84b9
commit a3ae3f9791
9 changed files with 70 additions and 148 deletions

View File

@ -43,50 +43,13 @@ static std::tuple<int, int, std::string> split_identifier_name(const std::string
// -----------------------------------------------------------------------
IdString Arch::belTypeToId(BelType type) const
{
if (type == TYPE_TRELLIS_SLICE)
return id("TRELLIS_SLICE");
if (type == TYPE_TRELLIS_IO)
return id("TRELLIS_IO");
return IdString();
}
BelType Arch::belTypeFromId(IdString type) const
{
if (type == id("TRELLIS_SLICE"))
return TYPE_TRELLIS_SLICE;
if (type == id("TRELLIS_IO"))
return TYPE_TRELLIS_IO;
return TYPE_NONE;
}
// -----------------------------------------------------------------------
void IdString::initialize_arch(const BaseCtx *ctx)
{
#define X(t) initialize_add(ctx, #t, PIN_##t);
#include "portpins.inc"
#define X(t) initialize_add(ctx, #t, ID_##t);
#include "constids.inc"
#undef X
}
IdString Arch::portPinToId(PortPin type) const
{
IdString ret;
if (type > 0 && type < PIN_MAXIDX)
ret.index = type;
return ret;
}
PortPin Arch::portPinFromId(IdString type) const
{
if (type.index > 0 && type.index < PIN_MAXIDX)
return PortPin(type.index);
return PIN_NONE;
}
// -----------------------------------------------------------------------
static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
@ -129,14 +92,6 @@ Arch::Arch(ArchArgs args) : args(args)
if (!package_info)
log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
id_trellis_slice = id("TRELLIS_SLICE");
id_clk = id("CLK");
id_lsr = id("LSR");
id_clkmux = id("CLKMUX");
id_lsrmux = id("LSRMUX");
id_srmode = id("SRMODE");
id_mode = id("MODE");
}
// -----------------------------------------------------------------------
@ -209,7 +164,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
return br;
}
WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
WireId ret;
@ -218,7 +173,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
if (bel_wires[i].port == pin) {
if (bel_wires[i].port == pin.index) {
ret.location = bel.location + bel_wires[i].rel_wire_loc;
ret.index = bel_wires[i].wire_index;
break;
@ -227,7 +182,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
return ret;
}
PortType Arch::getBelPinType(BelId bel, PortPin pin) const
PortType Arch::getBelPinType(BelId bel, IdString pin) const
{
NPNR_ASSERT(bel != BelId());
@ -235,7 +190,7 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
if (bel_wires[i].port == pin)
if (bel_wires[i].port == pin.index)
return PortType(bel_wires[i].type);
return PORT_INOUT;
@ -374,17 +329,20 @@ BelId Arch::getPioByFunctionName(const std::string &name) const
return BelId();
}
std::vector<PortPin> Arch::getBelPins(BelId bel) const
std::vector<IdString> Arch::getBelPins(BelId bel) const
{
std::vector<PortPin> ret;
std::vector<IdString> ret;
NPNR_ASSERT(bel != BelId());
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
ret.push_back(bel_wires[i].port);
for (int i = 0; i < num_bel_wires; i++) {
IdString id;
id.index = bel_wires[i].port;
ret.push_back(id);
}
return ret;
}
@ -447,7 +405,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
int z = locInfo(bel)->bel_data[bel.index].z;
auto bel_type = getBelType(bel);
if (bel_type == TYPE_TRELLIS_SLICE) {
if (bel_type == id_TRELLIS_SLICE) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@ -458,7 +416,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el);
}
if (bel_type == TYPE_TRELLIS_IO) {
if (bel_type == id_TRELLIS_IO) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;

View File

@ -50,13 +50,13 @@ template <typename T> struct RelPtr
NPNR_PACKED_STRUCT(struct BelWirePOD {
LocationPOD rel_wire_loc;
int32_t wire_index;
PortPin port;
int32_t port;
int32_t type;
});
NPNR_PACKED_STRUCT(struct BelInfoPOD {
RelPtr<char> name;
BelType type;
int32_t type;
int32_t z;
int32_t num_bel_wires;
RelPtr<BelWirePOD> bel_wires;
@ -65,7 +65,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
NPNR_PACKED_STRUCT(struct BelPortPOD {
LocationPOD rel_bel_loc;
int32_t bel_index;
PortPin port;
int32_t port;
});
NPNR_PACKED_STRUCT(struct PipInfoPOD {
@ -239,7 +239,7 @@ struct BelPinIterator
BelPin ret;
ret.bel.index = ptr->bel_index;
ret.bel.location = wire_loc + ptr->rel_bel_loc;
ret.pin = ptr->port;
ret.pin.index = ptr->port;
return ret;
}
};
@ -416,11 +416,6 @@ struct Arch : BaseCtx
IdString archId() const { return id("ecp5"); }
IdString archArgsToId(ArchArgs args) const;
IdString belTypeToId(BelType type) const;
BelType belTypeFromId(IdString id) const;
IdString portPinToId(PortPin type) const;
PortPin portPinFromId(IdString id) const;
// -------------------------------------------------
int getGridDimX() const { return chip_info->width; };
@ -517,13 +512,15 @@ struct Arch : BaseCtx
return range;
}
BelType getBelType(BelId bel) const
IdString getBelType(BelId bel) const
{
NPNR_ASSERT(bel != BelId());
return locInfo(bel)->bel_data[bel.index].type;
IdString id;
id.index = locInfo(bel)->bel_data[bel.index].type;
return id;
}
WireId getBelPinWire(BelId bel, PortPin pin) const;
WireId getBelPinWire(BelId bel, IdString pin) const;
BelPinRange getWireBelPins(WireId wire) const
{
@ -536,7 +533,7 @@ struct Arch : BaseCtx
return range;
}
std::vector<PortPin> getBelPins(BelId bel) const;
std::vector<IdString> getBelPins(BelId bel) const;
// -------------------------------------------------
@ -785,7 +782,7 @@ struct Arch : BaseCtx
std::string getPioFunctionName(BelId bel) const;
BelId getPioByFunctionName(const std::string &name) const;
PortType getBelPinType(BelId bel, PortPin pin) const;
PortType getBelPinType(BelId bel, IdString pin) const;
// -------------------------------------------------
@ -863,11 +860,6 @@ struct Arch : BaseCtx
}
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
}
IdString id_trellis_slice;
IdString id_clk, id_lsr;
IdString id_clkmux, id_lsrmux;
IdString id_srmode, id_mode;
};
NEXTPNR_NAMESPACE_END

View File

@ -40,21 +40,21 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
bool first = true;
for (auto cell : cells) {
if (first) {
clk_sig = port_or_nullptr(cell, id_clk);
lsr_sig = port_or_nullptr(cell, id_lsr);
CLKMUX = str_or_default(cell->params, id_clkmux, "CLK");
LSRMUX = str_or_default(cell->params, id_lsrmux, "LSR");
SRMODE = str_or_default(cell->params, id_srmode, "CE_OVER_LSR");
clk_sig = port_or_nullptr(cell, id_CLK);
lsr_sig = port_or_nullptr(cell, id_LSR);
CLKMUX = str_or_default(cell->params, id_CLKMUX, "CLK");
LSRMUX = str_or_default(cell->params, id_LSRMUX, "LSR");
SRMODE = str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR");
} else {
if (port_or_nullptr(cell, id_clk) != clk_sig)
if (port_or_nullptr(cell, id_CLK) != clk_sig)
return false;
if (port_or_nullptr(cell, id_lsr) != lsr_sig)
if (port_or_nullptr(cell, id_LSR) != lsr_sig)
return false;
if (str_or_default(cell->params, id_clkmux, "CLK") != CLKMUX)
if (str_or_default(cell->params, id_CLKMUX, "CLK") != CLKMUX)
return false;
if (str_or_default(cell->params, id_lsrmux, "LSR") != LSRMUX)
if (str_or_default(cell->params, id_LSRMUX, "LSR") != LSRMUX)
return false;
if (str_or_default(cell->params, id_srmode, "CE_OVER_LSR") != SRMODE)
if (str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR") != SRMODE)
return false;
}
first = false;
@ -64,7 +64,7 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
bool Arch::isBelLocationValid(BelId bel) const
{
if (getBelType(bel) == TYPE_TRELLIS_SLICE) {
if (getBelType(bel) == id_TRELLIS_SLICE) {
std::vector<const CellInfo *> bel_cells;
Loc bel_loc = getBelLocation(bel);
for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
@ -85,8 +85,8 @@ bool Arch::isBelLocationValid(BelId bel) const
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{
if (cell->type == id_trellis_slice) {
NPNR_ASSERT(getBelType(bel) == TYPE_TRELLIS_SLICE);
if (cell->type == id_TRELLIS_SLICE) {
NPNR_ASSERT(getBelType(bel) == id_TRELLIS_SLICE);
std::vector<const CellInfo *> bel_cells;
Loc bel_loc = getBelLocation(bel);

View File

@ -39,13 +39,6 @@ void arch_wrap_python()
class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
enum_<PortPin>("PortPin")
#define X(t) .value("PIN_" #t, PIN_##t)
#include "portpins.inc"
;
#undef X
auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
.def("checksum", &Context::checksum)
@ -53,7 +46,7 @@ void arch_wrap_python()
.def("place", &Context::place)
.def("route", &Context::route);
fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<BelType>,
fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<IdString>,
conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType");
fn_wrapper_1a<Context, decltype(&Context::checkBelAvail), &Context::checkBelAvail, pass_through<bool>,
conv_from_str<BelId>>::def_wrap(ctx_cls, "checkBelAvail");
@ -71,7 +64,7 @@ void arch_wrap_python()
"getBels");
fn_wrapper_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>,
conv_from_str<BelId>, conv_from_str<PortPin>>::def_wrap(ctx_cls, "getBelPinWire");
conv_from_str<BelId>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getBelPinWire");
fn_wrapper_1a<Context, decltype(&Context::getWireBelPins), &Context::getWireBelPins, wrap_context<BelPinRange>,
conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireBelPins");

View File

@ -40,13 +40,6 @@ template <> struct string_converter<BelId>
}
};
template <> struct string_converter<BelType>
{
BelType from_str(Context *ctx, std::string name) { return ctx->belTypeFromId(ctx->id(name)); }
std::string to_str(Context *ctx, BelType typ) { return ctx->belTypeToId(typ).str(ctx); }
};
template <> struct string_converter<WireId>
{
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
@ -61,13 +54,6 @@ template <> struct string_converter<PipId>
std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); }
};
template <> struct string_converter<PortPin>
{
PortPin from_str(Context *ctx, std::string name) { return ctx->portPinFromId(ctx->id(name)); }
std::string to_str(Context *ctx, PortPin id) { return ctx->portPinToId(id).str(ctx); }
};
} // namespace PythonConversion
NEXTPNR_NAMESPACE_END

View File

@ -51,21 +51,17 @@ struct DelayInfo
// -----------------------------------------------------------------------
enum BelType : int32_t
enum ConstIds
{
TYPE_NONE,
TYPE_TRELLIS_SLICE,
TYPE_TRELLIS_IO
ID_NONE
#define X(t) , ID_##t
#include "constids.inc"
#undef X
};
enum PortPin : int32_t
{
PIN_NONE,
#define X(t) PIN_##t,
#include "portpins.inc"
#define X(t) static constexpr auto id_##t = IdString(ID_##t);
#include "constids.inc"
#undef X
PIN_MAXIDX
};
NPNR_PACKED_STRUCT(struct LocationPOD { int16_t x, y; });
@ -209,11 +205,4 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
}
};
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType> : hash<int>
{
};
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int>
{
};
} // namespace std

View File

@ -44,3 +44,9 @@ X(I)
X(O)
X(T)
X(B)
X(TRELLIS_SLICE)
X(TRELLIS_IO)
X(CLKMUX)
X(LSRMUX)
X(SRMODE)

View File

@ -25,9 +25,9 @@ if (MSVC)
foreach (dev ${devices})
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/portpins.inc)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_PORTS_INC} ${dev} > ${DEV_CC_BBA_DB}
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
DEPENDS ${DB_PY}
)
add_custom_command(OUTPUT ${DEV_CC_DB}
@ -45,9 +45,9 @@ else()
foreach (dev ${devices})
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/portpins.inc)
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_PORTS_INC} ${dev} > ${DEV_CC_BBA_DB}.new
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}.new
COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
DEPENDS ${DB_PY}
)

View File

@ -11,7 +11,7 @@ tiletype_names = dict()
parser = argparse.ArgumentParser(description="import ECP5 routing and bels from Project Trellis")
parser.add_argument("device", type=str, help="target device")
parser.add_argument("-p", "--portspins", type=str, help="path to portpins.inc")
parser.add_argument("-p", "--constids", type=str, help="path to constids.inc")
args = parser.parse_args()
@ -28,7 +28,7 @@ def get_tiletype_index(name):
return idx
portpins = dict()
constids = dict()
class BinaryBlobAssembler:
@ -78,12 +78,6 @@ class BinaryBlobAssembler:
def pop(self):
print("pop")
bel_types = {
"NONE": 0,
"SLICE": 1,
"PIO": 2
}
def get_bel_index(ddrg, loc, name):
loctype = ddrg.locationTypes[ddrg.typeAtLocation[loc]]
idx = 0
@ -181,7 +175,7 @@ def write_database(dev_name, chip, ddrg, endianness):
for bp in wire.belPins:
write_loc(bp.bel.rel, "rel_bel_loc")
bba.u32(bp.bel.id, "bel_index")
bba.u32(portpins[ddrg.to_str(bp.pin)], "port")
bba.u32(constids[ddrg.to_str(bp.pin)], "port")
bba.l("loc%d_wires" % idx, "WireInfoPOD")
for wire_idx in range(len(loctype.wires)):
wire = loctype.wires[wire_idx]
@ -200,13 +194,13 @@ def write_database(dev_name, chip, ddrg, endianness):
for pin in bel.wires:
write_loc(pin.wire.rel, "rel_wire_loc")
bba.u32(pin.wire.id, "wire_index")
bba.u32(portpins[ddrg.to_str(pin.pin)], "port")
bba.u32(constids[ddrg.to_str(pin.pin)], "port")
bba.u32(int(pin.dir), "dir")
bba.l("loc%d_bels" % idx, "BelInfoPOD")
for bel_idx in range(len(loctype.bels)):
bel = loctype.bels[bel_idx]
bba.s(ddrg.to_str(bel.name), "name")
bba.u32(bel_types[ddrg.to_str(bel.type)], "type")
bba.u32(constids[ddrg.to_str(bel.type)], "type")
bba.u32(bel.z, "z")
bba.u32(len(bel.wires), "num_bel_wires")
bba.r("loc%d_bel%d_wires" % (idx, bel_idx), "bel_wires")
@ -305,7 +299,7 @@ def main():
args = parser.parse_args()
# Read port pin file
with open(args.portspins) as f:
with open(args.constids) as f:
for line in f:
line = line.replace("(", " ")
line = line.replace(")", " ")
@ -314,8 +308,12 @@ def main():
continue
assert len(line) == 2
assert line[0] == "X"
idx = len(portpins) + 1
portpins[line[1]] = idx
idx = len(constids) + 1
constids[line[1]] = idx
constids["SLICE"] = constids["TRELLIS_SLICE"]
constids["PIO"] = constids["TRELLIS_IO"]
# print("Initialising chip...")
chip = pytrellis.Chip(dev_names[args.device])