[Cryptech-Commits] [user/shatov/ice40mkm] 01/01: Utility script to convert iCE40 bitstream into .mcs format suitable for programming with Xilinx iMPACT tool.

git at cryptech.is git at cryptech.is
Mon Sep 13 08:23:50 UTC 2021


This is an automated email from the git hooks/post-receive script.

meisterpaul1 at yandex.ru pushed a commit to branch master
in repository user/shatov/ice40mkm.

commit 69eda72fa8db3e332de6a66a92f994dfed99de94
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Mon Sep 13 11:22:37 2021 +0300

    Utility script to convert iCE40 bitstream into .mcs format suitable for
    programming with Xilinx iMPACT tool.
---
 util/.gitignore       |   5 ++
 util/bitstream2mcs.py | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++
 util/requirements.txt |   1 +
 3 files changed, 168 insertions(+)

diff --git a/util/.gitignore b/util/.gitignore
new file mode 100644
index 0000000..03fbf09
--- /dev/null
+++ b/util/.gitignore
@@ -0,0 +1,5 @@
+.idea/
+venv/
+
+*.bin
+*.mcs
diff --git a/util/bitstream2mcs.py b/util/bitstream2mcs.py
new file mode 100644
index 0000000..571375f
--- /dev/null
+++ b/util/bitstream2mcs.py
@@ -0,0 +1,162 @@
+# ---------------------------------------------------------------------------------------------------------------------
+# bitstream2mcs.py
+# ---------------------------------------------------------------------------------------------------------------------
+#
+# Convert iCE40 bitstream into .mcs format suitable for programming using Xilinx iMPACT tool. Xilinx .mcs is in fact
+# just plain Intel Hex. Since the beginning of our configuration memory is occupied by the main FPGA bitstream, we
+# have to move iCE40 bitstream to the end of the configuration memory space.
+#
+# ---------------------------------------------------------------------------------------------------------------------
+#
+# Copyright 2021 The Commons Conservancy Cryptech Project
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Imports
+# ---------------------------------------------------------------------------------------------------------------------
+import os
+import sys
+import math
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# More Imports
+# ---------------------------------------------------------------------------------------------------------------------
+from typing import Union
+from intelhex import IntelHex
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Settings
+# ---------------------------------------------------------------------------------------------------------------------
+LATTICE_MAGIC_MARKER = b'\x7E\xAA\x99\x7E'
+
+PROM_SECTOR_SIZE = 256 * 256
+PROM_NUM_SECTORS = 256
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _load_bitstream(filename: str) -> Union[bytes, None]:
+
+    # try to load input bitstream
+    try:
+        with open(filename, 'rb') as f:
+            bitstream = f.read()
+    except FileNotFoundError:
+        print("File '%s' not found." % filename)
+        return
+    finally:
+        len_bitstream_orig = len(bitstream)
+        print("File '%s' loaded, %d bytes." % (filename, len_bitstream_orig))
+
+    # try to strip header
+    while not bitstream.startswith(LATTICE_MAGIC_MARKER):
+        bitstream = bitstream[1:]
+        if not bitstream:
+            print("Magic marker not found??")
+            return
+
+    # print how many bytes we stripped
+    num_stripped_bytes = len_bitstream_orig - len(bitstream)
+    print("Stripped %d bytes before the magic marker." % num_stripped_bytes)
+
+    # done
+    return bitstream
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _save_mcs(offset: int, bitstream: bytes, filename: str) -> int:
+
+    # create Intel Hex class
+    ih = IntelHex()
+
+    # initialize memory from bitstream
+    ih.frombytes(bitstream, offset=offset)
+
+    # write memory to file
+    with open(filename, 'w') as f:
+        ih.write_hex_file(f)
+
+    # done
+    return 0
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _bitstream2mcs(filename_in: str, filename_out: str) -> int:
+
+    # load bitstream
+    bitstream = _load_bitstream(filename_in)
+    if bitstream is None:
+        return 1
+
+    # determine number of sectors needed
+    num_sectors = math.ceil(len(bitstream) / PROM_SECTOR_SIZE)
+    print("Number of PROM sectors needed: %d" % num_sectors)
+    prom_offset = (PROM_NUM_SECTORS - num_sectors) * PROM_SECTOR_SIZE
+    print("Bitstream offset: 0x%x" % prom_offset)
+
+    # save mcs
+    return _save_mcs(prom_offset, bitstream, filename_out)
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def print_usage() -> int:
+    print("USAGE: %s <bitstream.bin> <bitstream.mcs>" % os.path.basename(sys.argv[0]))
+    return 2
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def main() -> int:
+
+    # check, that exactly two arguments were supplied
+    if len(sys.argv) != 3:
+        return print_usage()
+
+    # now run the script
+    return _bitstream2mcs(sys.argv[1], sys.argv[2])
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+if __name__ == '__main__':
+    sys.exit(main())
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# End-of-File
+# ---------------------------------------------------------------------------------------------------------------------
diff --git a/util/requirements.txt b/util/requirements.txt
new file mode 100644
index 0000000..e4a435a
--- /dev/null
+++ b/util/requirements.txt
@@ -0,0 +1 @@
+intelhex==2.3.0



More information about the Commits mailing list