aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam D. Jones <thor0505@comcast.net>2020-06-27 19:22:58 -0400
committergatecat <gatecat@ds0.me>2021-02-12 10:36:59 +0000
commit9704f422dcae5788d39edf35addd6ee5e9dfd428 (patch)
tree9777ab8790651c14d0622b035bac0a65da4645bb
parent98214865bef10f675b864dec4e1ae35bbd22c76f (diff)
downloadnextpnr-9704f422dcae5788d39edf35addd6ee5e9dfd428.tar.gz
nextpnr-9704f422dcae5788d39edf35addd6ee5e9dfd428.tar.bz2
nextpnr-9704f422dcae5788d39edf35addd6ee5e9dfd428.zip
machxo2: Start creating MachXO2CommandHandler.
-rw-r--r--machxo2/arch.cc54
-rw-r--r--machxo2/arch.h54
-rw-r--r--machxo2/cells.cc6
-rw-r--r--machxo2/main.cc42
-rw-r--r--machxo2/pack.cc4
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 <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; }
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 <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"); }
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<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) + "]");
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<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();
}
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<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();