Design-related Tooling Scripts
Life Cycle and OTP Tools
OTP Memory Map Translation Script
The gen-otp-mmap.py
script is used to translate the OTP memory map definition Hjson file into documentation and SV package collateral.
The memory map definition file for top_earlgrey is currently located at hw/ip/otp_ctrl/data/otp_ctrl_mmap.hjson
.
The script can either be invoked via the makefile
$ cd ${PROJ_ROOT}
$ make -C hw otp-mmap
or directly using the command
$ cd ${PROJ_ROOT}
$ ./util/design/gen-otp-mmap.py
The seed value used for generating OTP-related random netlist constants can optionally be overridden with the --seed
switch when calling the script directly.
Otherwise that seed value is taken from the Hjson file, or generated on-the-fly if the Hjson file does not contain a seed.
Life Cycle State Encoding Generator
The gen-lc-state-enc.py
script is used to generate the redundant life cycle state encoding and print the constants and type definitions into the life cycle state package.
The life cycle definition file for top_earlgrey is currently located at hw/ip/lc_ctrl/data/lc_ctrl_state.hjson
.
The script can either be invoked via the makefile
$ cd ${PROJ_ROOT}
$ make -C hw lc-state-enc
or directly using the command
$ cd ${PROJ_ROOT}
$ ./util/design/gen-lc-state-enc.py
The seed value used for generating life-cycle-state-related random netlist constants can optionally be overridden with the --seed
switch when calling the script directly.
Otherwise that seed value is taken from the Hjson file, or generated on-the-fly if the Hjson file does not contain a seed.
OTP Preload Image Generator
The OTP preload image generation tool builds on top of the memory map and life cycle state generation Python classes in order to transform a memory image configuration into a memory hexfile that can be used for OTP preloading in simulation and FPGA emulation runs.
The generated hexfile is compatible with the Verilog $readmemh
command.
The OTP memory image configuration file is basically an Hjson file that lists the names and corresponding values of items defined in the OTP memory map definition. Further, since the life cycle state is stored in OTP, the image generator script also supports generating the correct life cycle state encodings. To that end, the desired life cycle state name can be declared in the image configuration file, and the generator script looks up and assigns the correct netlist constants.
The following snippet shows a memory image configuration that puts the device into the DEV
life cycle state, and that defines the SECRET2 partition items and locks down the partition:
{
// Seed to be used for generation of partition randomized values.
// Can be overridden on the command line.
seed: 01931961561863975174
// The partition and item names must correspond with the OTP memory map.
partitions: [
{
name: "SECRET2",
// If True, a digest will be calculated for this partition.
// Note that this only applies to partitions with a hardware digest.
lock: "True",
items: [
{
name: "RMA_TOKEN",
// This item is assigned is a fixed Hex value
value: "0x9cfbd7383959a62a4438bc468d76eed6 ",
}
{
name: "CREATOR_ROOT_KEY_SHARE0",
// This item will be assigned a random value, based on the seed above.
value: "<random>",
}
{
name: "CREATOR_ROOT_KEY_SHARE1",
// This item will be assigned a random value, based on the seed above.
value: "<random>",
}
],
}
{
name: "LIFE_CYCLE",
// Can be one of the following strings:
// RAW, TEST_UNLOCKED0-3, TEST_LOCKED0-2, DEV, PROD, PROD_END, RMA, SCRAP
state: "DEV",
// Can be either "RAW", or any number from 1 to 16.
count: "5"
}
]
}
Common example configuration files that can be used for simulation and emulation are checked in under hw/ip/otp_ctrl/data
, e.g. hw/ip/otp_ctrl/data/otp_ctrl_img_dev.hjson
which provisions all buffered partitions and puts the device into the DEV
life cycle.
Note that the preload image generator script automatically scrambles secret partitions, computes digests of locked partitions using the PRESENT cipher, and computes the OTP ECC bits.
The OTP preload image generator expects at least one main image configuration file to be specified with the --img-cfg
switch, for example:
$ cd ${PROJ_ROOT}
$ ./util/design/gen-otp-img.py --img-cfg hw/ip/otp_ctrl/data/otp_ctrl_img_dev.hjson \
--out otp-img.mem
Additional configuration files can be added using the --add-cfg
switch.
The switch can be specified multiple times, and the configuration files are processed in the order they are specified.
This allows to incrementally “patch in” additional data, if needed.
For example, this can be used to patch in additional software configuration data, specified in an additional file otp_ctrl_img_sw_cfg.hjson
that looks as follows (it is also possible to split the individual items into their own files):
{
// The partition and item names must correspond with the OTP memory map.
partitions: [
{
name: "CREATOR_SW_CFG",
items: [
{
name: "CREATOR_SW_CFG_CONTENT",
value: "0x0", // data to be put into this partition
}
{
name: "CREATOR_SW_CFG_DIGEST",
value: "0x0", // 64bit digest to be written to this partition
}
],
},
{
name: "OWNER_SW_CFG",
items: [
{
name: "OWNER_SW_CFG_CONTENT",
value: "0x0", // data to be put into this partition
}
{
name: "OWNER_SW_CFG_DIGEST",
value: "0x0", // 64bit digest to be written to this partition
}
],
}
]
}
The generator script call would then look as follows:
$ cd ${PROJ_ROOT}
$ ./util/design/gen-otp-img.py --img-cfg hw/ip/otp_ctrl/data/otp_ctrl_img_dev.hjson \
--add-cfg otp_ctrl_img_sw_cfg.hjson \
--out otp-img.mem
ECC Generator Tool
TODO
LFSR Coefficient Generator Tool
The get-lfsr-coeffs.py
script is used to fetch a list of primitive polynomials for Galois and Fibonacci type LFSRs.
By default, the coefficients are downloaded from https://users.ece.cmu.edu/~koopman/lfsr/. The script downloads text files containing the first 100 primitive polynomials for LFSR widths ranging from 4 to 64 and places them into a temporary folder. The script also produces an output file containing a SystemVerilog template with LFSR polynomials for widths 4 to 64. This template contains exactly one polynomial for each LFSR width, which is always the first polynomial listed in the corresponding file.
When used with the --pdf <pdf file>
option, the script outputs polynomials extracted from the Xilinx application note.
To run this option, the user first needs to download the Xilinx application note from https://docs.xilinx.com/v/u/en-US/xapp052.
The produced output file contains a SystemVerilog template with LFSR polynomials for widths ranging from 3 to 168.
LFSR Seed Generator Tool
The gen-lfsr-seed.py
script creates a SystemVerilog template for LFSR parameters, i.e. width, default seed and the permutation of the output bits.
Switch -w
is used to specify the LFSR width.
The other two parameters are generated randomly.
The seed for the underlying pseudo-random number generator can optionally be passed using the --seed
parameter.
An optional name prefix can be specified using the --prefix
parameter.
For example, running the following command:
$ cd ${PROJ_ROOT}
$ ./util/design/gen-lfsr-seed.py -w 8 --prefix "my"
produces the following parameters for an 8-bit LFSR.
------------------------------------------------
| COPY PASTE THE CODE TEMPLATE BELOW INTO YOUR |
| RTL CODE, INLUDING THE COMMENT IN ORDER TO |
| EASE AUDITABILITY AND REPRODUCIBILITY. |
------------------------------------------------
// These LFSR parameters have been generated with
// $ ./util/design/gen-lfsr-seed.py --width 8 --seed 3816832368 --prefix "my"
parameter int myLfsrWidth = 8;
typedef logic [myLfsrWidth-1:0] my_lfsr_seed_t;
typedef logic [myLfsrWidth-1:0][$clog2(myLfsrWidth)-1:0] my_lfsr_perm_t;
parameter my_lfsr_seed_t RndCnstmyLfsrSeedDefault = {
8'h3a
};
parameter my_lfsr_perm_t RndCnstmyLfsrPermDefault = {
24'hde9622
};
Sparse FSM State Encoding Tool
TODO
KECCAK Coefficient Generation Tool
TODO