Exemple #1
0
class _SparseMemory( object ):
  _immutable_fields_ = [ "BlockMemory", "block_size", "addr_mask",
                         "block_mask" ]

  def __init__( self, BlockMemory, block_size=2**10 ):
    self.BlockMemory = BlockMemory
    self.block_size = block_size
    self.addr_mask  = block_size - 1
    self.block_mask = 0xffffffff ^ self.addr_mask
    self.debug = Debug()
    print "sparse memory size %x addr mask %x block mask %x" \
          % ( self.block_size, self.addr_mask, self.block_mask )
    #blocks     = []
    self.block_dict = {}

  def add_block( self, block_addr ):
    #print "adding block: %x" % block_addr
    self.block_dict[ block_addr ] = self.BlockMemory( size=self.block_size )

  @elidable
  def get_block_mem( self, block_addr ):
    #block_idx  = block_dict[ 
    if block_addr not in self.block_dict:
      self.add_block( block_addr )
    block_mem = self.block_dict[ block_addr ]
    return block_mem

  @elidable
  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 )

  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

  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 )
Exemple #2
0
class _ByteMemory( object ):
  def __init__( self, data=None, size=2**10 ):
    self.data  = data if data else [' '] * size
    self.size  = len( self.data )
    self.debug = Debug()

  def bounds_check( self, addr ):
    # check if the accessed data is larger than the memory size
    if addr > self.size:
      print "WARNING: accessing larger address than memory size. " + \
            "addr=%s size=%s" % ( pad_hex( addr ), pad_hex( self.size ) )
    if addr == 0:
      print "WARNING: writing null pointer!"
      raise Exception()

  @unroll_safe
  def read( self, start_addr, num_bytes ):
    if self.debug.enabled( "memcheck" ):
      self.bounds_check( start_addr )
    value = 0
    if self.debug.enabled( "mem" ):
      print ':: RD.MEM[%s] = ' % pad_hex( start_addr ),
    for i in range( num_bytes-1, -1, -1 ):
      value = value << 8
      value = value | ord( self.data[ start_addr + i ] )
    if self.debug.enabled( "mem" ):
      print '%s' % pad_hex( value ),
    return value

  # this is instruction read, which is otherwise identical to read. The
  # only difference is the elidable annotation, which we assume the
  # instructions are not modified (no side effects, assumes the addresses
  # correspond to the same instructions)
  @elidable
  def iread( self, start_addr, num_bytes ):
    value = 0
    for i in range( num_bytes-1, -1, -1 ):
      value = value << 8
      value = value | ord( self.data[ start_addr + i ] )
    return value

  @unroll_safe
  def write( self, start_addr, num_bytes, value ):
    if self.debug.enabled( "memcheck" ):
      self.bounds_check( start_addr )
    if self.debug.enabled( "mem" ):
      print ':: WR.MEM[%s] = %s' % ( pad_hex( start_addr ),
                                     pad_hex( value ) ),
    for i in range( num_bytes ):
      self.data[ start_addr + i ] = chr(value & 0xFF)
      value = value >> 8
Exemple #3
0
class RegisterFile( object ):
  def __init__( self, constant_zero=True, num_regs=32, nbits=32 ):
    self.num_regs = num_regs
    self.regs     = [ r_uint(0) ] * self.num_regs
    self.debug    = Debug()
    self.nbits    = nbits
    self.debug_nchars = nbits / 4

    if constant_zero: self._setitemimpl = self._set_item_const_zero
    else:             self._setitemimpl = self._set_item
  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]

  @specialize.argtype(2)
  def __setitem__( self, idx, value ):
    value = r_uint( value )
    self._setitemimpl( idx, value )

  def _set_item( self, idx, 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 ) ),
  def _set_item_const_zero( self, idx, value ):
    if idx != 0:
      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 ) ),

  #-----------------------------------------------------------------------
  # print_regs
  #-----------------------------------------------------------------------
  # prints all registers (register dump)
  # per_row specifies the number of registers to display per row
  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], len=(self.nbits/4) ) )
      print str
Exemple #4
0
class _ByteMemory(object):
    def __init__(self, data=None, size=2**10, suppress_debug=False):
        self.data = data if data else [' '] * size
        self.size = len(self.data)
        self.debug = Debug()
        self.suppress_debug = suppress_debug

    def bounds_check(self, addr):
        # check if the accessed data is larger than the memory size
        if addr > self.size:
            print "WARNING: accessing larger address than memory size. " + \
                  "addr=%s size=%s" % ( pad_hex( addr ), pad_hex( self.size ) )
        if addr == 0:
            print "WARNING: writing null pointer!"
            raise Exception()

    @unroll_safe
    def read(self, start_addr, num_bytes):
        if self.debug.enabled("memcheck") and not self.suppress_debug:
            self.bounds_check(start_addr)
        value = 0
        if self.debug.enabled("mem") and not self.suppress_debug:
            print ':: RD.MEM[%s] = ' % pad_hex(start_addr),
        for i in range(num_bytes - 1, -1, -1):
            value = value << 8
            value = value | ord(self.data[start_addr + i])
        if self.debug.enabled("mem") and not self.suppress_debug:
            print '%s' % pad_hex(value),
        return value

    # this is instruction read, which is otherwise identical to read. The
    # only difference is the elidable annotation, which we assume the
    # instructions are not modified (no side effects, assumes the addresses
    # correspond to the same instructions)
    @elidable
    def iread(self, start_addr, num_bytes):
        value = 0
        for i in range(num_bytes - 1, -1, -1):
            value = value << 8
            value = value | ord(self.data[start_addr + i])
        return value

    @unroll_safe
    def write(self, start_addr, num_bytes, value):
        if self.debug.enabled("memcheck") and not self.suppress_debug:
            self.bounds_check(start_addr)
        if self.debug.enabled("mem") and not self.suppress_debug:
            print ':: WR.MEM[%s] = %s' % (pad_hex(start_addr), pad_hex(value)),
        for i in range(num_bytes):
            self.data[start_addr + i] = chr(value & 0xFF)
            value = value >> 8
Exemple #5
0
class RegisterFile(object):
    def __init__(self, constant_zero=True, num_regs=32, nbits=32):
        self.num_regs = num_regs
        self.regs = [r_uint(0)] * self.num_regs
        self.debug = Debug()
        self.nbits = nbits
        self.debug_nchars = nbits / 4

        if constant_zero: self._setitemimpl = self._set_item_const_zero
        else: self._setitemimpl = self._set_item

    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]

    @specialize.argtype(2)
    def __setitem__(self, idx, value):
        value = r_uint(value)
        self._setitemimpl(idx, value)

    def _set_item(self, idx, 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)),

    def _set_item_const_zero(self, idx, value):
        if idx != 0:
            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)),

    #-----------------------------------------------------------------------
    # print_regs
    #-----------------------------------------------------------------------
    # prints all registers (register dump)
    # per_row specifies the number of registers to display per row
    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], len=(self.nbits / 4)))
            print str
Exemple #6
0
class _WordMemory( object ):
  def __init__( self, data=None, size=2**10 ):
    self.data  = data if data else [ r_uint32(0) ] * (size >> 2)
    self.size  = (len( self.data ) << 2)
    self.debug = Debug()

    # TODO: pass data_section to memory for bounds checking
    self.data_section = 0x00000000

  def bounds_check( self, addr, x ):
    # check if the accessed data is larger than the memory size
    if addr > self.size:
      print ("WARNING: %s accessing larger address than memory size. "
             "addr=%s size=%s") % ( x, pad_hex( addr ), pad_hex( self.size ) )
      raise Exception()
    if addr == 0:
      print "WARNING: accessing null pointer!"
      raise Exception()

    # Special write checks
    if x == 'WR' and addr < self.data_section:
      print ("WARNING: %s writing address below .data section!!!. "
             "addr=%s size=%s") % ( x, pad_hex( addr ), pad_hex( self.data_section ) )
      raise Exception()


  @unroll_safe
  def read( self, start_addr, num_bytes ):
    assert 0 < num_bytes <= 4
    word = start_addr >> 2
    byte = start_addr &  0b11

    if self.debug.enabled( "mem" ):
      print ':: RD.MEM[%s] = ' % pad_hex( start_addr ),
    if self.debug.enabled( "memcheck" ):
      self.bounds_check( start_addr, 'RD' )

    value = 0
    if   num_bytes == 4:  # TODO: byte should only be 0 (only aligned)
      value = widen( self.data[ word ] )
    elif num_bytes == 2:  # TODO: byte should only be 0, 1, 2, not 3
      mask = 0xFFFF << (byte * 8)
      value = ( widen( self.data[ word ] ) & mask) >> (byte * 8)
    elif num_bytes == 1:
      mask = 0xFF   << (byte * 8)
      value = ( widen( self.data[ word ] ) & mask) >> (byte * 8)
    else:
      raise Exception('Invalid num_bytes: %d!' % num_bytes)

    if self.debug.enabled( "mem" ):
      print '%s' % pad_hex( value ),

    return value

  # this is instruction read, which is otherwise identical to read. The
  # only difference is the elidable annotation, which we assume the
  # instructions are not modified (no side effects, assumes the addresses
  # correspond to the same instructions)
  @elidable
  def iread( self, start_addr, num_bytes ):
    assert start_addr & 0b11 == 0  # only aligned accesses allowed
    return widen( self.data[ start_addr >> 2 ] )

  @unroll_safe
  def write( self, start_addr, num_bytes, value ):
    assert 0 < num_bytes <= 4
    word = start_addr >> 2
    byte = start_addr &  0b11

    if self.debug.enabled( "memcheck" ):
      self.bounds_check( start_addr, 'WR' )

    if   num_bytes == 4:  # TODO: byte should only be 0 (only aligned)
      pass # no masking needed
    elif num_bytes == 2:  # TODO: byte should only be 0, 1, 2, not 3
      mask  = ~(0xFFFF << (byte * 8)) & 0xFFFFFFFF
      value = ( widen( self.data[ word ] ) & mask ) \
              | ( (value & 0xFFFF) << (byte * 8) )
    elif num_bytes == 1:
      mask  = ~(0xFF   << (byte * 8)) & 0xFFFFFFFF
      value = ( widen( self.data[ word ] ) & mask ) \
              | ( (value & 0xFF  ) << (byte * 8) )
    else:
      raise Exception('Invalid num_bytes: %d!' % num_bytes)

    if self.debug.enabled( "mem" ):
      print ':: WR.MEM[%s] = %s' % ( pad_hex( start_addr ),
                                     pad_hex( value ) ),
    self.data[ word ] = r_uint32( value )
Exemple #7
0
                    val = layer.getValue(x, y)
                    val[0] = int(val[0])
                    val[1] = int(val[1])
                    val[2] = int(val[2])
                    #myDebug.dprint("layer val: " + str(val))
                    pix[x, y] = tuple(val)
                    
                # time it took to generate 1 row of pixels   
            if not eta:
                newTime = time.time()
                timeRemaining = (newTime - oldTime) * float(width) * float(frames)
                hours = int(timeRemaining / 3600)
                mins = int(timeRemaining / 60) - hours * 3600
                seconds = int(timeRemaining) - mins * 60
                
                print "Render Time Estimate:",  hours, "hours", mins, "mins", seconds, "seconds"
                eta = True

        myDebug.dprint("Frame " + str(nImage + 1) + " of " + str(frames))
        draw = ImageDraw.Draw(image)
        if (myDebug.enabled()):
            draw.text((0, 0),"Frame: " + str(nImage + 1),(255,255,255))
        draw.text((0, height - 15),"PysiCrystals v" + VERSION,(255,255,255))
        images.append(image)
        layer.update()
    print ("Writing Gif...")
    # duration parameter seems a bit off...
    writeGif(outputFile, images, duration / 20, 0, 0, 0)


Exemple #8
0
class _SparseMemory( object ):
  _immutable_fields_ = [ "BlockMemory", "block_size", "addr_mask",
                         "block_mask" ]

  def __init__( self, BlockMemory, block_size=2**10 ):
    self.BlockMemory = BlockMemory
    self.block_size = block_size
    self.addr_mask  = block_size - 1
    self.block_mask = 0xffffffff ^ self.addr_mask
    self.debug = Debug()
    print "sparse memory size %x addr mask %x block mask %x" \
          % ( self.block_size, self.addr_mask, self.block_mask )
    #blocks     = []
    self.block_dict = {}
    self.debug = Debug()

  def add_block( self, block_addr ):
    #print "adding block: %x" % block_addr
    self.block_dict[ block_addr ] = self.BlockMemory( size=self.block_size )

  @elidable
  def get_block_mem( self, block_addr ):
    #block_idx  = block_dict[ 
    if block_addr not in self.block_dict:
      self.add_block( block_addr )
    block_mem = self.block_dict[ block_addr ]
    return block_mem

  @elidable
  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

  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

  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 )
Exemple #9
0
class _WordMemory(object):
    def __init__(self, data=None, size=2**10):
        self.data = data if data else [0] * (size >> 2)
        self.size = (len(self.data) << 2)
        self.debug = Debug()

    def bounds_check(self, addr, x):
        # check if the accessed data is larger than the memory size
        if addr > self.size:
            print(
                "WARNING: %s accessing larger address than memory size. "
                "addr=%s size=%s") % (x, pad_hex(addr), pad_hex(self.size))
            raise Exception()
        if addr == 0:
            print "WARNING: accessing null pointer!"
            raise Exception()

        # Special write checks
        if x == 'WR' and addr < self.data_section:
            print(
                "WARNING: %s writing address below .data section!!!. "
                "addr=%s size=%s") % (x, pad_hex(addr),
                                      pad_hex(self.data_section))
            raise Exception()

    @unroll_safe
    def read(self, start_addr, num_bytes):
        assert 0 < num_bytes <= 4
        word = start_addr >> 2
        byte = start_addr & 0b11

        if self.debug.enabled("mem"):
            print ':: RD.MEM[%s] = ' % pad_hex(start_addr),
        if self.debug.enabled("memcheck"):
            self.bounds_check(start_addr, 'RD')

        value = 0
        if num_bytes == 4:  # TODO: byte should only be 0 (only aligned)
            value = self.data[word]
        elif num_bytes == 2:  # TODO: byte should only be 0, 1, 2, not 3
            mask = 0xFFFF << (byte * 8)
            value = (self.data[word] & mask) >> (byte * 8)
        elif num_bytes == 1:
            mask = 0xFF << (byte * 8)
            value = (self.data[word] & mask) >> (byte * 8)
        else:
            raise Exception('Invalid num_bytes: %d!' % num_bytes)

        if self.debug.enabled("mem"):
            print '%s' % pad_hex(value),

        return value

    # this is instruction read, which is otherwise identical to read. The
    # only difference is the elidable annotation, which we assume the
    # instructions are not modified (no side effects, assumes the addresses
    # correspond to the same instructions)
    @elidable
    @unroll_safe
    def iread(self, start_addr, num_bytes):
        assert start_addr & 0b11 == 0  # only aligned accesses allowed
        return self.data[start_addr >> 2]

    @unroll_safe
    def write(self, start_addr, num_bytes, value):
        assert 0 < num_bytes <= 4
        word = start_addr >> 2
        byte = start_addr & 0b11

        if self.debug.enabled("memcheck"):
            self.bounds_check(start_addr, 'WR')

        if num_bytes == 4:  # TODO: byte should only be 0 (only aligned)
            self.data[word] = value
        elif num_bytes == 2:  # TODO: byte should only be 0, 1, 2, not 3
            mask = ~(0xFFFF << (byte * 8)) & 0xFFFFFFFF
            value = (self.data[word] & mask) | ((value & 0xFFFF) << (byte * 8))
        elif num_bytes == 1:
            mask = ~(0xFF << (byte * 8)) & 0xFFFFFFFF
            value = (self.data[word] & mask) | ((value & 0xFF) << (byte * 8))
        else:
            raise Exception('Invalid num_bytes: %d!' % num_bytes)

        if self.debug.enabled("mem"):
            print ':: WR.MEM[%s] = %s' % (pad_hex(start_addr), pad_hex(value)),
        self.data[word] = value
Exemple #10
0
class _SparseMemory(object):
    _immutable_fields_ = [
        "BlockMemory", "block_size", "addr_mask", "block_mask"
    ]

    def __init__(self, BlockMemory, block_size=2**10):
        self.BlockMemory = BlockMemory
        self.block_size = block_size
        self.addr_mask = block_size - 1
        self.block_mask = 0xffffffff ^ self.addr_mask
        self.debug = Debug()
        print "sparse memory size %x addr mask %x block mask %x" \
              % ( self.block_size, self.addr_mask, self.block_mask )
        #blocks     = []
        self.block_dict = {}
        self.debug = Debug()

    def add_block(self, block_addr):
        #print "adding block: %x" % block_addr
        self.block_dict[block_addr] = self.BlockMemory(size=self.block_size,
                                                       suppress_debug=True)

    @elidable
    def get_block_mem(self, block_addr):
        #block_idx  = block_dict[
        if block_addr not in self.block_dict:
            self.add_block(block_addr)
        block_mem = self.block_dict[block_addr]
        return block_mem

    @elidable
    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

    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

    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)