def construct( s, PacketType, QueueType=None ): # Local parameter # gating_out = PacketType() # TODO: add data gating support # Interface s.recv = RecvIfcRTL( PacketType ) s.send = SendIfcRTL( PacketType ) s.QueueType = QueueType #--------------------------------------------------------------------- # If no queue type is assigned #--------------------------------------------------------------------- if s.QueueType != None: # Component s.queue = QueueType( PacketType ) # Connections s.recv //= s.queue.recv s.queue.send //= s.send #--------------------------------------------------------------------- # No ouput queue #--------------------------------------------------------------------- else: s.send //= s.recv
def construct( s, PacketType, PositionType, k_ary, n_fly, InputUnitType=InputUnitRTL, RouteUnitType=DTRBflyRouteUnitRTL, SwitchUnitType=SwitchUnitRTL, OutputUnitType=OutputUnitRTL, ): s.dim = PhysicalDimension() s.num_inports = k_ary s.num_outports = k_ary # Interface s.pos = InPort(PositionType) s.recv = [RecvIfcRTL(PacketType) for _ in range(s.num_inports)] s.send = [SendIfcRTL(PacketType) for _ in range(s.num_outports)] # Components s.input_units = [ InputUnitType(PacketType) for _ in range(s.num_inports) ] s.route_units = [ RouteUnitType(PacketType, PositionType, s.num_outports, n_fly=n_fly) for i in range(s.num_inports) ] s.switch_units = [ SwitchUnitType(PacketType, s.num_inports) for _ in range(s.num_outports) ] s.output_units = [ OutputUnitType(PacketType) for _ in range(s.num_outports) ] # Connection for i in range(s.num_inports): s.recv[i] //= s.input_units[i].recv s.input_units[i].send //= s.route_units[i].recv s.pos //= s.route_units[i].pos for i in range(s.num_inports): for j in range(s.num_outports): s.route_units[i].send[j] //= s.switch_units[j].recv[i] for j in range(s.num_outports): s.switch_units[j].send //= s.output_units[j].recv s.output_units[j].send //= s.send[j]
def construct(s, Type, num_inports=1): assert num_inports == 1, 'Null switch unit can only be used for single-input router!' # Interface s.recv = [RecvIfcRTL(Type) for _ in range(num_inports)] s.hold = [InPort() for _ in range(num_inports)] s.send = SendIfcRTL(Type) connect(s.send, s.recv[0])
def construct(s, PacketType, QueueType=NormalQueueRTL): # Interface s.recv = RecvIfcRTL(PacketType) s.send = SendIfcRTL(PacketType) # Component s.queue = QueueType(PacketType) s.queue.recv //= s.recv s.queue.send //= s.send
def construct( s, PacketType, num_inports = 2, num_outports = 2, InputUnitType = InputUnitRTL, RouteUnitType = XbarRouteUnitRTL, SwitchUnitType = SwitchUnitRTL, OutputUnitType = OutputUnitRTL, ): # Local parameter s.num_inports = num_inports s.num_outports = num_outports # Special case for num_inports = 1 if num_inports == 1: SwitchUnitType = SwitchUnitNullRTL # Interface s.recv = [ RecvIfcRTL( PacketType ) for _ in range( s.num_inports ) ] s.send = [ SendIfcRTL( PacketType ) for _ in range( s.num_outports ) ] # Components s.input_units = [ InputUnitType( PacketType ) for _ in range( s.num_inports ) ] s.route_units = [ RouteUnitType( PacketType, s.num_outports ) for i in range( s.num_inports ) ] s.switch_units = [ SwitchUnitType( PacketType, s.num_inports ) for _ in range( s.num_outports ) ] s.output_units = [ OutputUnitType( PacketType ) for _ in range( s.num_outports ) ] # Connections for i in range( s.num_inports ): s.recv[i] //= s.input_units[i].recv s.input_units[i].send //= s.route_units[i].recv for i in range( s.num_inports ): for j in range( s.num_outports ): s.route_units[i].send[j] //= s.switch_units[j].recv[i] for j in range( s.num_outports ): s.switch_units[j].send //= s.output_units[j].recv s.output_units[j].send //= s.send[j]
def construct(s, PacketType, PositionType, num_outports=8): # Constants s.num_outports = num_outports TType = mk_bits(clog2(num_outports)) # Interface s.recv = RecvIfcRTL(PacketType) s.send = [SendIfcRTL(PacketType) for _ in range(s.num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(mk_bits(clog2(num_outports))) s.send_rdy = Wire(mk_bits(num_outports)) # Connections for i in range(num_outports): s.recv.msg //= s.send[i].msg s.send_rdy[i] //= s.send[i].rdy # Routing logic @update def up_ru_routing(): s.out_dir @= 0 for i in range(s.num_outports): s.send[i].val @= Bits1(0) if s.recv.val: if (s.pos.pos_x == s.recv.msg.dst_x) & (s.pos.pos_y == s.recv.msg.dst_y): s.out_dir @= SELF + zext(s.recv.msg.dst_ter, TType) elif s.recv.msg.dst_x < s.pos.pos_x: s.out_dir @= WEST elif s.recv.msg.dst_x > s.pos.pos_x: s.out_dir @= EAST elif s.recv.msg.dst_y < s.pos.pos_y: s.out_dir @= SOUTH else: s.out_dir @= NORTH s.send[s.out_dir].val @= Bits1(1) @update def up_ru_recv_rdy(): s.recv.rdy @= s.send_rdy[s.out_dir]
def construct(s, MsgType, vc=2, credit_line=1): assert vc > 1 # Interface s.recv = RecvIfcRTL(MsgType) s.send = CreditSendIfcRTL(MsgType, vc) s.MsgType = MsgType s.vc = vc # Components CreditType = mk_bits(clog2(credit_line + 1)) # FIXME: use multiple buffers to avoid deadlock. # s.buffer = BypassQueueRTL( MsgType, num_entries=1 ) s.credit = [Counter(CreditType, credit_line) for _ in range(vc)] # s.recv //= s.buffer.enq # s.buffer.deq.ret //= s.send.msg s.recv.msg //= s.send.msg @update def up_credit_send(): s.send.en @= 0 s.recv.rdy @= 0 # NOTE: recv.rdy depends on recv.val. # Be careful about combinationl loop. if s.recv.val: for i in range(vc): if (i == s.recv.msg.vc_id) & (s.credit[i].count > 0): s.send.en @= 1 s.recv.rdy @= 1 @update def up_counter_decr(): for i in range(vc): s.credit[i].decr @= s.send.en & (i == s.send.msg.vc_id) for i in range(vc): s.credit[i].incr //= s.send.yum[i] s.credit[i].load //= 0 s.credit[i].load_value //= 0
def construct( s, PacketType, PositionType, num_routers=4, chl_lat=0, vc=2, credit_line=2, ): # Constants s.num_routers = num_routers # IDType = mk_bits(clogs(num_routers)) # Interface s.recv = [ RecvIfcRTL(PacketType) for _ in range(s.num_routers)] s.send = [ SendIfcRTL(PacketType) for _ in range(s.num_routers)] # Components s.routers = [ RingRouterRTL( PacketType, PositionType, num_routers, vc=vc ) for i in range( num_routers ) ] s.recv_adp = [ RecvRTL2CreditSendRTL( PacketType, vc=vc, credit_line=credit_line ) for _ in range( num_routers ) ] s.send_adp = [ CreditRecvRTL2SendRTL( PacketType, vc=vc, credit_line=credit_line ) for _ in range( num_routers ) ] # Connect s.routers together in ring for i in range( s.num_routers ): next_id = (i+1) % num_routers s.routers[i].send[RIGHT] //= s.routers[next_id].recv[LEFT] s.routers[next_id].send[LEFT] //= s.routers[i].recv[RIGHT] # Connect the self port (with Network Interface) s.recv[i] //= s.recv_adp[i].recv s.recv_adp[i].send //= s.routers[i].recv[SELF] s.routers[i].send[SELF] //= s.send_adp[i].recv s.send_adp[i].send //= s.send[i] @update def up_pos(): for r in range( s.num_routers ): s.routers[r].pos @= r
def construct(s, PacketType, QueueType=NormalQueueRTL, latency=0): # Constant s.dim = PhysicalDimension() s.QueueType = QueueType s.latency = latency s.num_entries = 2 # Interface s.recv = RecvIfcRTL(PacketType) s.send = SendIfcRTL(PacketType) #--------------------------------------------------------------------- # If latency > 0 and channel queue exists #--------------------------------------------------------------------- if s.QueueType != None and s.latency > 0: # Component s.queues = [ s.QueueType(PacketType, s.num_entries) for _ in range(s.latency) ] # Connections s.recv //= s.queues[0].recv for i in range(s.latency - 1): s.queues[i + 1].recv //= s.queues[i].send s.queues[-1].send //= s.send #--------------------------------------------------------------------- # If latency==0 simply bypass #--------------------------------------------------------------------- else: s.recv //= s.send
def construct( s, PacketType, num_inports=5 ): # Local parameters s.num_inports = num_inports s.sel_width = clog2( num_inports ) # Interface s.recv = [ RecvIfcRTL( PacketType ) for _ in range( s.num_inports ) ] s.send = SendIfcRTL( PacketType ) # Components s.arbiter = RoundRobinArbiterEn( num_inports ) s.arbiter.en //= 1 s.mux = Mux( PacketType, num_inports ) s.mux.out //= s.send.msg s.encoder = Encoder( num_inports, s.sel_width ) s.encoder.in_ //= s.arbiter.grants s.encoder.out //= s.mux.sel # Connections for i in range( num_inports ): s.recv[i].val //= s.arbiter.reqs[i] s.recv[i].msg //= s.mux.in_[i] @update def up_send_val(): s.send.val @= s.arbiter.grants > 0 # TODO: assert at most one rdy bit @update def up_get_en(): for i in range( num_inports ): s.recv[i].rdy @= s.send.rdy & ( s.mux.sel == i )
def construct( s, PacketType, num_outports ): # Local parameters dir_nbits = 1 if num_outports==1 else clog2( num_outports ) DirT = mk_bits( dir_nbits ) BitsN = mk_bits( num_outports ) # Interface s.recv = RecvIfcRTL( PacketType ) s.send = [ SendIfcRTL( PacketType ) for _ in range( num_outports ) ] # Componets s.out_dir = Wire( DirT ) s.send_val = Wire( BitsN ) # Connections for i in range( num_outports ): s.recv.msg //= s.send[i].msg s.send_val[i] //= s.send[i].val # Routing logic @update def up_ru_routing(): s.out_dir @= trunc( s.recv.msg.dst, dir_nbits ) for i in range( num_outports ): s.send[i].val @= b1(0) if s.recv.val: s.send[ s.out_dir ].val @= b1(1) @update def up_ru_recv_rdy(): s.recv.rdy @= s.send[ s.out_dir ].rdy > 0
def construct(s, MsgType, vc=2, credit_line=2): assert vc > 1 # Interface s.recv = RecvIfcRTL(MsgType) s.send = CreditSendIfcRTL(MsgType, vc) s.MsgType = MsgType s.vc = vc # Loval types credit_type = mk_bits(clog2(credit_line + 1)) s.credit = [Counter(credit_type, credit_line) for _ in range(vc)] s.recv.msg //= s.send.msg @update def up_credit_send(): s.send.en @= 0 s.recv.rdy @= 0 # NOTE: Here the recv.rdy depends on recv.val. # Be careful about combinational loop. if s.recv.val: for i in range(vc): if (i == s.recv.msg.vc_id) & (s.credit[i].count > 0): s.send.en @= 1 s.recv.rdy @= 1 @update def up_counter_decr(): for i in range(vc): s.credit[i].decr @= s.send.en & (i == s.send.msg.vc_id) for i in range(vc): s.credit[i].incr //= s.send.yum[i] s.credit[i].load //= 0 s.credit[i].load_value //= 0
def construct( s, Type, msgs, initial_delay=0, interval_delay=0, arrival_time=None, cmp_fn=lambda a, b : a == b ): # Interface s.recv = RecvIfcRTL( Type ) # Data # [msgs] and [arrival_time] must have the same length. if arrival_time is None: s.arrival_time = None else: assert len( msgs ) == len( arrival_time ) s.arrival_time = list( arrival_time ) s.idx = 0 s.count = 0 s.cycle_count = 0 s.msgs = list( msgs ) s.nmsgs = len( msgs ) s.error_msg = '' s.received = False s.all_msg_recved = False s.done_flag = False @update_ff def up_sink(): # Raise exception at the start of next cycle so that the errored # line trace gets printed out if s.error_msg: raise PyMTLTestSinkError( s.error_msg ) # Tick one more cycle after all message is received so that the # exception gets thrown if s.all_msg_recved: s.done_flag = True if s.idx >= s.nmsgs: s.all_msg_recved = True s.received = False if s.reset: s.cycle_count = 0 s.idx = 0 s.count = initial_delay s.recv.rdy <<= (s.idx < s.nmsgs) & (s.count == 0) else: s.cycle_count += 1 # This means at least previous cycle count = 0 if s.recv.val & s.recv.rdy: msg = s.recv.msg # Sanity check if s.idx >= s.nmsgs: s.error_msg = ( 'Test Sink received more msgs than expected!\n' f'Received : {msg}' ) else: # Check correctness first if not [ m for m in s.msgs if cmp_fn( msg, m ) ]: s.error_msg = ( f'Test sink {s} received WRONG message!\n' f'Expected : { s.msgs }\n' f'Received : { msg }' ) # Check timing if performance regeression is turned on elif s.arrival_time and s.cycle_count > s.arrival_time[ s.idx ]: s.error_msg = ( f'Test sink {s} received message LATER than expected!\n' f'Expected msg : {s.msgs[ s.idx ]}\n' f'Expected at : {s.arrival_time[ s.idx ]}\n' f'Received msg : {msg}\n' f'Received at : {s.cycle_count}' ) # No error else: for m in s.msgs: if cmp_fn( msg, m ): s.msgs.remove( m ) break s.idx += 1 s.count = interval_delay if s.count > 0: s.count -= 1 s.recv.rdy <<= 0 else: # s.count == 0 s.recv.rdy <<= (s.idx < s.nmsgs)
def construct( s, PacketType, PositionType, num_routers=4 ): # Constants s.num_outports = 3 s.num_routers = num_routers DistType = mk_bits( clog2( num_routers ) ) s.last_idx = DistType( num_routers-1 ) # Interface s.recv = RecvIfcRTL( PacketType ) s.send = [ SendIfcRTL (PacketType) for _ in range ( s.num_outports ) ] s.pos = InPort( PositionType ) # Componets s.out_dir = Wire( mk_bits( clog2( s.num_outports ) ) ) s.send_rdy = Wire( mk_bits( s.num_outports ) ) s.left_dist = Wire( DistType ) s.right_dist = Wire( DistType ) s.send_msg_wire = Wire( PacketType ) # Connections for i in range( s.num_outports ): s.send_rdy[i] //= s.send[i].rdy # Routing logic @update def up_left_right_dist(): if s.recv.msg.dst < s.pos: s.left_dist @= zext(s.pos, DistType) - zext(s.recv.msg.dst, DistType) s.right_dist @= zext(s.last_idx, DistType) - zext(s.pos, DistType) + zext(s.recv.msg.dst, DistType) + 1 else: s.left_dist @= 1 + zext(s.last_idx, DistType) + zext(s.pos, DistType) - zext(s.recv.msg.dst, DistType) s.right_dist @= zext(s.recv.msg.dst, DistType) - zext(s.pos, DistType) @update def up_ru_routing(): s.out_dir @= 0 s.send_msg_wire @= s.recv.msg for i in range( s.num_outports ): s.send[i].val @= 0 if s.recv.val: if s.pos == s.recv.msg.dst: s.out_dir @= SELF elif s.left_dist < s.right_dist: s.out_dir @= LEFT else: s.out_dir @= RIGHT if ( s.pos == s.last_idx ) & ( s.out_dir == RIGHT ): s.send_msg_wire.vc_id @= 1 elif ( s.pos == 0 ) & ( s.out_dir == LEFT ): s.send_msg_wire.vc_id @= 1 s.send[ s.out_dir ].val @= 1 s.send[ s.out_dir ].msg @= s.send_msg_wire @update def up_ru_recv_rdy(): s.recv.rdy @= s.send_rdy[ s.out_dir ]
def construct(s, PacketType, PositionType, ncols=4, nrows=4, chl_lat=0, vc=2, credit_line=2): # Constants s.ncols = ncols s.nrows = nrows s.num_routers = ncols * nrows s.num_terminals = s.num_routers XType = mk_bits(clog2(ncols)) YType = mk_bits(clog2(nrows)) # Interface s.recv = [RecvIfcRTL(PacketType) for _ in range(s.num_terminals)] s.send = [SendIfcRTL(PacketType) for _ in range(s.num_terminals)] # Components s.routers = [ TorusRouterRTL(PacketType, PositionType, ncols=ncols, nrows=nrows, vc=vc, credit_line=credit_line) for i in range(s.num_routers) ] s.recv_adapters = [ RecvRTL2CreditSendRTL(PacketType, vc=vc, credit_line=credit_line) for _ in range(s.num_routers) ] s.send_adapters = [ CreditRecvRTL2SendRTL(PacketType, vc=vc, credit_line=credit_line) for _ in range(s.num_routers) ] # Connect s.routers together in Torus chl_id = 0 for i in range(s.num_routers): s_idx = (i - nrows + s.num_routers) % s.num_routers s.routers[i].send[SOUTH] //= s.routers[s_idx].recv[NORTH] s.routers[i].send[NORTH] //=\ s.routers[(i+ncols+s.num_routers)%s.num_routers].recv[SOUTH] s.routers[i].send[WEST] //=\ s.routers[i-(i%ncols-(i-1)%ncols)].recv[EAST] s.routers[i].send[EAST] //=\ s.routers[i+(i+1)%ncols-i%ncols].recv[WEST] # Connect the self port (with Network Interface) s.recv[i] //= s.recv_adapters[i].recv s.recv_adapters[i].send //= s.routers[i].recv[SELF] s.routers[i].send[SELF] //= s.send_adapters[i].recv s.send_adapters[i].send //= s.send[i] # @update # def up_pos(): for y in range(nrows): for x in range(ncols): # idx = y * ncols + x # s.routers[idx].pos = PositionType( x, y ) s.routers[y * ncols + x].pos.pos_x //= XType(x) s.routers[y * ncols + x].pos.pos_y //= YType(y)
def construct(s, PacketType, PositionType, k_ary, n_fly, chl_lat=0): # Constants s.dim = PhysicalDimension() s.k_ary = k_ary s.n_fly = n_fly s.r_rows = k_ary**(n_fly - 1) s.num_routers = n_fly * (s.r_rows) s.num_terminals = k_ary**n_fly num_channels = (n_fly - 1) * (s.r_rows) * k_ary # Interface s.recv = [RecvIfcRTL(PacketType) for _ in range(s.num_terminals)] s.send = [SendIfcRTL(PacketType) for _ in range(s.num_terminals)] # Components s.routers = [ BflyRouterRTL(PacketType, PositionType, k_ary, n_fly) for i in range(s.num_routers) ] s.channels = [ ChannelRTL(PacketType, latency=chl_lat) for _ in range(num_channels) ] s.pos = [ PositionType(r % s.r_rows, r // s.r_rows) for r in range(s.num_routers) ] # Connect routers together in Butterfly for r in range(s.num_routers): s.routers[r].pos.row //= s.pos[r].row s.routers[r].pos.stage //= s.pos[r].stage chl_id = 0 terminal_id_recv = 0 terminal_id_send = 0 group_size = s.r_rows for f in range(n_fly - 1): num_group = s.r_rows // group_size for g in range(num_group): for gs in range(group_size): for k in range(k_ary): index = g * group_size + gs base = g * group_size interval = group_size // k_ary * k router_left = f * s.r_rows + index router_right = (f + 1) * s.r_rows + base + ( gs + interval) % group_size group_left = router_left % s.r_rows group_right = router_right % s.r_rows group_left_x = group_left % k_ary group_right_x = group_right % k_ary group_left_y = group_left // k_ary group_right_y = group_right // k_ary rtr_idx = f * s.r_rows + index ifc_tdx = (k + gs // (group_size // k_ary)) % k_ary rtr_idx_n = (f + 1) * s.r_rows + base + ( gs + interval) % group_size s.routers[rtr_idx].send[ifc_tdx] //= s.channels[ chl_id].recv s.channels[chl_id].send //= s.routers[rtr_idx_n].recv[ k] chl_id += 1 group_size = group_size // k_ary # Connect the router ports with Network Interfaces for i in range(s.num_routers): if i < s.r_rows: for j in range(k_ary): s.recv[terminal_id_recv] //= s.routers[i].recv[j] terminal_id_recv += 1 if i >= s.num_routers - s.r_rows: for j in range(k_ary): s.send[terminal_id_send] //= s.routers[i].send[j] terminal_id_send += 1
def construct(s, PacketType, PositionType, ncols=2, nrows=2): # Constants num_outports = 5 s.ncols = ncols s.nrows = nrows # Here we add 1 to avoid overflow posx_type = mk_bits(clog2(ncols)) posy_type = mk_bits(clog2(nrows)) ns_dist_type = mk_bits(clog2(nrows + 1)) we_dist_type = mk_bits(clog2(ncols + 1)) s.last_row_id = nrows - 1 s.last_col_id = ncols - 1 # Interface s.recv = RecvIfcRTL(PacketType) s.send = [SendIfcRTL(PacketType) for _ in range(num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(Bits3) s.send_rdy = Wire(Bits5) s.turning = Wire(Bits1) s.north_dist = Wire(ns_dist_type) s.south_dist = Wire(ns_dist_type) s.west_dist = Wire(we_dist_type) s.east_dist = Wire(we_dist_type) s.send_msg_wire = Wire(PacketType) # Connections for i in range(num_outports): s.send_rdy[i] //= s.send[i].rdy s.send_msg_wire //= s.send[i].msg # Calculate distance @update def up_ns_dist(): if s.recv.msg.dst_y < s.pos.pos_y: s.south_dist @= zext(s.pos.pos_y, ns_dist_type) - zext( s.recv.msg.dst_y, ns_dist_type) s.north_dist @= s.last_row_id - zext( s.pos.pos_y, ns_dist_type) + 1 + zext( s.recv.msg.dst_y, ns_dist_type) else: s.south_dist @= zext(s.pos.pos_y, ns_dist_type) + 1 + s.last_row_id - zext( s.recv.msg.dst_y, ns_dist_type) s.north_dist @= zext(s.recv.msg.dst_y, ns_dist_type) - zext( s.pos.pos_y, ns_dist_type) @update def up_we_dist(): if s.recv.msg.dst_x < s.pos.pos_x: s.west_dist @= zext(s.pos.pos_x, we_dist_type) - zext( s.recv.msg.dst_x, we_dist_type) s.east_dist @= s.last_col_id - zext( s.pos.pos_x, we_dist_type) + 1 + zext( s.recv.msg.dst_x, we_dist_type) else: s.west_dist @= zext(s.pos.pos_x, we_dist_type) + 1 + s.last_col_id - zext( s.recv.msg.dst_x, we_dist_type) s.east_dist @= zext(s.recv.msg.dst_x, we_dist_type) - zext( s.pos.pos_x, we_dist_type) # Routing logic @update def up_ru_routing(): s.send_msg_wire @= s.recv.msg s.out_dir @= 0 s.turning @= 0 for i in range(num_outports): s.send[i].val @= 0 if s.recv.val: if (s.pos.pos_x == s.recv.msg.dst_x) & (s.pos.pos_y == s.recv.msg.dst_y): s.out_dir @= SELF elif s.recv.msg.dst_y != s.pos.pos_y: s.out_dir @= NORTH if s.north_dist < s.south_dist else SOUTH else: s.out_dir @= WEST if s.west_dist < s.east_dist else EAST # Turning logic s.turning @= ( s.recv.msg.src_x == s.pos.pos_x ) & \ ( s.recv.msg.src_y != s.pos.pos_y ) & \ ( s.out_dir == WEST ) | ( s.out_dir == EAST ) # Dateline logic if s.turning: s.send_msg_wire.vc_id @= 0 if (s.pos.pos_x == 0) & (s.out_dir == WEST): s.send_msg_wire.vc_id @= 1 elif (s.pos.pos_x == s.last_col_id) & (s.out_dir == EAST): s.send_msg_wire.vc_id @= 1 elif (s.pos.pos_y == 0) & (s.out_dir == SOUTH): s.send_msg_wire.vc_id @= 1 elif (s.pos.pos_y == s.last_row_id) & (s.out_dir == NORTH): s.send_msg_wire.vc_id @= 1 s.send[s.out_dir].val @= 1 @update def up_ru_recv_rdy(): s.recv.rdy @= s.send[s.out_dir].rdy
def construct(s, PacketType, PositionType, ncols=4, nrows=4, num_nodes_each=4, chl_lat=0): # Constants s.num_routers = ncols * nrows s.num_terminals = s.num_routers * num_nodes_each num_channels = (nrows * (ncols - 1) + ncols * (nrows - 1)) * 2 num_inports = 4 + num_nodes_each num_outports = 4 + num_nodes_each XType = mk_bits(clog2(ncols)) YType = mk_bits(clog2(nrows)) # Interface s.recv = [RecvIfcRTL(PacketType) for _ in range(s.num_terminals)] s.send = [SendIfcRTL(PacketType) for _ in range(s.num_terminals)] # Components s.routers = [ CMeshRouterRTL(PacketType, PositionType, num_inports, num_outports) for i in range(s.num_routers) ] s.channels = [ ChannelRTL(PacketType, latency=chl_lat) for _ in range(num_channels) ] # Connect s.routers together in Mesh # FIXME: we need to calculate the bit width for directions. Currently # the translation pass may throw an error. chl_id = 0 for i in range(s.num_routers): if i // ncols > 0: s.routers[i].send[SOUTH] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i - ncols].recv[NORTH] chl_id += 1 if i // ncols < nrows - 1: s.routers[i].send[NORTH] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i + ncols].recv[SOUTH] chl_id += 1 if i % ncols > 0: s.routers[i].send[WEST] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i - 1].recv[EAST] chl_id += 1 if i % ncols < ncols - 1: s.routers[i].send[EAST] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i + 1].recv[WEST] chl_id += 1 # Connect the self port (with Network Interface) for j in range(num_nodes_each): ifc_idx = i * num_nodes_each + j s.recv[ifc_idx] //= s.routers[i].recv[4 + j] s.send[ifc_idx] //= s.routers[i].send[4 + j] # Connect the unused ports if i // ncols == 0: s.routers[i].send[SOUTH].rdy //= 0 s.routers[i].recv[SOUTH].val //= 0 s.routers[i].recv[SOUTH].msg.payload //= 0 if i // ncols == nrows - 1: s.routers[i].send[NORTH].rdy //= 0 s.routers[i].recv[NORTH].val //= 0 s.routers[i].recv[NORTH].msg.payload //= 0 if i % ncols == 0: s.routers[i].send[WEST].rdy //= 0 s.routers[i].recv[WEST].val //= 0 s.routers[i].recv[WEST].msg.payload //= 0 if i % ncols == ncols - 1: s.routers[i].send[EAST].rdy //= 0 s.routers[i].recv[EAST].val //= 0 s.routers[i].recv[EAST].msg.payload //= 0 for y in range(nrows): for x in range(ncols): s.routers[y * ncols + x].pos //= PositionType(x, y)
def construct(s, PacketType, PositionType, ncols=4, nrows=4, chl_lat=0): # Local parameters s.num_routers = ncols * nrows s.num_terminals = s.num_routers num_channels = (nrows * (ncols - 1) + ncols * (nrows - 1)) * 2 XType = mk_bits(clog2(ncols)) YType = mk_bits(clog2(nrows)) # Interface s.recv = [RecvIfcRTL(PacketType) for _ in range(s.num_terminals)] s.send = [SendIfcRTL(PacketType) for _ in range(s.num_terminals)] # Components s.routers = [ MeshRouterRTL(PacketType, PositionType) for _ in range(s.num_routers) ] s.channels = [ ChannelRTL(PacketType, latency=chl_lat) for _ in range(num_channels) ] # Wire the position ports of router for y in range(nrows): for x in range(ncols): s.routers[y * ncols + x].pos.pos_x //= x s.routers[y * ncols + x].pos.pos_y //= y # Connect routers together in Mesh # NOTE: for now we put all channels in a single list. In the future we # may want to divide channels into different groups so that it is # easier to configure. chl_id = 0 for i in range(s.num_routers): if i // ncols > 0: s.routers[i].send[SOUTH] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i - ncols].recv[NORTH] chl_id += 1 if i // ncols < nrows - 1: s.routers[i].send[NORTH] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i + ncols].recv[SOUTH] chl_id += 1 if i % ncols > 0: s.routers[i].send[WEST] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i - 1].recv[EAST] chl_id += 1 if i % ncols < ncols - 1: s.routers[i].send[EAST] //= s.channels[chl_id].recv s.channels[chl_id].send //= s.routers[i + 1].recv[WEST] chl_id += 1 # Connect the self port (with Network Interface) s.recv[i] //= s.routers[i].recv[SELF] s.send[i] //= s.routers[i].send[SELF] # Connect the unused ports # FIXME: for now we hackily ground the payload field so that pymtl # won't complain about net need driver. if i // ncols == 0: s.routers[i].send[SOUTH].rdy //= 0 s.routers[i].recv[SOUTH].val //= 0 s.routers[i].recv[SOUTH].msg.payload //= 0 if i // ncols == nrows - 1: s.routers[i].send[NORTH].rdy //= 0 s.routers[i].recv[NORTH].val //= 0 s.routers[i].recv[NORTH].msg.payload //= 0 if i % ncols == 0: s.routers[i].send[WEST].rdy //= 0 s.routers[i].recv[WEST].val //= 0 s.routers[i].recv[WEST].msg.payload //= 0 if i % ncols == ncols - 1: s.routers[i].send[EAST].rdy //= 0 s.routers[i].recv[EAST].val //= 0 s.routers[i].recv[EAST].msg.payload //= 0