machxo2: Start creating MachXO2CommandHandler.

This commit is contained in:
William D. Jones 2020-06-27 19:22:58 -04:00 committed by gatecat
parent 98214865be
commit 9704f422dc
5 changed files with 127 additions and 33 deletions

View File

@ -20,6 +20,7 @@
#include <iostream>
#include <math.h>
#include "nextpnr.h"
#include "embed.h"
#include "placer1.h"
#include "placer_heap.h"
#include "router1.h"
@ -36,7 +37,44 @@ Arch::Arch(ArchArgs args) : chipName("generic"), args(args)
decal_graphics[IdString()];
}
void IdString::initialize_arch(const BaseCtx *ctx) {}
// -----------------------------------------------------------------------
void IdString::initialize_arch(const BaseCtx *ctx) {
#define X(t) initialize_add(ctx, #t, ID_##t);
#include "constids.inc"
#undef X
}
// ---------------------------------------------------------------
static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip)
{
std::string chipdb;
if (chip == ArchArgs::LCMXO2_256HC) {
chipdb = "machxo2/chipdb-256.bin";
} else if (chip == ArchArgs::LCMXO2_640HC) {
chipdb = "machxo2/chipdb-640.bin";
} else if (chip == ArchArgs::LCMXO2_1200HC) {
chipdb = "machxo2/chipdb-1200.bin";
} else if (chip == ArchArgs::LCMXO2_2000HC) {
chipdb = "machxo2/chipdb-2000.bin";
} else if (chip == ArchArgs::LCMXO2_4000HC) {
chipdb = "machxo2/chipdb-4000.bin";
} else if (chip == ArchArgs::LCMXO2_7000HC) {
chipdb = "machxo2/chipdb-7000.bin";
} else {
log_error("Unknown chip\n");
}
auto ptr = reinterpret_cast<const RelPtr<ChipInfoPOD> *>(get_chipdb(chipdb));
if (ptr == nullptr)
return nullptr;
return ptr->get();
}
bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip) { return get_chip_info(chip) != nullptr; }
// ---------------------------------------------------------------
@ -265,22 +303,12 @@ const std::vector<GroupId> &Arch::getGroupGroups(GroupId group) const { return g
delay_t Arch::estimateDelay(WireId src, WireId dst) const
{
const WireInfo &s = wires.at(src);
const WireInfo &d = wires.at(dst);
int dx = abs(s.x - d.x);
int dy = abs(s.y - d.y);
return (dx + dy) * args.delayScale + args.delayOffset;
return 0;
}
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
{
const auto &driver = net_info->driver;
auto driver_loc = getBelLocation(driver.cell->bel);
auto sink_loc = getBelLocation(sink.cell->bel);
int dx = abs(sink_loc.x - driver_loc.x);
int dy = abs(sink_loc.y - driver_loc.y);
return (dx + dy) * args.delayScale + args.delayOffset;
return 0;
}
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }

View File

@ -23,13 +23,55 @@
NEXTPNR_NAMESPACE_BEGIN
/**** Everything in this section must be kept in sync with chipdb.py ****/
template <typename T> struct RelPtr
{
int32_t offset;
// void set(const T *ptr) {
// offset = reinterpret_cast<const char*>(ptr) -
// reinterpret_cast<const char*>(this);
// }
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
const T &operator[](size_t index) const { return get()[index]; }
const T &operator*() const { return *(get()); }
const T *operator->() const { return get(); }
};
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
int32_t stub;
});
/************************ End of chipdb section. ************************/
struct ArchArgs
{
// Number of LUT inputs
int K = 4;
// y = mx + c relationship between distance and delay for interconnect
// delay estimates
double delayScale = 0.1, delayOffset = 0;
enum ArchArgsTypes
{
NONE,
LCMXO2_256HC,
LCMXO2_640HC,
LCMXO2_1200HC,
LCMXO2_2000HC,
LCMXO2_4000HC,
LCMXO2_7000HC,
} type = NONE;
std::string package;
enum SpeedGrade
{
SPEED_1 = 0,
SPEED_2,
SPEED_3,
SPEED_4,
SPEED_5,
SPEED_6,
} speed = SPEED_4;
};
struct WireInfo;
@ -146,6 +188,8 @@ struct Arch : BaseCtx
ArchArgs args;
Arch(ArchArgs args);
static bool isAvailable(ArchArgs::ArchArgsTypes chip);
std::string getChipName() const { return chipName; }
IdString archId() const { return id("generic"); }

View File

@ -42,11 +42,11 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
}
new_cell->type = type;
if (type == ctx->id("GENERIC_SLICE")) {
new_cell->params[ctx->id("K")] = ctx->args.K;
new_cell->params[ctx->id("K")] = 4;
new_cell->params[ctx->id("INIT")] = 0;
new_cell->params[ctx->id("FF_USED")] = 0;
for (int i = 0; i < ctx->args.K; i++)
for (int i = 0; i < 4; i++)
add_port(ctx, new_cell.get(), "I[" + std::to_string(i) + "]", PORT_IN);
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
@ -73,7 +73,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
lc->params[ctx->id("INIT")] = lut->params[ctx->id("INIT")];
int lut_k = int_or_default(lut->params, ctx->id("K"), 4);
NPNR_ASSERT(lut_k <= ctx->args.K);
NPNR_ASSERT(lut_k <= 4);
for (int i = 0; i < lut_k; i++) {
IdString port = ctx->id("I[" + std::to_string(i) + "]");

View File

@ -27,11 +27,11 @@
USING_NEXTPNR_NAMESPACE
class GenericCommandHandler : public CommandHandler
class MachXO2CommandHandler : public CommandHandler
{
public:
GenericCommandHandler(int argc, char **argv);
virtual ~GenericCommandHandler(){};
MachXO2CommandHandler(int argc, char **argv);
virtual ~MachXO2CommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override;
@ -40,26 +40,48 @@ class GenericCommandHandler : public CommandHandler
po::options_description getArchOptions() override;
};
GenericCommandHandler::GenericCommandHandler(int argc, char **argv) : CommandHandler(argc, argv) {}
MachXO2CommandHandler::MachXO2CommandHandler(int argc, char **argv) : CommandHandler(argc, argv) {}
po::options_description GenericCommandHandler::getArchOptions()
po::options_description MachXO2CommandHandler::getArchOptions()
{
po::options_description specific("Architecture specific options");
specific.add_options()("generic", "set device type to generic");
if (Arch::isAvailable(ArchArgs::LCMXO2_256HC))
specific.add_options()("256", "set device type to LCMXO2-256HC");
if (Arch::isAvailable(ArchArgs::LCMXO2_640HC))
specific.add_options()("640", "set device type to LCMXO2-640HC");
if (Arch::isAvailable(ArchArgs::LCMXO2_1200HC))
specific.add_options()("1200", "set device type to LCMXO2-1200HC");
if (Arch::isAvailable(ArchArgs::LCMXO2_2000HC))
specific.add_options()("2000", "set device type to LCMXO2-2000HC");
if (Arch::isAvailable(ArchArgs::LCMXO2_4000HC))
specific.add_options()("4000", "set device type to LCMXO2-4000HC");
if (Arch::isAvailable(ArchArgs::LCMXO2_7000HC))
specific.add_options()("7000", "set device type to LCMXO2-7000HC");
specific.add_options()("package", po::value<std::string>(), "select device package (defaults to QFN32)");
specific.add_options()("speed", po::value<int>(), "select device speedgrade (1 to 6 inclusive)");
specific.add_options()("override-basecfg", po::value<std::string>(),
"base chip configuration in Trellis text format");
specific.add_options()("textcfg", po::value<std::string>(), "textual configuration in Trellis format to write");
specific.add_options()("lpf", po::value<std::vector<std::string>>(), "LPF pin constraint file(s)");
specific.add_options()("no-iobs", "disable automatic IO buffer insertion");
return specific;
}
void GenericCommandHandler::customBitstream(Context *ctx) {}
void MachXO2CommandHandler::customBitstream(Context *ctx) {}
std::unique_ptr<Context> GenericCommandHandler::createContext(std::unordered_map<std::string, Property> &values)
std::unique_ptr<Context> MachXO2CommandHandler::createContext(std::unordered_map<std::string, Property> &values)
{
ArchArgs chipArgs;
if (values.find("arch.name") != values.end()) {
std::string arch_name = values["arch.name"].as_string();
if (arch_name != "generic")
if (arch_name != "machxo2")
log_error("Unsuported architecture '%s'.\n", arch_name.c_str());
}
auto ctx = std::unique_ptr<Context>(new Context(chipArgs));
if (vm.count("no-iobs"))
ctx->settings[ctx->id("disable_iobs")] = Property::State::S1;
@ -68,7 +90,7 @@ std::unique_ptr<Context> GenericCommandHandler::createContext(std::unordered_map
int main(int argc, char *argv[])
{
GenericCommandHandler handler(argc, argv);
MachXO2CommandHandler handler(argc, argv);
return handler.exec();
}

View File

@ -138,7 +138,7 @@ static void pack_constants(Context *ctx)
log_info("Packing constants..\n");
std::unique_ptr<CellInfo> gnd_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_GND");
gnd_cell->params[ctx->id("INIT")] = Property(0, 1 << ctx->args.K);
gnd_cell->params[ctx->id("INIT")] = Property(0, 1 << 4);
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
gnd_net->name = ctx->id("$PACKER_GND_NET");
gnd_net->driver.cell = gnd_cell.get();
@ -147,7 +147,7 @@ static void pack_constants(Context *ctx)
std::unique_ptr<CellInfo> vcc_cell = create_generic_cell(ctx, ctx->id("GENERIC_SLICE"), "$PACKER_VCC");
// Fill with 1s
vcc_cell->params[ctx->id("INIT")] = Property(Property::S1).extract(0, (1 << ctx->args.K), Property::S1);
vcc_cell->params[ctx->id("INIT")] = Property(Property::S1).extract(0, (1 << 4), Property::S1);
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
vcc_net->name = ctx->id("$PACKER_VCC_NET");
vcc_net->driver.cell = vcc_cell.get();