示例#1
0
    def end_finite(self, target_name, automatic_label=False):
        """At the ending of a finite loop
        Adds a bdec instruction and fills the branch delay slots
        @param target_name: String identifier of the label to jump to
        @param automatic_label: Generate an automated label
        """
        register_addr = len(self.sequencer.bdec_register) - 1
        if register_addr < 0:
            raise RuntimeError("Cannot pop from empty loop stack")
        self.sequencer.bdec_register.pop()

        # apply address of register earlier to prevent timing problems in the bus
        nop_insn = instructions.nop(val=(register_addr << 23))
        self.sequencer.add_insn(nop_insn)

        if automatic_label == False:
            bdec_insn = instructions.bdec(target_name, register_addr)
        else:
            l = len(self.sequencer.open_automatic_labels) - 1
            aut_target_name = self.sequencer.open_automatic_labels[l]
            self.sequencer.open_automatic_labels.pop()
            bdec_insn = instructions.bdec(aut_target_name, register_addr)

        nop_insn = instructions.nop()
        self.sequencer.add_insn(bdec_insn)
        for index in range(self.branch_delay_slots):
            self.sequencer.add_insn(copy.copy(nop_insn))
示例#2
0
    def compile_sequence(self):
        """generates the binary list
        """
        # Addresses are broken when using subroutines

        # Add a halt instruction to the current sequence !
        halt_insn = instructions.halt()
        self.add_insn(halt_insn)
        nop_insn = instructions.nop()
        for i in range(self.branch_delay_slots):
            self.add_insn(copy.copy(nop_insn))

        sequence_list = self.current_sequence
        word_index = len(self.current_sequence)

        # Add the subroutines to current_sequence
        for insn_list in self.sub_list:
            self.label_dict[insn_list[0].label] = word_index
            sequence_list += insn_list
            word_index += len(insn_list)
        self.word_list = []
        # reset the address counter
        address = 0
        # Append the binary charlist to the word_list
        # If the calue of the insn is None we are dealing
        # with a jump insn and adding it to the jump_list

        for insn in sequence_list:
            # calculate the instruction's machine code as an int
            value = insn.get_value()
            if insn.is_branch == True:
                self.word_list.append(insn)
                self.jump_list.append(len(self.word_list) - 1)
            else:
                # Generate a 32bit binary word from value
                self.word_list.append(self.get_binary_charlist(value, 4))
            # set the insn address and increase the address counter
            insn.address = address
            address += 1

        # calculate the addresses for the branch insns in jump_list
        for word_num in self.jump_list:
            jump_insn = self.word_list[word_num]
            try:
                target_num = self.label_dict[jump_insn.target_name]
                target_insn = self.current_sequence[target_num]
                target_address = target_insn.address
                value = jump_insn.get_jump_value(target_address)
                self.word_list[word_num] = self.get_binary_charlist(value, 4)
            except:
                self.logger.exception("error while handling jump: " \
                                          + str(jump_insn.target_name))
        # update current_sequence to make debugging possible
        if len(sequence_list) > self.max_sequence_length - 1:
            raise RuntimeError("Maximum sequence length exceeded: " + \
                                   str(hex(len(sequence_list))))
        self.current_sequence = sequence_list
示例#3
0
 def jump(self, target_name):
     """unconditional jump to label
     @param target_name: String identifier of the label to jump to
     """
     jump_insn = instructions.j(target_name)
     nop_insn = instructions.nop()
     self.sequencer.add_insn(jump_insn)
     for index in range(self.branch_delay_slots):
         self.sequencer.add_insn(copy.copy(nop_insn))
示例#4
0
 def call_subroutine(self, sub_name):
     """calls a subroutine
     sub_name
     @param sub_name:  String identifier of the subroutine to call
     """
     call_insn = instructions.call(sub_name)
     nop_insn = instructions.nop()
     self.sequencer.add_insn(call_insn)
     self.sequencer.add_insn(nop_insn)
     self.sequencer.add_insn(copy.copy(nop_insn))
     self.sequencer.add_insn(copy.copy(nop_insn))
示例#5
0
 def jump_trigger(self, target_name, trigger, invert=False):
     """branch on trigger
     Adds a conditional jump
     @param target_name:  String identifier of the label to jump to
     @param trigger : trigger state in hex
     """
     jump_insn = instructions.btr(target_name, trigger, invert=invert)
     nop_insn = instructions.nop()
     self.sequencer.add_insn(jump_insn)
     for index in range(self.branch_delay_slots):
         self.sequencer.add_insn(copy.copy(nop_insn))
示例#6
0
    def wait_trigger(self, trigger):
        """Inserts a wait on trigger operation
        @param trigger: trigger state in hex
        """
        #generate an automatic label
        aut_target_name = self.generate_auto_label()
        label_insn = instructions.label(aut_target_name)

        halt_insn = instructions.halt()
        jump_insn = instructions.btr(aut_target_name, trigger)
        nop_insn = instructions.nop()
        self.sequencer.add_insn(halt_insn)
        for index in range(self.branch_delay_slots - 1):
            self.sequencer.add_insn(copy.copy(nop_insn))
        self.sequencer.add_insn(jump_insn)
        for index in range(self.branch_delay_slots):
            self.sequencer.add_insn(copy.copy(nop_insn))
        self.sequencer.add_insn(label_insn)
示例#7
0
    def wait(self, wait_time, use_cycles=False):
        """inserts a wait event
        needs calibration !!! wait has to be > 4 ?
        @param wait_time : time in us to wait
        @param use_cycles: If set to True the wait_time will be interpreted as cycles
        """
        if use_cycles:
            wait_cycles = wait_time
        else:
            wait_cycles = int(wait_time / self.cycle_time)

        if wait_cycles < 1.0:
            self.logger.debug("Cannot wait for less than one cycle")
            return

        nop_insn = instructions.nop()
        while wait_cycles > 0:
            if wait_cycles > self.branch_delay_slots + 2:
                #                wait_cycles -= self.branch_delay_slots - 1
                # Subtract one more cycle - we need it for the wait
                # instruction itself
                if wait_cycles > self.max_wait_cycles:
                    my_wait = self.max_wait_cycles
                else:
                    my_wait = wait_cycles - self.branch_delay_slots - 1
                wait_insn = instructions.wait(my_wait)
                # Do we really need wait_cycles - 5 ??
                wait_cycles -= my_wait + self.branch_delay_slots + 1
                self.sequencer.add_insn(wait_insn)

                for i in range(self.branch_delay_slots):
                    self.sequencer.add_insn(copy.copy(nop_insn))
            else:
                for i in range(wait_cycles):
                    self.sequencer.add_insn(copy.copy(nop_insn))
                wait_cycles = 0