Ejemplo n.º 1
0
def test_i_instruction_from_binary():
    instruction = "00000000110000011000001000010011"

    res = ISA().instruction_from_bin(instruction, 0)
    assert res.rd == 4
    assert res.rs == 3
    assert res.imm == 12
Ejemplo n.º 2
0
def test_i_instruction_from_string():
    instruction = "addi r4, r3, 12"

    res = ISA().instruction_from_str(instruction, None, None)
    assert res.rd == 4
    assert res.rs == 3
    assert res.imm == 12
Ejemplo n.º 3
0
def test_sym_reg_names():
    instruction = "add sp, ra, gp"

    res = ISA().instruction_from_str(instruction, None, None)
    assert res.rd == 2
    assert res.rs1 == 1
    assert res.rs2 == 3
Ejemplo n.º 4
0
def test_r_instruction_from_binary():
    instruction = "00000000001000011001001000110011"

    res = ISA().instruction_from_bin(instruction, 0)
    assert res.rd == 4
    assert res.rs2 == 2
    assert res.rs1 == 3
Ejemplo n.º 5
0
def test_r_instruction_from_string():
    instruction = "add r4, r3, r2"

    res = ISA().instruction_from_str(instruction, None, None)
    assert res.rd == 4
    assert res.rs1 == 3
    assert res.rs2 == 2
Ejemplo n.º 6
0
def test_MW_step():
    w = MainWindow()

    w.emulators[0].IFQ.put(ISA().instruction_from_str("mul x1, x0, x0", None, 0))
    s1 = w.emulators[0].emulator_instance.get_steps()
    w.emulator_step()

    assert w.emulators[0].emulator_instance.get_steps() > s1, "Emulator did not perform a step"
Ejemplo n.º 7
0
def test_lui():
    imm = "00000000000010101010"
    rd = "0" * 5
    instruction = "$imm$rd0110111"
    instruction = instruction.replace("$imm", imm)
    instruction = instruction.replace("$rd", rd)
    exp = "10101010000000000000"

    instr = ISA().instruction_from_bin(instruction, 0)
    assert int(exp, 2) == instr.execute(None)
Ejemplo n.º 8
0
def test_auipc():
    imm = "00000000000010101010"
    rd = "0" * 5
    instruction = "$imm$rd0010111"
    instruction = instruction.replace("$imm", imm)
    instruction = instruction.replace("$rd", rd)
    exp_par = "10101010000000000000"
    PC = 24
    exp = int(exp_par, 2) + PC

    instr = ISA().instruction_from_bin(instruction, 0)
    assert exp == instr.execute(PC)
def test_beq():
    rd = "0" * 5
    instruction = "0000000$rs2$rs1000100001100011"
    instruction = instruction.replace("$rs1", rd)
    instruction = instruction.replace("$rs2", rd)
    rs1 = 0b00000000000000000000000000001101  # 13
    rs2 = 0b00000000000000000000000000001011  # 11
    exp = 16

    instr = ISA().instruction_from_bin(instruction, 0)
    assert exp == instr.execute(rs1, rs1)

    assert 4 == instr.execute(rs1, rs2)
Ejemplo n.º 10
0
    def create_tab_isa(self):
        isa = ISA().ISA
        toolbox = QtWidgets.QToolBox()

        # Lambdas do not preserve context when updating ISA from event signal
        def get_isa_updater(t, i, f):
            def _(v):
                print(t, i, f, v)
                isa[t][i][f] = v

            return _

        for type in isa.keys():
            for inst in isa[type]:
                f = QtWidgets.QFrame()
                f.setLayout(QtWidgets.QFormLayout())

                for inst in isa[type]:
                    f.layout().addRow(inst.upper(), None)

                    op_txt = QtWidgets.QLineEdit()
                    op_txt.setText(isa[type][inst]['exec'])
                    op_txt.textChanged.connect(
                        get_isa_updater(type, inst, 'exec'))
                    f.layout().addRow("Expression:", op_txt)

                    cyc = QtWidgets.QSpinBox()
                    cyc.setMinimum(1)
                    cyc.setValue(isa[type][inst]['clockNeeded'])
                    cyc.valueChanged.connect(
                        get_isa_updater(type, inst, 'clockNeeded'))
                    f.layout().addRow("Clock cycles:", cyc)

                    f.layout().addRow(" ", None)

                scroll = QtWidgets.QScrollArea()
                scroll.setWidgetResizable(True)
                scroll.setWidget(f)

            toolbox.addItem(f, type.upper())

        return toolbox
Ejemplo n.º 11
0
    def __init__(self, DM):
        self.DM = DM
        self.ISA = ISA()

        self.syntax_errors = []  # Line numbers for text
        self.unknown_instructions = []  # Instruction indexes for ELF

        self.IM = []  # Instruction Memory
        self.sections = {'.text': 0}
        self.symbol_table = {}
        self.alignment = 4
        self.directives = {
            '.byte': 1,
            '.2byte': 2,
            '.4byte': 4,
            '.8byte': 8,
            '.half': 2,
            '.word': 4,
            '.dword': 8,
            # '.asciz': None,
            # '.string': None,
            # '.zero': None
        }
def test_to_bin():
    inst = ISA().instruction_from_str(
        'beq x5, x0, 4', None, 0)  # BType_Instruction(1100011, 5, '000', 1, 2)
    assert inst.to_binary() == '00000000010100000000010001100011'
Ejemplo n.º 13
0
    def load_program(self, prog):
        print("\nLoading program into memory...")
        next_addr = 0  # If file is relocatable, need to store sections one after the other

        for s in self.sections.values():
            if s.sh_type == 0:  # SHT_NULL
                continue

            print("    {}:".format(s.sh_name))

            # Load in memory
            if s.sh_flags & 0x02 != 0x02:
                print("        ! SHF_ALLOC flag not set, skipping")
                continue
            if s.sh_addr == 0 and self.eheader['e_type'] != 1:  # Not ET_REL (relocatable)
                print("        ! sh_addr is set to 0 and file is not relocatable, skipping")
                continue
            if s.sh_addr == 0:
                s.sh_addr = next_addr
            if s.sh_type == 8:  # SHT_NOBITS, like .bss, doesn't have content
                print("        - sh_type is set to SHT_NOBITS, setting {} bytes to 0x00".format(s.sh_size))
                for offset in range(s.sh_size):
                    prog.DM.store(s.sh_addr + offset, 0x00)
            else:
                self.file.seek(s.sh_offset)
                s.content = self.file.read(s.sh_size)
                for offset, byte in enumerate(s.content):
                    prog.DM.store(s.sh_addr + offset, byte)

            print("        > Loaded {} bytes from {} to {} excluded. (Read from offset {})".format(
                s.sh_size, s.sh_addr, s.sh_addr + s.sh_size, s.sh_offset
            ))
            next_addr += s.sh_size

            # Insert start address in program's section array
            prog.sections[s.sh_name] = s.sh_addr

        # Dump DM
        print("\nData Memory dump (first 128 bytes):")
        bin, hex, ascii = [], [], []
        for addr, val in enumerate(prog.DM):
            if addr >= 128:
                break
            bin.append('{:08b}'.format(val))
            hex.append('{:02x}'.format(val))
            ascii.append(chr(val) if chr(val).isprintable() and chr(val) != '\n' else '.')

        bin_idx, hex_idx, ascii_idx = 0, 0, 0
        while bin_idx < len(bin):
            print('   ', ' '.join(bin[bin_idx:bin_idx+8]), end=' │ ')
            bin_idx += 8
            print(' '.join(hex[hex_idx:hex_idx+8]), end=' │ ')
            hex_idx += 8
            print(''.join(ascii[ascii_idx:ascii_idx+8]))
            ascii_idx += 8

        # Make relocation of symbols
        symbol_bindings = self.parse_rs()  # Relocation section

        # Fill program's symbol table
        for s in self.symbols:
            if s.st_shndx < len(self.ordered_sections):
                prog.symbol_table[s.st_name] = {
                    'name': s.st_name,
                    'value': s.st_value,
                    'size': s.st_size,
                    'section': self.ordered_sections[s.st_shndx].sh_name
                }

        # Parse .text section to instructions
        print("\nParsing .text section into ISA.Instruction objects...")
        isa = ISA()
        pc = prog.sections['.text']
        self.file.seek(self.sections['.text'].sh_offset)

        while self.file.tell() < self.sections['.text'].sh_offset + self.sections['.text'].sh_size:
            bin = ''.join(["{:08b}".format(b) for b in reversed(self.file.read(4))])

            try:
                inst = isa.instruction_from_bin(bin, pc)
            except NotImplementedError:
                inst = None

            if symbol_bindings is not None and len(prog.IM) in symbol_bindings:  # Relocate symbol in the instruction
                sym = symbol_bindings[len(prog.IM)]
                print("    (relocating a symbol: {})".format(sym))
                if isinstance(inst, (IType_Instruction, UType_Instruction, UJType_Instruction)):
                    inst.imm = sym

            print('   ', bin, '->', inst if inst is not None else "! [error]")
            prog.IM.append(inst)
            if inst is None:
                self.unknown_instructions.append(len(prog.IM)-1)

            pc += 4