#!/usr/bin/env python3
'''
UltraScalePlus bitstream analyzer tool.

This script reads a UltraScalePlus bitstream and prints out some useful information.
It can also create a frames file with the configuration data words.
The bitstream is analyzed word by word and interpreted according to
the UG570 Configuration User Guide.

The tool can be used to derive the initialization, startup and finalization
sequence as well as the configuration data. The latter is written to a frames
file which can be used by the bitstream tools such as frames2bit to generate
a valid bitstream.
'''

import argparse
from io import StringIO

conf_regs = {
    0: "CRC",
    1: "FAR",
    2: "FDRI",
    3: "FDRO",
    4: "CMD",
    5: "CTL0",
    6: "MASK",
    7: "STAT",
    8: "LOUT",
    9: "COR0",
    10: "MFWR",
    11: "CBC",
    12: "IDCODE",
    13: "AXSS",
    14: "COR1",
    16: "WBSTAR",
    17: "TIMER",
    22: "BOOTSTS",
    24: "CTL1",
    31: "BSPI"
}

cmd_reg_codes = {
    0: "NULL",
    1: "WCFG",
    2: "MFW",
    3: "LFRM",
    4: "RCFG",
    5: "START",
    7: "RCRC",
    8: "AGHIGH",
    9: "SWITCH",
    10: "GRESTORE",
    11: "SHUTDOWN",
    13: "DESYNC",
    15: "IPROG",
    16: "CRCC",
    17: "LTIMER",
    18: "BSPI_READ",
    19: "FALL_EDGE"
}

opcodes = ("NOP", "READ", "WRITE", "UNKNOWN")


class Bitstream:
    def __init__(self, file_name, verbose=False):
        self.frame_data = []
        self.fdri_write_len = 0
        self.fdri_in_progress = False
        self.words = []
        with open(file_name, "rb") as f:
            word = f.read(4)
            while word:
                self.words.append(int.from_bytes(word, byteorder='big'))
                word = f.read(4)
        pos, self.header = self.get_header()
        self.body = self.words[pos + 1:]
        self.parse_bitstream(verbose)

    def get_header(self):
        '''Return position and content of header'''
        pos = self.words.index(0xaa995566)
        return pos, self.words[:pos + 1]

    def parse_bitstream(self, verbose):
        payload_len = 0
        for word in self.body:
            if payload_len > 0:
                payload_len = self.parse_reg(reg_addr, word, payload_len,
                                             verbose)
                continue
            else:
                packet_header = self.parse_packet_header(word)
                opcode = packet_header["opcode"]
                reg_addr = packet_header["reg_addr"]
                words = packet_header["word_count"]
                type = packet_header["type"]
                if verbose:
                    if not opcode:
                        print("\n\tNOP")
                    else:
                        print(
                            "\n\tConfiguration Register Word: ", hex(word),
                            'Type: {}, Op: {}, Addr: {} ({}), Words: {}'.
                            format(
                                type, opcodes[opcode], conf_regs[reg_addr]
                                if reg_addr in conf_regs else "UNKNOWN",
                                reg_addr, words))
                if opcode and reg_addr in conf_regs:
                    payload_len = words
                    if conf_regs[reg_addr] == "FDRI" and type == 1:
                        self.fdri_in_progress = True
                        self.fdri_write_len = payload_len
                    continue

    def parse_packet_header(self, word):
        type = (word >> 29) & 0x7
        opcode = (word >> 27) & 0x3
        reg_addr = (word >> 13) & 0x1F
        if type == 1:
            word_count = word & 0x7FF
        elif type == 2:
            word_count = word & 0x7FFFFFF
        else:
            word_count = 0
        return {
            "type": type,
            "opcode": opcode,
            "reg_addr": reg_addr,
            "word_count": word_count
        }

    def parse_command(self, word, verbose):
        if verbose:
            print("\tCommand: {} ({})".format(cmd_reg_codes[word], word))

    #TODO Add COR0 options parsing
    def parse_cor0(self, word, verbose):
        if verbose:
            print("\tCOR0 options: {:08X}".format(word))

    def parse_reg(self, reg_addr, word, payload_len, verbose):
        assert reg_addr in conf_regs
        reg = conf_regs[reg_addr]
        if reg == "CMD":
            self.parse_command(word, verbose)
        elif reg == "COR0":
            self.parse_cor0(word, verbose)
        elif reg == "FDRI":
            # We are in progress of a FDRI operation
            # Keep adding data words
            if self.fdri_in_progress:
                if verbose:
                    print("\t{:2d}. 0x{:08X}".format(
                        self.fdri_write_len - payload_len, word))
                self.frame_data.append(word)
                if payload_len == 1:
                    self.fdri_in_progress = False
                    return 0
            else:
                #FIXME add Type 2 FDRI writes
                assert False
                #self.curr_fdri_write_len = word
                #self.fdri_in_progress = True
                # Check if 0 words actually means read something
                #payload_len = self.curr_fdri_write_len
                #if verbose:
                #    print("\t{}: {}\n".format(reg, self.curr_fdri_write_len))
                #return payload_len
        else:
            if verbose:
                print("\tRegister: {} Value: 0x{:08X}".format(reg, word))
        payload_len -= 1
        return payload_len

    def write_frames_txt(self, file_name):
        '''Write frame data in a more readable format'''
        frame_stream = StringIO()
        for i in range(len(self.frame_data)):
            if i % 93 == 0:
                frame_stream.write("\nFrame {:4}\n".format(i // 93))
        with open(file_name, "w") as f:
            print(frame_stream.getvalue(), file=f)

    #FIXME Add storing of frame address
    def write_frames(self, file_name):
        '''Write configuration data to frames file'''
        frame_stream = StringIO()
        for i in range(len(self.frame_data)):
            if i % 93 == 0:
                frame_stream.write("0x{:08x} ".format(i // 93))
            frame_stream.write("0x{:04x}".format(self.frame_data[i]))
            if i % 93 == 92:
                frame_stream.write("\n")
            elif i < len(self.frame_data) - 1:
                frame_stream.write(",")
        with open(file_name, "w") as f:
            print(frame_stream.getvalue(), file=f)


def main(args):
    verbose = not args.silent
    bitstream = Bitstream(args.bitstream, verbose)
    print("Frame data length: ", len(bitstream.frame_data))
    if args.frames_out:
        bitstream.write_frames(args.frames_out)
        #bitstream.write_frames_txt(args.frames_out + ".txt")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--bitstream', help='Input bitstream')
    parser.add_argument('--frames_out', help='Output frames file')
    parser.add_argument(
        '--silent', help="Don't print analysis details", action='store_true')
    args = parser.parse_args()
    main(args)
