def generate_decoder_file(MODULENAME, INPUTS, OUTPUTS, format_dicts):
    # Get ISA information
    isa_info = format_dicts["ISA"]
    # Get register names
    registers = format_dicts["REGISTERS"]
    # Get memory fields needed for modification
    memory = format_dicts["MEMORY"]
    # Get constraints for qed module setup
    qed_constraints = format_dicts["QEDCONSTRAINTS"]
    # Get the instruction types
    ins_types = format_dicts["INSTYPES"]
    # Get the instruction fields for each type
    ins_fields = format_dicts["INSFIELDS"]
    # Get instruction types requirements
    ins_reqs = format_dicts["INSREQS"]
    # Get the bit fields
    bit_fields = format_dicts["BITFIELDS"]
    # Get all instruction types
    instructions = {}
    for ins in format_dicts["INSTYPES"].keys():
        if ins != "CONSTRAINT":
            instructions[ins] = format_dicts[ins]

    # Verilog file
    verilog = ""

    # Fill out the OUTPUTS dict
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            bits = int(msb) - int(lsb) + 1
            OUTPUTS[bit_field] = bits

    for ins_type in instructions:
        if ins_type in ins_reqs:
            OUTPUTS["IS_" + ins_type] = 1

    # Header for module
    verilog += I.module_header(MODULENAME, INPUTS, OUTPUTS)
    verilog += I.newline(2)

    # Instantiate inputs
    for inp in INPUTS:
        verilog += I.signal_def(INPUTS[inp], "input", inp, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate outputs
    verilog += I.newline(1)
    for out in OUTPUTS:
        verilog += I.signal_def(OUTPUTS[out], "output", out, num_spaces=2)
        verilog += I.newline(1)

    # Assign the bit fields to the correct bits in instruction
    verilog += I.newline(1)
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            verilog += I.assign_def(bit_field,
                                    I.signal_index(INPUTS.keys()[0], msb, lsb),
                                    num_spaces=2)
            verilog += I.newline(1)

    # Assign instruction types requirements
    verilog += I.newline(1)
    for ins_type in instructions:
        if not ins_type in ins_reqs:
            continue
        ins_req = ins_reqs[ins_type]
        reqs = ins_req["CONSTRAINT"]
        for field in ins_req:
            if field != "CONSTRAINT":
                if type(ins_req[field]) == type([]):
                    first = ins_req[field][0]
                    req_expression = I._equals(field,
                                               I._constant(len(first), first),
                                               parens=True)
                    for req in ins_req[field][1:]:
                        equality = I._equals(field,
                                             I._constant(len(req), req),
                                             parens=True)
                        req_expression = I._or(req_expression,
                                               equality,
                                               parens=False)
                    req_expression = "(" + req_expression + ")"
                    reqs.append(req_expression)
                else:
                    equality = I._equals(field,
                                         I._constant(len(ins_req[field]),
                                                     ins_req[field]),
                                         parens=True)
                    reqs.append(equality)

        reqs_expression = reqs[0]
        for i in range(1, len(reqs)):
            reqs_expression = I._and(reqs_expression, reqs[i], parens=False)

        verilog += I.assign_def("IS_" + ins_type,
                                reqs_expression,
                                num_spaces=2)
        verilog += I.newline(1)

    # Module footer
    verilog += I.newline(1)
    verilog += I.module_footer()

    return verilog
Exemple #2
0
def generate_qed_file(MODULENAME, INPUTS, OUTPUTS, format_dicts):
    # Get ISA information
    isa_info = format_dicts["ISA"]
    # Get register names
    registers = format_dicts["REGISTERS"]
    # Get memory fields needed for modification
    memory = format_dicts["MEMORY"]
    # Get constraints for qed module setup
    qed_constraints = format_dicts["QEDCONSTRAINTS"]
    # Get the instruction types
    ins_types = format_dicts["INSTYPES"]
    # Get the instruction fields for each type
    ins_fields = format_dicts["INSFIELDS"]
    # Get instruction types requirements
    ins_reqs = format_dicts["INSREQS"]
    # Get the bit fields
    bit_fields = format_dicts["BITFIELDS"]
    # Get all instruction types
    instructions = {}
    for ins in format_dicts["INSTYPES"].keys():
        if ins != "CONSTRAINT":
            instructions[ins] = format_dicts[ins]

    # Verilog file
    verilog = ""

    # Adds module header definition
    verilog += I.module_header(MODULENAME, INPUTS, OUTPUTS)
    verilog += I.newline(2)

    # Instantiate inputs
    for inp in INPUTS:
        verilog += I.signal_def(INPUTS[inp], "input", inp, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate outputs
    verilog += I.newline(1)
    for out in OUTPUTS:
        verilog += I.signal_def(OUTPUTS[out], "output", out, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate bit fields as wires
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            bits = int(msb) - int(lsb) + 1
            verilog += I.signal_def(bits, "wire", bit_field, num_spaces=2)
            verilog += I.newline(1)

    # Instantiate new instruction types wires
    verilog += I.newline(1)
    for ins_type in ins_reqs:
        if ins_type != "CONSTRAINT":
            verilog += I.signal_def(1, "wire", "IS_" + ins_type, num_spaces=2)
            verilog += I.newline(1)

    # Instantiate internal instruction versions
    verilog += I.newline(1)
    verilog += I.signal_def(int(isa_info["instruction_length"]),
                            "wire",
                            "qed_instruction",
                            num_spaces=2)
    verilog += I.newline(1)
    verilog += I.signal_def(int(isa_info["instruction_length"]),
                            "wire",
                            "qic_qimux_instruction",
                            num_spaces=2)
    verilog += I.newline(2)

    # Decoder module
    decoder_args = ["qic_qimux_instruction"]
    decoder_args = decoder_args + list(bit_fields.keys())
    decoder_args.remove("CONSTRAINT")
    decoder_args = decoder_args + [("IS_" + key) for key in ins_reqs]
    decoder_args.remove("IS_CONSTRAINT")
    signals = decoder_args
    names = copy.deepcopy(signals)
    names[0] = "ifu_qed_instruction"
    verilog += I.module_def("qed_decoder", "dec", names, signals, num_spaces=2)
    verilog += I.newline(2)

    # Modify module
    modify_args = ["qed_instruction", "qic_qimux_instruction"]
    modify_args = modify_args + list(bit_fields.keys())
    modify_args.remove("CONSTRAINT")
    modify_args = modify_args + [("IS_" + key) for key in ins_reqs]
    modify_args.remove("IS_CONSTRAINT")
    signals = modify_args
    names = modify_args
    verilog += I.module_def("modify_instruction",
                            "minst",
                            names,
                            signals,
                            num_spaces=2)
    verilog += I.newline(2)

    # Mux module
    mux_args = [
        "qed_ifu_instruction", "ifu_qed_instruction", "qed_instruction",
        "exec_dup", "ena"
    ]
    signals = mux_args
    names = mux_args
    verilog += I.module_def("qed_instruction_mux",
                            "imux",
                            names,
                            signals,
                            num_spaces=2)
    verilog += I.newline(2)

    # Cache module
    cache_args = [
        "qic_qimux_instruction", "vld_out", "clk", "rst", "exec_dup",
        "stall_IF", "ifu_qed_instruction"
    ]
    signals = cache_args
    names = copy.deepcopy(signals)
    names[-2] = "IF_stall"
    verilog += I.module_def("qed_i_cache", "qic", names, signals, num_spaces=2)
    verilog += I.newline(2)

    verilog += I.module_footer()

    return verilog
Exemple #3
0
def generate_constraints_file(MODULENAME, INPUTS, OUTPUTS, format_dicts):
    # Get ISA information
    isa_info = format_dicts["ISA"]
    # Get register names
    registers = format_dicts["REGISTERS"]
    # Get memory fields needed for modification
    memory = format_dicts["MEMORY"]
    # Get constraints for qed module setup
    qed_constraints = format_dicts["QEDCONSTRAINTS"]
    # Get the instruction types
    ins_types = format_dicts["INSTYPES"]
    # Get the instruction fields for each type
    ins_fields = format_dicts["INSFIELDS"]
    # Get instruction types requirements
    ins_reqs = format_dicts["INSREQS"]
    # Get the bit fields
    bit_fields = format_dicts["BITFIELDS"]
    # Get all instruction types
    instructions = {}
    for ins in format_dicts["INSTYPES"].keys():
        if ins != "CONSTRAINT":
            instructions[ins] = format_dicts[ins]
    
    # Verilog file
    verilog = ""

    # Adds module header definition
    verilog += I.module_header(MODULENAME, INPUTS, OUTPUTS)
    verilog += I.newline(2)

    # Instantiate inputs
    for inp in INPUTS:
        verilog += I.signal_def(INPUTS[inp], "input", inp, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate outputs
    for out in OUTPUTS:
        verilog += I.signal_def(OUTPUTS[out], "output", out, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate bit fields
    verilog += I.newline(1)
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            bits = int(msb) - int(lsb) + 1
            verilog += I.signal_def(bits, "wire", bit_field, num_spaces=2)
            verilog += I.newline(1)

    # Instantiate instructions
    verilog += I.newline(1)
    for ins_type in instructions:
        if ins_type != "NOP":
            verilog += I.signal_def(1, "wire", "FORMAT_"+ins_type, num_spaces=2)
            verilog += I.newline(1)
        verilog += I.signal_def(1, "wire", "ALLOWED_"+ins_type, num_spaces=2)
        verilog += I.newline(1)
        for ins in instructions[ins_type]:
            if ins != "CONSTRAINT":
                verilog += I.signal_def(1, "wire", ins, num_spaces=2)
                verilog += I.newline(1)
        verilog += I.newline(1)

    # Assign bit fields
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            verilog += I.assign_def(bit_field, I.signal_index("instruction", msb, lsb), num_spaces=2)
            verilog += I.newline(1)

    # Assign instruction types
    verilog += I.newline(1)
    for ins_type in instructions:
        type_constraints = instructions[ins_type]["CONSTRAINT"]
        constraints = type_constraints

        if qed_constraints["half_registers"] == "1":
            fields = ins_fields[ins_type].split()
            for field in fields:
                if field in registers:
                    constraints.append(I._lt(field, str(int(isa_info["num_registers"])/2), parens=True))

        if ins_type != "NOP" and len(constraints) > 0:
            expression = constraints[0]
            for i in range(1, len(constraints)):
                expression = I._and(expression, constraints[i], parens=False)

            verilog += I.assign_def("FORMAT_"+ins_type, expression, num_spaces=2)
            verilog += I.newline(1)

        allowed_expression = ""
        for ins in instructions[ins_type]:
            if ins != "CONSTRAINT":
                fields = instructions[ins_type][ins]
                reqs = fields["CONSTRAINT"]
                for field in fields:
                    if field != "CONSTRAINT":
                        if type(fields[field]) == type([]):
                            first = fields[field][0]
                            req_expression = I._equals(field, I._constant(len(first), first), parens=True)
                            for req in fields[field][1:]:
                                equality = I._equals(field, I._constant(len(req), req), parens=True)
                                req_expression = I._or(req_expression, equality, parens=False)
                            req_expression = "(" + req_expression + ")"
                            reqs.append(req_expression)
                        else:
                            equality = I._equals(field, I._constant(len(fields[field]), fields[field]), parens=True)
                            reqs.append(equality)

                if ins != "NOP":
                    reqs_expression = "FORMAT_" + ins_type
                    for i in range(len(reqs)):
                        reqs_expression = I._and(reqs_expression, reqs[i], parens=False)
                else:
                    reqs_expression = reqs[0]
                    for i in range(1, len(reqs)):
                        reqs_expression = I._and(reqs_expression, reqs[i], parens=False)

                verilog += I.assign_def(ins, reqs_expression, num_spaces=2)
                verilog += I.newline(1)

                if allowed_expression == "":
                    allowed_expression = ins
                else:
                    allowed_expression = I._or(allowed_expression, ins, parens=False)

        verilog += I.assign_def("ALLOWED_"+ins_type, allowed_expression, num_spaces=2)
        verilog += I.newline(2)

    # Property assertion
    assertions = instructions.keys()
    property_expression = ""
    for ins_type in assertions:
        if property_expression == "":
            property_expression = "ALLOWED_" + ins_type
        else:
            property_expression = I._or(property_expression, "ALLOWED_"+ins_type, parens=False)

    verilog += I.always_def("clk", num_spaces=2) + I.begin(num_spaces=1)
    verilog += I.newline(1)
    verilog += I.property_def(property_expression, num_spaces=4)
    verilog += I.newline(1)
    verilog += I.end(num_spaces=2)
    verilog += I.newline(1)

    # End module with footer
    verilog += I.newline(1)
    verilog += I.module_footer()

    return verilog 
# Mux module
mux_args = [
    "qed_ifu_instruction", "ifu_qed_instruction", "qed_instruction",
    "exec_dup", "ena"
]
signals = mux_args
names = mux_args
verilog += I.module_def("qed_instruction_mux",
                        "imux",
                        names,
                        signals,
                        num_spaces=2)
verilog += I.newline(2)

# Cache module
cache_args = [
    "qic_qimux_instruction", "vld_out", "clk", "rst", "exec_dup", "stall_IF",
    "ifu_qed_instruction"
]
signals = cache_args
names = copy.deepcopy(signals)
names[-2] = "IF_stall"
verilog += I.module_def("qed_i_cache", "qic", names, signals, num_spaces=2)
verilog += I.newline(2)

verilog += I.module_footer()

f = open("../QEDFiles/qed.v", 'w')
f.write(verilog)
f.close()
def generate_modify_file(MODULENAME, INPUTS, OUTPUTS, format_dicts):
    # Get ISA information
    isa_info = format_dicts["ISA"]
    # Get register names
    registers = format_dicts["REGISTERS"]
    # Get memory fields needed for modification
    memory = format_dicts["MEMORY"]
    # Get constraints for qed module setup
    qed_constraints = format_dicts["QEDCONSTRAINTS"]
    # Get the instruction types
    ins_types = format_dicts["INSTYPES"]
    # Get the instruction fields for each type
    ins_fields = format_dicts["INSFIELDS"]
    # Get instruction types requirements
    ins_reqs = format_dicts["INSREQS"]
    # Get the bit fields
    bit_fields = format_dicts["BITFIELDS"]
    # Get all instruction types
    instructions = {}
    for ins in format_dicts["INSTYPES"].keys():
        if ins != "CONSTRAINT":
            instructions[ins] = format_dicts[ins]

    # Verilog file
    verilog = ""

    # Fill out the INPUTS dict
    for bit_field in bit_fields:
        if bit_field != "CONSTRAINT":
            msb, lsb = bit_fields[bit_field].split()
            bits = int(msb) - int(lsb) + 1
            INPUTS[bit_field] = bits

    for ins_type in instructions:
        if ins_type in ins_reqs:
            INPUTS["IS_" + ins_type] = 1

    verilog += I.module_header(MODULENAME, INPUTS, OUTPUTS)
    verilog += I.newline(2)

    # Instantiate inputs
    for inp in INPUTS:
        verilog += I.signal_def(INPUTS[inp], "input", inp, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate outputs
    verilog += I.newline(1)
    for out in OUTPUTS:
        verilog += I.signal_def(OUTPUTS[out], "output reg", out, num_spaces=2)
        verilog += I.newline(1)

    # Instantiate new instruction types wires
    verilog += I.newline(1)
    for ins_type in ins_reqs:
        verilog += I.signal_def(int(isa_info["instruction_length"]),
                                "wire",
                                "INS_" + ins_type,
                                num_spaces=2)
        verilog += I.newline(1)

    # Instantiate the new registers and immediate values
    verilog += I.newline(1)
    if qed_constraints["half_registers"] == "1":
        for reg in registers:
            if reg != "CONSTRAINT":
                msb, lsb = bit_fields[reg].split()
                bits = int(msb) - int(lsb) + 1
                verilog += I.signal_def(bits,
                                        "wire",
                                        "NEW_" + reg,
                                        num_spaces=2)
                verilog += I.newline(1)

    if qed_constraints["half_memory"] == "1":
        for mem in memory:
            if mem != "CONSTRAINT":
                msb, lsb = bit_fields[mem].split()
                bits = int(msb) - int(lsb) + 1
                verilog += I.signal_def(bits,
                                        "wire",
                                        "NEW_" + mem,
                                        num_spaces=2)
                verilog += I.newline(1)

    # Keeps track of modified fields
    modified_fields = []

    # Assign the new values for the registers
    verilog += I.newline(1)
    if qed_constraints["half_registers"] == "1":
        for reg in registers:
            if reg != "CONSTRAINT":
                msb, lsb = bit_fields[reg].split()
                bits = int(msb) - int(lsb) + 1
                equals_zero = I._equals(reg, I._constant(bits, "0" * bits),
                                        True)
                new_reg = I.bit_vector([
                    I._constant(1, "1"),
                    I.signal_index(reg, str(bits - 2), "0")
                ])
                cond = I.inline_conditional(equals_zero, reg, new_reg, False)
                verilog += I.assign_def("NEW_" + reg, cond, num_spaces=2)
                verilog += I.newline(1)
                modified_fields.append(reg)

    if qed_constraints["half_memory"] == "1":
        for mem in memory:
            if mem != "CONSTRAINT":
                msb, lsb = bit_fields[mem].split()
                bits = int(msb) - int(lsb) + 1
                new_mem = I.bit_vector([
                    I._constant(2, "01"),
                    I.signal_index(mem, str(bits - 3), "0")
                ])
                verilog += I.assign_def("NEW_" + mem, new_mem)
                verilog += I.newline(1)
                modified_fields.append(mem)

    # Assign the new instruction types with the modified fields
    verilog += I.newline(1)
    if len(ins_types["CONSTRAINT"]) > 0:
        ins_types_defs = {}
        for c in ins_types["CONSTRAINT"]:
            parts = c.split(",")
            ins_types_defs[parts[0]] = parts[1:]

        mem_types = ins_types_defs["MEMORYTYPE"]
    else:
        mem_types = []

    for ins_type in ins_reqs:
        if ins_type != "CONSTRAINT":
            fields = ins_fields[ins_type].split()
            new_fields = []
            for field in fields:
                if ((field in modified_fields and field in registers)
                        or (field in modified_fields and field in memory
                            and ins_type in mem_types)):
                    new_fields.append("NEW_" + field)
                else:
                    new_fields.append(field)
            verilog += I.assign_def("INS_" + ins_type,
                                    I.bit_vector(new_fields),
                                    num_spaces=2)
            verilog += I.newline(1)

    # Assign the final qed instruction output after modification
    verilog += I.newline(1)
    output_instruction = OUTPUTS.keys()[0]
    types = ins_reqs.keys()
    types.remove("CONSTRAINT")
    conditional = ""
    for i in range(len(types)):
        ins_type = types[i]
        if i < len(types) - 1:
            false = "("
        else:
            false = "qic_qimux_instruction"
        conditional += I.inline_conditional("IS_" + ins_type,
                                            "INS_" + ins_type, false, False)
    conditional += (len(types) - 1) * ")"
    verilog += I.assign_def(output_instruction, conditional, num_spaces=2)
    verilog += I.newline(1)

    # This code does the same thing as above,
    # but utilizes the always_comb logic
    # to make it more readable. However
    # this will cause certain verilog compilers
    # to complain.
    """
    verilog += I.always_comb_def(num_spaces=2)
    verilog += I.newline(1)
    output_instruction = OUTPUTS.keys()[0]
    types = ins_reqs.keys()
    types.remove("CONSTRAINT")
    for i in range(len(types)+1):
        if i == 0:
            ins_type = types[i]
            verilog += I.if_header("IS_"+ins_type, num_spaces=4)
        elif i < len(types):
            ins_type = types[i]
            verilog += I.else_if_header("IS_"+ins_type, num_spaces=4)
        else:
            verilog += I.else_header(num_spaces=4)
            verilog += I.newline(1)
            verilog += I.direct_assignment_def(output_instruction, "qic_qimux_instruction", num_spaces=6)
            verilog += I.newline(1)
            verilog += I.end(num_spaces=4)
            verilog += I.newline(1)
            continue

        verilog += I.newline(1)
        verilog += I.direct_assignment_def(output_instruction, "INS_"+ins_type, num_spaces=6)
        verilog += I.newline(1)
        verilog += I.end(num_spaces=4)
        verilog += I.newline(1)
    verilog += I.end(num_spaces=2)
    verilog += I.newline(1)
    """

    # Module footer
    verilog += I.newline(1)
    verilog += I.module_footer()

    return verilog