5
5
# Written by Myrtle Shah <[email protected] >
6
6
# SPDX-License-Identifier: GPL-2.0-only
7
7
#
8
- # patch_uds_udi.py
9
- # --------------
10
- # Python program that patches the UDS and UDI implemented using
11
- # named LUT4 instances to have unique initial values, not the generic
12
- # values used during synthesis, p&r and mapping. This allows us to
13
- # generate device unique bitstreams without running the complete flow.
8
+ # Script to patch in a Unique Device Secret (UDS) and a Unique Device
9
+ # Identifier (UDI) from files into a bitstream.
14
10
#
15
- # Both the UDI and UDS are using bit indexing from 32 LUTs for each
16
- # word, i.e., the first word consists of bit 0 from each 32 LUTs and
17
- # so on.
11
+ # It's supposed to be run like this:
18
12
#
19
- # The size requirements for the UDI and UDS are specified as 1 bit (8
20
- # bytes of data) and 3 bits (32 bytes of data), respectively. The UDI
21
- # does not occupy the entire LUT4 instance, and to conserve resources,
22
- # the pattern of the UDI is repeated over the unused portion of the
23
- # LUT4 instance. This eliminates the need to drive the three MSB pins
24
- # while still achieving the correct output.
13
+ # nextpnr-ice40 --up5k --package sg48 --ignore-loops \
14
+ # --json application_fpga_par.json --run patch_uds_udi.py
25
15
#
26
- # In the case of UDS, a read-enable signal is present, and the most
27
- # significant bit serves as the read-enable input. This requires the
28
- # lower half of initialization bits to be forced to zero, ensuring
29
- # that the memory outputs zero when the read-enable signal is
30
- # inactive.
16
+ # with this environment:
31
17
#
18
+ # - UDS_HEX: path to the UDS file, typically the path to
19
+ # ../data/uds.hex
20
+ # - UDI_HEX: path to the UDI file, typically the path to ../data/udi.hex
21
+ # - OUT_ASC: path to the ASC output that is then used by icebram and icepack.
32
22
#
33
- #=======================================================================
23
+ # The script changes the UDS and UDI that are stored in named 4-bit
24
+ # LUT instances in the JSON file so we can generate device
25
+ # unique bitstreams without running the complete flow just to change
26
+ # UDS and UDI. Then we can just run the final bitstream generation
27
+ # from the ASC file.
28
+ #
29
+ # We represent our UDI and UDS values as a number of 32 bit words:
30
+ #
31
+ # - UDI: 2 words.
32
+ # - UDS: 8 words.
33
+ #
34
+ # We reserve 32 named 4-bit LUTs *each* to store the data: UDS in
35
+ # "uds_rom_idx" and UDI in "udi_rom_idx".
36
+ #
37
+ # The script repeats the value in the LUTs so we don't have to care
38
+ # about the value of the unused address bits.
39
+ #
40
+ # See documentation in their implementation in ../core/uds/README.md
41
+ # and ../core/tk1/README.md
34
42
35
43
import os
36
44
@@ -49,7 +57,8 @@ def rewrite_lut(lut, idx, data, has_re=False):
49
57
new_init = 0
50
58
for i , word in enumerate (data ):
51
59
if (word >> idx ) & 0x1 :
52
- # repeat so inputs above address have a don't care value
60
+ # repeat so we don't have to care about inputs above
61
+ # address
53
62
repeat = (16 // len (data ))
54
63
for k in range (repeat ):
55
64
# UDS also has a read enable
0 commit comments