[Cryptech-Commits] [user/shatov/ice40mkm] branch master updated: Script to combine main FPGA bitstream with the MKM bitmap so that the combined binary blob can be flashed using the upload script.

git at cryptech.is git at cryptech.is
Mon Dec 20 09:51:41 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.

The following commit(s) were added to refs/heads/master by this push:
     new 9ecc9e8  Script to combine main FPGA bitstream with the MKM bitmap so that the combined binary blob can be flashed using the upload script.
9ecc9e8 is described below

commit 9ecc9e83e8d182b7dbc3e21f3ba7870747c81e92
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Mon Dec 20 12:50:54 2021 +0300

    Script to combine main FPGA bitstream with the MKM bitmap so that the combined
    binary blob can be flashed using the upload script.
---
 util/.gitignore         |   1 +
 util/link_bitstreams.py | 205 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 206 insertions(+)

diff --git a/util/.gitignore b/util/.gitignore
index 03fbf09..f7d1bfe 100644
--- a/util/.gitignore
+++ b/util/.gitignore
@@ -1,5 +1,6 @@
 .idea/
 venv/
 
+*.bit
 *.bin
 *.mcs
diff --git a/util/link_bitstreams.py b/util/link_bitstreams.py
new file mode 100644
index 0000000..7e1439a
--- /dev/null
+++ b/util/link_bitstreams.py
@@ -0,0 +1,205 @@
+# ---------------------------------------------------------------------------------------------------------------------
+# link_bitstreams.py
+# ---------------------------------------------------------------------------------------------------------------------
+#
+# Glue iCE40 bitstream to the main FPGA bitstream. The MKM bitstream is aligned on a sector boundary.
+#
+# ---------------------------------------------------------------------------------------------------------------------
+#
+# 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 enum import Enum
+from typing import Optional
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Markers
+# ---------------------------------------------------------------------------------------------------------------------
+MARKER_XILINX = b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
+                b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
+                b"\x00\x00\x00\xBB\x11\x22\x00\x44\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
+                b"\xAA\x99\x55\x66"
+
+MARKER_LATTICE = b"\x7E\xAA\x99\x7E"
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+class FPGA(Enum):
+    Artix7 = 'artix7'
+    iCE40 = 'ice40'
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Settings
+# ---------------------------------------------------------------------------------------------------------------------
+PROM_PAGE_BYTES = 256
+PROM_SECTOR_BYTES = 256 * PROM_PAGE_BYTES
+
+MARKER_DICT = {FPGA.Artix7: MARKER_XILINX,
+               FPGA.iCE40: MARKER_LATTICE}
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _load_bitstream(filename: str, fpga: FPGA) -> Optional[bytes]:
+
+    # 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))
+
+    # check magic marker and strip leading bytes
+    bitstream = _check_marker(bitstream, fpga)
+
+    # done
+    return bitstream
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _check_marker(bitstream: bytes, fpga: FPGA) -> Optional[bytes]:
+
+    len_bitstream_orig = len(bitstream)
+    marker = MARKER_DICT[fpga]
+
+    # check, that marker is present
+    if marker not in bitstream:
+        print("  Magic marker for device '%s' not found, did you specify the right filename?" % fpga.value)
+        return
+
+    # try to strip leading redundant bytes
+    while not bitstream.startswith(marker):
+        bitstream = bitstream[1:]
+
+    # 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_bit(bitstream: bytes, filename: str) -> int:
+
+    # write memory to file
+    with open(filename, 'wb') as f:
+        f.write(bitstream)
+
+    print("Output bitstream written.")
+
+    # done
+    return 0
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def _link_bitstreams(filename_artix7: str, filename_ice40: str, filename_output: str) -> int:
+
+    # load bitstream
+    bitstream_artix7 = _load_bitstream(filename_artix7, FPGA.Artix7)
+    bitstream_ice40 = _load_bitstream(filename_ice40, FPGA.iCE40)
+    if bitstream_artix7 is None or bitstream_ice40 is None:
+        return 1
+
+    # grow main bitstream to sector boundary
+    num_sectors_artix7 = math.ceil(len(bitstream_artix7) / PROM_SECTOR_BYTES)
+    num_padding_bytes = num_sectors_artix7 * PROM_SECTOR_BYTES - len(bitstream_artix7)
+    print("Added %d byte(s) after the main bitstream to align the MKM bitmap on sector boundary." % num_padding_bytes)
+    padding_bytes = bytes(0xFF for _ in range(num_padding_bytes))
+    bitstream_artix7_padded = bitstream_artix7 + padding_bytes
+
+    # glue two bitstreams
+    bitstream_output = bitstream_artix7_padded + bitstream_ice40
+
+    # fill bitstream with 0xFF's up to page boundary
+    num_padding_bytes = PROM_PAGE_BYTES - (len(bitstream_output) % 256)
+    print("Added %d byte(s) after the mkm bitmap to align output on page boundary." % num_padding_bytes)
+    padding_bytes = bytes(0xFF for _ in range(num_padding_bytes))
+    bitstream_output += padding_bytes
+
+    # save bit
+    return _save_bit(bitstream_output, filename_output)
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def print_usage() -> int:
+    print("USAGE: %s <fpga_bitstream.bit> <mkm_bitmap.bin> <combined_bitstream.bit>" %
+          os.path.basename(sys.argv[0]))
+    return 2
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+def main() -> int:
+
+    # check, that exactly three arguments were supplied
+    if len(sys.argv) != 4:
+        return print_usage()
+
+    # now run the script
+    return _link_bitstreams(*sys.argv[1:4])
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+if __name__ == '__main__':
+    sys.exit(main())
+# ---------------------------------------------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------------------------------------------------------------
+# End-of-File
+# ---------------------------------------------------------------------------------------------------------------------

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Commits mailing list