#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""This script generates random seeds and state permutations for LFSRs
and outputs them them as a packed SV logic vectors suitable for use with
prim_lfsr.sv.
"""
import argparse
import random
import textwrap
import logging as log
from math import ceil, log2


SV_INSTRUCTIONS = """
------------------------------------------------
| COPY PASTE THE CODE TEMPLATE BELOW INTO YOUR |
| RTL CODE, INLUDING THE COMMENT IN ORDER TO   |
| EASE AUDITABILITY AND REPRODUCIBILITY.       |
------------------------------------------------
"""


def _as_snake_case_prefix(name):
    """ Convert PascalCase name into snake_case name"""
    outname = ""
    for c in name:
        if c.isupper() and len(outname) > 0:
            outname += '_'
        outname += c.lower()
    return outname + ('_' if name else '')


def _get_random_data_hex_literal(width):
    """ Fetch 'width' random bits and return them as hex literal"""
    width = int(width)
    literal_str = hex(random.getrandbits(width))
    literal_str = str(width) + "'h" + literal_str[2:]
    return literal_str


def _blockify(s, size, limit):
    """ Make sure the output does not exceed a certain size per line"""

    str_idx = 2
    remain = size % (limit * 4)
    numbits = remain if remain else limit * 4
    s_list = []

    remain = size
    while remain > 0:
        s_incr = int(numbits / 4)
        s_list.append("{}'h{}".format(numbits, s[str_idx: str_idx + s_incr]))
        str_idx += s_incr
        remain -= numbits
        numbits = limit * 4

    return(",\n  ".join(s_list))


def _get_random_perm_hex_literal(numel):
    """ Compute a random permutation of 'numel' elements and
    return as packed hex literal"""
    num_elements = int(numel)
    width = int(ceil(log2(num_elements)))
    idx = [x for x in range(num_elements)]
    random.shuffle(idx)
    literal_str = ""
    for k in idx:
        literal_str += format(k, '0' + str(width) + 'b')
    # convert to hex for space efficiency
    literal_str = hex(int(literal_str, 2))
    return _blockify(literal_str, width * numel, 64)


def _wrapped_docstring():
    '''Return a text-wrapped version of the module docstring'''
    paras = []
    para = []
    for line in __doc__.strip().split('\n'):
        line = line.strip()
        if not line:
            if para:
                paras.append('\n'.join(para))
                para = []
        else:
            para.append(line)
    if para:
        paras.append('\n'.join(para))

    return '\n\n'.join(textwrap.fill(p) for p in paras)


def main():
    log.basicConfig(level=log.INFO,
                    format="%(asctime)s - %(message)s",
                    datefmt="%Y-%m-%d %H:%M")

    parser = argparse.ArgumentParser(
        prog="gen-lfsre-perm",
        description=_wrapped_docstring(),
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('-w',
                        '--width',
                        type=int,
                        default=32,
                        metavar='<#bitwidth>',
                        help='LFSR width.')
    parser.add_argument('-s',
                        '--seed',
                        type=int,
                        metavar='<seed>',
                        help='Custom seed for RNG.')
    parser.add_argument('-p',
                        '--prefix',
                        type=str,
                        metavar='name',
                        default="",
                        help='Optional prefix to add to '
                             'types and parameters. '
                             'Make sure this is PascalCase.')

    args = parser.parse_args()

    if args.width <= 0:
        log.error("LFSR width must be nonzero")
        exit(1)

    if args.seed is None:
        random.seed()
        args.seed = random.getrandbits(32)

    random.seed(args.seed)

    print(SV_INSTRUCTIONS)

    type_prefix = _as_snake_case_prefix(args.prefix)

    outstr = '''
// These LFSR parameters have been generated with
// $ hw/ip/prim/util/gen-lfsr-seed.py --width {} --seed {} --prefix "{}"
parameter int {}LfsrWidth = {};
typedef logic [{}LfsrWidth-1:0] {}lfsr_seed_t;
typedef logic [{}LfsrWidth-1:0][$clog2({}LfsrWidth)-1:0] {}lfsr_perm_t;
parameter {}lfsr_seed_t RndCnst{}LfsrSeedDefault = {};
parameter {}lfsr_perm_t RndCnst{}LfsrPermDefault = {{
  {}
}};
'''.format(args.width, args.seed, args.prefix,
           args.prefix, args.width,
           args.prefix, type_prefix,
           args.prefix, args.prefix, type_prefix,
           type_prefix, args.prefix, _get_random_data_hex_literal(args.width),
           type_prefix, args.prefix, _get_random_perm_hex_literal(args.width))

    print(outstr)


if __name__ == "__main__":
    main()
