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, QueueType=NormalQueueRTL, vc=2, credit_line=2): # Local paramters s.vc = vc # Interface # FIXME: Implement ISLIP so that only one send interface is needed s.recv = CreditRecvIfcRTL(PacketType, vc=vc) s.send = [SendIfcRTL(PacketType) for _ in range(vc)] s.buffers = [ QueueType(PacketType, num_entries=credit_line) for _ in range(vc) ] for i in range(vc): s.buffers[i].recv.msg //= s.recv.msg s.buffers[i].send //= s.send[i] s.recv.yum[i] //= lambda: s.send[i].val & s.send[i].rdy @update def up_enq(): if s.recv.en: for i in range(vc): s.buffers[i].recv.val @= (s.recv.msg.vc_id == i) else: for i in range(vc): s.buffers[i].recv.val @= 0
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, MsgType, vc=2, credit_line=1, QType=BypassQueueRTL): assert vc > 1 # Interface s.recv = CreditRecvIfcRTL(MsgType, vc) s.send = SendIfcRTL(MsgType) s.MsgType = MsgType s.vc = vc # Components CreditType = mk_bits(clog2(credit_line + 1)) s.buffers = [ QType(MsgType, num_entries=credit_line) for _ in range(vc) ] s.arbiter = RoundRobinArbiterEn(nreqs=vc) s.encoder = Encoder(in_nbits=vc, out_nbits=clog2(vc)) for i in range(vc): s.buffers[i].recv.msg //= s.recv.msg s.buffers[i].send.val //= s.arbiter.reqs[i] s.arbiter.grants //= s.encoder.in_ s.arbiter.en //= s.send.val @update def up_enq(): if s.recv.en: for i in range(vc): s.buffers[i].recv.val @= (s.recv.msg.vc_id == i) else: for i in range(vc): s.buffers[i].recv.val @= 0 # TODO: add some assertions to make sure val/rdy are both high # when they should. @update def up_deq_and_send(): for i in range(vc): s.buffers[i].send.rdy @= 0 s.send.msg @= s.buffers[s.encoder.out].send.msg if s.arbiter.grants > 0: s.send.val @= 1 s.buffers[s.encoder.out].send.rdy @= 1 else: s.send.val @= 0 @update def up_yummy(): for i in range(vc): s.recv.yum[i] @= s.buffers[i].recv.val & s.buffers[i].recv.rdy
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, 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, 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_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_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, 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, 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