Exemplo n.º 1
0
 def __getitem__( self, idx ):
   if self.debug.enabled( "rf" ):
     print ':: RD.RF[%s] = %s' % (
                         pad( "%d" % idx, 2 ),
                         pad_hex( self.regs[idx],
                                  len=self.debug_nchars ) ),
   return self.regs[idx]
Exemplo n.º 2
0
 def __setitem__(self, idx, value):
     value = trim_64(value)
     self.regs[idx] = value
     if self.debug.enabled("rf"):
         print ':: WR.RF[%s] = %s' % (pad(
             "%d" % idx, 2), pad_hex(self.regs[idx],
                                     len=self.debug_nchars)),
Exemplo n.º 3
0
 def print_regs( self, per_row=6 ):
   for c in xrange( 0, self.num_regs, per_row ):
     str = ""
     for r in xrange( c, min( self.num_regs, c+per_row ) ):
       str += "%s:%s " % ( pad( "%d" % r, 2 ),
                           pad_hex( self.regs[r] ) )
     print str
Exemplo n.º 4
0
 def __setitem__( self, idx, value ):
   value = trim_64(value)
   self.regs[idx] = value
   if self.debug.enabled( "rf" ):
     print ':: WR.RF[%s] = %s' % (
                       pad( "%d" % idx, 2 ),
                       pad_hex( self.regs[idx],
                                len=self.debug_nchars ) ),
Exemplo n.º 5
0
 def __getitem__(self, index):
     address, bitsize, _ = reg_memory_map[index]
     mask = (1 << bitsize) - 1
     value = self.memory.iread(address, 4, from_core=self.coreid) & mask
     if (self.debug.enabled('rf') and self.logger and index < 64 and
           self.is_first_core):
         self.logger.log(' :: RD.RF[%s] = %s' % (pad('%d' % index, 2),
                           pad_hex(value, len=self.debug_nchars)))
     return value
Exemplo n.º 6
0
 def __setitem__(self, idx, value):
     if idx == 15:
         self.state.pc = value
         if self.debug.enabled("rf"):
             print ':: WR.RF[15] = %s' % (pad_hex(value)),
     else:
         self.regs[idx] = value
         if self.debug.enabled("rf"):
             print ':: WR.RF[%s] = %s' % (pad("%d" % idx,
                                              2), pad_hex(value)),
Exemplo n.º 7
0
 def __setitem__( self, idx, value ):
   if idx == 15:
     self.state.pc = value
     if self.debug.enabled( "rf" ):
       print ':: WR.RF[15] = %s' % ( pad_hex( value ) ),
   else:
     self.regs[idx] = value
     if self.debug.enabled( "rf" ):
       print ':: WR.RF[%s] = %s' % (
                         pad( "%d" % idx, 2 ),
                         pad_hex( value ) ),
Exemplo n.º 8
0
 def __setitem__(self, index, value):
     if index == 0x65:  # COREID register. Read only. Other Read/Write only
         return         # registers need to be accessed by instructions.
     address, bitsize, _ = reg_memory_map[index]  # Lower 20 bits of address.
     mask = (1 << bitsize) - 1
     self.memory.write(self.coreid_mask | address, 4, value & mask,
                              from_core=self.coreid, quiet=True)
     if (self.debug.enabled('rf') and self.logger and index < 64 and
           self.is_first_core):
         self.logger.log(' :: WR.RF[%s] = %s' % ((pad('%d' % index, 2),
                           pad_hex(value, len=self.debug_nchars))))
Exemplo n.º 9
0
  def __getitem__( self, idx ):
    # special-case for idx = 15 which is the pc
    if self.debug.enabled( "rf" ):
      if idx == 15:
        rd_str = pad_hex( self.state.pc ) + "+ 8"
      else:
        rd_str = pad_hex( self.regs[idx] )

      print ':: RD.RF[%s] = %s' % ( pad( "%d" % idx, 2 ), rd_str ),

    if idx == 15:
      return self.state.pc + 8
    else:
      return self.regs[idx]
Exemplo n.º 10
0
    def __getitem__(self, idx):
        # special-case for idx = 15 which is the pc
        if self.debug.enabled("rf"):
            if idx == 15:
                rd_str = pad_hex(self.state.pc) + "+ 8"
            else:
                rd_str = pad_hex(self.regs[idx])

            print ':: RD.RF[%s] = %s' % (pad("%d" % idx, 2), rd_str),

        if idx == 15:
            return self.state.pc + 8
        else:
            return self.regs[idx]
Exemplo n.º 11
0
def run(state, max_insts=0):
    s = state

    while s.status == 0:

        jitdriver.jit_merge_point(
            pc=s.fetch_pc(),
            max_insts=max_insts,
            state=s,
        )

        # constant-fold pc and mem
        pc = hint(s.fetch_pc(), promote=True)
        old = pc
        mem = hint(s.mem, promote=True)

        if s.debug.enabled("insts"):
            print pad("%x" % pc, 6, " ", False),

        # the print statement in memcheck conflicts with @elidable in iread.
        # So we use normal read if memcheck is enabled which includes the
        # memory checks

        if s.debug.enabled("memcheck"):
            inst = mem.read(pc, 4)
        else:
            # we use trace elidable iread instead of just read
            inst = mem.iread(pc, 4)

        inst_str, exec_fun = decode(inst)

        if s.debug.enabled("insts"):
            print "%s %s %s" % (
                pad_hex(inst),
                pad(inst_str, 8),
                pad("%d" % s.ncycles, 8),
            ),

        try:
            exec_fun(s, Instruction(inst))
        except FatalError as error:
            # TODO: maybe we can add a command line arg to just give a warning
            # and not terminate execution
            print "Exception in execution, aborting!"
            print "Exception message: %s" % error.msg
            break

        s.ncycles += 1  # TODO: should this be done inside instruction definition?
        if s.stats_en: s.stat_ncycles += 1

        if s.debug.enabled("insts"):
            print
        if s.debug.enabled("regdump"):
            s.rf.print_regs(per_row=4)
            print '%s%s%s%s' % ('N' if s.N else '-', 'Z' if s.Z else '-',
                                'C' if s.C else '-', 'V' if s.V else '-')

        # check if we have reached the end of the maximum instructions and
        # exit if necessary
        if max_insts != 0 and s.ncycles >= max_insts:
            print "Reached the max_insts (%d), exiting." % max_insts
            break

        if s.fetch_pc() < old:
            jitdriver.can_enter_jit(
                pc=s.fetch_pc(),
                max_insts=max_insts,
                state=s,
            )

    print 'DONE! Status =', s.status
    print 'Instructions Executed =', s.ncycles
Exemplo n.º 12
0
    def run(self):
        self = hint(self, promote=True)
        s = self.state

        max_insts = self.max_insts
        jitdriver = self.jitdriver

        while s.running:

            jitdriver.jit_merge_point(
                pc=s.fetch_pc(),
                max_insts=max_insts,
                state=s,
                sim=self,
            )

            # constant-fold pc and mem
            pc = hint(s.fetch_pc(), promote=True)
            old = pc
            mem = hint(s.mem, promote=True)

            if s.debug.enabled("insts"):
                print pad("%x" % pc, 8, " ", False),

            # the print statement in memcheck conflicts with @elidable in iread.
            # So we use normal read if memcheck is enabled which includes the
            # memory checks

            if s.debug.enabled("memcheck"):
                inst_bits = mem.read(pc, 4)
            else:
                # we use trace elidable iread instead of just read
                inst_bits = mem.iread(pc, 4)

            try:
                inst, exec_fun = self.decode(inst_bits)

                if s.debug.enabled("insts"):
                    print "%s %s %s" % (
                        pad_hex(inst_bits),
                        pad(inst.str, 12),
                        pad("%d" % s.num_insts, 8),
                    ),

                self.pre_execute()

                exec_fun(s, inst)
            except NotImplementedInstError:
                # re-decode instruction to get the instruction name
                inst, _ = self.decode(inst_bits)

                print "Instruction not implemented: %s (pc: 0x%s), aborting!" \
                      % ( inst.str, pad_hex( pc ) )
                break
            except FatalError as error:
                print "Exception in execution (pc: 0x%s), aborting!" % pad_hex(
                    pc)
                print "Exception message: %s" % error.msg
                break

            s.num_insts += 1  # TODO: should this be done inside instruction definition?
            if s.stats_en: s.stat_num_insts += 1

            self.post_execute()

            if s.debug.enabled("insts"):
                print
            if s.debug.enabled("regdump"):
                s.rf.print_regs(per_row=4)

            # check if we have reached the end of the maximum instructions and
            # exit if necessary
            if max_insts != 0 and s.num_insts >= max_insts:
                print "Reached the max_insts (%d), exiting." % max_insts
                break

            if s.fetch_pc() < old:
                jitdriver.can_enter_jit(
                    pc=s.fetch_pc(),
                    max_insts=max_insts,
                    state=s,
                    sim=self,
                )

        print 'DONE! Status =', s.status
        print 'Instructions Executed =', s.num_insts
Exemplo n.º 13
0
    def run(self):
        """Fetch, decode, execute, service interrupts loop.
        Override Sim.run to provide multicore and close the logger on exit.
        """
        coreids = self.states.keys()
        core = coreids[0]      # Key to self.states dictionary.
        state = self.states[core]  # revelation.machine.State object.
        pc = state.fetch_pc()  # Program counter.
        tick_counter = 0       # Number of instructions executed by all cores.
        old_pc = 0
        self.start_time = time.time()

        while True:
            self.jitdriver.jit_merge_point(pc=pc,
                                           core=core,
                                           tick_counter=tick_counter,
                                           coreids=coreids,
                                           sim=self,
                                           state=state,)
            # Fetch next instruction.
            opcode = state.mem.iread(pc, 4, from_core=state.coreid)
            try:
                # Decode instruction.
                mnemonic, function = decode(opcode)
                instruction = Instruction(opcode, mnemonic)
                # --debug
                if (state.is_first_core and self.logger and
                      state.debug.enabled('trace')):
                    state.logger.log('%s %s %s %s' %
                        (pad('%x' % pc, 8, ' ', False),
                         pad_hex(opcode), pad(instruction.name, 12),
                         pad('%d' % state.num_insts, 8)))
                # Check whether or not we are in a hardware loop, and set
                # registers after the next instruction, as appropriate. See
                # Section 7.9 of the Architecture Reference Rev. 14.03.11.
                if (state.GID and state.pc == state.rf[reg_map['LE']]):
                    state.rf[reg_map['LC']] -= 1
                    state.is_in_hardware_loop = True
                # Execute next instruction.
                function(state, instruction)
                # --debug
                if (state.is_first_core and state.logger and
                      state.debug.enabled('trace')):
                    state.logger.log('\n')
                # Check hardware loop registers.
                if state.is_in_hardware_loop and state.rf[reg_map['LC']] > 0:
                    state.pc = state.rf[reg_map['LS']]
                    state.is_in_hardware_loop = False
                # Service interrupts.
                if (state.rf[reg_map['ILAT']] > 0 and not (state.GID or
                       state.rf[reg_map['DEBUGSTATUS']] == 1)):
                    interrupt_level = state.get_latched_interrupt()
                    if interrupt_level > -1:  # Interrupt to process.
                        # If a pending interrupt is of a higher priority than
                        # the latched interrupt, carry on with the pending
                        # interrupt.
                        pending_interrupt = state.get_pending_interrupt()
                        if (pending_interrupt == -1 or
                              (pending_interrupt > -1 and
                              interrupt_level <= pending_interrupt)):
                            state.rf[reg_map['IRET']] = state.pc
                            state.rf[reg_map['ILAT']] &= ~(1 << interrupt_level)
                            state.rf[reg_map['IPEND']] |= 1 << interrupt_level
                            state.GID = True  # Set global interrupt disabled bit.
                            state.pc = IVT[interrupt_level]
                            state.ACTIVE = 1  # Wake up IDLE cores.
            except (FatalError, NotImplementedInstError) as error:
                mnemonic, _ = decode(opcode)
                print ('Exception in execution of %s (pc: 0x%s), aborting!' %
                       (mnemonic, pad_hex(pc)))
                print 'Exception message: %s' % error.msg
                return EXIT_GENERAL_ERROR, tick_counter  # pragma: no cover
            # Update instruction counters.
            tick_counter += 1
            state.num_insts += 1
            # Halt if we have reached the maximum instruction count.
            if self.max_insts != 0 and state.num_insts >= self.max_insts:
                print 'Reached the max_insts (%d), exiting.' % self.max_insts
                break
            # Check whether state has halted.
            if not state.running:
                if len(coreids) == 1:  # Last running core has halted.
                    break
                old_core = core
                core = coreids[(coreids.index(core) + 1) % len(coreids)]
                state = self.states[core]
                coreids.remove(old_core)
            # Switch cores after every instruction. TODO: Honour switch interval.
            elif len(coreids) > 1 and tick_counter % self.switch_interval == 0:
                while True:
                    core = coreids[(coreids.index(core) + 1) % len(coreids)]
                    if self.states[core].ACTIVE == 1:
                        break
                    # Idle cores can be made active by interrupts.
                    elif (self.states[core].ACTIVE == 0 and
                            self.states[core].rf[reg_map['ILAT']] > 0):
                        interrupt_level = self.states[core].get_latched_interrupt()
                        self.states[core].rf[reg_map['IRET']] = self.states[core].pc
                        self.states[core].rf[reg_map['ILAT']] &= ~(1 << interrupt_level)
                        self.states[core].rf[reg_map['IPEND']] |= 1 << interrupt_level
                        self.states[core].GID = True  # Set global interrupt disabled bit.
                        self.states[core].pc = IVT[interrupt_level]
                        self.states[core].ACTIVE = 1  # Wake up IDLE cores.
                        break
                state = self.states[core]
            # Move program counter to next instruction.
            old_pc = pc
            pc = state.fetch_pc()
            if pc < old_pc:
                self.jitdriver.can_enter_jit(pc=pc,
                                             core=core,
                                             tick_counter=tick_counter,
                                             coreids=coreids,
                                             sim=self,
                                             state=state,)
        return EXIT_SUCCESS, tick_counter
Exemplo n.º 14
0
 def print_regs(self, per_row=6):
     for c in xrange(0, self.num_regs, per_row):
         str = ""
         for r in xrange(c, min(self.num_regs, c + per_row)):
             str += "%s:%s " % (pad("%d" % r, 2), pad_hex(self.regs[r]))
         print str
Exemplo n.º 15
0
 def __getitem__(self, idx):
     if self.debug.enabled("rf"):
         print ':: RD.RF[%s] = %s' % (pad(
             "%d" % idx, 2), pad_hex(self.regs[idx],
                                     len=self.debug_nchars)),
     return self.regs[idx]
Exemplo n.º 16
0
  def run( self ):
    self = hint( self, promote=True )
    s = self.state

    max_insts = self.max_insts
    jitdriver = self.jitdriver

    while s.running:

      jitdriver.jit_merge_point(
        pc        = s.fetch_pc(),
        max_insts = max_insts,
        state     = s,
        sim       = self,
      )

      # constant-fold pc and mem
      pc  = hint( s.fetch_pc(), promote=True )
      old = pc
      mem = hint( s.mem, promote=True )

      if s.debug.enabled( "insts" ):
        print pad( "%x" % pc, 8, " ", False ),

      # the print statement in memcheck conflicts with @elidable in iread.
      # So we use normal read if memcheck is enabled which includes the
      # memory checks

      if s.debug.enabled( "memcheck" ):
        inst_bits = mem.read( pc, 4 )
      else:
        # we use trace elidable iread instead of just read
        inst_bits = mem.iread( pc, 4 )

      try:
        inst, exec_fun = self.decode( inst_bits )

        if s.debug.enabled( "insts" ):
          print "%s %s %s" % (
                  pad_hex( inst_bits ),
                  pad( inst.str, 12 ),
                  pad( "%d" % s.num_insts, 8 ), ),

        self.pre_execute()

        exec_fun( s, inst )
      except NotImplementedInstError:
        # re-decode instruction to get the instruction name
        inst, _ = self.decode( inst_bits )

        print "Instruction not implemented: %s (pc: 0x%s), aborting!" \
              % ( inst.str, pad_hex( pc ) )
        break
      except FatalError as error:
        print "Exception in execution (pc: 0x%s), aborting!" % pad_hex( pc )
        print "Exception message: %s" % error.msg
        break

      s.num_insts += 1    # TODO: should this be done inside instruction definition?
      if s.stats_en: s.stat_num_insts += 1

      self.post_execute()

      if s.debug.enabled( "insts" ):
        print
      if s.debug.enabled( "regdump" ):
        s.rf.print_regs( per_row=4 )

      # check if we have reached the end of the maximum instructions and
      # exit if necessary
      if max_insts != 0 and s.num_insts >= max_insts:
        print "Reached the max_insts (%d), exiting." % max_insts
        break

      if s.fetch_pc() < old:
        jitdriver.can_enter_jit(
          pc        = s.fetch_pc(),
          max_insts = max_insts,
          state     = s,
          sim       = self,
        )

    print 'DONE! Status =', s.status
    print 'Instructions Executed =', s.num_insts
Exemplo n.º 17
0
def run(state, max_insts=0):
    s = state

    while s.running:

        jitdriver.jit_merge_point(
            pc=s.pc,
            max_insts=max_insts,
            state=s,
        )

        # constant fold the pc
        pc = hint(s.pc, promote=True)
        old = pc

        # We constant fold the s.mem object. This is important because
        # otherwise the trace elidable iread doesn't work (assumes s.mem might
        # have changed)
        mem = hint(s.mem, promote=True)

        if s.debug.enabled("insts"):
            print pad("%x" % s.pc, 6, " ", False),

        # the print statement in memcheck conflicts with @elidable in iread.
        # So we use normal read if memcheck is enabled which includes the
        # memory checks

        if s.debug.enabled("memcheck"):
            inst = mem.read(pc, 4)
        else:
            # we use trace elidable iread instead of just read
            inst = mem.iread(pc, 4)

        inst_str, exec_fun = decode(inst)

        if s.debug.enabled("insts"):
            print "%s %s %s" % (
                pad_hex(inst),
                pad(inst_str, 8),
                pad("%d" % s.ncycles, 8),
            ),

        exec_fun(s, Instruction(inst))

        s.ncycles += 1  # TODO: should this be done inside instruction definition?
        if s.stats_en: s.stat_ncycles += 1

        if s.debug.enabled("insts"):
            print
        if s.debug.enabled("regdump"):
            s.rf.print_regs()

        # check if we have reached the end of the maximum instructions and
        # exit if necessary
        if max_insts != 0 and s.ncycles >= max_insts:
            print "Reached the max_insts (%d), exiting." % max_insts
            break

        if s.pc < old:
            jitdriver.can_enter_jit(
                pc=s.pc,
                max_insts=max_insts,
                state=s,
            )

    print 'DONE! Status =', s.status
    print 'Instructions Executed =', s.ncycles