Skip to content

Commit

Permalink
HW to give North I/O tiles SB
Browse files Browse the repository at this point in the history
  • Loading branch information
mcoduoza committed Dec 5, 2024
1 parent 420d831 commit 52b8694
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 15 deletions.
41 changes: 40 additions & 1 deletion canal/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,8 @@ def __init__(self, tiles: Dict[int, Tile],
full_config_addr_width: int = 32,
stall_signal_width: int = 4,
double_buffer: bool = False,
ready_valid: bool = False):
ready_valid: bool = False,
give_north_io_sbs: bool = False):
super().__init__()

# turn off hashing because we controls that hashing here
Expand Down Expand Up @@ -700,6 +701,44 @@ def __init__(self, tiles: Dict[int, Tile],
for bit_width, tile in self.tiles.items():
# connection box time
for port_name, port_node in tile.ports.items():

if give_north_io_sbs:
# Lift up if io2glb or glb2io port (and skip the rest i.e., adding SB and CB connections)
if "glb2io" in port_name:
ready_port_name = port_name + "_ready"
valid_port_name = port_name + "_valid"

core_port = self.__get_port(port_name)
core_ready_port = self.__get_port(ready_port_name)
core_valid_port = self.__get_port(valid_port_name)

self.add_port(port_name, magma.In(core_port.base_type()))
self.add_port(valid_port_name, magma.In(magma.Bit))
self.add_port(ready_port_name, magma.Out(magma.Bit))

self.wire(self.ports[port_name], core_port)
self.wire(self.convert(self.ports[valid_port_name], magma.Bits[1]), core_valid_port)
self.wire(self.convert(core_ready_port, magma.bit), self.ports[ready_port_name])

continue

if "io2glb" in port_name:
ready_port_name = port_name + "_ready"
valid_port_name = port_name + "_valid"

core_port = self.__get_port(port_name)
core_ready_port = self.__get_port(ready_port_name)
core_valid_port = self.__get_port(valid_port_name)

self.add_port(port_name, magma.Out(core_port.base_type()))
self.add_port(valid_port_name, magma.Out(magma.Bit))
self.add_port(ready_port_name, magma.In(magma.Bit))

self.wire(core_port, self.ports[port_name])
self.wire(self.convert(core_valid_port, magma.bit), self.ports[valid_port_name])
self.wire(self.convert(self.ports[ready_port_name], magma.Bits[1]), core_ready_port)
continue

# input ports
if len(port_node) == 0:
assert bit_width == port_node.width
Expand Down
30 changes: 25 additions & 5 deletions canal/interconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def __init__(self, interconnects: Dict[int, InterconnectGraph],
stall_signal_width: int = 4,
lift_ports=False,
double_buffer: bool = False,
ready_valid: bool = False):
ready_valid: bool = False,
give_north_io_sbs: bool = False):
super().__init__()

self.__interface = {}
Expand All @@ -43,6 +44,8 @@ def __init__(self, interconnects: Dict[int, InterconnectGraph],
self.double_buffer = double_buffer
self.ready_valid = ready_valid

self.give_north_io_sbs = give_north_io_sbs

# loop through the grid and create tile circuits
# first find all the coordinates
coordinates = OrderedSet()
Expand Down Expand Up @@ -84,7 +87,8 @@ def __init__(self, interconnects: Dict[int, InterconnectGraph],
TileCircuit(tiles, config_addr_width, config_data_width,
stall_signal_width=stall_signal_width,
double_buffer=self.double_buffer,
ready_valid=self.ready_valid)
ready_valid=self.ready_valid,
give_north_io_sbs=self.give_north_io_sbs)

# we need to deal with inter-tile connections now
# we only limit mesh
Expand Down Expand Up @@ -264,15 +268,30 @@ def __lift_ports(self):
self.wire(p, tile.ports[sb_name + "_ready"])
self.__interface[ready_name] = sb_port


def skip_margin_connection(self, tile):
if self.give_north_io_sbs:
return tile.switchbox.num_track > 0 and tile.y != 0
else:
return tile.switchbox.num_track > 0

# FIXME: This is a hack. Why are io2f and f2io tiles ports in the first place? They shouldn't be...
def dont_lift_port(self, tile, port_name):
# dont lift f2io and io2f ports to interconnect level since these connect to the SB within the I/O tile
return self.give_north_io_sbs and (tile.y == 0 and ("f2io" in port_name or "io2f" in port_name))

# This function makes the tile-to-tile connection for the margin tiles
# And lifts up ports at the "edge" of the Interconnect graph as ports for the
# Interconnect module
def __connect_margin_tiles(self):
# connect these margin tiles
# margin tiles have empty switchbox
for coord, tile_dict in self.__tiles.items():
for bit_width, tile in tile_dict.items():
if tile.switchbox.num_track > 0 or tile.core is None:
if self.skip_margin_connection(tile) or tile.core is None:
continue
for port_name, port_node in tile.ports.items():
if port_name == "flush":
if port_name == "flush" or self.dont_lift_port(tile, port_name):
continue
tile_port = self.tile_circuits[coord].ports[port_name]
# FIXME: this is a hack
Expand Down Expand Up @@ -719,7 +738,8 @@ def clone(self):
self.tile_id_width,
self.stall_signal_width,
self.__lifted_ports,
double_buffer=self.double_buffer)
double_buffer=self.double_buffer,
give_north_io_sbs=self.give_north_io_sbs)
return ic

def get_column(self, x: int):
Expand Down
35 changes: 26 additions & 9 deletions canal/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def create_uniform_interconnect(width: int,
List[Tuple[int, SwitchBoxSide]] = None,
io_sides: List[IOSide] = [IOSide.None_],
io_conn: Dict[str, Dict[str, List[int]]] = None,
give_north_io_sbs: bool = False,
additional_core_fn: Callable[[int, int], Core] = lambda _, __: None,
inter_core_connection: Dict[str, List[str]] = None
) -> InterconnectGraph:
Expand Down Expand Up @@ -96,9 +97,15 @@ def create_uniform_interconnect(width: int,
if IOSide.None_ in io_sides:
io_sides = [IOSide.None_]
x_min, x_max, y_min, y_max = get_array_size(width, height, io_sides)

interconnect_x_min = x_min
interconnect_x_max = x_max
interconnect_y_min = y_min-1 if give_north_io_sbs else y_min
interconnect_y_max = y_max

# create tiles and set cores
for x in range(x_min, x_max + 1):
for y in range(y_min, y_max + 1, tile_height):
for x in range(interconnect_x_min, interconnect_x_max + 1):
for y in range(interconnect_y_min, interconnect_y_max + 1, tile_height):
# compute the number of tracks
num_track = compute_num_tracks(x_min, y_min,
x, y, track_info)
Expand Down Expand Up @@ -158,15 +165,15 @@ def create_uniform_interconnect(width: int,
current_track = 0
for track_len in track_lens:
for _ in range(track_info[track_len]):
interconnect.connect_switchbox(x_min, y_min, x_max,
y_max,
interconnect.connect_switchbox(interconnect_x_min, interconnect_y_min, interconnect_x_max,
interconnect_y_max,
track_len,
current_track,
InterconnectPolicy.Ignore)
current_track += 1

# insert io
connect_io(interconnect, io_conn["in"], io_conn["out"], io_sides)
connect_io(interconnect, io_conn["in"], io_conn["out"], io_sides, give_north_io_sbs)

# insert pipeline register
if pipeline_reg is None:
Expand All @@ -181,22 +188,32 @@ def create_uniform_interconnect(width: int,

return interconnect


# This function connects tiles that are at the edge to nearby tiles in the
# appropriate direction (North, west, east, or south neighbor). Makes this
# connection in the interconnect graph. Actual magma connection is done in
# a separate pass.
def connect_io(interconnect: InterconnectGraph,
input_port_conn: Dict[str, List[int]],
output_port_conn: Dict[str, List[int]],
io_sides: List[IOSide]):
io_sides: List[IOSide],
give_north_io_sbs: bool = False):
"""connect tiles on the side"""
if IOSide.None_ in io_sides:
return

width, height = interconnect.get_size()
x_min, x_max, y_min, y_max = get_array_size(width, height, io_sides)

interconnect_x_min = x_min
interconnect_x_max = x_max
interconnect_y_min = y_min-1 if give_north_io_sbs else y_min
interconnect_y_max = y_max

# compute tiles and sides
for x in range(width):
for y in range(height):
if x in range(x_min, x_max + 1) and \
y in range(y_min, y_max + 1):
if x in range(interconnect_x_min, interconnect_x_max + 1) and \
y in range(interconnect_y_min, interconnect_y_max + 1):
continue

# make sure that these margins tiles have empty switch boxes
Expand Down

0 comments on commit 52b8694

Please sign in to comment.