def __init__(s, single_dest, mopaque_nbits, addr_nbits, data_nbits, nopaque_nbits, num_nodes): # Parameters src_nbits = clog2(num_nodes) #--------------------------------------------------------------------- # Interface #--------------------------------------------------------------------- s.memifc = MemMsg(mopaque_nbits, addr_nbits, data_nbits) s.netreqifc = NetMsg(num_nodes, 2**nopaque_nbits, s.memifc.req.nbits) s.netrespifc = NetMsg(num_nodes, 2**nopaque_nbits, s.memifc.resp.nbits) s.memreq = InValRdyBundle(s.memifc.req) s.netreq = OutValRdyBundle(s.netreqifc) s.memresp = OutValRdyBundle(s.memifc.resp) s.netresp = InValRdyBundle(s.netrespifc) s.src_id = InPort(src_nbits) #--------------------------------------------------------------------- # Connections #--------------------------------------------------------------------- s.connect(s.memreq.val, s.netreq.val) s.connect(s.memreq.rdy, s.netreq.rdy) s.connect(s.memresp.val, s.netresp.val) s.connect(s.memresp.rdy, s.netresp.rdy) # Modify memreq's opaque bit to add src information s.temp_memreq = Wire(s.memifc.req) s.connect(s.temp_memreq, s.netreq.msg.payload) @s.combinational def comb_req(): if single_dest: s.netreq.msg.dest.value = 0 else: s.netreq.msg.dest.value = s.memreq.msg.addr[ 4:6] # hard code 4 bank for now s.temp_memreq.value = s.memreq.msg s.temp_memreq.opaque[mopaque_nbits - src_nbits:mopaque_nbits].value = s.src_id s.connect(s.netreq.msg.src, s.src_id) s.connect(s.netreq.msg.opaque, 0) # Clear the opaque field of memresp @s.combinational def comb_resp(): s.memresp.msg.value = s.netresp.msg.payload s.memresp.msg.opaque[mopaque_nbits - src_nbits:mopaque_nbits].value = 0
def mk_msg( dest, src, seqnum, payload ): msg = NetMsg( nrouters, nmessages, payload_nbits ) msg.src = src msg.dest = dest msg.seqnum = seqnum msg.payload = payload return msg
def mk_msg( dest, src, seqnum, payload ): """Utility function to create a NetMsg object.""" msg = NetMsg( nrouters, nmessages, payload_nbits ) msg.src = src msg.dest = dest msg.seqnum = seqnum msg.payload = payload return msg
def __init__(s, payload_nbits=32): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 # Interface s.in_ = InValRdyBundle[num_ports](NetMsg(num_ports, 2**opaque_nbits, payload_nbits)) s.out = OutValRdyBundle[num_ports](NetMsg(num_ports, 2**opaque_nbits, payload_nbits)) # Connection s.inner = BusNetVRTL_inner(payload_nbits) s.in_hdrs = [Wire(NetHdr()) for _ in xrange(num_ports)] s.out_hdrs = [Wire(NetHdr()) for _ in xrange(num_ports)] hdr_nbits = s.in_hdrs[0].nbits msg_nbits = payload_nbits for i in xrange(num_ports): s.connect_pairs( s.in_[i].msg.dest, s.in_hdrs[i].dest, s.in_[i].msg.src, s.in_hdrs[i].src, s.in_[i].msg.opaque, s.in_hdrs[i].opaque, s.out_hdrs[i].dest, s.out[i].msg.dest, s.out_hdrs[i].src, s.out[i].msg.src, s.out_hdrs[i].opaque, s.out[i].msg.opaque, ) s.connect_pairs( s.in_[i].val, s.inner.in_val[i], s.in_[i].rdy, s.inner.in_rdy[i], s.in_hdrs[i], s.inner.in_msg_hdr[i * hdr_nbits:(i + 1) * hdr_nbits], s.in_[i].msg.payload, s.inner.in_msg_payload[i * msg_nbits:(i + 1) * msg_nbits], s.out[i].val, s.inner.out_val[i], s.out[i].rdy, s.inner.out_rdy[i], s.out_hdrs[i], s.inner.out_msg_hdr[i * hdr_nbits:(i + 1) * hdr_nbits], s.out[i].msg.payload, s.inner.out_msg_payload[i * msg_nbits:(i + 1) * msg_nbits], )
def __init__(s, single_dest, mopaque_nbits, addr_nbits, data_nbits, nopaque_nbits, num_nodes): # Parameters src_nbits = clog2(num_nodes) #--------------------------------------------------------------------- # Interface #--------------------------------------------------------------------- s.memifc = MemMsg(mopaque_nbits, addr_nbits, data_nbits) s.netreqifc = NetMsg(num_nodes, 2**nopaque_nbits, s.memifc.req.nbits) s.netrespifc = NetMsg(num_nodes, 2**nopaque_nbits, s.memifc.resp.nbits) s.netreq = InValRdyBundle(s.netreqifc) s.netresp = OutValRdyBundle(s.netrespifc) s.memreq = OutValRdyBundle(s.memifc.req) s.memresp = InValRdyBundle(s.memifc.resp) s.src_id = InPort(src_nbits) #--------------------------------------------------------------------- # Connections #--------------------------------------------------------------------- s.connect(s.netreq.val, s.memreq.val) s.connect(s.netreq.rdy, s.memreq.rdy) s.connect(s.netresp.val, s.memresp.val) s.connect(s.netresp.rdy, s.memresp.rdy) # Just need to unpack netreq s.connect(s.netreq.msg.payload, s.memreq.msg) # For resp, need to pack memresp.msg with the header s.connect(s.netresp.msg.src, s.src_id) s.connect(s.netresp.msg.opaque, 0) s.connect(s.netresp.msg.payload, s.memresp.msg) # Use the hidden dest information to determine the recipient @s.combinational def comb_resp(): if single_dest: s.netresp.msg.dest.value = 0 else: s.netresp.msg.dest.value = s.memresp.msg.opaque[ mopaque_nbits - src_nbits:mopaque_nbits]
def __init__(s, payload_nbits=32): # Parameters # Your design does not need to support other values nrouters = 4 opaque_nbits = 8 srcdest_nbits = clog2(nrouters) # Interface s.router_id = InPort(srcdest_nbits) msg_type = NetMsg(nrouters, 2**opaque_nbits, payload_nbits) s.in0 = InValRdyBundle(msg_type) s.in1 = InValRdyBundle(msg_type) s.in2 = InValRdyBundle(msg_type) s.out0 = OutValRdyBundle(msg_type) s.out1 = OutValRdyBundle(msg_type) s.out2 = OutValRdyBundle(msg_type) # Components s.dpath = RouterDpathPRTL(payload_nbits) s.ctrl = RouterCtrlPRTL() s.connect(s.ctrl.router_id, s.router_id)
def __init__(s, payload_nbits=32): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 # Interface msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) s.in_ = InValRdyBundle[num_ports](msg_type) s.out = OutValRdyBundle[num_ports](msg_type) # Components s.dpath = BusNetDpathPRTL(payload_nbits) s.ctrl = BusNetCtrlPRTL() s.connect_auto(s.ctrl, s.dpath) for i in xrange(num_ports): s.connect_pairs(s.in_[i], s.dpath.in_[i], s.out[i].msg, s.dpath.out_msg[i], s.out[i].val, s.ctrl.out_val[i], s.out[i].rdy, s.ctrl.out_rdy[i])
def __init__( s, payload_nbits = 32 ): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 # Interface msg_type = NetMsg( num_ports, 2**opaque_nbits, payload_nbits ) s.in_ = InValRdyBundle [num_ports]( msg_type ) s.out = OutValRdyBundle[num_ports]( msg_type ) # Components s.dpath = BusNetDpathPRTL( payload_nbits ) s.ctrl = BusNetCtrlPRTL () # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' # LAB TASK: Connect datapath to control unit # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' for i in xrange( num_ports ):
def __init__( s, NetModel, src_msgs, sink_msgs, src_delay, sink_delay, num_ports, opaque_nbits, payload_nbits, dump_vcd=False, test_verilog=False ): s.src_msgs = src_msgs s.sink_msgs = sink_msgs s.src_delay = src_delay s.sink_delay = sink_delay s.num_ports = num_ports msg_type = NetMsg( num_ports, 2**opaque_nbits, payload_nbits ) s.src = [ TestSource ( msg_type, s.src_msgs[x], s.src_delay[x] ) for x in xrange(num_ports) ]# s.net = NetModel s.sink = [ TestNetSink( msg_type, s.sink_msgs[x], s.sink_delay[x] ) for x in xrange(num_ports) ] # Dump VCD if dump_vcd: s.net.vcd_file = dump_vcd if hasattr(s.net, 'inner'): s.net.inner.vcd_file = dump_vcd # Translation if test_verilog: s.net = TranslationTool( s.net ) # Connect for i in xrange(num_ports): s.connect( s.net.in_[i], s.src[i].out ) s.connect( s.net.out[i], s.sink[i].in_ )
def elaborate_logic(s): # Instantiate Models msg_type = lambda: NetMsg(s.nrouters, s.nmessages, s.payload_nbits) s.src = [ TestSource(msg_type(), s.src_msgs[x], s.src_delay) for x in xrange(5) ] s.router = s.ModelType(s.id_, s.nrouters, s.nmessages, s.payload_nbits, s.nentries) s.sink = [ TestNetSink(msg_type(), s.sink_msgs[x], s.sink_delay) for x in xrange(5) ] if s.test_verilog: s.router.vcd_file = s.vcd_file s.router = TranslationTool(s.router) # connect for i in xrange(5): s.connect(s.router.in_[i], s.src[i].out) s.connect(s.router.out[i], s.sink[i].in_)
def elaborate_logic(s): # instantiate models msg_type = NetMsg(s.nrouters, s.nmessages, s.payload_nbits) s.src = [ TestSource(msg_type, s.src_msgs[x], s.src_delay) for x in xrange(s.nrouters) ] s.mesh = s.ModelType(s.nrouters, s.nmessages, s.payload_nbits, s.nentries) s.sink = [ TestNetSink(msg_type, s.sink_msgs[x], s.sink_delay) for x in xrange(s.nrouters) ] # enable verilog testing (only for RTL models) if s.test_verilog: s.mesh.vcd_file = s.vcd_file s.mesh = TranslationTool(s.mesh) # connect signals for i in xrange(s.nrouters): s.connect(s.mesh.in_[i], s.src[i].out) s.connect(s.mesh.out[i], s.sink[i].in_)
def run_test( dump_vcd, src_delay, sink_delay, src_msgs, sink_msgs ): # Instantiate and elaborate the model dtype = NetMsg( 4, 16, 32 ) model = TestHarness( dtype, src_msgs, sink_msgs, src_delay, sink_delay ) model.vcd_file = dump_vcd model.elaborate() # Create a simulator using the simulation tool sim = SimulationTool( model ) # Run the simulation print() sim.reset() while not model.done(): sim.print_line_trace() sim.cycle() # Add a couple extra ticks so that the VCD dump is nicer sim.cycle() sim.cycle() sim.cycle()
def __init__(s, RouterModel, router_id, num_ports, src_msgs, sink_msgs, src_delay, sink_delay, num_routers, opaque_nbits, payload_nbits, dump_vcd=False, test_verilog=False): s.src_msgs = src_msgs s.sink_msgs = sink_msgs s.src_delay = src_delay s.sink_delay = sink_delay s.num_ports = num_ports s.num_routers = num_routers s.payload_nbits = payload_nbits s.opaque_nbits = opaque_nbits s.addr_nbits = clog2(num_routers) msg_type = NetMsg(num_routers, 2**opaque_nbits, payload_nbits) s.src = [ TestSource(msg_type, s.src_msgs[x], s.src_delay) for x in xrange(num_ports) ] s.router = RouterModel s.sink = [ TestNetSink(msg_type, s.sink_msgs[x], s.sink_delay) for x in xrange(num_ports) ] for x in range(num_ports): print('src [{}]:{}'.format(x, s.src_msgs[x])) print('sink[{}]:{}'.format(x, s.sink_msgs[x])) # Dump VCD if dump_vcd: s.router.vcd_file = dump_vcd if hasattr(s.router, 'inner'): s.router.inner.vcd_file = dump_vcd # Translation if test_verilog: s.router = TranslationTool(s.router) # Connect for i in range(num_ports): s.connect(s.router.in_[i], s.src[i].out) s.connect(s.router.out[i], s.sink[i].in_) s.connect(s.router.router_id, router_id)
def __init__(s, payload_nbits): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 # Interface msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) s.in_ = InValRdyBundle[num_ports](msg_type) s.out_msg = OutPort[num_ports](msg_type) # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' # LAB TASK: # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' # Constants DEST_HIGH = payload_nbits + 12 DEST_LOW = DEST_HIGH - clog2(num_ports) QUEUE_NUM_ENTRIES = 2 # Control signals (ctrl -> dpath) s.bus_sel = InPort(clog2(num_ports)) s.inq_rdy = InPort(num_ports) # Status signals (dpath -> ctrl) s.inq_val = OutPort(num_ports) s.inq_dests = [OutPort(clog2(num_ports)) for _ in range(num_ports)] # Queues s.queues = [] for i in range(num_ports): queue = NormalQueue(QUEUE_NUM_ENTRIES, msg_type) # Enq val/rdy/msg s.connect(queue.enq, s.in_[i]) # Deq val/rdy s.connect(queue.deq.val, s.inq_val[i]) s.connect(queue.deq.rdy, s.inq_rdy[i]) # Deq dest s.connect(queue.deq.msg[DEST_LOW:DEST_HIGH], s.inq_dests[i]) # Append s.queues.append(queue) # Bus s.bus = Bus(num_ports, msg_type) s.connect(s.bus.sel, s.bus_sel) for i in range(num_ports): # Deq msg s.connect(s.bus.in_[i], s.queues[i].deq.msg) # Result s.connect(s.bus.out[i], s.out_msg[i])
def __init__(s, RouterModel, router_id, src_msgs, sink_msgs, src_delay, sink_delay, num_ports, opaque_nbits, payload_nbits, dump_vcd=False, test_verilog=False): s.src_msgs = src_msgs s.sink_msgs = sink_msgs s.src_delay = src_delay s.sink_delay = sink_delay msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) s.src = [ TestSource(msg_type, s.src_msgs[x], s.src_delay) for x in xrange(3) ] s.router = RouterModel s.sink = [ TestNetSink(msg_type, s.sink_msgs[x], s.sink_delay) for x in xrange(3) ] # Dump VCD if dump_vcd: s.router.vcd_file = dump_vcd if hasattr(s.router, 'inner'): s.router.inner.vcd_file = dump_vcd # Translation if test_verilog: s.router = TranslationTool(s.router) # Connect s.connect(s.router.in0, s.src[0].out) s.connect(s.router.out0, s.sink[0].in_) s.connect(s.router.in1, s.src[1].out) s.connect(s.router.out1, s.sink[1].in_) s.connect(s.router.in2, s.src[2].out) s.connect(s.router.out2, s.sink[2].in_) s.connect(s.router.router_id, router_id)
def __init__(s, nrouters, nmessages, payload_nbits, nentries): # ensure nrouters is a perfect square assert sqrt(nrouters) % 1 == 0 s.nrouters = nrouters s.params = [nrouters, nmessages, payload_nbits, nentries] net_msg = NetMsg(nrouters, nmessages, payload_nbits) s.in_ = InValRdyBundle[nrouters](net_msg) s.out = OutValRdyBundle[nrouters](net_msg)
def mk_msg( src, dest, seqnum, payload ): msg = NetMsg( 4, 16, 32 ) msg.src = src msg.dest = dest msg.seqnum = seqnum msg.payload = payload return msg
def mk_msg(dest, src, seqnum, payload): msg = NetMsg(nrouters, nmessages, payload_nbits) msg.src = src msg.dest = dest msg.seqnum = seqnum msg.payload = payload return msg
def mk_msg(dest, src, seqnum, payload): """Utility function to create a NetMsg object.""" msg = NetMsg(nrouters, nmessages, payload_nbits) msg.src = src msg.dest = dest msg.seqnum = seqnum msg.payload = payload return msg
def __init__(s, num_ports=3, num_routers=4, payload_nbits=32, routing_algorithm='greedy'): # Network parameters opaque_nbits = 8 addr_nbits = clog2(num_routers) id_nbits = addr_nbits msg_type = NetMsg(num_routers, 2**opaque_nbits, payload_nbits) DIR_W = 0 DIR_E = 1 DIR_C = 2 #wid = clog2( num_routers ) #ht = clog2( num_routers ) # interface s.in_ = InValRdyBundle[num_routers](msg_type) s.out = OutValRdyBundle[num_routers](msg_type) # components # TODO : calculate number of routers correctly # calculate number of channels correctly if routing_algorithm == 'even-odd': s.routers = RingRouterRTL[num_routers](payload_nbits=32, num_routers=num_routers, num_ports=num_ports) else: s.routers = RingRouterGreedyRTL[num_routers]( payload_nbits=32, num_routers=num_routers, num_ports=num_ports) s.channel_queues_E = NormalQueue[num_routers](2, msg_type) s.channel_queues_W = NormalQueue[num_routers](2, msg_type) s.router_ids = OutPort[num_routers](id_nbits) # connecting components for idx in range(num_routers): # set router ids, connect in/out for each router idx_next = (idx + 1) % num_routers s.connect_pairs(s.router_ids[idx], idx, s.routers[idx].router_id, idx, s.routers[idx].out[DIR_C], s.out[idx], s.routers[idx].in_[DIR_C], s.in_[idx]) # connect channels queues s.connect_pairs( s.routers[idx].out[DIR_E], s.channel_queues_E[idx].enq, s.channel_queues_E[idx].deq, s.routers[idx_next].in_[DIR_W], s.routers[idx].in_[DIR_E], s.channel_queues_W[idx].deq, s.channel_queues_W[idx].enq, s.routers[idx_next].out[DIR_W])
def __init__(s, payload_nbits): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 # Interface msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) s.in_ = InValRdyBundle[num_ports](msg_type) s.out_msg = OutPort[num_ports](msg_type)
def __init__(s, id_, nrouters, nmessages, payload_nbits, nentries): s.id_ = id_ s.nrouters = nrouters s.nmessages = nmessages s.payload_nbits = payload_nbits s.nentries = nentries s.msg_type = NetMsg(nrouters, nmessages, payload_nbits) #------------------------------------------------------------------- # Interface #------------------------------------------------------------------- s.c2d = [CtrlBundle(s.msg_type) for x in xrange(5)]
def __init__(s, payload_nbits=32): # Parameters # Your design does not need to support other values num_ports = 4 opaque_nbits = 8 srcdest_nbits = clog2(num_ports) msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) # Interface s.in_ = InValRdyBundle[num_ports](msg_type) s.out = OutValRdyBundle[num_ports](msg_type)
def __init__(s, id_, nrouters, nmessages, payload_nbits, nentries): s.id_ = id_ s.nrouters = nrouters s.nmessages = nmessages s.payload_nbits = payload_nbits s.nentries = nentries s.msg_type = NetMsg(nrouters, nmessages, payload_nbits) #------------------------------------------------------------------- # Interface #------------------------------------------------------------------- s.in_ = InValRdyBundle[5](s.msg_type) s.out = OutValRdyBundle[5](s.msg_type)
def __init__(s, id_, nrouters, nmessages, payload_nbits, nentries): s.id_ = id_ s.xnodes = int(sqrt(nrouters)) s.x = id_ % s.xnodes s.y = id_ / s.xnodes s.msg_type = NetMsg(nrouters, nmessages, payload_nbits) s.nentries = nentries #s.params = [ nrouters, nmessages, payload_nbits, buffering ] #--------------------------------------------------------------------- # Interface #--------------------------------------------------------------------- s.in_ = InValRdyBundle[5](s.msg_type) s.out = OutValRdyBundle[5](s.msg_type)
def mk_msg( src, dest, opaque, payload, payload_nbits=32, opaque_nbits=8, num_ports=4 ): """Utility function to create a NetMsg object.""" msg = NetMsg( num_ports, 2**opaque_nbits, payload_nbits ) msg.src = src msg.dest = dest msg.opaque = opaque msg.payload = payload return msg
def __init__(s, payload_nbits=32): # Parameters # Your design does not need to support other values nrouters = 4 opaque_nbits = 8 #--------------------------------------------------------------------- # Interface #--------------------------------------------------------------------- msg_type = NetMsg(nrouters, 2**opaque_nbits, payload_nbits) s.in0 = InValRdyBundle(msg_type) s.in1 = InValRdyBundle(msg_type) s.in2 = InValRdyBundle(msg_type) s.out0_msg = OutPort(msg_type) s.out1_msg = OutPort(msg_type) s.out2_msg = OutPort(msg_type)
def __init__(s, payload_nbits=32): # Parameters num_ports = 4 opaque_nbits = 8 # Interface msg_type = NetMsg(num_ports, 2**opaque_nbits, payload_nbits) s.in_ = InValRdyBundle[num_ports](msg_type) s.out = OutValRdyBundle[num_ports](msg_type) s.output_fifos = [deque() for x in xrange(num_ports)] # Simulate the network @s.tick_cl def network_logic(): # Dequeue logic for i, outport in enumerate(s.out): if outport.val and outport.rdy: s.output_fifos[i].popleft() # Enqueue logic for i, inport in enumerate(s.in_): if inport.val and inport.rdy: s.output_fifos[inport.msg.dest].append(inport.msg[:]) # Set output signals for i, fifo in enumerate(s.output_fifos): is_full = len(fifo) == 2**opaque_nbits is_empty = len(fifo) == 0 s.out[i].val.next = not is_empty s.in_[i].rdy.next = not is_full if not is_empty: s.out[i].msg.next = fifo[0]
def __init__(s, num_ports=5, num_routers=4, mesh_wid=2, mesh_ht=2, payload_nbits=32): # Network parameters opaque_nbits = 8 num_routers = mesh_wid * mesh_ht addr_nbits = clog2(num_routers) id_nbits = addr_nbits msg_type = NetMsg(num_routers, 2**opaque_nbits, payload_nbits) DIR_N = 1 DIR_S = 3 DIR_E = 2 DIR_W = 0 DIR_C = 4 #wid = clog2( num_routers ) #ht = clog2( num_routers ) wid = mesh_wid ht = mesh_ht # interface s.in_ = InValRdyBundle[num_routers](msg_type) s.out = OutValRdyBundle[num_routers](msg_type) # components # TODO : calculate number of routers correctly # calculate number of channels correctly s.routers = BadMeshRouterRTL[num_routers](payload_nbits=32, num_routers=num_routers, num_ports=num_ports) s.channel_queues_x_2 = NormalQueue[(wid - 1) * ht](2, msg_type) s.channel_queues_x_0 = NormalQueue[(wid - 1) * ht](2, msg_type) s.channel_queues_y_2 = NormalQueue[(ht - 1) * wid](2, msg_type) s.channel_queues_y_0 = NormalQueue[(ht - 1) * wid](2, msg_type) s.router_ids = OutPort[num_routers](id_nbits) # connecting components for i in range(ht): for j in range(wid): idx = i * wid + j # set router ids, connect in/out for each router s.connect_pairs(s.router_ids[idx], idx, s.routers[idx].router_id, idx, s.routers[idx].row_min, i * wid, s.routers[idx].row_max, i * wid + wid - 1, s.routers[idx].out[DIR_C], s.out[idx], s.routers[idx].in_[DIR_C], s.in_[idx]) # connect channels in x direction if (j < wid - 1): s.connect_pairs( s.routers[idx].out[DIR_E], s.channel_queues_x_2[i * (wid - 1) + j].enq, s.channel_queues_x_2[i * (wid - 1) + j].deq, s.routers[idx + 1].in_[DIR_W], s.routers[idx].in_[DIR_E], s.channel_queues_x_0[i * (wid - 1) + j].deq, s.channel_queues_x_0[i * (wid - 1) + j].enq, s.routers[idx + 1].out[DIR_W]) #connect channels in y direction if (i < ht - 1): s.connect_pairs(s.routers[idx].out[DIR_S], s.channel_queues_y_2[i * wid + j].enq, s.channel_queues_y_2[i * wid + j].deq, s.routers[idx + wid].in_[DIR_N], s.routers[idx].in_[DIR_S], s.channel_queues_y_0[i * wid + j].deq, s.channel_queues_y_0[i * wid + j].enq, s.routers[idx + wid].out[DIR_N])
def __init__( s, payload_nbits=32, num_routers=4, num_ports=5, ): #------------------------------------------------------------- # Parameters & Constants #------------------------------------------------------------- opaque_nbits = 8 msg_type = NetMsg(num_routers, 2**opaque_nbits, payload_nbits) sel_nbits = clog2(num_ports) addr_nbits = clog2(num_routers) port_nbits = clog2(num_ports) # not useful anymore addr_offset = addr_nbits + opaque_nbits + payload_nbits # routing directions 1 for north, 2 for east, etc DIR_N = 1 DIR_S = 3 DIR_E = 2 DIR_W = 0 DIR_C = 4 #------------------------------------------------------------- # Interface #------------------------------------------------------------- s.in_ = InValRdyBundle[num_ports](msg_type) s.out = OutValRdyBundle[num_ports](msg_type) s.router_id = InPort(addr_nbits) #s.coord_x = InPort( addr_nbits ) #s.coord_y = InPort( addr_nbits ) s.row_min = InPort(addr_nbits) s.row_max = InPort(addr_nbits) #------------------------------------------------------------- # Components #------------------------------------------------------------- # Signals s.sels = Wire[num_ports](sel_nbits) s.dest = Wire[num_ports](addr_nbits) s.arbitor_en = Wire(num_ports) s.has_grant = Wire(num_ports) #s.deq_rdy = Wire( num_ports ) # Crossbar -- no output buffers s.crossbar = m = Crossbar(num_ports, msg_type) for i in range(num_ports): s.connect(m.out[i], s.out[i].msg) s.connect_wire(dest=m.sel[i], src=s.sels[i]) # Input buffers s.input_buffer = NormalQueue[num_ports](2, msg_type) for i in range(num_ports): s.connect_pairs(s.input_buffer[i].enq, s.in_[i], s.input_buffer[i].deq.msg, s.crossbar.in_[i]) # Arbitors s.arbitors = RoundRobinArbiterEn[num_ports](num_ports) for i in range(num_ports): s.connect_pairs(s.arbitors[i].en, s.arbitor_en[i]) #-------------------------------------------------------------- # Control Logic #-------------------------------------------------------------- @s.combinational def getDestAddr(): for i in range(num_ports): s.dest[i].value = s.input_buffer[i].deq.msg[ addr_offset:addr_offset + addr_nbits] @s.combinational def setCrossbarSel(): for i in range(num_ports): for j in range(num_ports): if s.arbitors[i].grants[j]: s.sels[i].value = j @s.combinational def setOutVal(): for i in range(num_ports): s.out[i].val.value = 0 if s.arbitors[i].grants > 0: s.out[i].val.value = 1 @s.combinational def setDeqRdy(): for i in range(num_ports): s.has_grant[i].value = 0 for j in range(num_ports): if s.arbitors[j].grants[i]: s.has_grant[i].value = s.out[j].rdy for i in range(num_ports): s.input_buffer[i].deq.rdy.value = s.has_grant[i] @s.combinational def setArbitorEnable(): for i in range(num_ports): s.arbitor_en[i].value = s.out[i].val & s.out[i].rdy # Routing Algorithm goes HERE!!! # y-dimension-order routing @s.combinational def setArbitorReq(): for i in range(num_ports): s.arbitors[i].reqs.value = 0 for i in range(num_ports): if s.router_id == s.dest[i]: s.arbitors[DIR_C].reqs[i].value = s.input_buffer[i].deq.val elif s.dest[i] < s.row_min: s.arbitors[DIR_N].reqs[i].value = s.input_buffer[i].deq.val elif s.dest[i] > s.row_max: s.arbitors[DIR_S].reqs[i].value = s.input_buffer[i].deq.val elif s.dest[i] < s.router_id: s.arbitors[DIR_W].reqs[i].value = s.input_buffer[i].deq.val else: s.arbitors[DIR_E].reqs[i].value = s.input_buffer[i].deq.val
def simulate( model, sim, opts, ): # Simulation Variables packets_gen = 0 packets_recv = 0 sim_done = False verbose = opts.verbose # Message generator if opts.impl == 'rtl': mk_net_msg = NetMsg(opts.nrouters, NMESSAGES, PAYLOAD_NBITS).mk_msg else: mk_net_msg = NetObject # Source queues src = [deque() for x in xrange(opts.nrouters)] # Reset the simulator for i in xrange(opts.nrouters): model.out[i].rdy.value = 1 sim.reset() # Simulation loop while not sim_done: for i in xrange(opts.nrouters): # Generate packet and insert into source queue #if ( packets_gen < opts.npackets and # random.randint( 0, 100 ) < opts.injection_rate ): #if ( random.randint( 0, 100 ) < opts.injection_rate ): if ((libc.rand() % 100) < opts.injection_rate): # Create uniform random traffic #dest = random.randint( 0, opts.nrouters-1 ) dest = libc.rand() % opts.nrouters msg = mk_net_msg(dest, i, 0, INVALID_TIMESTAMP) src[i].append(msg) packets_gen += 1 # Inject from source queue if (len(src[i]) > 0): model.in_[i].msg.value = src[i][0] model.in_[i].val.value = 1 else: model.in_[i].val.value = 0 # Receive a packet if (model.out[i].val.value == 1): packets_recv += 1 # Pop the source queue if (model.in_[i].rdy.value == 1) and (len(src[i]) > 0): src[i].popleft() # Increment simulator and print line trace sim.cycle() if verbose: sim.print_line_trace() # Check for completion after drain phase #if ( packets_gen >= opts.npackets and packets_gen == packets_recv ): if (sim.ncycles >= opts.ncycles): sim_done = True break # Debug #if sim.ncycles % 100 == 1: # print "{:4}: gen {:5} recv {:5}".format( sim.ncycles, # packets_gen, # packets_recv ) print "Packets Sent/Recv: {}/{}".format(packets_gen, packets_recv)
def __init__(s, payload_nbits=32, num_routers=4, num_ports=3, channel_queue_entries=2, routing_algorithm='deterministic'): #------------------------------------------------------------- # Parameters & Constants #------------------------------------------------------------- opaque_nbits = 8 msg_type = NetMsg(num_routers, 2**opaque_nbits, payload_nbits) sel_nbits = clog2(num_ports) addr_nbits = clog2(num_routers) addr_offset = addr_nbits + opaque_nbits + payload_nbits # routing directions 1 for north, 2 for east, etc DIR_W = 0 DIR_E = 1 DIR_C = 2 #------------------------------------------------------------- # Interface #------------------------------------------------------------- s.in_ = InValRdyBundle[num_ports](msg_type) s.out = OutValRdyBundle[num_ports](msg_type) s.router_id = InPort(addr_nbits) #s.coord_x = InPort( addr_nbits ) #s.coord_y = InPort( addr_nbits ) #s.row_min = InPort( addr_nbits ) #s.row_max = InPort( addr_nbits ) #------------------------------------------------------------- # Components #------------------------------------------------------------- # Signals s.sels = Wire[num_ports](sel_nbits) s.dest = Wire[num_ports](addr_nbits) s.arbitor_en = Wire(num_ports) s.has_grant = Wire(num_ports) s.id_odd = Wire(1) s.dist_west = Wire[num_ports](addr_nbits + 1) s.dist_east = Wire[num_ports](addr_nbits + 1) # Sinal indicating if the id is an even number s.connect(s.id_odd, s.router_id[addr_nbits - 1]) # Crossbar -- no output buffers s.crossbar = m = Crossbar(num_ports, msg_type) for i in range(num_ports): s.connect(m.out[i], s.out[i].msg) s.connect_wire(dest=m.sel[i], src=s.sels[i]) # Input buffers s.input_buffer = NormalQueue[num_ports](2, msg_type) for i in range(num_ports): s.connect_pairs(s.input_buffer[i].enq, s.in_[i], s.input_buffer[i].deq.msg, s.crossbar.in_[i]) # Arbitors s.arbitors = RoundRobinArbiterEn[num_ports](num_ports) for i in range(num_ports): s.connect_pairs(s.arbitors[i].en, s.arbitor_en[i]) #-------------------------------------------------------------- # Control Logic #-------------------------------------------------------------- @s.combinational def getDestAddr(): for i in range(num_ports): s.dest[i].value = s.input_buffer[i].deq.msg[ addr_offset:addr_offset + addr_nbits] @s.combinational def calculateDistance(): for i in range(num_ports): if s.dest[i] > s.router_id: s.dist_east[i].value = s.dest[i] - s.router_id s.dist_west[i].value = (num_routers - 1) - s.dest[i] + s.router_id + 1 else: s.dist_east[i].value = (num_routers - 1) - s.router_id + s.dest[i] + 1 s.dist_west[i].value = s.router_id - s.dest[i] @s.combinational def setCrossbarSel(): for i in range(num_ports): for j in range(num_ports): if s.arbitors[i].grants[j]: s.sels[i].value = j @s.combinational def setOutVal(): for i in range(num_ports): s.out[i].val.value = 0 if s.arbitors[i].grants > 0: s.out[i].val.value = 1 @s.combinational def setDeqRdy(): for i in range(num_ports): s.has_grant[i].value = 0 for j in range(num_ports): if s.arbitors[j].grants[i]: s.has_grant[i].value = s.out[j].rdy for i in range(num_ports): s.input_buffer[i].deq.rdy.value = s.has_grant[i] @s.combinational def setArbitorEnable(): for i in range(num_ports): s.arbitor_en[i].value = s.out[i].val & s.out[i].rdy # Routing Algorithm goes HERE!!! # deterministic routing @s.combinational def setArbitorReq(): for i in range(num_ports): s.arbitors[i].reqs.value = 0 for i in range(num_ports): if s.router_id == s.dest[i]: s.arbitors[DIR_C].reqs[i].value = s.input_buffer[i].deq.val elif s.dist_west[i] < s.dist_east[i]: s.arbitors[DIR_W].reqs[i].value = s.input_buffer[i].deq.val elif s.dist_west[i] > s.dist_east[i]: s.arbitors[DIR_E].reqs[i].value = s.input_buffer[i].deq.val else: # break ties if s.id_odd: s.arbitors[DIR_W].reqs[i].value = s.input_buffer[ i].deq.val else: s.arbitors[DIR_E].reqs[i].value = s.input_buffer[ i].deq.val