예제 #1
0
    def __init__(s, interface):
        UseInterface(s, interface)
        size = len(s.interface.clients)
        Pipe = Bits(clog2nz(size))
        s.require(
            MethodSpec(
                'in_peek',
                args=None,
                rets={
                    'msg': s.interface.Data,
                },
                call=False,
                rdy=True,
            ),
            MethodSpec(
                'in_take',
                args=None,
                rets=None,
                call=True,
                rdy=False,
            ),
            MethodSpec(
                'sort',
                args={'msg': s.interface.Data},
                rets={'pipe': Pipe},
                call=False,
                rdy=False,
            ),
        )

        s.peek_array = [
            getattr(s, '{}_peek'.format(client))
            for client in s.interface.clients
        ]
        s.take_array = [
            getattr(s, '{}_take'.format(client))
            for client in s.interface.clients
        ]
        s.rdy_array = [Wire(1) for _ in range(size)]
        for i in range(size):
            s.connect(s.peek_array[i].rdy, s.rdy_array[i])

        s.connect(s.sort_msg, s.in_peek_msg)
        s.take_mux = Mux(Bits(1), size)
        s.effective_call = Wire(1)

        for i in range(size):

            @s.combinational
            def handle_rdy(i=i):
                s.rdy_array[i].v = (s.sort_pipe == i) and s.in_peek_rdy

            s.connect(s.peek_array[i].msg, s.in_peek_msg)
            s.connect(s.take_mux.mux_in_[i], s.take_array[i].call)
        s.connect(s.take_mux.mux_select, s.sort_pipe)
        s.connect(s.in_take_call, s.take_mux.mux_out)
예제 #2
0
파일: cam.py 프로젝트: stwendy/lizard
    def __init__(s, interface, nregs):
        super(RandomReplacementCAMFL, s).__init__(interface)
        Addr = Bits(clog2nz(nregs))
        Key = s.interface.Key
        Value = s.interface.Value

        s.Entry = Entry(Key, Value)
        s.state(
            entries=[s.Entry() for _ in range(nregs)],
            overwrite_counter=Addr(),
        )

        @s.model_method
        def read(key):
            for i in range(nregs - 1, -1, -1):
                entry = s.entries[i]
                if entry.key == key and entry.valid:
                    return Result(value=entry.value, valid=1)
            return Result(value=s.entries[0].value, valid=0)

        @s.model_method
        def write(key, remove, value):
            new = s.Entry()
            new.key = key
            new.value = value
            if remove:
                new.valid = 0
            else:
                new.valid = 1

            last_invalid = -1
            for i in range(nregs - 1, -1, -1):
                entry = s.entries[i]
                if entry.key == key and entry.valid:
                    s.entries[i] = new
                    return
                if last_invalid == -1 and not entry.valid:
                    last_invalid = i

            if remove:
                return

            if last_invalid != -1:
                s.entries[last_invalid] = new
            else:
                i = s.overwrite_counter
                s.entries[int(i)] = new
                if i == nregs - 1:
                    s.overwrite_counter = 0
                else:
                    s.overwrite_counter = i + 1

        @s.model_method
        def clear():
            for i in range(len(s.entries)):
                s.entries[i] = s.Entry()
예제 #3
0
    def __init__(s, dtype, nregs, num_read_ports, num_write_ports,
                 write_read_bypass, write_dump_bypass):
        s.Addr = Bits(clog2nz(nregs))
        s.Data = canonicalize_type(dtype)

        ordering_chains = [
            s.bypass_chain('write', 'read', write_read_bypass),
            s.bypass_chain('write', 'dump', write_dump_bypass),
        ] + s.successor('set', ['read', 'write', 'dump'])

        super(RegisterFileInterface, s).__init__(
            [
                MethodSpec('read',
                           args={
                               'addr': s.Addr,
                           },
                           rets={
                               'data': s.Data,
                           },
                           call=False,
                           rdy=False,
                           count=num_read_ports),
                MethodSpec('write',
                           args={
                               'addr': s.Addr,
                               'data': s.Data,
                           },
                           rets=None,
                           call=True,
                           rdy=False,
                           count=num_write_ports),
                MethodSpec(
                    'dump',
                    args=None,
                    rets={
                        'out': Array(s.Data, nregs),
                    },
                    call=False,
                    rdy=False,
                ),
                MethodSpec(
                    'set',
                    args={
                        'in_': Array(s.Data, nregs),
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
            ],
            ordering_chains=ordering_chains,
        )
예제 #4
0
    def __init__(s, dtype, nclients):
        s.Data = canonicalize_type(dtype)
        s.nclients = nclients
        s.Spec = Bits(clog2nz(nclients))

        super(PipelineSplitterControllerInterface, s).__init__([
            MethodSpec(
                'sort',
                args={'msg': s.Data},
                rets={'pipe': s.Spec},
                call=False,
                rdy=False,
            ),
        ])
예제 #5
0
 def __init__(s, noutbits, enable=False):
     s.Out = Bits(noutbits)
     s.In = clog2nz(noutbits)
     s.En = enable
     super(OneHotEncoderInterface, s).__init__([
         MethodSpec('encode',
                    args={
                        'number': s.In,
                    },
                    rets={
                        'onehot': s.Out,
                    },
                    call=enable,
                    rdy=False),
     ])
예제 #6
0
  def __init__(s,
               dtype,
               nwords,
               num_read_ports,
               num_write_ports,
               write_read_bypass=False):
    s.Addr = Bits(clog2nz(nwords))
    s.Data = canonicalize_type(dtype)
    s.Bypass = write_read_bypass
    s.NumWords = nwords

    ordering_chains = [
        s.bypass_chain('write', 'read', write_read_bypass),
    ]

    super(SynchronousRAMInterface, s).__init__(
        [
            MethodSpec(
                'read_next',
                args={
                    'addr': s.Addr,
                },
                call=False,
                rdy=False,
                count=num_read_ports),
            MethodSpec(
                'read',
                rets={
                    'data': s.Data,
                },
                call=False,
                rdy=False,
                count=num_read_ports),
            MethodSpec(
                'write',
                args={
                    'addr': s.Addr,
                    'data': s.Data,
                },
                rets=None,
                call=True,
                rdy=False,
                count=num_write_ports),
        ],
        ordering_chains=ordering_chains,
    )
예제 #7
0
파일: coders.py 프로젝트: stwendy/lizard
    def __init__(s, inwidth):
        s.In = Bits(inwidth)
        s.Out = clog2nz(inwidth)

        super(PriorityDecoderInterface, s).__init__([
            MethodSpec(
                'decode',
                args={
                    'signal': s.In,
                },
                rets={
                    'decoded': s.Out,
                    'valid': Bits(1),
                },
                call=False,
                rdy=False,
            ),
        ])
예제 #8
0
    def __init__(s, dtype, nports):
        s.Data = canonicalize_type(dtype)
        s.Select = Bits(clog2nz(nports))

        super(MuxInterface, s).__init__([
            MethodSpec(
                'mux',
                args={
                    'in_': Array(s.Data, nports),
                    'select': s.Select,
                },
                rets={
                    'out': s.Data,
                },
                call=False,
                rdy=False,
            ),
        ])
예제 #9
0
    def __init__(s, dtype, nregs, num_read_ports, num_write_ports,
                 write_read_bypass, write_snapshot_bypass, nsnapshots):
        # No dump port exposed, so write_dump_snapshot is False
        base = RegisterFileInterface(dtype, nregs, num_read_ports,
                                     num_write_ports, write_read_bypass, False)

        s.SnapshotId = Bits(clog2nz(nsnapshots))
        s.Addr = base.Addr
        s.Data = base.Data

        ordering_chains = [
            s.bypass_chain('write', 'snapshot', write_snapshot_bypass),
        ] + s.successor('restore', ['read', 'write']) + [
            ['snapshot', 'restore', 'set'],
        ]

        super(SnapshottingRegisterFileInterface, s).__init__(
            [
                MethodSpec(
                    'snapshot',
                    args={
                        'target_id': s.SnapshotId,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
                MethodSpec(
                    'restore',
                    args={
                        'source_id': s.SnapshotId,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
            ],
            bases=[
                IncludeSome(base, {'read', 'write', 'set'}),
            ],
            ordering_chains=ordering_chains,
        )
예제 #10
0
  def __init__(s, base_width, max_size):
    s.Base = canonicalize_type(base_width)
    s.Size = canonicalize_type(clog2nz(max_size + 1))

    super(OverlapCheckerInterface, s).__init__([
        MethodSpec(
            'check',
            args={
                'base_a': s.Base,
                'size_a': s.Size,
                'base_b': s.Base,
                'size_b': s.Size,
            },
            rets={
                'disjoint': Bits(1),
            },
            call=False,
            rdy=False,
        ),
    ])
예제 #11
0
  def __init__(s, naregs, npregs, num_lookup_ports, num_update_ports,
               nsnapshots):
    s.Preg = Bits(clog2nz(npregs))
    snapshot_interface = SnapshottingRegisterFileInterface(
        s.Preg, naregs, 0, 0, False, True, nsnapshots)
    s.Areg = snapshot_interface.Addr
    s.SnapshotId = snapshot_interface.SnapshotId

    super(RenameTableInterface, s).__init__(
        [
            MethodSpec(
                'lookup',
                args={
                    'areg': s.Areg,
                },
                rets={
                    'preg': s.Preg,
                },
                call=False,
                rdy=False,
                count=num_lookup_ports,
            ),
            MethodSpec(
                'update',
                args={
                    'areg': s.Areg,
                    'preg': s.Preg,
                },
                rets=None,
                call=True,
                rdy=False,
                count=num_update_ports,
            ),
        ],
        bases=[
            IncludeSome(snapshot_interface, {'snapshot', 'restore', 'set'}),
        ],
        ordering_chains=[
            ['lookup', 'update', 'snapshot', 'restore', 'set'],
        ],
    )
예제 #12
0
    def __init__(s, nslots, num_alloc_ports, num_free_ports, nsnapshots):
        base = FreeListInterface(nslots,
                                 num_alloc_ports,
                                 num_free_ports,
                                 free_alloc_bypass=False,
                                 release_alloc_bypass=False)

        s.SnapshotId = Bits(clog2nz(nsnapshots))

        super(SnapshottingFreeListInterface, s).__init__(
            [
                MethodSpec(
                    'reset_alloc_tracking',
                    args={
                        'target_id': s.SnapshotId,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
                MethodSpec(
                    'revert_allocs',
                    args={
                        'source_id': s.SnapshotId,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
                # calling reset_alloc_tracking and revert_allocs
                # with the same target ID in the same cycle is not permitted
            ],
            bases=[
                IncludeSome(base, {'free', 'alloc', 'set', 'get_state'}),
            ],
            ordering_chains=[
                ['alloc', 'reset_alloc_tracking', 'revert_allocs', 'set'],
            ],
        )
예제 #13
0
  def __init__(s, interface, nregs):
    UseInterface(s, interface)

    Addr = Bits(clog2nz(nregs))
    Key = s.interface.Key
    Value = s.interface.Value

    s.Entry = Entry(Key, Value)
    s.entries = [
        Register(RegisterInterface(s.Entry(), enable=True), reset_value=0)
        for _ in range(nregs)
    ]
    s.overwrite_counter = Register(
        RegisterInterface(Addr, enable=True), reset_value=0)
    s.read_addr_chain = [Wire(Addr) for _ in range(nregs)]
    s.read_addr_valid = [Wire(1) for _ in range(nregs)]

    # PYMTL_BROKEN
    s.entries_read_data_key = [Wire(Key) for _ in range(nregs)]
    s.entries_read_data_value = [Wire(Value) for _ in range(nregs)]
    s.entries_read_data_valid = [Wire(1) for _ in range(nregs)]
    s.entries_write_data_key = [Wire(Key) for _ in range(nregs)]
    s.entries_write_data_value = [Wire(Value) for _ in range(nregs)]
    s.entries_write_data_valid = [Wire(1) for _ in range(nregs)]
    for i in range(nregs):
      s.connect(s.entries_read_data_key[i], s.entries[i].read_data.key)
      s.connect(s.entries_read_data_value[i], s.entries[i].read_data.value)
      s.connect(s.entries_read_data_valid[i], s.entries[i].read_data.valid)
      s.connect(s.entries[i].write_data.key, s.entries_write_data_key[i])
      s.connect(s.entries[i].write_data.value, s.entries_write_data_value[i])
      s.connect(s.entries[i].write_data.valid, s.entries_write_data_valid[i])

    for i in range(nregs):
      if i == 0:

        @s.combinational
        def handle_read_addr_0(i=i):
          s.read_addr_chain[i].v = i
          s.read_addr_valid[i].v = s.entries_read_data_key[
              i] == s.read_key and s.entries_read_data_valid[i]
      else:

        @s.combinational
        def handle_read_addr(i=i, j=i - 1):
          if s.entries_read_data_key[
              i] == s.read_key and s.entries_read_data_valid[i]:
            s.read_addr_chain[i].v = i
            s.read_addr_valid[i].v = 1
          else:
            s.read_addr_chain[i].v = s.read_addr_chain[j]
            s.read_addr_valid[i].v = s.read_addr_valid[j]

    @s.combinational
    def handle_read():
      s.read_value.v = s.entries_read_data_value[s.read_addr_chain[nregs - 1]]
      s.read_valid.v = s.read_addr_valid[nregs - 1]

    s.write_addr_chain = [Wire(Addr) for _ in range(nregs)]
    s.write_addr_valid = [Wire(1) for _ in range(nregs)]
    s.invalid_addr_chain = [Wire(Addr) for _ in range(nregs)]
    s.invalid_addr_valid = [Wire(1) for _ in range(nregs)]

    for i in range(nregs):
      if i == 0:

        @s.combinational
        def handle_write_addr_0(i=i):
          s.write_addr_chain[i].v = i
          s.write_addr_valid[i].v = s.entries_read_data_key[
              i] == s.write_key and s.entries_read_data_valid[i]
          s.invalid_addr_chain[i].v = i
          s.invalid_addr_valid[i].v = not s.entries_read_data_valid[i]
      else:

        @s.combinational
        def handle_write_addr(i=i, j=i - 1):
          if s.entries_read_data_key[
              i] == s.write_key and s.entries_read_data_valid[i]:
            s.write_addr_chain[i].v = i
            s.write_addr_valid[i].v = 1
          else:
            s.write_addr_chain[i].v = s.write_addr_chain[j]
            s.write_addr_valid[i].v = s.write_addr_valid[j]

          if not s.entries_read_data_valid[i]:
            s.invalid_addr_chain[i].v = i
            s.invalid_addr_valid[i].v = 1
          else:
            s.invalid_addr_chain[i].v = s.invalid_addr_chain[j]
            s.invalid_addr_valid[i].v = s.invalid_addr_valid[j]

    s.overwrite = Wire(1)

    @s.combinational
    def compute_overwrite():
      s.overwrite.v = not s.write_remove and not s.write_addr_valid[
          nregs - 1] and not s.invalid_addr_valid[nregs - 1]

    for i in range(nregs):

      @s.combinational
      def handle_write(i=i):
        if not s.clear_call:
          s.entries[i].write_call.v = s.write_call and (
              (s.overwrite and s.overwrite_counter.read_data == i) or
              (s.write_addr_chain[nregs - 1] == i and
               s.write_addr_valid[nregs - 1]) or
              (not s.write_addr_valid[nregs - 1] and
               s.invalid_addr_chain[nregs - 1] == i and
               s.invalid_addr_valid[nregs - 1] and not s.write_remove))
          s.entries_write_data_key[i].v = s.write_key
          s.entries_write_data_value[i].v = s.write_value
          s.entries_write_data_valid[i].v = not s.write_remove
        else:
          s.entries[i].write_call.v = 1
          s.entries_write_data_key[i].v = 0
          s.entries_write_data_value[i].v = 0
          s.entries_write_data_valid[i].v = 0

    @s.combinational
    def update_overwrite_counter(nregsm1=nregs - 1):
      if s.write_call and s.overwrite:
        s.overwrite_counter.write_call.v = 1
        if s.overwrite_counter.read_data == nregsm1:
          s.overwrite_counter.write_data.v = 0
        else:
          s.overwrite_counter.write_data.v = s.overwrite_counter.read_data + 1
      else:
        s.overwrite_counter.write_call.v = 0
        s.overwrite_counter.write_data.v = 0
예제 #14
0
    def __init__(s, addr_len, max_size, nslots):
        s.nslots = nslots
        s.max_size = max_size
        s.StoreID = canonicalize_type(clog2nz(nslots))
        s.Addr = canonicalize_type(addr_len)
        s.Size = canonicalize_type(clog2nz(max_size + 1))
        # size is in bytes
        s.Data = Bits(max_size * 8)

        super(MemoryFlowManagerInterface, s).__init__([
            MethodSpec(
                'store_pending',
                args={
                    'live_mask': Bits(nslots),
                    'addr': s.Addr,
                    'size': s.Size,
                },
                rets={
                    'pending': Bits(1),
                },
                call=False,
                rdy=False,
            ),
            MethodSpec(
                'recv_load',
                args=None,
                rets={
                    'data': s.Data,
                },
                call=True,
                rdy=True,
            ),
            MethodSpec(
                'store_data_available',
                args={
                    'id_': s.StoreID,
                },
                rets={
                    'ret': Bits(1),
                },
                call=False,
                rdy=False,
            ),
            MethodSpec(
                'send_store',
                args={
                    'id_': s.StoreID,
                },
                rets=None,
                call=True,
                rdy=True,
            ),
            MethodSpec(
                'store_acks_outstanding',
                args=None,
                rets={
                    'ret': Bits(1),
                },
                call=False,
                rdy=False,
            ),
            MethodSpec(
                'send_load',
                args={
                    'addr': s.Addr,
                    'size': s.Size,
                },
                rets=None,
                call=True,
                rdy=True,
            ),
            MethodSpec(
                'register_store',
                args={
                    'id_': s.StoreID,
                },
                rets=None,
                call=True,
                rdy=False,
            ),
            MethodSpec(
                'enter_store_address',
                args={
                    'id_': s.StoreID,
                    'addr': s.Addr,
                    'size': s.Size,
                },
                rets=None,
                call=True,
                rdy=False,
            ),
            MethodSpec(
                'enter_store_data',
                args={
                    'id_': s.StoreID,
                    'data': s.Data,
                },
                rets=None,
                call=True,
                rdy=False,
            ),
        ])
예제 #15
0
파일: freelist.py 프로젝트: stwendy/lizard
  def __init__(s, nslots, num_alloc_ports, num_free_ports, free_alloc_bypass,
               release_alloc_bypass):
    s.Vector = Bits(nslots)
    s.Index = Bits(clog2nz(nslots))

    # Define the ordering
    # Handle the free-alloc bypass, and the release-alloc bypass
    # Require set to be last
    ordering_chains = s.predecessor(
        'get_state', ['alloc', 'free', 'release', 'set']) + [
            s.bypass_chain('free', 'alloc', free_alloc_bypass),
            s.bypass_chain('release', 'alloc', release_alloc_bypass),
        ] + s.successor('set', ['alloc', 'free', 'release'])

    super(FreeListInterface, s).__init__(
        [
            MethodSpec(
                'get_state',
                args=None,
                rets={
                    'state': s.Vector,
                },
                call=False,
                rdy=False,
            ),
            MethodSpec(
                'free',
                args={
                    'index': s.Index,
                },
                rets=None,
                call=True,
                rdy=False,
                count=num_free_ports,
            ),
            MethodSpec(
                'release',
                args={
                    'mask': s.Vector,
                },
                rets=None,
                call=True,
                rdy=False,
            ),
            MethodSpec(
                'alloc',
                args=None,
                rets={
                    'index': s.Index,
                    'mask': s.Vector,
                },
                call=True,
                rdy=True,
                count=num_alloc_ports,
            ),
            MethodSpec(
                'set',
                args={
                    'state': s.Vector,
                },
                rets=None,
                call=True,
                rdy=False,
            ),
        ],
        ordering_chains=ordering_chains,
    )
예제 #16
0
    def __init__(s, dlen, naregs, npregs, nsnapshots, nstore_queue,
                 num_src_ports, num_dst_ports, num_is_ready_ports,
                 num_forward_ports):
        s.DataLen = dlen
        s.NumAregs = naregs
        s.NumPregs = npregs
        s.NumSnapshots = nsnapshots
        s.NumStoreQueue = nstore_queue
        s.StoreQueueIdxNbits = clog2nz(nstore_queue)
        s.NumSrcPorts = num_src_ports
        s.NumDstPorts = num_dst_ports
        s.NumIsReadyPorts = num_is_ready_ports
        s.NumForwardPorts = num_forward_ports
        rename_table_interface = RenameTableInterface(naregs, npregs, 0, 0,
                                                      nsnapshots)

        s.Areg = rename_table_interface.Areg
        s.Preg = rename_table_interface.Preg
        s.SnapshotId = rename_table_interface.SnapshotId

        super(DataFlowManagerInterface, s).__init__(
            [
                MethodSpec(
                    'get_src',
                    args={
                        'areg': s.Areg,
                    },
                    rets={
                        'preg': s.Preg,
                    },
                    call=False,
                    rdy=False,
                    count=num_src_ports,
                ),
                MethodSpec(
                    'get_dst',
                    args={
                        'areg': s.Areg,
                    },
                    rets={
                        'preg': s.Preg,
                    },
                    call=True,
                    rdy=True,
                    count=num_dst_ports,
                ),
                MethodSpec(
                    'valid_store_mask',
                    args=None,
                    rets={
                        'mask': s.NumStoreQueue,
                    },
                    call=False,
                    rdy=False,
                ),
                MethodSpec(
                    'get_store_id',
                    args=None,
                    rets={
                        'store_id': s.StoreQueueIdxNbits,
                    },
                    call=True,
                    rdy=True,
                    count=num_dst_ports,
                ),
                MethodSpec(
                    'is_ready',
                    args={
                        'tag': s.Preg,
                    },
                    rets={
                        'ready': Bits(1),
                    },
                    call=False,
                    rdy=False,
                    count=num_is_ready_ports,
                ),
                MethodSpec(
                    'read',
                    args={
                        'tag': s.Preg,
                    },
                    rets={
                        'value': Bits(dlen),
                    },
                    call=False,
                    rdy=False,
                    count=num_is_ready_ports,
                ),
                MethodSpec(
                    'write',
                    args={
                        'tag': s.Preg,
                        'value': Bits(dlen),
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                    count=num_dst_ports,
                ),
                MethodSpec(
                    'forward',
                    args={
                        'tag': s.Preg,
                        'value': Bits(dlen),
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                    count=num_forward_ports,
                ),
                MethodSpec(
                    'reset_cl_forwarded',
                    args=None,
                    rets=None,
                    call=False,
                    rdy=False,
                ),
                MethodSpec(
                    'get_updated',
                    args=None,
                    rets={
                        'tags': Array(s.Preg,
                                      num_dst_ports + num_forward_ports),
                        'valid': Array(Bits(1),
                                       num_dst_ports + num_forward_ports),
                    },
                    call=False,
                    rdy=False,
                ),
                MethodSpec(
                    'free_store_id',
                    args={
                        'id_': s.StoreQueueIdxNbits,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                    count=num_dst_ports,
                ),
                MethodSpec(
                    'commit',
                    args={
                        'tag': s.Preg,
                        'areg': s.Areg,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                    count=num_dst_ports,
                ),
                MethodSpec(
                    'rollback',
                    args=None,
                    rets=None,
                    call=True,
                    rdy=False,
                ),
                MethodSpec(
                    'snapshot',
                    args=None,
                    rets={
                        'id_': s.SnapshotId,
                    },
                    call=True,
                    rdy=True,
                ),
                MethodSpec(
                    'free_snapshot',
                    args={
                        'id_': s.SnapshotId,
                    },
                    rets=None,
                    call=True,
                    rdy=False,
                ),
            ],
            bases=[
                IncludeSome(rename_table_interface, {'restore'}),
            ],
            ordering_chains=[
                [
                    'is_ready', 'write', 'forward', 'get_updated', 'get_src',
                    'get_dst', 'valid_store_mask', 'get_store_id',
                    'free_store_id', 'commit', 'read', 'reset_cl_forwarded',
                    'snapshot', 'free_snapshot', 'restore', 'rollback'
                ],
            ],
        )