libtrellis: Allow specifying idcode override in ecpunpack

Signed-off-by: Jens Andersen <jens.andersen@gmail.com>
diff --git a/libtrellis/tools/ecpunpack.cpp b/libtrellis/tools/ecpunpack.cpp
index d76aba1..68ad3a8 100644
--- a/libtrellis/tools/ecpunpack.cpp
+++ b/libtrellis/tools/ecpunpack.cpp
@@ -3,6 +3,7 @@
 #include "Chip.hpp"
 #include "Database.hpp"
 #include <iostream>
+#include <boost/optional.hpp>
 #include <boost/program_options.hpp>
 #include <stdexcept>
 #include <streambuf>
@@ -14,6 +15,7 @@
 {
     using namespace Trellis;
     namespace po = boost::program_options;
+    boost::optional<uint32_t> idcode;
 
     std::string database_folder = TRELLIS_PREFIX "/share/trellis/database";
 
@@ -21,6 +23,7 @@
     options.add_options()("help,h", "show help");
     options.add_options()("verbose,v", "verbose output");
     options.add_options()("db", po::value<std::string>(), "Trellis database folder location");
+    options.add_options()("idcode", po::value<std::string>(), "IDCODE to override in bitstream");
     po::positional_options_description pos;
     options.add_options()("input", po::value<std::string>()->required(), "input bitstream file");
     pos.add("input", 1);
@@ -59,6 +62,17 @@
         database_folder = vm["db"].as<string>();
     }
 
+    if (vm.count("idcode")) {
+        string idcode_str = vm["idcode"].as<string>();
+        uint32_t idcode_val;
+        idcode_val = uint32_t(strtoul(idcode_str.c_str(), nullptr, 0));
+        if (idcode_val == 0) {
+            cerr << "Invalid idcode: " << idcode_str << endl;
+            return 1;
+        }
+        idcode = idcode_val;
+    }
+
     try {
         load_database(database_folder);
     } catch (runtime_error &e) {
@@ -67,7 +81,7 @@
     }
 
     try {
-        Chip c = Bitstream::read_bit(bit_file).deserialise_chip();
+        Chip c = Bitstream::read_bit(bit_file).deserialise_chip(idcode);
         ChipConfig cc = ChipConfig::from_chip(c);
         ofstream out_file(vm["textcfg"].as<string>());
         if (!out_file) {