Skip to content

Commit 145b0d9

Browse files
authored
Merge branch 'tancheng:master' into master
2 parents 4a1201e + be086de commit 145b0d9

12 files changed

Lines changed: 336 additions & 160 deletions

File tree

cgra/CgraTemplateRTL.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,53 @@
1919
from ..lib.util.data_struct_attr import *
2020
from ..lib.messages import *
2121

22+
from ..fu.single.PhiRTL import PhiRTL
23+
from ..fu.single.AdderRTL import AdderRTL
24+
from ..fu.single.ShifterRTL import ShifterRTL
25+
from ..fu.single.MemUnitRTL import MemUnitRTL
26+
from ..fu.single.SelRTL import SelRTL
27+
from ..fu.single.CompRTL import CompRTL
28+
from ..fu.double.SeqMulAdderRTL import SeqMulAdderRTL
29+
from ..fu.single.RetRTL import RetRTL
30+
from ..fu.single.MulRTL import MulRTL
31+
from ..fu.single.ExclusiveDivRTL import ExclusiveDivRTL
32+
from ..fu.single.LogicRTL import LogicRTL
33+
from ..fu.single.GrantRTL import GrantRTL
34+
from ..fu.single.LoopControlRTL import LoopControlRTL
35+
from ..fu.single.ConstRTL import ConstRTL
36+
from ..fu.float.FpAddRTL import FpAddRTL
37+
from ..fu.float.FpMulRTL import FpMulRTL
38+
39+
fu_map = {
40+
"add": AdderRTL,
41+
"mul": MulRTL,
42+
"div": ExclusiveDivRTL,
43+
"fadd": FpAddRTL,
44+
"fmul": FpMulRTL,
45+
"fdiv": None,
46+
"logic": LogicRTL,
47+
"cmp": CompRTL,
48+
"sel": SelRTL,
49+
"type_conv": None,
50+
"vfmul": None,
51+
"fadd_fadd": None,
52+
"fmul_fadd": None,
53+
"grant": GrantRTL,
54+
"loop_control": LoopControlRTL,
55+
"phi": PhiRTL,
56+
"constant": ConstRTL,
57+
"mem": MemUnitRTL,
58+
"return": RetRTL,
59+
"mem_indexed": MemUnitRTL,
60+
"alloca": None,
61+
"shift": ShifterRTL,
62+
}
63+
64+
def map_fu2rtl(fu_type: list[str]):
65+
fuRTL = list({fu_map[fu] for fu in fu_type})
66+
fuRTL_new = [fu for fu in fuRTL if fu is not None]
67+
return fuRTL_new
68+
2269

2370
class CgraTemplateRTL(Component):
2471

@@ -33,7 +80,8 @@ def construct(s, CgraPayloadType,
3380
FunctionUnit, FuList, TileList, LinkList,
3481
dataSPM, controller2addr_map, idTo2d_map,
3582
is_multi_cgra = True,
36-
has_ctrl_ring = True):
83+
has_ctrl_ring = True,
84+
simplified_modeling_for_synthesis = False):
3785

3886
DataType = CgraPayloadType.get_field_type(kAttrData)
3987
PredicateType = DataType.get_field_type(kAttrPredicate)
@@ -87,7 +135,7 @@ def construct(s, CgraPayloadType,
87135
total_steps, 4, 2, s.num_mesh_ports,
88136
s.num_mesh_ports, num_cgras, s.num_tiles,
89137
num_registers_per_reg_bank,
90-
FuList = FuList)
138+
FuList = FuList if simplified_modeling_for_synthesis else map_fu2rtl(TileList[i].getAllValidFuTypes()))
91139
for i in range(s.num_tiles)]
92140
# FIXME: Need to enrish data-SPM-related user-controlled parameters, e.g., number of banks.
93141
s.data_mem = DataMemControllerRTL(NocPktType,
@@ -165,16 +213,30 @@ def construct(s, CgraPayloadType,
165213
s.data_mem.recv_raddr[memPort] //= s.tile[dstTileIndex].to_mem_raddr
166214
s.data_mem.send_rdata[memPort] //= s.tile[dstTileIndex].from_mem_rdata
167215

216+
# Grounds the generic routing port since it is unused for memory links when in single-CGRA mode.
217+
if not link.disabled and not is_multi_cgra:
218+
s.tile[dstTileIndex].recv_data[link.dstPort].val //= 0
219+
s.tile[dstTileIndex].recv_data[link.dstPort].msg //= DataType(0, 0)
220+
168221
elif link.isToMem():
169222
memPort = link.getMemWritePort()
170223
srcTileIndex = link.srcTile.getIndex(TileList)
171224
s.tile[srcTileIndex].to_mem_waddr //= s.data_mem.recv_waddr[memPort]
172225
s.tile[srcTileIndex].to_mem_wdata //= s.data_mem.recv_wdata[memPort]
173226

227+
# Grounds the generic routing port ready signal when in single-CGRA mode.
228+
if not link.disabled and not is_multi_cgra:
229+
s.tile[srcTileIndex].send_data[link.srcPort].rdy //= 0
230+
174231
else:
175232
srcTileIndex = link.srcTile.getIndex(TileList)
176233
dstTileIndex = link.dstTile.getIndex(TileList)
177-
s.tile[srcTileIndex].send_data[link.srcPort] //= s.tile[dstTileIndex].recv_data[link.dstPort]
234+
if not link.disabled:
235+
s.tile[srcTileIndex].send_data[link.srcPort] //= s.tile[dstTileIndex].recv_data[link.dstPort]
236+
else:
237+
s.tile[dstTileIndex].recv_data[link.dstPort].val //= 0
238+
s.tile[dstTileIndex].recv_data[link.dstPort].msg //= DataType(0, 0)
239+
s.tile[srcTileIndex].send_data[link.srcPort].rdy //= 0
178240

179241
if is_multi_cgra:
180242
for row in range(per_cgra_rows):

cgra/test/CgraTemplateRTL_test.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ def construct(s, DUT, FunctionUnit, FuList,
7070
has_ctrl_ring,
7171
TileList, LinkList, dataSPM,
7272
controller2addr_map, idTo2d_map,
73-
complete_signal_sink_out):
73+
complete_signal_sink_out,
74+
simplified_modeling_for_synthesis):
7475

7576
CgraPayloadType = CtrlPktType.get_field_type(kAttrPayload)
7677
DataAddrType = mk_bits(clog2(data_mem_size_global))
@@ -92,7 +93,8 @@ def construct(s, DUT, FunctionUnit, FuList,
9293
TileList, LinkList, dataSPM, controller2addr_map,
9394
idTo2d_map,
9495
is_multi_cgra = False,
95-
has_ctrl_ring = has_ctrl_ring)
96+
has_ctrl_ring = has_ctrl_ring,
97+
simplified_modeling_for_synthesis = simplified_modeling_for_synthesis)
9698

9799
s.has_ctrl_ring = has_ctrl_ring
98100

@@ -300,7 +302,8 @@ def test_cgra_universal(cmdline_opts, simplified_modeling_for_synthesis = False,
300302
mem_access_is_combinational,
301303
has_ctrl_ring,
302304
tiles, links, dataSPM,
303-
controller2addr_map, idTo2d_map, complete_signal_sink_out)
305+
controller2addr_map, idTo2d_map, complete_signal_sink_out,
306+
simplified_modeling_for_synthesis)
304307

305308
th.elaborate()
306309
th.dut.set_metadata(VerilogTranslationPass.explicit_module_name,
@@ -310,13 +313,6 @@ def test_cgra_universal(cmdline_opts, simplified_modeling_for_synthesis = False,
310313
'ALWCOMBORDER', 'CMPCONST'])
311314
th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut'])
312315

313-
for tile in tiles:
314-
if not tile.isDefaultFus():
315-
targetFuList = []
316-
for fuType in tile.getAllValidFuTypes():
317-
targetFuList.append(fuType2RTL[fuType])
318-
targetTile = "top.dut.tile[" + str(tile.getIndex(tiles)) + "].construct"
319-
th.set_param(targetTile, FuList=targetFuList)
320316

321317
run_sim(th)
322318

cgra/test/arch.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ cgra_defaults:
99

1010
tile_defaults:
1111
num_registers: 16
12-
operations: ["add", "mul", "sub", "div", "rem", "fadd", "fmul", "fsub", "fdiv", "or", "not", "icmp", "fcmp", "sel", "cast", "sext", "zext", "shl", "vfmul", "fadd_fadd", "fmul_fadd", "data_mov", "ctrl_mov", "reserve", "grant_predicate", "grant_once", "grant_always", "loop_control", "phi", "constant"] # comprehensive operation set
12+
fu_types: ["add", "mul", "div", "fadd", "fmul", "fdiv", "logic", "cmp", "sel", "type_conv", "vfmul", "fadd_fadd", "fmul_fadd", "grant", "loop_control", "phi", "constant", "mem", "return", "mem_indexed", "alloca", "shift"]

cgra/test/arch_override.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# This is an example of overriding the tiles/links.
2+
multi_cgra_defaults:
3+
rows: 1
4+
columns: 1
5+
6+
cgra_defaults:
7+
rows: 2
8+
columns: 2
9+
configMemSize: 8
10+
11+
tile_defaults:
12+
num_registers: 16
13+
fu_types: ["add", "mul", "div", "fadd", "fmul", "fdiv", "logic", "cmp", "sel", "type_conv", "vfmul", "fadd_fadd", "fmul_fadd", "grant", "loop_control", "phi", "constant", "mem", "return", "mem_indexed", "alloca", "shift"]
14+
15+
link_overrides:
16+
- src_cgra_x: 0
17+
src_cgra_y: 0
18+
dst_cgra_x: 0
19+
dst_cgra_y: 0
20+
src_tile_x: 1
21+
src_tile_y: 1
22+
dst_tile_x: 0
23+
dst_tile_y: 1
24+
existence: false
25+
tile_overrides:
26+
- cgra_x: 0
27+
cgra_y: 0
28+
tile_x: 0
29+
tile_y: 0
30+
fu_types: ["phi", "shift", "mem", "return", "add"]
31+
existence: true

lib/util/cgra/Link.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,37 @@ def isFromMem(s):
2222
return s.fromMem
2323

2424
def validatePorts(s):
25-
if not s.toMem and not s.fromMem:
26-
s.srcTile.invalidOutPorts.remove(s.srcPort)
27-
s.dstTile.invalidInPorts.remove(s.dstPort)
28-
if s.toMem:
29-
s.srcTile.toMem = True
30-
if s.fromMem:
31-
s.dstTile.fromMem = True
25+
26+
"""
27+
Validates the ports of the link.
28+
If the link is not disabled, the ports are removed from the invalidOutPorts and invalidInPorts of the srcTile and dstTile.
29+
- If the link is to memory, the toMem flag of the srcTile is set to True.
30+
- If the link is from memory, the fromMem flag of the dstTile is set to True.
31+
If the link is disabled, the ports are added to the invalidOutPorts and invalidInPorts of the srcTile and dstTile.
32+
- If the link is to memory, the toMem flag of the srcTile is set to False.
33+
- If the link is from memory, the fromMem flag of the dstTile is set to False.
34+
"""
35+
if not s.disabled:
36+
if not s.toMem and not s.fromMem:
37+
# the link is between two tiles.
38+
s.srcTile.invalidOutPorts.remove(s.srcPort)
39+
s.dstTile.invalidInPorts.remove(s.dstPort)
40+
elif s.toMem:
41+
s.srcTile.invalidOutPorts.remove(s.srcPort)
42+
s.srcTile.toMem = True
43+
elif s.fromMem:
44+
s.dstTile.invalidInPorts.remove(s.dstPort)
45+
s.dstTile.fromMem = True
46+
else:# the link is disabled.
47+
if not s.toMem and not s.fromMem:
48+
# the link is between two tiles.
49+
s.srcTile.invalidOutPorts.add(s.srcPort)
50+
s.dstTile.invalidInPorts.add(s.dstPort)
51+
elif s.toMem:
52+
# the link is to memory.
53+
s.srcTile.invalidOutPorts.add(s.srcPort)
54+
s.srcTile.toMem = False
55+
elif s.fromMem:
56+
# the link is from memory.
57+
s.dstTile.invalidInPorts.add(s.dstPort)
58+
s.dstTile.fromMem = False

lib/util/cgra/Tile.py

Lines changed: 98 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,100 @@
11
from ..common import PORT_DIRECTION_COUNTS
2+
3+
4+
25
class Tile:
3-
def __init__(s, dimX, dimY, num_registers, operations):
4-
s.disabled = False
5-
s.dimX = dimX
6-
s.dimY = dimY
7-
s.num_registers = num_registers
8-
s.operations = operations
9-
s.isDefaultFus_ = True
10-
s.toMem = False
11-
s.fromMem = False
12-
s.invalidOutPorts = set()
13-
s.invalidInPorts = set()
14-
for i in range(PORT_DIRECTION_COUNTS):
15-
s.invalidOutPorts.add(i)
16-
s.invalidInPorts.add(i)
17-
18-
def getInvalidInPorts(s):
19-
return s.invalidInPorts
20-
21-
def getInvalidOutPorts(s):
22-
return s.invalidOutPorts
23-
24-
def hasToMem(s):
25-
return s.toMem
26-
27-
def hasFromMem(s):
28-
return s.fromMem
29-
30-
def getIndex(s, TileList):
31-
if s.disabled:
32-
return -1
33-
index = 0
34-
for tile in TileList:
35-
if tile.dimY < s.dimY and not tile.disabled:
36-
index += 1
37-
elif tile.dimY == s.dimY and tile.dimX < s.dimX and not tile.disabled:
38-
index += 1
39-
return index
40-
41-
def isDefaultFus(s):
42-
return s.isDefaultFus_
43-
44-
def getAllValidFuTypes(s):
45-
return s.operations
46-
47-
def override(s):
48-
# TODO @benkangpeng
49-
raise NotImplementedError
6+
"""
7+
Represents a single tile in the CGRA array configuration.
8+
This class holds the static configuration parameters for a tile, including its location,
9+
functional units, and connectivity status (memory access, valid ports).
10+
It is used during the parameterization phase to configure the RTL generation.
11+
"""
12+
13+
def __init__(self, dimX, dimY, num_registers, fu_types):
14+
self.disabled = False
15+
self.dimX = dimX # Column index (X coordinate) in the CGRA mesh
16+
self.dimY = dimY # Row index (Y coordinate) in the CGRA mesh
17+
# Number of registers in the tile's register file
18+
self.num_registers = num_registers
19+
self.fu_types = fu_types
20+
self.isDefaultFus_ = True # Flag indicating if the tile uses the default set of FUs
21+
22+
# toMem: Indicates if this tile has a dedicated link TO the data memory (for Store operations).
23+
self.toMem = False
24+
25+
# fromMem: Indicates if this tile has a dedicated link FROM the data memory (for Load operations).
26+
self.fromMem = False
27+
28+
# invalidOutPorts: A set containing port indices (e.g., PORT_NORTH, PORT_EAST) that are NOT used
29+
# as output ports. Initialized to contain ALL ports. When a link is created originating from this
30+
# tile, the corresponding port is removed from this set.
31+
# Used in RTL generation to ground/disable unused output ports.
32+
self.invalidOutPorts = set()
33+
34+
# invalidInPorts: A set containing port indices that are NOT used as input ports.
35+
# Initialized to contain ALL ports. When a link is created terminating at this tile,
36+
# the corresponding port is removed from this set.
37+
# Used in RTL generation to ground/disable unused input ports.
38+
self.invalidInPorts = set()
39+
40+
for i in range(PORT_DIRECTION_COUNTS):
41+
self.invalidOutPorts.add(i)
42+
self.invalidInPorts.add(i)
43+
44+
def getInvalidInPorts(self):
45+
"""Returns the set of unused input ports."""
46+
return self.invalidInPorts
47+
48+
def getInvalidOutPorts(self):
49+
"""Returns the set of unused output ports."""
50+
return self.invalidOutPorts
51+
52+
def hasToMem(self):
53+
"""Returns True if the tile connects to memory (write/store)."""
54+
return self.toMem
55+
56+
def hasFromMem(self):
57+
"""Returns True if the tile receives from memory (read/load)."""
58+
return self.fromMem
59+
60+
def getIndex(self, TileList):
61+
"""
62+
Calculates the flattened index of this tile within a given list of tiles.
63+
This is used to map the logical Tile object to the physical TileRTL instance index
64+
in the top-level CGRA component.
65+
66+
Args:
67+
TileList: A list of all Tile objects in the CGRA.
68+
69+
Returns:
70+
int: The 0-based index of this tile, skipping disabled tiles.
71+
Returns -1 if this tile is disabled.
72+
"""
73+
if self.disabled:
74+
return -1
75+
index = 0
76+
for tile in TileList:
77+
# Counts valid tiles that appear before 's' in row-major order (Row Y, then Col X)
78+
if tile.dimY < self.dimY and not tile.disabled:
79+
index += 1
80+
elif tile.dimY == self.dimY and tile.dimX < self.dimX and not tile.disabled:
81+
index += 1
82+
return index
83+
84+
def isDefaultFus(self):
85+
return self.isDefaultFus_
86+
87+
def getAllValidFuTypes(self):
88+
return self.fu_types
89+
90+
def override(self, fu_types, existence):
91+
"""
92+
Overrides the default configuration for this tile.
93+
94+
Args:
95+
fu_types: New list of supported fu_types.
96+
existence: Boolean, if False, marks the tile as disabled (not physically present/active).
97+
"""
98+
self.fu_types = fu_types
99+
self.disabled = not existence
100+
self.isDefaultFus_ = False

0 commit comments

Comments
 (0)