def construct(s, Type, num_inports=1): assert num_inports == 1, 'Null switch unit can only be used for single-input router!' # Interface s.get = [GetIfcRTL(Type) for _ in range(num_inports)] s.hold = [InPort() for _ in range(num_inports)] s.give = GiveIfcRTL(Type) connect(s.give, s.get[0])
def construct(s, PacketType, PositionType, num_outports, n_fly=3): # Constants s.num_outports = num_outports k_ary = num_outports OutType = mk_bits(clog2(s.num_outports)) rows = k_ary**(n_fly - 1) DstType = mk_bits(clog2(k_ary) * n_fly) RowWidth = clog2(k_ary) END = n_fly * RowWidth BEGIN = END - RowWidth # Interface s.get = GetIfcRTL(PacketType) s.give = [GiveIfcRTL(PacketType) for _ in range(s.num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(OutType) s.give_rdy = [Wire() for _ in range(s.num_outports)] s.give_ens = Wire(mk_bits(s.num_outports)) # Connections for i in range(s.num_outports): s.give_ens[i] //= s.give[i].en s.give_rdy[i] //= s.give[i].rdy # Routing logic @update def up_ru_routing(): for i in range(s.num_outports): s.give_rdy[i] @= 0 if s.get.rdy: s.out_dir @= s.get.ret.dst[BEGIN:END] s.give_rdy[s.out_dir] @= 1 @update def up_ru_get_en(): s.get.en @= s.give_ens > 0 for i in range(s.num_outports): s.give[i].ret @= s.get.ret if s.get.rdy: s.give[s.out_dir].ret.dst @= s.get.ret.dst << RowWidth
def construct( s, PacketType, PositionType, num_outports = 8 ): # Constants s.num_outports = num_outports TType = mk_bits( clog2(num_outports) ) # Interface s.get = GetIfcRTL( PacketType ) s.give = [ GiveIfcRTL (PacketType) for _ in range ( s.num_outports ) ] s.pos = InPort( PositionType ) # Componets s.give_ens = Wire( mk_bits( s.num_outports ) ) s.give_rdy = [ Wire() for _ in range( s.num_outports )] # Connections for i in range( s.num_outports ): s.get.ret //= s.give[i].ret s.give_ens[i] //= s.give[i].en s.give_rdy[i] //= s.give[i].rdy # Routing logic @update def up_ru_routing(): s.out_dir @= 0 for i in range( s.num_outports ): s.give_rdy[i] @= Bits1(0) if s.get.rdy: if (s.pos.pos_x == s.get.ret.dst_x) & (s.pos.pos_y == s.get.ret.dst_y): s.give_rdy[ Bits3( 4 ) + s.get.ret.dst_ter ] @= 1 elif s.get.ret.dst_x < s.pos.pos_x: s.give_rdy[2] @= 1 elif s.get.ret.dst_x > s.pos.pos_x: s.give_rdy[3] @= 1 elif s.get.ret.dst_y < s.pos.pos_y: s.give_rdy[1] @= 1 else: s.give_rdy[0] @= 1 @update def up_ru_get_en(): s.get.en = s.give_ens > 0
def construct(s, Type, num_inports=5): # Local parameters s.num_inports = num_inports s.Type = Type s.sel_width = clog2(num_inports) # Interface s.get = [GetIfcRTL(s.Type) for _ in range(num_inports)] s.hold = InPort(num_inports) s.give = GiveIfcRTL(s.Type) # Components s.granted_get_rdy = Wire() s.any_hold = Wire() s.arbiter = GrantHoldArbiter(nreqs=num_inports) s.arbiter.hold //= s.any_hold s.arbiter.en //= lambda: ~s.any_hold & s.give.en s.mux = Mux(s.Type, num_inports) s.mux.out //= s.give.ret s.encoder = Encoder(num_inports, s.sel_width) s.encoder.in_ //= s.arbiter.grants s.encoder.out //= s.mux.sel # Combinational Logic @update def up_any_hold(): s.any_hold @= s.hold > 0 @update def up_granted_get_rdy(): s.granted_get_rdy @= 0 for i in range(num_inports): if s.arbiter.grants[i]: s.granted_get_rdy @= s.get[i].rdy for i in range(num_inports): s.get[i].rdy //= s.arbiter.reqs[i] s.get[i].ret //= s.mux.in_[i] for i in range(num_inports): s.get[i].en //= lambda: s.give.en & (s.mux.sel == i) s.give.rdy //= s.granted_get_rdy
def construct(s, PacketType, num_inports=5): # Local parameters s.num_inports = num_inports s.sel_width = clog2(num_inports) s.set_ocp = 0 s.clear_ocp = 0 # Interface s.get = [GetIfcRTL(PacketType) for _ in range(s.num_inports)] s.give = GiveIfcRTL(PacketType) s.out_ocp = OutPort() # Components s.get_en = [Wire() for _ in range(s.num_inports)] s.get_rdy = [Wire() for _ in range(s.num_inports)] s.arbiter = RoundRobinArbiterEn(num_inports) s.arbiter.en //= 1 s.mux = Mux(PacketType, num_inports) s.mux.out //= s.give.ret 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.get[i].rdy //= s.arbiter.reqs[i] s.get[i].ret //= s.mux.in_[i] s.get[i].en //= s.get_en[i] s.get[i].rdy //= s.get_rdy[i] @update def up_give(): s.give.rdy @= s.arbiter.grants > 0 @update def up_get_en(): for i in range(num_inports): s.get_en[i] @= s.give.en & (s.mux.sel == i)
def construct(s, dtype): s.drop = InPort() s.in_ = GetIfcRTL(dtype) s.out = GiveIfcRTL(dtype) s.out.ret //= s.in_.ret s.snoop_state = Wire() #------------------------------------------------------------------ # state_transitions #------------------------------------------------------------------ @s.update_ff def state_transitions(): if s.reset: s.snoop_state <<= SNOOP elif s.snoop_state == SNOOP: if s.drop & ~s.in_.rdy: s.snoop_state <<= WAIT elif s.snoop_state == WAIT: if s.in_.rdy: s.snoop_state <<= SNOOP #------------------------------------------------------------------ # set_outputs #------------------------------------------------------------------ @s.update def set_outputs(): s.out.rdy = b1(0) s.in_.en = b1(0) if s.snoop_state == SNOOP: s.out.rdy = s.in_.rdy & ~s.drop s.in_.en = s.out.en elif s.snoop_state == WAIT: s.out.rdy = b1(0) s.in_.en = s.in_.rdy
def construct(s, PacketType, PositionType, num_outports): # Interface s.get = GetIfcRTL(PacketType) s.give = [GiveIfcRTL(PacketType) for _ in range(num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(mk_bits(clog2(num_outports))) s.give_ens = Wire(mk_bits(num_outports)) # Connections for i in range(num_outports): s.get.ret //= s.give[i].ret s.give_ens[i] //= s.give[i].en # Routing logic @update def up_ru_routing(): s.out_dir = Bits3(0) for i in range(num_outports): s.give[i].rdy = Bits1(0) if s.get.rdy: if s.pos.pos_x == s.get.ret.dst_x and s.pos.pos_y == s.get.ret.dst_y: s.out_dir = SELF elif s.get.ret.dst_x < s.pos.pos_x: s.out_dir = WEST elif s.get.ret.dst_x > s.pos.pos_x: s.out_dir = EAST elif s.get.ret.dst_y > s.pos.pos_y: s.out_dir = NORTH else: s.out_dir = SOUTH s.give[s.out_dir].rdy = Bits1(1) @update def up_ru_give_en(): s.get.en = s.give_ens > Bits5(0)
def construct(s, PacketType, QueueType=None): # Local parameter gating_out = PacketType() # Interface s.get = GetIfcRTL(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.get.ret //= s.queue.enq.msg s.queue.deq.ret //= s.send.msg @update def up_get_deq(): both_rdy = s.get.rdy & s.queue.enq.rdy s.get.en @= both_rdy s.queue.enq.en @= both_rdy @update def up_deq_send(): both_rdy = s.send.rdy & s.queue.deq.rdy s.send.en @= both_rdy s.queue.deq.en @= both_rdy # No ouput queue else: s.send.msg //= lambda: s.get.ret if s.send.en else PacketType() @update def up_get_send(): both_rdy = s.get.rdy & s.send.rdy s.get.en @= both_rdy s.send.en @= both_rdy
def construct( s, MsgType, PositionType, num_outports = 5 ): # Interface s.get = GetIfcRTL( MsgType ) s.give = [ GiveIfcRTL (MsgType) for _ in range ( num_outports ) ] s.pos = InPort( PositionType ) # Componets s.give_ens = Wire( mk_bits( num_outports ) ) # Connections for i in range( num_outports ): s.get.ret //= s.give[i].ret s.give_ens[i] //= s.give[i].en # Routing logic @update def up_ru_routing(): s.give[0].rdy @= 0 s.give[1].rdy @= 0 s.give[2].rdy @= 0 s.give[3].rdy @= 0 s.give[4].rdy @= 0 if s.get.rdy: if (s.pos.pos_x == s.get.ret.dst_x) & (s.pos.pos_y == s.get.ret.dst_y): s.give[4].rdy @= 1 elif s.get.ret.dst_y < s.pos.pos_y: s.give[1].rdy @= 1 elif s.get.ret.dst_y > s.pos.pos_y: s.give[0].rdy @= 1 elif s.get.ret.dst_x < s.pos.pos_x: s.give[2].rdy @= 1 else: s.give[3].rdy @= 1 @update def up_ru_get_en(): s.get.en @= s.give_ens > 0
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.get = GetIfcRTL(PacketType) s.give = [GiveIfcRTL(PacketType) for _ in range(num_outports)] # Componets s.out_dir = Wire(DirT) s.give_ens = Wire(BitsN) # Connections for i in range(num_outports): s.get.ret //= s.give[i].ret s.give_ens[i] //= s.give[i].en # Routing logic @update def up_ru_routing(): s.out_dir @= trunc(s.get.ret.dst, dir_nbits) for i in range(num_outports): s.give[i].rdy @= b1(0) if s.get.rdy: s.give[s.out_dir].rdy @= b1(1) @update def up_ru_give_en(): s.get.en @= s.give_ens > 0
def construct(s, MsgType, vc=2, credit_line=2): assert vc > 1 # Interface s.get = GetIfcRTL(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.get.ret //= s.send.msg @update def up_credit_send(): s.send.en @= 0 s.get.en @= 0 if s.get.rdy: # print( str(s) + " : " + str(s.get.ret) ) for i in range(vc): if (i == s.get.ret.vc_id) & (s.credit[i].count > 0): s.send.en @= 1 s.get.en @= 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): # 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.get = GetIfcRTL(PacketType) s.give = [GiveIfcRTL(PacketType) for _ in range(s.num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(mk_bits(clog2(s.num_outports))) s.give_ens = Wire(mk_bits(s.num_outports)) s.left_dist = Wire(DistType) s.right_dist = Wire(DistType) s.give_msg_wire = Wire(PacketType) # Connections for i in range(s.num_outports): s.give_ens[i] //= s.give[i].en # Routing logic @update def up_left_right_dist(): if s.get.ret.dst < s.pos: s.left_dist @= zext(s.pos, DistType) - zext( s.get.ret.dst, DistType) s.right_dist @= zext(s.last_idx, DistType) - zext( s.pos, DistType) + zext(s.get.ret.dst, DistType) + 1 else: s.left_dist @= 1 + zext(s.last_idx, DistType) + zext( s.pos, DistType) - zext(s.get.ret.dst, DistType) s.right_dist @= zext(s.get.ret.dst, DistType) - zext( s.pos, DistType) @update def up_ru_routing(): s.out_dir @= 0 s.give_msg_wire @= s.get.ret for i in range(s.num_outports): s.give[i].rdy @= 0 if s.get.rdy: if s.pos == s.get.ret.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.give_msg_wire.vc_id @= 1 elif (s.pos == 0) & (s.out_dir == LEFT): s.give_msg_wire.vc_id @= 1 s.give[s.out_dir].rdy @= 1 s.give[s.out_dir].ret @= s.give_msg_wire @update def up_ru_get_en(): s.get.en @= s.give_ens > 0
def construct(s, PositionType, plen_field_name='plen'): # Local parameter assert PitonNoCHeader.nbits == 64 s.num_outports = 5 s.PhitType = Bits64 s.STATE_HEADER = 0 s.STATE_BODY = 1 PLenType = Bits8 XType = get_field_type(PositionType, 'pos_x') YType = get_field_type(PositionType, 'pos_y') # Interface s.get = GetIfcRTL(s.PhitType) s.pos = InPort( PositionType) # TODO: figure out a way to encode position s.give = [GiveIfcRTL(s.PhitType) for _ in range(s.num_outports)] s.hold = [OutPort(Bits1) for _ in range(s.num_outports)] # Components s.header = Wire(PitonNoCHeader) s.state = Wire(Bits1) s.state_next = Wire(Bits1) s.out_dir_r = Wire(Bits3) s.out_dir = Wire(Bits3) s.any_give_en = Wire(Bits1) s.offchip = Wire(Bits1) s.dst_x = Wire(Bits8) s.dst_y = Wire(Bits8) s.counter = Counter(PLenType) s.counter.incr //= 0 s.counter.load_value //= s.header.plen connect_bitstruct(s.get.ret, s.header) for i in range(5): s.get.ret //= s.give[i].ret s.get.en //= s.any_give_en @update def up_any_give_en(): s.any_give_en @= 0 for i in range(s.num_outports): if s.give[i].en: s.any_give_en @= 1 # State transition logic @update_ff def up_state_r(): if s.reset: s.state <<= s.STATE_HEADER else: s.state <<= s.state_next @update def up_state_next(): s.state_next @= s.state if s.state == s.STATE_HEADER: # If the packet has body flits if s.any_give_en & (s.header.plen > 0): s.state_next @= s.STATE_BODY else: # STATE_BODY if (s.counter.count == 1) & s.any_give_en: s.state_next @= s.STATE_HEADER # State output logic @update def up_counter_decr(): s.counter.decr @= 0 if s.state != s.STATE_HEADER: s.counter.decr @= s.any_give_en @update def up_counter_load(): s.counter.load @= 0 if s.state == s.STATE_HEADER: s.counter.load @= (s.state_next == s.STATE_BODY) # Routing logic s.offchip //= s.header.chipid[13] @update def up_dst(): s.dst_x @= 0 s.dst_y @= 0 if ~s.offchip: s.dst_x @= s.header.xpos s.dst_y @= s.header.ypos @update def up_out_dir(): s.out_dir @= s.out_dir_r if (s.state == s.STATE_HEADER) & s.get.rdy: s.out_dir @= 0 # Offchip port if (s.pos.pos_x == 0) & (s.pos.pos_y == 0) & s.offchip: s.out_dir @= WEST elif (s.dst_x == s.pos.pos_x) & (s.dst_y == s.pos.pos_y): s.out_dir @= SELF elif s.dst_x < s.pos.pos_x: s.out_dir @= WEST elif s.dst_x > s.pos.pos_x: s.out_dir @= EAST elif s.dst_y < s.pos.pos_y: s.out_dir @= NORTH elif s.dst_y > s.pos.pos_y: s.out_dir @= SOUTH @update_ff def up_out_dir_r(): s.out_dir_r <<= s.out_dir @update def up_give_rdy_hold(): for i in range(s.num_outports): s.give[i].rdy @= (i == s.out_dir) & s.get.rdy s.hold[i] @= (i == s.out_dir) & (s.state == s.STATE_BODY)
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.get = GetIfcRTL(PacketType) s.give = [GiveIfcRTL(PacketType) for _ in range(num_outports)] s.pos = InPort(PositionType) # Componets s.out_dir = Wire(Bits3) s.give_ens = 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.give_msg_wire = Wire(PacketType) # Connections for i in range(num_outports): s.give_ens[i] //= s.give[i].en s.give_msg_wire //= s.give[i].ret # Calculate distance @update def up_ns_dist(): if s.get.ret.dst_y < s.pos.pos_y: s.south_dist @= zext(s.pos.pos_y, ns_dist_type) - zext( s.get.ret.dst_y, ns_dist_type) s.north_dist @= s.last_row_id - zext( s.pos.pos_y, ns_dist_type) + 1 + zext( s.get.ret.dst_y, ns_dist_type) else: s.south_dist @= zext(s.pos.pos_y, ns_dist_type) + 1 + s.last_row_id - zext( s.get.ret.dst_y, ns_dist_type) s.north_dist @= zext(s.get.ret.dst_y, ns_dist_type) - zext( s.pos.pos_y, ns_dist_type) @update def up_we_dist(): if s.get.ret.dst_x < s.pos.pos_x: s.west_dist @= zext(s.pos.pos_x, we_dist_type) - zext( s.get.ret.dst_x, we_dist_type) s.east_dist @= s.last_col_id - zext( s.pos.pos_x, we_dist_type) + 1 + zext( s.get.ret.dst_x, we_dist_type) else: s.west_dist @= zext(s.pos.pos_x, we_dist_type) + 1 + s.last_col_id - zext( s.get.ret.dst_x, we_dist_type) s.east_dist @= zext(s.get.ret.dst_x, we_dist_type) - zext( s.pos.pos_x, we_dist_type) # Routing logic @update def up_ru_routing(): s.give_msg_wire @= s.get.ret s.out_dir @= 0 s.turning @= 0 for i in range(num_outports): s.give[i].rdy @= 0 if s.get.rdy: if (s.pos.pos_x == s.get.ret.dst_x) & (s.pos.pos_y == s.get.ret.dst_y): s.out_dir @= SELF elif s.get.ret.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.get.ret.src_x == s.pos.pos_x ) & \ ( s.get.ret.src_y != s.pos.pos_y ) & \ ( s.out_dir == WEST ) | ( s.out_dir == EAST ) # Dateline logic if s.turning: s.give_msg_wire.vc_id @= 0 if (s.pos.pos_x == 0) & (s.out_dir == WEST): s.give_msg_wire.vc_id @= 1 elif (s.pos.pos_x == s.last_col_id) & (s.out_dir == EAST): s.give_msg_wire.vc_id @= 1 elif (s.pos.pos_y == 0) & (s.out_dir == SOUTH): s.give_msg_wire.vc_id @= 1 elif (s.pos.pos_y == s.last_row_id) & (s.out_dir == NORTH): s.give_msg_wire.vc_id @= 1 s.give[s.out_dir].rdy @= 1 @update def up_ru_get_en(): s.get.en @= s.give_ens > 0
def construct(s, HeaderFormat, num_outports=4, plen_field_name='plen'): # Meta data s.num_outports = num_outports s.HeaderFormat = HeaderFormat s.PhitType = mk_bits(HeaderFormat.nbits) dir_nbits = clog2(num_outports) if num_outports > 1 else 1 DirType = mk_bits(dir_nbits) PLenType = get_plen_type(HeaderFormat) s.STATE_HEADER = b1(0) s.STATE_BODY = b1(1) # Interface s.get = GetIfcRTL(s.PhitType) s.give = [GiveIfcRTL(s.PhitType) for _ in range(s.num_outports)] s.hold = [OutPort(Bits1) for _ in range(s.num_outports)] # Components s.header = Wire(HeaderFormat) s.state = Wire() s.state_next = Wire() s.out_dir_r = Wire(dir_nbits) s.out_dir = Wire(dir_nbits) s.any_give_en = Wire() s.counter = Counter(PLenType) s.counter.incr //= 0 s.counter.load_value //= s.header.plen @update def up_header(): s.header @= s.get.ret for i in range(s.num_outports): s.get.ret //= s.give[i].ret s.get.en //= s.any_give_en @update def up_any_give_en(): s.any_give_en @= 0 for i in range(s.num_outports): if s.give[i].en: s.any_give_en @= 1 # State transition logic @update_ff def up_state_r(): if s.reset: s.state <<= s.STATE_HEADER else: s.state <<= s.state_next @update def up_state_next(): s.state_next @= s.state if s.state == s.STATE_HEADER: # If the packet has body flits if s.any_give_en & (s.header.plen > 0): s.state_next @= s.STATE_BODY else: # STATE_BODY if (s.counter.count == 1) & s.any_give_en: s.state_next @= s.STATE_HEADER # State output logic @update def up_counter_decr(): if s.state == s.STATE_HEADER: s.counter.decr @= 0 else: s.counter.decr @= s.any_give_en @update def up_counter_load(): if s.state == s.STATE_HEADER: s.counter.load @= (s.state_next == s.STATE_BODY) else: s.counter.load @= 0 # Routing logic # TODO: Figure out how to encode dest id @update def up_out_dir(): if (s.state == s.STATE_HEADER) & s.get.rdy: s.out_dir @= s.header.dst[0:dir_nbits] else: s.out_dir @= s.out_dir_r @update_ff def up_out_dir_r(): s.out_dir_r <<= s.out_dir @update def up_give_rdy_hold(): for i in range(s.num_outports): s.give[i].rdy @= (i == s.out_dir) & s.get.rdy s.hold[i] @= (i == s.out_dir) & (s.state == s.STATE_BODY)
def construct(s, HeaderFormat, PositionType, plen_field_name='plen'): # Meta data s.num_outports = 5 s.HeaderFormat = HeaderFormat s.PhitType = mk_bits(HeaderFormat.nbits) s.STATE_HEADER = b1(0) s.STATE_BODY = b1(1) PLenType = get_plen_type(HeaderFormat) # Interface s.get = GetIfcRTL(s.PhitType) s.pos = InPort( PositionType) # TODO: figure out a way to encode position s.give = [GiveIfcRTL(s.PhitType) for _ in range(s.num_outports)] s.hold = [OutPort(Bits1) for _ in range(s.num_outports)] # Components s.header = Wire(HeaderFormat) s.state = Wire(Bits1) s.state_next = Wire(Bits1) s.out_dir_r = Wire(Bits3) s.out_dir = Wire(Bits3) s.any_give_en = Wire(Bits1) s.counter = m = Counter(PLenType) m.incr //= 0 m.load_value //= s.header.plen @update def up_get_ret(): s.header @= s.get.ret for i in range(5): s.get.ret //= s.give[i].ret s.get.en //= s.any_give_en @update def up_any_give_en(): s.any_give_en @= 0 for i in range(s.num_outports): if s.give[i].en: s.any_give_en @= 1 # State transition logic @update_ff def up_state_r(): if s.reset: s.state <<= s.STATE_HEADER else: s.state <<= s.state_next @update def up_state_next(): if s.state == s.STATE_HEADER: # If the packet has body flits if s.any_give_en & (s.header.plen > 0): s.state_next @= s.STATE_BODY else: s.state_next @= s.STATE_HEADER else: # STATE_BODY if (s.counter.count == 1) & s.any_give_en: s.state_next @= s.STATE_HEADER else: s.state_next @= s.STATE_BODY # State output logic @update def up_counter_decr(): if s.state == s.STATE_HEADER: s.counter.decr @= 0 else: s.counter.decr @= s.any_give_en @update def up_counter_load(): if s.state == s.STATE_HEADER: s.counter.load @= (s.state_next == s.STATE_BODY) else: s.counter.load @= 0 # Routing logic # TODO: Figure out how to encode dest id @update def up_out_dir(): if (s.state == s.STATE_HEADER) & s.get.rdy: if (s.header.dst_x == s.pos.pos_x) & (s.header.dst_y == s.pos.pos_y): s.out_dir @= SELF elif s.header.dst_x < s.pos.pos_x: s.out_dir @= WEST elif s.header.dst_x > s.pos.pos_x: s.out_dir @= EAST elif s.header.dst_y < s.pos.pos_y: s.out_dir @= SOUTH else: s.out_dir @= NORTH else: s.out_dir @= s.out_dir_r @update_ff def up_out_dir_r(): s.out_dir_r <<= s.out_dir @update def up_give_rdy_hold(): for i in range(s.num_outports): s.give[i].rdy @= (i == s.out_dir) & s.get.rdy s.hold[i] @= (i == s.out_dir) & (s.state == s.STATE_BODY)