Пример #1
0
    def construct(s):

        MemReqMsg, MemRespMsg = mk_mem_msg(8, 32, 32)

        # Interface

        s.xcel = XcelMinionIfcCL(XcelReqMsg, XcelRespMsg)

        s.mem = MemMasterIfcCL(*mk_mem_msg(8, 32, 32))
Пример #2
0
  def construct( s ):

    MemReqMsg, MemRespMsg = mk_mem_msg( 8,32,32 )
    MEM_TYPE_READ  = b4(MemMsgType.READ)
    MEM_TYPE_WRITE = b4(MemMsgType.WRITE)

    # Interface

    s.xcel = XcelMinionIfcRTL( XcelReqMsg, XcelRespMsg )

    s.mem  = MemMasterIfcRTL( *mk_mem_msg(8,32,32) )
Пример #3
0
    def construct(s, proc, imem, dmem, xcel):

        CacheReqType, CacheRespType = mk_mem_msg(8, 32, 32)
        MemReqType, MemRespType = mk_mem_msg(8, 32, 128)

        # interface to outside ProcMemXcel

        s.go = InPort()
        s.stats_en = OutPort()
        s.mngr2proc = RecvIfcRTL(Bits32)
        s.proc2mngr = SendIfcRTL(Bits32)

        s.imem = MemMasterIfcRTL(MemReqType, MemRespType)
        s.dmem = MemMasterIfcRTL(MemReqType, MemRespType)

        s.proc = proc
        s.xcel = xcel
        s.icache = imem
        s.dcache = dmem

        s.funnel = Funnel(CacheReqType, 2)(
            in_={
                0: s.proc.dmem.req,
                1: s.xcel.mem.req
            },
            out=s.dcache.cache.req,
        )

        s.router = Router(CacheRespType, 2)(in_=s.dcache.cache.resp,
                                            out={
                                                0: s.proc.dmem.resp,
                                                1: s.xcel.mem.resp
                                            })

        # connect signals

        s.stats_en //= s.proc.stats_en
        s.proc2mngr //= s.proc.proc2mngr
        s.mngr2proc //= s.proc.mngr2proc

        # proc

        s.proc.core_id //= 0
        s.xcel.xcel //= s.proc.xcel
        s.icache.cache //= s.proc.imem

        # mem

        s.imem //= s.icache.mem
        s.dmem //= s.dcache.mem
Пример #4
0
    def construct(s):

        # Interface

        s.xcel = XcelMinionIfcRTL(XcelReqMsg, XcelRespMsg)

        s.mem = MemMasterIfcRTL(*mk_mem_msg(8, 32, 32))

        from os import path
        s.config_placeholder = VerilogPlaceholderConfigs(
            # Path to the Verilog source file
            src_file=path.dirname(__file__) + '/SortXcelVRTL.v',
            # Name of the Verilog top level module
            top_module='lab2_xcel_SortXcelVRTL',
            # Port name map
            port_map={
                'xcel.req.en': 'xcelreq_en',
                'xcel.req.rdy': 'xcelreq_rdy',
                'xcel.req.msg': 'xcelreq_msg',
                'xcel.resp.en': 'xcelresp_en',
                'xcel.resp.rdy': 'xcelresp_rdy',
                'xcel.resp.msg': 'xcelresp_msg',
                'mem.req.en': 'memreq_en',
                'mem.req.rdy': 'memreq_rdy',
                'mem.req.msg': 'memreq_msg',
                'mem.resp.en': 'memresp_en',
                'mem.resp.rdy': 'memresp_rdy',
                'mem.resp.msg': 'memresp_msg',
            },
        )
        s.config_verilog_import = VerilatorImportConfigs(
            # Enable native Verilog line trace through Verilator
            vl_line_trace=True, )
Пример #5
0
  def construct( s, nbits=32 ):
    dtype = mk_bits(nbits)

    # Interface

    s.xcel = XcelMinionIfcRTL( XcelReqMsg, XcelRespMsg )
    s.mem  = MemMasterIfcRTL( *mk_mem_msg(8,nbits,32) )

    # Queues

    s.xcelreq_q = NormalQueueRTL( XcelReqMsg, 2 )( enq = s.xcel.req )

    # Single accelerator register

    s.xr0 = RegEn( Bits32 )

    # Direct connections for xcelreq/xcelresp

    s.xr0.in_             //= s.xcelreq_q.deq.ret.data
    s.xcel.resp.msg.type_ //= s.xcelreq_q.deq.ret.type_

    # Even though memreq/memresp interface is not hooked up, we still
    # need to set the output ports correctly.

    s.mem.req.en   //= 0
    s.mem.req.msg  //= mk_mem_msg(8,nbits,32)[0]()
    s.mem.resp.rdy //= 0

    # Combinational block

    @s.update
    def block():

      # Mux to force xcelresp data to zero on a write

      if s.xcelreq_q.deq.ret.type_ == XCEL_TYPE_WRITE:
        s.xcel.resp.msg.data = dtype(0)
      else:
        s.xcel.resp.msg.data = s.xr0.out

      # Logic for register enable
      both_rdy = s.xcelreq_q.deq.rdy & s.xcel.resp.rdy

      s.xr0.en = (s.xcelreq_q.deq.ret.type_ == XCEL_TYPE_WRITE) & both_rdy

      s.xcelreq_q.deq.en = both_rdy
      s.xcel.resp.en     = both_rdy
  def construct( s, image_column,image_row,window_size,window_size_ext):
  #def construct( s ):

    
    # Interface

    s.xcel = XcelMinionIfcRTL( XcelReqMsg, XcelRespMsg )

    s.mem  = MemMasterIfcRTL( *mk_mem_msg(8,32,32) )

    from os import path
    s.config_placeholder = VerilogPlaceholderConfigs(
      # Path to the Verilog source file
      src_file = path.dirname(__file__) + '/Optical_flowVRTL.v',
      # Name of the Verilog top level module
      top_module = 'Final_Project_Optical_flowVRTL',
      # Port name map
      params={
       'image_column':image_column,
       'image_row'   :image_row,
       'window_size' :window_size,
       'window_size_ext':window_size_ext,
      },
      port_map = {
        'xcel.req.en'   : 'xcelreq_en',
        'xcel.req.rdy'  : 'xcelreq_rdy',
        'xcel.req.msg'  : 'xcelreq_msg',

        'xcel.resp.en'  : 'xcelresp_en',
        'xcel.resp.rdy' : 'xcelresp_rdy',
        'xcel.resp.msg' : 'xcelresp_msg',

        'mem.req.en'   : 'memreq_en',
        'mem.req.rdy'  : 'memreq_rdy',
        'mem.req.msg'  : 'memreq_msg',

        'mem.resp.en'  : 'memresp_en',
        'mem.resp.rdy' : 'memresp_rdy',
        'mem.resp.msg' : 'memresp_msg',
      },
    )
    s.config_verilog_import = VerilatorImportConfigs(
      # Enable native Verilog line trace through Verilator
      vl_line_trace = True,
    )
Пример #7
0
  def construct( s ):

    MemReqMsg, MemRespMsg = mk_mem_msg( 8,32,32 )
    MEM_TYPE_READ  = b4(MemMsgType.READ)
    MEM_TYPE_WRITE = b4(MemMsgType.WRITE)

    # Interface

    s.xcel = XcelMinionIfcRTL( XcelReqMsg, XcelRespMsg )

    s.mem  = MemMasterIfcRTL( *mk_mem_msg(8,32,32) )

    # ''' LAB TASK ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    # Create RTL model for sorting xcel
    # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/

    # Queues

    s.xcelreq_q = PipeQueueRTL( XcelReqMsg, 1 )( enq = s.xcel.req )
    s.memresp_q = PipeQueueRTL( MemRespMsg, 1 )( enq = s.mem.resp )

    # Internal state

    s.base_addr   = Reg( Bits32 )
    s.size        = Reg( Bits32 )
    s.inner_count = Reg( Bits32 )
    s.outer_count = Reg( Bits32 )
    s.a           = Reg( Bits32 )

    # Line tracing

    s.prev_state = 0
    s.xcfg_trace = "  "

    #=====================================================================
    # State Update
    #=====================================================================

    s.STATE_XCFG    = b8(0)
    s.STATE_FIRST0  = b8(1)
    s.STATE_FIRST1  = b8(2)
    s.STATE_BUBBLE0 = b8(3)
    s.STATE_BUBBLE1 = b8(4)
    s.STATE_LAST    = b8(5)

    s.state         = Wire(Bits8)
    s.go            = Wire()

    @s.update_ff
    def block0():

      if s.reset:
        s.state <<= s.STATE_XCFG

      elif s.state == s.STATE_XCFG:
        if s.go & s.xcel.resp.rdy:
          s.state <<= s.STATE_FIRST0

      elif s.state == s.STATE_FIRST0:
        if s.mem.req.rdy:
          s.state <<= s.STATE_FIRST1

      elif s.state == s.STATE_FIRST1:
        if s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.state <<= s.STATE_BUBBLE0

      elif s.state == s.STATE_BUBBLE0:
        if s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.state <<= s.STATE_BUBBLE1

      elif s.state == s.STATE_BUBBLE1:
        if s.mem.req.rdy and s.memresp_q.deq.rdy:
          if s.inner_count.out+1 < s.size.out:
            s.state <<= s.STATE_BUBBLE0
          else:
            s.state <<= s.STATE_LAST

      elif s.state == s.STATE_LAST:
        if s.mem.req.rdy and s.memresp_q.deq.rdy:
          if s.outer_count.out+1 < s.size.out:
            s.state <<= s.STATE_FIRST1
          else:
            s.state <<= s.STATE_XCFG

    #=====================================================================
    # State Outputs
    #=====================================================================

    @s.update
    def block1():

      s.xcelreq_q.deq.en = b1(0)
      s.xcel.resp.en     = b1(0)
      s.mem.req.en       = b1(0)
      s.mem.req.msg      = MemReqMsg()
      s.memresp_q.deq.en = b1(0)
      s.go               = b1(0)

      s.outer_count.in_ = s.outer_count.out
      s.inner_count.in_ = s.inner_count.out
      s.a.in_           = s.a.out
      s.size.in_        = s.size.out
      s.base_addr.in_   = s.base_addr.out

      #-------------------------------------------------------------------
      # STATE: XCFG
      #-------------------------------------------------------------------

      if s.state == s.STATE_XCFG:

        if s.xcelreq_q.deq.rdy & s.xcel.resp.rdy:
          s.xcelreq_q.deq.en = b1(1)
          s.xcel.resp.en     = b1(1)

          if s.xcelreq_q.deq.ret.type_ == XCEL_TYPE_WRITE:

            if   s.xcelreq_q.deq.ret.addr == b5(0):
              s.outer_count.in_ = b32(0)
              s.inner_count.in_ = b32(0)
              s.go              = b1(1)

            elif s.xcelreq_q.deq.ret.addr == b5(1):
              s.base_addr.in_ = s.xcelreq_q.deq.ret.data

            elif s.xcelreq_q.deq.ret.addr == b5(2):
              s.size.in_ = s.xcelreq_q.deq.ret.data

            # Send xcel response message

            s.xcel.resp.msg = XcelRespMsg( XCEL_TYPE_WRITE, b32(0) )

          else:

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

            s.xcel.resp.msg = XcelRespMsg( XCEL_TYPE_READ, b32(1) )

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

      elif s.state == s.STATE_FIRST0:
        if s.mem.req.rdy:
          s.mem.req.en      = s.mem.req.rdy
          s.mem.req.msg     = MemReqMsg( MEM_TYPE_READ, b8(0), s.base_addr.out + 4*s.inner_count.out, b2(0), b32(0) )
          s.inner_count.in_ = b32(1)

      #-------------------------------------------------------------------
      # 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 s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.memresp_q.deq.en = b1(1)
          s.mem.req.en       = b1(1)

          s.a.in_ = s.memresp_q.deq.ret.data

          s.mem.req.msg = MemReqMsg( MEM_TYPE_READ, b8(0), s.base_addr.out + 4*s.inner_count.out, b2(0), b32(0) )

      #-------------------------------------------------------------------
      # 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 s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.memresp_q.deq.en = b1(1)
          s.mem.req.en       = b1(1)

          if s.a.out > s.memresp_q.deq.ret.data:
            s.a.in_ = s.a.out
            s.mem.req.msg = MemReqMsg( MEM_TYPE_WRITE, b8(0),
                                       s.base_addr.out + 4*(s.inner_count.out-1), b2(0),
                                       s.memresp_q.deq.ret.data )
          else:
            s.a.in_ = s.memresp_q.deq.ret.data
            s.mem.req.msg = MemReqMsg( MEM_TYPE_WRITE, b8(0),
                                       s.base_addr.out + 4*(s.inner_count.out-1), b2(0),
                                       s.a.out )

      #-------------------------------------------------------------------
      # 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 s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.memresp_q.deq.en = b1(1)
          s.mem.req.en       = b1(1)

          s.inner_count.in_ = s.inner_count.out + 1

          if s.inner_count.out+1 < s.size.out:
            s.mem.req.msg = MemReqMsg( MEM_TYPE_READ, b8(0),
                                       s.base_addr.out + 4*(s.inner_count.out+1), b2(0), b32(0) )

          else:
            s.mem.req.msg = MemReqMsg( MEM_TYPE_WRITE, b8(0),
                                       s.base_addr.out + 4*s.inner_count.out, b2(0),
                                       s.a.out )

      #-------------------------------------------------------------------
      # 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 s.mem.req.rdy and s.memresp_q.deq.rdy:
          s.memresp_q.deq.en = b1(1)

          s.outer_count.in_ = s.outer_count.out + b32(1)

          if s.outer_count.out + b32(1) < s.size.out:

            s.mem.req.en      = b1(1)
            s.mem.req.msg     = MemReqMsg( MEM_TYPE_READ, b8(0), s.base_addr.out, b2(0), b32(0) )
            s.inner_count.in_ = b32(1)
Пример #8
0
  def construct( s ):

    MemReqMsg, MemRespMsg = mk_mem_msg( 8,32,32 )

    # Interface

    s.xcel = XcelMinionIfcCL( XcelReqMsg, XcelRespMsg )

    s.mem  = MemMasterIfcCL( *mk_mem_msg(8,32,32) )

    # ''' LAB TASK ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    # Create CL model for sorting xcel
    # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\/

    # Components

    s.xcelreq_q = PipeQueueCL( num_entries=1 )( enq = s.xcel.req )
    s.memresp_q = PipeQueueCL( num_entries=1 )( enq = s.mem.resp )

    # Internal state

    s.base_addr   = 0
    s.size        = 0
    s.inner_count = 0
    s.outer_count = 0
    s.a           = b32(0)
    s.b           = b32(0)

    # State

    s.STATE_XCFG    = 0
    s.STATE_FIRST0  = 1
    s.STATE_FIRST1  = 2
    s.STATE_BUBBLE0 = 3
    s.STATE_BUBBLE1 = 4
    s.STATE_LAST    = 5
    s.state         = s.STATE_XCFG

    # Line tracing

    s.prev_state = 0
    s.xcfg_trace = "  "

    # logic

    @s.update
    def block():

      # 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 s.xcelreq_q.deq.rdy() and s.xcel.resp.rdy():

          xcelreq_msg = s.xcelreq_q.deq()

          if xcelreq_msg.type_ == XCEL_TYPE_WRITE:

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

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

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

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

            # Send xcel response message

            s.xcel.resp( XcelRespMsg(XCEL_TYPE_WRITE, 0) )

          else:

            s.xcfg_trace = "x0"

            assert xcelreq_msg.addr == 0

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

            s.xcel.resp( XcelRespMsg(XCEL_TYPE_READ, 1) )

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

      elif s.state == s.STATE_FIRST0:
        if s.mem.req.rdy():
          s.mem.req( MemReqMsg( MemMsgType.READ, 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 s.mem.req.rdy() and s.memresp_q.deq.rdy():
          s.a = s.memresp_q.deq().data
          addr = s.base_addr + 4*s.inner_count
          s.mem.req( MemReqMsg( MemMsgType.READ, 4, 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 s.mem.req.rdy() and s.memresp_q.deq.rdy():
          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.mem.req( MemReqMsg( MemMsgType.WRITE, 4, 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 s.mem.req.rdy() and s.memresp_q.deq.rdy():
          s.memresp_q.deq()
          s.inner_count += 1
          if s.inner_count < s.size:

            addr = s.base_addr + 4*s.inner_count
            s.mem.req( MemReqMsg( MemMsgType.READ, 4, addr, 0 ) )
            s.state = s.STATE_BUBBLE0

          else:

            addr = s.base_addr + 4*s.inner_count
            s.mem.req( MemReqMsg( MemMsgType.WRITE, 4, 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 s.mem.req.rdy() and s.memresp_q.deq.rdy():
          s.memresp_q.deq()
          s.outer_count += 1
          if s.outer_count < s.size:

            s.mem.req( MemReqMsg( MemMsgType.READ, 4, s.base_addr, 0 ) )
            s.inner_count = 1
            s.state = s.STATE_FIRST1

          else:
            s.state = s.STATE_XCFG