def buildStructMembers(chip, struct):
    # Write a single field
    def writeField(out, field):
        bit_width = field["bits"][chip][1] - field["bits"][chip][0] + 1
        line = ("\t\t" + c_type + " " +
                field["name"]).ljust(38) + " : " + str(bit_width) + ";"
        access = field.get("access", None)
        if access:
            access = "(%s)" % access[chip]
        else:
            access = ""
        line += "\n"
        out.write(line)

    fields = struct["fields"]
    out = StringIO.StringIO()
    total_size = csr_utils.getSizeBits(struct, multipleOf=32)
    if total_size % 64 == 0:
        c_type = "u64"
        word_size = 64
    else:
        c_type = "u32"
        word_size = 32
    num_words = total_size / word_size
    for word in range(num_words):
        # Create a list of all fields in this word
        min_bit = word * word_size
        max_bit = min_bit + word_size - 1
        word_fields = {}
        for name in fields:
            # Skip fields not in this chip
            if not chip in fields[name]["bits"]:
                continue
            # Add fields in this word to the word's field list
            bits = fields[name]["bits"][chip]
            if (bits[0] >= min_bit) and (bits[0] <= max_bit):
                if (bits[1] < min_bit) or (bits[1] > max_bit):
                    csr_utils.raiseException(fields[name],
                                             "Struct: Field spans a word")
                word_fields[bits[0]] = fields[name]
        # Sort the fields into big endian order
        bits = word_fields.keys()
        bits.sort()
        # Write the bits in little endian order
        for bit in bits:
            writeField(out, word_fields[bit])
    result = out.getvalue()
    out.close()
    return result
示例#2
0
def _validateReg(root, name):
    reg = root[name]
    # Validate the type name
    if not re.match("^[a-z][a-z0-9#_]*$", name):
        raiseException(reg, "Reg: Illegal name \"%s\"" % name)
    # Count the number of parameters
    num_params = name.count("#")
    # Limit to MAX_CSR_PARAMS parameters as a sanity check. This can be raised
    # bu editing the C database code
    if num_params > chip_list.MAX_CSR_PARAMS:
        raiseException(reg, "Reg: Too many params, name \"%s\"" % name)
    # Make sure the address equation agrees on the number of params
    for chip in reg["address"]:
        eq = reg["address"][chip]
        if isinstance(eq, StringType):
            continue
        if len(eq) != num_params + 1:
            raiseException(
                reg, "Reg: Unexpected equation length for %s %s" % (chip, eq))
        if len(reg["ranges"][chip]) != num_params:
            raiseException(
                reg, "Reg: Unexpected range length for %s %s" %
                (chip, reg["ranges"][chip]))
    # Check fields
    for n in reg["fields"]:
        if not re.match("^[a-z][a-z0-9_]*$", n):
            raiseException(reg, "Reg: Illegal field name \"%s\"" % n)
    # Find any missing bits
    chip_holes = csr_utils.findBitHoles(reg, multipleOf=32)
    # Create reserved fields for bits
    for chip in chip_holes:
        raiseException(
            reg, "Reg: Missing bits for chip %s %s" % (chip, chip_holes[chip]))
    # Sanity check the size. These can be changed without issue
    size = csr_utils.getSizeBits(reg, multipleOf=0)
    if (size != 32) and (size != 64):
        raiseException(struct, "Reg: Size not 32 or 64 bits")
示例#3
0
def _validateStruct(root, name):
    struct = root[name]
    # Validate the type name
    if not re.match("^[a-z][a-z0-9_]*$", name):
        raiseException(struct, "Struct: Illegal name \"%s\"" % name)
    for n in struct["fields"]:
        if not re.match("^[a-z][a-z0-9_]*$", n):
            raiseException(struct, "Struct: Illegal field name \"%s\"" % n)
    # Find any missing bits
    chip_holes = csr_utils.findBitHoles(struct, multipleOf=32)
    # Create reserved fields for bits
    for chip in chip_holes:
        if ((getChild(struct["attributes"][chip],
                      "allow_missing_bits",
                      allowMissing=True) == "True")
                or (getChild(struct["attributes"][chip],
                             "struct_not_64b_multiple",
                             allowMissing=True) == "True")):
            for hole in chip_holes[chip]:
                n = csr_utils.getReservedName(hole)
                if not n in struct["fields"]:
                    struct["fields"][n] = csr_data.StructField(n)
                assert not chip in struct["fields"][n]["bits"]
                struct["fields"][n]["bits"][chip] = hole
        else:
            raiseException(
                struct, "Struct: Missing bits for chip %s %s" %
                (chip, chip_holes[chip]))
    # Sanity check the size. These can be changed without issue
    size = csr_utils.getSizeBits(struct, multipleOf=0)
    if (size < 32):
        raiseException(struct, "Struct: Size smaller than 32 bits")
    if (size > 32) and (size % 64 != 0):
        raiseException(struct, "Struct: Must be multiple of 64 bits")
    if (size > 512 * 8):
        raiseException(struct, "Struct: Size smaller than 512 bytes")
def writeStruct(out, arch, struct, title="Structure"):
    out.write("\n")
    out.write("/**\n")
    out.write(" * %s %s\n" % (title, struct["name"]))
    description = getAnyField(struct, "description", arch)
    if description:
        out.write(" *\n")
        description = description.replace("<", "\<")
        description = description.replace(">", "\>")
        description = textwrap.dedent(description)
        description = textwrap.fill(description, 70)
        for l in description.split("\n"):
            l = l.rstrip()
            if l:
                out.write(" * %s\n" % l)
            else:
                out.write(" *\n")
    out.write(" */\n")
    struct_name = (PREFIX + struct["name"]).replace("#", "X").lower()
    out.write("union %s {\n" % struct_name)
    width = csr_utils.getSizeBits(struct, multipleOf=32)
    if width % 64 == 0:
        if width > 64:
            out.write("\tu64 u[%d];\n" % (width / 64))
        else:
            out.write("\tu64 u;\n")
    else:
        if width % 32 != 0:
            csr_utils.raiseException(
                struct, "Struct: Size expected to be a multiple of 32")
        if width > 32:
            out.write("\tu32 u[%d];\n" % (width / 32))
        else:
            out.write("\tu32 u;\n")
    # Create a dictionary of all per chip structures
    struct_items = {}
    for chip in struct["description"]:
        is_this_arch = csr_utils.isChipArch(arch, chip)
        if not is_this_arch:
            continue
        struct_items[chip] = buildStructMembers(chip, struct)
    # Consolidate all chips
    consolidateChips(struct_items)
    # Start writing structures with subset first
    written_structs = {}
    out.write("\tstruct %s_s {\n" % struct_name)
    subset = csr_utils.createSubset(arch, "s", struct)
    struct_chip = buildStructMembers("s", subset)
    written_structs[struct_chip] = struct_name + "_s"
    out.write(struct_chip)
    out.write("\t} s;\n")
    for chip in csr_data.iterChipOrder(struct_items):
        struct_chip = struct_items[chip]
        chip_member = chip_list.chipToStructName(chip)
        if struct_chip in written_structs:
            # Chip duplicates one we have already written
            out.write("\t/* struct %s %s; */\n" %
                      (written_structs[struct_chip], chip_member))
        else:
            # New structure
            name = "%s_%s" % (struct_name, chip_member)
            written_structs[struct_chip] = name
            out.write("\tstruct %s {\n" % name)
            out.write(struct_chip)
            out.write("\t} %s;\n" % chip_member)
    out.write("};\n")
示例#5
0
def buildStructMembers(chip, struct):
    # Write a single field
    def writeField(out, field):
        bit_width = field["bits"][chip][1] - field["bits"][chip][0] + 1
        line = ("        " + c_type + " " +
                field["name"]).ljust(38) + " : " + str(bit_width) + ";"
        description = formatDescription(field["description"].get(chip, ""), 66)
        access = field.get("access", None)
        if access:
            access = "(%s)" % access[chip]
        else:
            access = ""
        if not csr_utils.isReserved(field["name"]):
            description = description.replace("<", "\<")
            description = description.replace(">", "\>")
            l = line.ljust(45) + "/**< [%3d:%3d]%s %s */" % (
                field["bits"][chip][1], field["bits"][chip][0], access,
                description)
            line = ""
            for l in l.split("\n"):
                line += l.rstrip() + "\n"
        else:
            line += "\n"
        out.write(line)

    fields = struct["fields"]
    out = StringIO.StringIO()
    total_size = csr_utils.getSizeBits(struct, multipleOf=32)
    if total_size % 64 == 0:
        c_type = "uint64_t"
        word_size = 64
    else:
        c_type = "uint32_t"
        word_size = 32
    num_words = total_size / word_size
    for word in range(num_words):
        # Create a list of all fields in this word
        min_bit = word * word_size
        max_bit = min_bit + word_size - 1
        word_fields = {}
        for name in fields:
            # Skip fields not in this chip
            if not chip in fields[name]["bits"]:
                continue
            # Add fields in this word to the word's field list
            bits = fields[name]["bits"][chip]
            if (bits[0] >= min_bit) and (bits[0] <= max_bit):
                if (bits[1] < min_bit) or (bits[1] > max_bit):
                    csr_utils.raiseException(fields[name],
                                             "Struct: Field spans a word")
                word_fields[bits[0]] = fields[name]
        # Sort the fields into big endian order
        bits = word_fields.keys()
        bits.sort()
        bits.reverse()
        out.write(
            "#if __BYTE_ORDER == __BIG_ENDIAN /* Word %d - Big Endian */\n" %
            word)
        for bit in bits:
            writeField(out, word_fields[bit])
        # Write the bits in big endian order
        out.write("#else /* Word %d - Little Endian */\n" % word)
        # Write the bits in little endian order
        bits.reverse()
        for bit in bits:
            writeField(out, word_fields[bit])
        out.write("#endif /* Word %d - End */\n" % word)
    result = out.getvalue()
    out.close()
    return result
def writeDB(arch, regs):
    global globalStringTable
    global globalStringTableLookup
    global globalStringTableLen
    global globalNumberTable
    global globalNumberTableLen
    global globalFieldTable
    global globalFieldTableLen
    global globalFieldListTable
    global globalFieldListTableLen
    global globalRangeTable
    global globalRangeTableLen
    global globalParamIndexTable
    global globalParamIndexTableLen
    global globalCsrTable
    global globalCsrTableLen
    globalStringTable = {}
    globalStringTableLookup = {}
    globalStringTableLen = 0
    globalNumberTable = {}
    globalNumberTableLen = 0
    globalFieldTable = {}
    globalFieldTableLen = 0
    globalFieldListTable = {}
    globalFieldListTableLen = 0
    globalRangeTable = {}
    globalRangeTableLen = 0
    globalParamIndexTable = {}
    globalParamIndexTableLen = 0
    globalCsrTable = {}
    globalCsrTableLen = 0

    filename = "output/%s/%s.c" % (arch, FILE_PREFIX)
    out = open(filename, "w")
    writeCopyrightBanner(out)
    out.write('#include <bdk.h>\n')
    out.write("\n")
    empty_range = getRangeTable([(-1,-1)])

    #
    # Write the per chip CSR tables
    #

    null_csr_ranges = getParamIndexTable([0 for x in range(chip_list.MAX_CSR_PARAMS)])
    null_csr = getCsrTable("{0, 0, 0, BDK_CSR_TYPE_NCB, 0, 0, %d, %d}" % (null_csr_ranges, null_csr_ranges))
    for chip in chip_list.getChips():
        if not csr_utils.isChipArch(arch, chip):
            continue
        # Skip minor passes as they are basically the same as the major pass
        if not chip.endswith("_0"):
            continue
        out.write("static const int16_t __bdk_csr_db_%s[] = {\n" % chip)
        names = regs.keys()
        names.sort()
        for name in names:
            reg = regs[name]
            if not chip in reg["description"]:
                continue
            # Don't insert CSRs that we couldn't simplify the equation
            if isinstance(reg["address"][chip], StringType):
                continue
            # Skip dv_uvm_no_create registers
            if (("attributes" in reg) and (chip in reg["attributes"]) and
                ("dv_uvm_no_create" in reg["attributes"][chip])):
                    if reg["attributes"][chip]["dv_uvm_no_create"]:
                        assert reg["attributes"][chip]["dv_uvm_no_create"] == "True", "dv_uvm_no_create is expected to be True"
                        continue
            range_len = len(reg["ranges"][chip])
            assert range_len <= chip_list.MAX_CSR_PARAMS, "Only support %d params for now" % chip_list.MAX_CSR_PARAMS
            range_list = [empty_range for x in range(chip_list.MAX_CSR_PARAMS)]
            param_inc = [0 for x in range(chip_list.MAX_CSR_PARAMS)]
            for i in range(range_len):
                range_list[i] = getRangeTable(reg["ranges"][chip][i])
                param_inc[i] = getNumberTable(reg["address"][chip][i+1])
            range_index = getParamIndexTable(range_list)
            param_index = getParamIndexTable(param_inc)
            csr_str = "{%5d, %4d, %d, BDK_CSR_TYPE_%s, %d, %d, %d, %d}" % (
                        getStringTable(name.replace("#", "X")), # Name index
                        getNumberTable(reg["address"][chip][0]), # Base index
                        0, # Unused
                        reg["bus"][chip], # Bus Type
                        csr_utils.getSizeBits(reg, 32) / 8, # Width in bytes
                        getFieldListTable(reg, chip), # Field index
                        range_index,
                        param_index)
            csr_index = getCsrTable(csr_str)
            out.write("    %d, /* %s */\n" % (csr_index, name))

        out.write("    %s\n" % null_csr)
        out.write("};\n\n")
    #
    # Write the global CSR table
    #
    out.write("const __bdk_csr_db_type_t __bdk_csr_db_csr[] = {\n")
    keys = getKeysSorted(globalCsrTable)
    for key in keys:
        out.write("    %s, /* %d */\n" % (key, globalCsrTable[key]))
    out.write("};\n\n")
    #
    # Write the CSR fieldList table
    #
    out.write("const uint16_t __bdk_csr_db_fieldList[] = {\n")
    keys = getKeysSorted(globalFieldListTable)
    for key in keys:
        out.write("    %s, /* %d */\n" % (key, globalFieldListTable[key]))
    out.write("};\n\n")
    #
    # Write the CSR field table
    #
    out.write("const __bdk_csr_db_field_t __bdk_csr_db_field[] = {\n")
    keys = getKeysSorted(globalFieldTable)
    for key in keys:
        out.write("    %s, /* %d */\n" % (key, globalFieldTable[key]))
    out.write("};\n\n")
    #
    # Write the CSR range table
    #
    out.write("const int __bdk_csr_db_range[] = {\n")
    keys = getKeysSorted(globalRangeTable)
    for key in keys:
        out.write("    %s, /* %d */\n" % (key, globalRangeTable[key]))
    out.write("};\n\n")
    #
    # Write the CSR string table
    #
    out.write("const char __bdk_csr_db_string[] = ")
    keys = getKeysSorted(globalStringTable)
    for key in keys:
        if len(key) &1 == 0:
            out.write("\n    \"%s\\0\\0\" /* %s/2 */" % (key, globalStringTable[key]))
        else:
            out.write("\n    \"%s\\0\" /* %s/2 */" % (key, globalStringTable[key]))
    out.write("\n    \"\";\n\n")
    #
    # Write the CSR number table
    #
    out.write("const uint64_t __bdk_csr_db_number[] = {\n")
    keys = getKeysSorted(globalNumberTable)
    for key in keys:
        out.write("    0x%016xull, /* %s */\n" % (key, globalNumberTable[key]))
    out.write("};\n\n")
    #
    # Write the param index table
    #
    out.write("const uint16_t __bdk_csr_db_param_index[][BDK_CSR_DB_MAX_PARAM] = {\n")
    keys = getKeysSorted(globalParamIndexTable)
    for key in keys:
        out.write("    %s, /* %d */\n" % (key, globalParamIndexTable[key]))
    out.write("};\n\n")
    #
    # Write the chip id to CSR table map
    #
    out.write("const __bdk_csr_db_map_t __bdk_csr_db[] = {\n")
    for chip in chip_list.getChips():
        if not csr_utils.isChipArch(arch, chip):
            continue
        # Skip minor passes as they are basically the same as the major pass
        if not chip.endswith("_0"):
            continue
        model_check = chip_list.chipToModelDefine(chip)
        assert model_check.endswith("_0"), model_check
        model_check = model_check[0:-2] + "_X"
        out.write("    {%s, __bdk_csr_db_%s},\n" % (model_check, chip))
    out.write("    {0, NULL}\n")
    out.write("};\n\n")
    out.close()