aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam D. Jones <thor0505@comcast.net>2021-01-30 22:42:16 -0500
committergatecat <gatecat@ds0.me>2021-02-12 10:36:59 +0000
commitcf2db7a4c474569d372c176e9790dd4f6ae24a03 (patch)
tree93d029cca0f5a4ef9d522c5f55950a8112a39d1b
parent56656b2b244127763ced9cb95332b09e1aa5ab81 (diff)
downloadnextpnr-cf2db7a4c474569d372c176e9790dd4f6ae24a03.tar.gz
nextpnr-cf2db7a4c474569d372c176e9790dd4f6ae24a03.tar.bz2
nextpnr-cf2db7a4c474569d372c176e9790dd4f6ae24a03.zip
machxo2: Write out pips to bitstream.
-rw-r--r--machxo2/arch.cc27
-rw-r--r--machxo2/arch.h15
-rw-r--r--machxo2/bitstream.cc41
3 files changed, 83 insertions, 0 deletions
diff --git a/machxo2/arch.cc b/machxo2/arch.cc
index 4ab3dc5b..dbe17fd9 100644
--- a/machxo2/arch.cc
+++ b/machxo2/arch.cc
@@ -124,6 +124,33 @@ std::string Arch::getChipName() const
}
}
+std::string Arch::getFullChipName() const
+{
+ std::string name = getChipName();
+ name += "-";
+ switch (args.speed) {
+ case ArchArgs::SPEED_1:
+ name += "1";
+ break;
+ case ArchArgs::SPEED_2:
+ name += "2";
+ break;
+ case ArchArgs::SPEED_3:
+ name += "3";
+ case ArchArgs::SPEED_4:
+ name += "4";
+ break;
+ case ArchArgs::SPEED_5:
+ name += "5";
+ break;
+ case ArchArgs::SPEED_6:
+ name += "6";
+ break;
+ }
+ name += args.package;
+ return name;
+}
+
IdString Arch::archArgsToId(ArchArgs args) const
{
if (args.type == ArchArgs::LCMXO2_256HC) {
diff --git a/machxo2/arch.h b/machxo2/arch.h
index f06739e4..6cca9798 100644
--- a/machxo2/arch.h
+++ b/machxo2/arch.h
@@ -501,6 +501,8 @@ struct Arch : BaseCtx
static bool isAvailable(ArchArgs::ArchArgsTypes chip);
std::string getChipName() const;
+ // Extra helper
+ std::string getFullChipName() const;
IdString archId() const { return id("machxo2"); }
ArchArgs archArgs() const { return args; }
@@ -882,6 +884,19 @@ struct Arch : BaseCtx
return range;
}
+ // Extra Pip helpers.
+ int8_t getPipClass(PipId pip) const { return tileInfo(pip)->pips_data[pip.index].pip_type; }
+
+ std::string getPipTilename(PipId pip) const
+ {
+ auto &tileloc = chip_info->tile_info[pip.location.y * chip_info->width + pip.location.x];
+ for (int i = 0; i < tileloc.num_tiles; i++) {
+ if (tileloc.tile_names[i].type_idx == tileInfo(pip)->pips_data[pip.index].tile_type)
+ return tileloc.tile_names[i].name.get();
+ }
+ NPNR_ASSERT_FALSE("failed to find Pip tile");
+ }
+
// Group
GroupId getGroupByName(IdString name) const;
IdString getGroupName(GroupId group) const;
diff --git a/machxo2/bitstream.cc b/machxo2/bitstream.cc
index eec07cb1..58f5f85e 100644
--- a/machxo2/bitstream.cc
+++ b/machxo2/bitstream.cc
@@ -22,6 +22,7 @@
#include "bitstream.h"
#include "config.h"
+#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -47,6 +48,35 @@ namespace BaseConfigs {
}
} // namespace BaseConfigs
+// Convert an absolute wire name to a relative Trellis one
+static std::string get_trellis_wirename(Context *ctx, Location loc, WireId wire)
+{
+ std::string basename = ctx->tileInfo(wire)->wire_data[wire.index].name.get();
+ std::string prefix2 = basename.substr(0, 2);
+ if (prefix2 == "G_" || prefix2 == "L_" || prefix2 == "R_")
+ return basename;
+ if (loc == wire.location)
+ return basename;
+ std::string rel_prefix;
+ if (wire.location.y < loc.y)
+ rel_prefix += "N" + std::to_string(loc.y - wire.location.y);
+ if (wire.location.y > loc.y)
+ rel_prefix += "S" + std::to_string(wire.location.y - loc.y);
+ if (wire.location.x > loc.x)
+ rel_prefix += "E" + std::to_string(wire.location.x - loc.x);
+ if (wire.location.x < loc.x)
+ rel_prefix += "W" + std::to_string(loc.x - wire.location.x);
+ return rel_prefix + "_" + basename;
+}
+
+static void set_pip(Context *ctx, ChipConfig &cc, PipId pip)
+{
+ std::string tile = ctx->getPipTilename(pip);
+ std::string source = get_trellis_wirename(ctx, pip.location, ctx->getPipSrcWire(pip));
+ std::string sink = get_trellis_wirename(ctx, pip.location, ctx->getPipDstWire(pip));
+ cc.tiles[tile].add_arc(sink, source);
+}
+
void write_bitstream(Context *ctx, std::string text_config_file)
{
ChipConfig cc;
@@ -59,6 +89,17 @@ void write_bitstream(Context *ctx, std::string text_config_file)
NPNR_ASSERT_FALSE("Unsupported device type");
}
+ cc.metadata.push_back("Part: " + ctx->getFullChipName());
+
+ // Add all set, configurable pips to the config
+ for (auto pip : ctx->getPips()) {
+ if (ctx->getBoundPipNet(pip) != nullptr) {
+ if (ctx->getPipClass(pip) == 0) { // ignore fixed pips
+ set_pip(ctx, cc, pip);
+ }
+ }
+ }
+
// Configure chip
if (!text_config_file.empty()) {
std::ofstream out_config(text_config_file);