Example #1
0
  def iread( self, start_addr, num_bytes ):
    start_addr = hint( start_addr, promote=True )
    num_bytes  = hint( num_bytes,  promote=True )

    block_addr = self.block_mask & start_addr
    block_mem = self.get_block_mem( block_addr )
    return block_mem.iread( start_addr & self.addr_mask, num_bytes )
Example #2
0
  def iread( self, start_addr, num_bytes ):
    start_addr = hint( start_addr, promote=True )
    num_bytes  = hint( num_bytes,  promote=True )
    end_addr   = start_addr + num_bytes - 1

    block_addr = self.block_mask & start_addr
    block_mem = self.get_block_mem( block_addr )
    # For mixed-width ISAs, the start_addr is not necessarily
    # word-aligned, and can cross block memory boundaries. If there is
    # such a case, we have two instruction reads and then form the word
    # for it
    block_end_addr = self.block_mask & end_addr
    if block_addr == block_end_addr:
      return block_mem.iread( start_addr & self.addr_mask, num_bytes )
    else:
      num_bytes1 = min( self.block_size - (start_addr & self.addr_mask),
                        num_bytes )
      num_bytes2 = num_bytes - num_bytes1

      block_mem1 = block_mem
      block_mem2 = self.get_block_mem( block_end_addr )
      value1 = block_mem1.iread( start_addr & self.addr_mask, num_bytes1 )
      value2 = block_mem2.iread( 0, num_bytes2 )
      value = value1 | ( value2 << (num_bytes1*8) )
      #print "nb1", num_bytes1, "nb2", num_bytes2, \
      #      "ba1", hex(block_addr), "ba2", hex(block_end_addr), \
      #      "v1", hex(value1), "v2", hex(value2), "v", hex(value)
      return value
Example #3
0
    def iread(self, start_addr, num_bytes):
        start_addr = hint(start_addr, promote=True)
        num_bytes = hint(num_bytes, promote=True)
        end_addr = start_addr + num_bytes - 1

        block_addr = self.block_mask & start_addr
        block_mem = self.get_block_mem(block_addr)
        # For mixed-width ISAs, the start_addr is not necessarily
        # word-aligned, and can cross block memory boundaries. If there is
        # such a case, we have two instruction reads and then form the word
        # for it
        block_end_addr = self.block_mask & end_addr
        if block_addr == block_end_addr:
            return block_mem.iread(start_addr & self.addr_mask, num_bytes)
        else:
            num_bytes1 = min(self.block_size - (start_addr & self.addr_mask),
                             num_bytes)
            num_bytes2 = num_bytes - num_bytes1

            block_mem1 = block_mem
            block_mem2 = self.get_block_mem(block_end_addr)
            value1 = block_mem1.iread(start_addr & self.addr_mask, num_bytes1)
            value2 = block_mem2.iread(0, num_bytes2)
            value = value1 | (value2 << (num_bytes1 * 8))
            #print "nb1", num_bytes1, "nb2", num_bytes2, \
            #      "ba1", hex(block_addr), "ba2", hex(block_end_addr), \
            #      "v1", hex(value1), "v2", hex(value2), "v", hex(value)
            return value
Example #4
0
 def write(self, start_addr, num_bytes, value):
     if self.debug.enabled("mem"):
         print ':: WR.MEM[%s] = %s' % (pad_hex(start_addr), pad_hex(value)),
     block_addr = self.block_mask & start_addr
     block_addr = hint(block_addr, promote=True)
     block_mem = self.get_block_mem(block_addr)
     block_mem.write(start_addr & self.addr_mask, num_bytes, value)
Example #5
0
 def write( self, start_addr, num_bytes, value ):
   if self.debug.enabled( "mem" ):
     print ':: WR.MEM[%s] = %s' % ( pad_hex( start_addr ),
                                    pad_hex( value ) ),
   block_addr = self.block_mask & start_addr
   block_addr = hint( block_addr, promote=True )
   block_mem = self.get_block_mem( block_addr )
   block_mem.write( start_addr & self.addr_mask, num_bytes, value )
Example #6
0
 def read( self, start_addr, num_bytes ):
   if self.debug.enabled( "mem" ):
     print ':: RD.MEM[%s] = ' % pad_hex( start_addr ),
   block_addr = self.block_mask & start_addr
   block_addr = hint( block_addr, promote=True )
   block_mem = self.get_block_mem( block_addr )
   value = block_mem.read( start_addr & self.addr_mask, num_bytes )
   if self.debug.enabled( "mem" ):
     print '%s' % pad_hex( value ),
   return value
Example #7
0
 def read(self, start_addr, num_bytes):
     if self.debug.enabled("mem"):
         print ':: RD.MEM[%s] = ' % pad_hex(start_addr),
     block_addr = self.block_mask & start_addr
     block_addr = hint(block_addr, promote=True)
     block_mem = self.get_block_mem(block_addr)
     value = block_mem.read(start_addr & self.addr_mask, num_bytes)
     if self.debug.enabled("mem"):
         print '%s' % pad_hex(value),
     return value
Example #8
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
Example #9
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