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)
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()
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, )
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, ), ])
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), ])
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, )
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, ), ])
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, ), ])
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, )
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, ), ])
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'], ], )
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'], ], )
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
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, ), ])
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, )
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' ], ], )