From 9704f422dcae5788d39edf35addd6ee5e9dfd428 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 27 Jun 2020 19:22:58 -0400 Subject: machxo2: Start creating MachXO2CommandHandler. --- machxo2/arch.cc | 54 +++++++++++++++++++++++++++++++++++++++++------------- machxo2/arch.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- machxo2/cells.cc | 6 +++--- machxo2/main.cc | 42 ++++++++++++++++++++++++++++++++---------- machxo2/pack.cc | 4 ++-- 5 files changed, 127 insertions(+), 33 deletions(-) diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 56899ced..70de80cf 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -20,6 +20,7 @@ #include #include #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 *>(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 &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; } diff --git a/machxo2/arch.h b/machxo2/arch.h index ba34f8dc..b8b9ce85 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -23,13 +23,55 @@ NEXTPNR_NAMESPACE_BEGIN +/**** Everything in this section must be kept in sync with chipdb.py ****/ + +template struct RelPtr +{ + int32_t offset; + + // void set(const T *ptr) { + // offset = reinterpret_cast(ptr) - + // reinterpret_cast(this); + // } + + const T *get() const { return reinterpret_cast(reinterpret_cast(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"); } diff --git a/machxo2/cells.cc b/machxo2/cells.cc index c4421f90..21c233d0 100644 --- a/machxo2/cells.cc +++ b/machxo2/cells.cc @@ -42,11 +42,11 @@ std::unique_ptr 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) + "]"); diff --git a/machxo2/main.cc b/machxo2/main.cc index bb780996..84b99edc 100644 --- a/machxo2/main.cc +++ b/machxo2/main.cc @@ -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 createContext(std::unordered_map &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(), "select device package (defaults to QFN32)"); + specific.add_options()("speed", po::value(), "select device speedgrade (1 to 6 inclusive)"); + + specific.add_options()("override-basecfg", po::value(), + "base chip configuration in Trellis text format"); + specific.add_options()("textcfg", po::value(), "textual configuration in Trellis format to write"); + + specific.add_options()("lpf", po::value>(), "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 GenericCommandHandler::createContext(std::unordered_map &values) +std::unique_ptr MachXO2CommandHandler::createContext(std::unordered_map &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(new Context(chipArgs)); if (vm.count("no-iobs")) ctx->settings[ctx->id("disable_iobs")] = Property::State::S1; @@ -68,7 +90,7 @@ std::unique_ptr GenericCommandHandler::createContext(std::unordered_map int main(int argc, char *argv[]) { - GenericCommandHandler handler(argc, argv); + MachXO2CommandHandler handler(argc, argv); return handler.exec(); } diff --git a/machxo2/pack.cc b/machxo2/pack.cc index 43157b6c..b995375a 100644 --- a/machxo2/pack.cc +++ b/machxo2/pack.cc @@ -138,7 +138,7 @@ static void pack_constants(Context *ctx) log_info("Packing constants..\n"); std::unique_ptr 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 gnd_net = std::unique_ptr(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 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 vcc_net = std::unique_ptr(new NetInfo); vcc_net->name = ctx->id("$PACKER_VCC_NET"); vcc_net->driver.cell = vcc_cell.get(); -- cgit v1.2.3