Exemplo n.º 1
0
def resp(type_, data):
    msg = XcelRespMsg()

    if type_ == 'rd': msg.type_ = XcelRespMsg.TYPE_READ
    elif type_ == 'wr': msg.type_ = XcelRespMsg.TYPE_WRITE

    msg.data = data
    return msg
Exemplo n.º 2
0
def resp( type_, data ):
  msg = XcelRespMsg()

  if   type_ == 'rd': msg.type_ = XcelRespMsg.TYPE_READ
  elif type_ == 'wr': msg.type_ = XcelRespMsg.TYPE_WRITE

  msg.data  = data
  return msg
Exemplo n.º 3
0
def resp(opaque, type_, data, id):
    msg = XcelRespMsg()

    msg.opaque = opaque

    if type_ == 'rd': msg.type_ = XcelRespMsg.TYPE_READ
    elif type_ == 'wr': msg.type_ = XcelRespMsg.TYPE_WRITE

    msg.data = data
    msg.id = id
    return msg
Exemplo n.º 4
0
def resp( opaque, type_, data, id ):
  msg = XcelRespMsg()

  msg.opaque = opaque

  if   type_ == 'rd': msg.type_ = XcelRespMsg.TYPE_READ
  elif type_ == 'wr': msg.type_ = XcelRespMsg.TYPE_WRITE

  msg.data  = data
  msg.id    = id
  return msg
Exemplo n.º 5
0
    def block():

      go = False
      while not go:

        xcelreq_msg = s.xcelreq_q.popleft()

        if xcelreq_msg.type_ == XcelReqMsg.TYPE_WRITE:

          assert  xcelreq_msg.raddr in [1,2], \
            "Only reg writes to 1,2 allowed during setup!"

          # Use xcel register address to configure accelerator

          if   xcelreq_msg.raddr == 1: s.operandA = xcelreq_msg.data
          elif xcelreq_msg.raddr == 2: s.operandB = xcelreq_msg.data

          # Send xcel response message

          xcelresp_msg        = XcelRespMsg()
          xcelresp_msg.opaque = xcelreq_msg.opaque
          xcelresp_msg.type_  = XcelRespMsg.TYPE_WRITE
          s.xcelresp_q.append( xcelresp_msg )

        elif xcelreq_msg.type_ == XcelReqMsg.TYPE_READ:

          assert  xcelreq_msg.raddr in [0], \
            "Only reg read to 0 allowed!"

          go = True

      # Compute Gcd of the operands

      s.result = gcd( s.operandA, s.operandB )

      # Send xcel response message indicating xcel is done

      xcelresp_msg        = XcelRespMsg()
      xcelresp_msg.opaque = xcelreq_msg.opaque
      xcelresp_msg.type_  = XcelRespMsg.TYPE_READ
      xcelresp_msg.data   = s.result
      xcelresp_msg.id     = xcelreq_msg.id
      s.xcelresp_q.append( xcelresp_msg )
Exemplo n.º 6
0
        def block():

            # Tick adapters

            s.xcelreq_q.xtick()
            s.xcelresp_q.xtick()
            s.memreq_q.xtick()
            s.memresp_q.xtick()

            # Line tracing string

            s.prev_state = s.state

            #-------------------------------------------------------------------
            # STATE: XCFG
            #-------------------------------------------------------------------
            # In this state we handle the accelerator configuration protocol,
            # where we write the base address, size, and then tell the
            # accelerator to start. We also handle responding when the
            # accelerator is done.

            if s.state == s.STATE_XCFG:
                s.xcfg_trace = "  "
                if not s.xcelreq_q.empty() and not s.xcelresp_q.full():

                    xcelreq_msg = s.xcelreq_q.deq()

                    if xcelreq_msg.type_ == XcelReqMsg.TYPE_WRITE:

                        assert xcelreq_msg.raddr in [0,1,2], \
                          "Only reg writes to 0,1,2 allowed during setup!"

                        if xcelreq_msg.raddr == 0:
                            s.xcfg_trace = "X0"
                            s.outer_count = 0
                            s.state = s.STATE_FIRST0

                        elif xcelreq_msg.raddr == 1:
                            s.xcfg_trace = "X1"
                            s.base_addr = xcelreq_msg.data.uint()

                        elif xcelreq_msg.raddr == 2:
                            s.xcfg_trace = "X2"
                            s.size = xcelreq_msg.data.uint()

                        # Send xcel response message

                        xcelresp_msg = XcelRespMsg()
                        xcelresp_msg.type_ = XcelRespMsg.TYPE_WRITE
                        s.xcelresp_q.enq(xcelresp_msg)

                    else:

                        s.xcfg_trace = "x0"

                        assert xcelreq_msg.raddr == 0

                        # Send xcel response message, obviously you only want to
                        # send the response message when accelerator is done

                        xcelresp_msg = XcelRespMsg()
                        xcelresp_msg.type_ = XcelRespMsg.TYPE_READ
                        xcelresp_msg.data = 1
                        s.xcelresp_q.enq(xcelresp_msg)

            #-------------------------------------------------------------------
            # STATE: FIRST0
            #-------------------------------------------------------------------
            # Send the first memory read request for the very first
            # element in the array.

            elif s.state == s.STATE_FIRST0:
                if not s.memreq_q.full():
                    s.memreq_q.enq(s.mk_rd(0, s.base_addr, 0))
                    s.inner_count = 1
                    s.state = s.STATE_FIRST1

            #-------------------------------------------------------------------
            # STATE: FIRST1
            #-------------------------------------------------------------------
            # Wait for the memory response for the first element in the array,
            # and once it arrives store this element in a, and send the memory
            # read request for the second element.

            elif s.state == s.STATE_FIRST1:
                if not s.memreq_q.full() and not s.memresp_q.empty():
                    s.a = deepcopy(s.memresp_q.deq().data)
                    addr = s.base_addr + 4 * s.inner_count
                    s.memreq_q.enq(s.mk_rd(0, addr, 0))
                    s.state = s.STATE_BUBBLE0

            #-------------------------------------------------------------------
            # STATE: BUBBLE0
            #-------------------------------------------------------------------
            # Wait for the memory read response to get the next element,
            # compare the new value to the previous max value, update b with
            # the new max value, and send a memory request to store the new min
            # value. Notice how we decrement the write address by four since we
            # want to store to the new min value _previous_ element.

            elif s.state == s.STATE_BUBBLE0:
                if not s.memreq_q.full() and not s.memresp_q.empty():
                    s.b = deepcopy(s.memresp_q.deq().data)
                    max_value = max(s.a, s.b)
                    min_value = min(s.a, s.b)
                    s.a = max_value
                    addr = s.base_addr + 4 * s.inner_count
                    s.memreq_q.enq(s.mk_wr(0, addr - 4, 0, min_value))
                    s.state = s.STATE_BUBBLE1

            #-------------------------------------------------------------------
            # STATE: BUBBLE1
            #-------------------------------------------------------------------
            # Wait for the memory write response, and then check to see if we
            # have reached the end of the array. If we have not reached the end
            # of the array, then make a new memory read request for the next
            # element; if we have reached the end of the array, then make a
            # final write request (with value from a) to update the final
            # element in the array.

            elif s.state == s.STATE_BUBBLE1:
                if not s.memreq_q.full() and not s.memresp_q.empty():
                    s.memresp_q.deq()
                    s.inner_count += 1
                    if s.inner_count < s.size:

                        addr = s.base_addr + 4 * s.inner_count
                        s.memreq_q.enq(s.mk_rd(0, addr, 0))
                        s.state = s.STATE_BUBBLE0

                    else:

                        addr = s.base_addr + 4 * s.inner_count
                        s.memreq_q.enq(s.mk_wr(0, addr - 4, 0, s.a))
                        s.state = s.STATE_LAST

            #-------------------------------------------------------------------
            # STATE: LAST
            #-------------------------------------------------------------------
            # Wait for the last response, and then check to see if we need to
            # go through the array again. If we do need to go through array
            # again, then make a new memory read request for the very first
            # element in the array; if we do not need to go through the array
            # again, then we are all done and we can go back to accelerator
            # configuration.

            elif s.state == s.STATE_LAST:
                if not s.memreq_q.full() and not s.memresp_q.empty():
                    s.memresp_q.deq()
                    s.outer_count += 1
                    if s.outer_count < s.size:

                        s.memreq_q.enq(s.mk_rd(0, s.base_addr, 0))
                        s.inner_count = 1
                        s.state = s.STATE_FIRST1

                    else:
                        s.state = s.STATE_XCFG
Exemplo n.º 7
0
    def block():

      # We loop handling accelerator requests. We are only expecting
      # writes to xr0-2, so any other requests are an error. We exit the
      # loop when we see the write to xr0.

      go = False
      while not go:

        xcelreq_msg = s.xcelreq_q.popleft()

        # Only expecting writes to xr0-2, so any other request is an xcel
        # protocol error.

        assert xcelreq_msg.type_ == XcelReqMsg.TYPE_WRITE, \
          "Only reg writes allowed during setup!"

        assert xcelreq_msg.raddr in [0,1,2], \
          "Only reg writes to 0,1,2 allowed during setup!"

        # Use xcel register address to configure accelerator

        if   xcelreq_msg.raddr == 0: go = True
        elif xcelreq_msg.raddr == 1: s.data.set_base( xcelreq_msg.data )
        elif xcelreq_msg.raddr == 2: s.data.set_size( xcelreq_msg.data )

        # Send xcel response message

        xcelresp_msg = XcelRespMsg()
        xcelresp_msg.type_ = XcelRespMsg.TYPE_WRITE
        s.xcelresp_q.append( xcelresp_msg )

      # Now that we have setup the list memory port adapter, we can use
      # the data as a standard Python list. The adapter handles turning
      # reads and writes to the list into the corresponding read/write
      # memory requests, and also waiting for the responses. So we first
      # create a sorted version of the list ...

      data_sorted = sorted(s.data)

      # And then we copy the result out to memory

      for i in xrange(len(data_sorted)):
        s.data[i] = data_sorted[i]

      # Now wait for read of xr0

      xcelmsg = s.xcelreq_q.popleft()

      # Only expecting read from xr0, so any other request is an xcel
      # protocol error.

      assert xcelreq_msg.type_ == XcelReqMsg.TYPE_READ, \
        "Only reg reads allowed during done phase!"

      assert xcelreq_msg.raddr == 0, \
        "Only reg writes to 0,1,2 allowed during done phase!"

      # Send xcel response message indicating xcel is done

      xcelresp_msg = XcelRespMsg()
      xcelresp_msg.type_ = XcelRespMsg.TYPE_READ
      xcelresp_msg.data  = 1
      s.xcelresp_q.append( xcelresp_msg )
Exemplo n.º 8
0
    def block():

      # Tick adapters

      s.xcelreq_q.xtick()
      s.xcelresp_q.xtick()
      s.memreq_q.xtick()
      s.memresp_q.xtick()

      # Line tracing string

      s.prev_state = s.state

      #-------------------------------------------------------------------
      # STATE: XCFG
      #-------------------------------------------------------------------
      # In this state we handle the accelerator configuration protocol,
      # where we write the base address, size, and then tell the
      # accelerator to start. We also handle responding when the
      # accelerator is done.

      if s.state == s.STATE_XCFG:
        s.xcfg_trace = "  "
        if not s.xcelreq_q.empty() and not s.xcelresp_q.full():

          xcelreq_msg = s.xcelreq_q.deq()

          if xcelreq_msg.type_ == XcelReqMsg.TYPE_WRITE:

            assert xcelreq_msg.raddr in [0,1,2], \
              "Only reg writes to 0,1,2 allowed during setup!"

            if   xcelreq_msg.raddr == 0:
              s.xcfg_trace = "X0"
              s.outer_count = 0
              s.state = s.STATE_FIRST0

            elif xcelreq_msg.raddr == 1:
              s.xcfg_trace = "X1"
              s.base_addr = xcelreq_msg.data.uint()

            elif xcelreq_msg.raddr == 2:
              s.xcfg_trace = "X2"
              s.size = xcelreq_msg.data.uint()

            # Send xcel response message

            xcelresp_msg = XcelRespMsg()
            xcelresp_msg.type_ = XcelRespMsg.TYPE_WRITE
            s.xcelresp_q.enq( xcelresp_msg )

          else:

            s.xcfg_trace = "x0"

            assert xcelreq_msg.raddr == 0

            # Send xcel response message, obviously you only want to
            # send the response message when accelerator is done

            xcelresp_msg = XcelRespMsg()
            xcelresp_msg.type_ = XcelRespMsg.TYPE_READ
            xcelresp_msg.data  = 1
            s.xcelresp_q.enq( xcelresp_msg )

      #-------------------------------------------------------------------
      # STATE: FIRST0
      #-------------------------------------------------------------------
      # Send the first memory read request for the very first
      # element in the array.

      elif s.state == s.STATE_FIRST0:
        if not s.memreq_q.full():
          s.memreq_q.enq( s.mk_rd( 0, s.base_addr, 0 ) )
          s.inner_count = 1
          s.state = s.STATE_FIRST1

      #-------------------------------------------------------------------
      # STATE: FIRST1
      #-------------------------------------------------------------------
      # Wait for the memory response for the first element in the array,
      # and once it arrives store this element in a, and send the memory
      # read request for the second element.

      elif s.state == s.STATE_FIRST1:
        if not s.memreq_q.full() and not s.memresp_q.empty():
          s.a = deepcopy( s.memresp_q.deq().data )
          addr = s.base_addr + 4*s.inner_count
          s.memreq_q.enq( s.mk_rd( 0, addr, 0 ) )
          s.state = s.STATE_BUBBLE0

      #-------------------------------------------------------------------
      # STATE: BUBBLE0
      #-------------------------------------------------------------------
      # Wait for the memory read response to get the next element,
      # compare the new value to the previous max value, update b with
      # the new max value, and send a memory request to store the new min
      # value. Notice how we decrement the write address by four since we
      # want to store to the new min value _previous_ element.

      elif s.state == s.STATE_BUBBLE0:
        if not s.memreq_q.full() and not s.memresp_q.empty():
          s.b = deepcopy( s.memresp_q.deq().data )
          max_value = max( s.a, s.b )
          min_value = min( s.a, s.b )
          s.a = max_value
          addr = s.base_addr + 4*s.inner_count
          s.memreq_q.enq( s.mk_wr( 0, addr-4, 0, min_value ) )
          s.state = s.STATE_BUBBLE1

      #-------------------------------------------------------------------
      # STATE: BUBBLE1
      #-------------------------------------------------------------------
      # Wait for the memory write response, and then check to see if we
      # have reached the end of the array. If we have not reached the end
      # of the array, then make a new memory read request for the next
      # element; if we have reached the end of the array, then make a
      # final write request (with value from a) to update the final
      # element in the array.

      elif s.state == s.STATE_BUBBLE1:
        if not s.memreq_q.full() and not s.memresp_q.empty():
          s.memresp_q.deq()
          s.inner_count += 1
          if s.inner_count < s.size:

            addr = s.base_addr + 4*s.inner_count
            s.memreq_q.enq( s.mk_rd( 0, addr, 0 ) )
            s.state = s.STATE_BUBBLE0

          else:

            addr = s.base_addr + 4*s.inner_count
            s.memreq_q.enq( s.mk_wr( 0, addr-4, 0, s.a ) )
            s.state = s.STATE_LAST

      #-------------------------------------------------------------------
      # STATE: LAST
      #-------------------------------------------------------------------
      # Wait for the last response, and then check to see if we need to
      # go through the array again. If we do need to go through array
      # again, then make a new memory read request for the very first
      # element in the array; if we do not need to go through the array
      # again, then we are all done and we can go back to accelerator
      # configuration.

      elif s.state == s.STATE_LAST:
        if not s.memreq_q.full() and not s.memresp_q.empty():
          s.memresp_q.deq()
          s.outer_count += 1
          if s.outer_count < s.size:

            s.memreq_q.enq( s.mk_rd( 0, s.base_addr, 0 ) )
            s.inner_count = 1
            s.state = s.STATE_FIRST1

          else:
            s.state = s.STATE_XCFG
Exemplo n.º 9
0
        def block():

            # We loop handling accelerator requests. We are only expecting
            # writes to xr0-2, so any other requests are an error. We exit the
            # loop when we see the write to xr0.

            go = False
            while not go:

                xcelreq_msg = s.xcelreq_q.popleft()

                # Only expecting writes to xr0-2, so any other request is an xcel
                # protocol error.

                assert xcelreq_msg.type_ == XcelReqMsg.TYPE_WRITE, \
                  "Only reg writes allowed during setup!"

                assert xcelreq_msg.raddr in [0,1,2], \
                  "Only reg writes to 0,1,2 allowed during setup!"

                # Use xcel register address to configure accelerator

                if xcelreq_msg.raddr == 0: go = True
                elif xcelreq_msg.raddr == 1: s.data.set_base(xcelreq_msg.data)
                elif xcelreq_msg.raddr == 2: s.data.set_size(xcelreq_msg.data)

                # Send xcel response message

                xcelresp_msg = XcelRespMsg()
                xcelresp_msg.type_ = XcelRespMsg.TYPE_WRITE
                s.xcelresp_q.append(xcelresp_msg)

            # Now that we have setup the list memory port adapter, we can use
            # the data as a standard Python list. The adapter handles turning
            # reads and writes to the list into the corresponding read/write
            # memory requests, and also waiting for the responses. So we first
            # create a sorted version of the list ...

            data_sorted = sorted(s.data)

            # And then we copy the result out to memory

            for i in xrange(len(data_sorted)):
                s.data[i] = data_sorted[i]

            # Now wait for read of xr0

            xcelmsg = s.xcelreq_q.popleft()

            # Only expecting read from xr0, so any other request is an xcel
            # protocol error.

            assert xcelreq_msg.type_ == XcelReqMsg.TYPE_READ, \
              "Only reg reads allowed during done phase!"

            assert xcelreq_msg.raddr == 0, \
              "Only reg writes to 0,1,2 allowed during done phase!"

            # Send xcel response message indicating xcel is done

            xcelresp_msg = XcelRespMsg()
            xcelresp_msg.type_ = XcelRespMsg.TYPE_READ
            xcelresp_msg.data = 1
            s.xcelresp_q.append(xcelresp_msg)