Skip to content

Commit

Permalink
[feature] Ring connecting multiple CGRAs (each with a controller)
Browse files Browse the repository at this point in the history
  • Loading branch information
tancheng committed Dec 5, 2024
1 parent 21d1417 commit a863769
Show file tree
Hide file tree
Showing 11 changed files with 649 additions and 0 deletions.
127 changes: 127 additions & 0 deletions cgra/CGRAWithControllerRTL.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
"""
=========================================================================
CGRAWithControllerRTL.py
=========================================================================
Author : Cheng Tan
Date : Dec 4, 2024
"""

from pymtl3 import *
from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL
from ..fu.single.MemUnitRTL import MemUnitRTL
from ..fu.single.AdderRTL import AdderRTL
from ..lib.util.common import *
from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL
from ..lib.basic.val_rdy.ifcs import SendIfcRTL as ValRdySendIfcRTL
from ..lib.basic.val_rdy.ifcs import RecvIfcRTL as ValRdyRecvIfcRTL
from ..lib.opt_type import *
from ..mem.data.DataMemScalableRTL import DataMemScalableRTL
from ..noc.ChannelNormalRTL import ChannelNormalRTL
from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL
from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL
from ..controller.ControllerRTL import ControllerRTL


class CGRAWithControllerRTL(Component):

def construct(s, DataType, PredicateType, CtrlType, NocPktType,
width, height, ctrl_mem_size, data_mem_size, num_ctrl,
total_steps, FunctionUnit, FuList, preload_data = None,
preload_const = None):

s.num_tiles = width * height
s.num_mesh_ports = 4
AddrType = mk_bits(clog2(ctrl_mem_size))

# Interfaces
s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(s.num_tiles)]
s.recv_wopt = [RecvIfcRTL(CtrlType) for _ in range(s.num_tiles)]

s.recv_from_other = ValRdyRecvIfcRTL(NocPktType)
s.send_to_other = ValRdySendIfcRTL(NocPktType)

# s.recv_towards_controller = RecvIfcRTL(DataType)
# s.send_from_controller = SendIfcRTL(DataType)


# Components
if preload_const == None:
preload_const = [[DataType(0, 0)] for _ in range(width*height)]
s.tile = [TileSeparateCrossbarRTL(DataType, PredicateType, CtrlType,
ctrl_mem_size, data_mem_size, num_ctrl,
total_steps, 4, 2, s.num_mesh_ports,
s.num_mesh_ports, const_list = preload_const[i])
for i in range( s.num_tiles)]
s.data_mem = DataMemScalableRTL(DataType, data_mem_size, height, height, preload_data)
s.controller = ControllerRTL(NocPktType, DataType, AddrType)

# Connections

# Connects data memory with controller.
s.data_mem.recv_from_noc //= s.controller.send_to_master
s.data_mem.send_to_noc //= s.controller.recv_from_master

s.recv_from_other //= s.controller.recv_from_other
s.send_to_other //= s.controller.send_to_other

# s.recv_towards_controller //= s.controller.recv_from_master
# s.send_from_controller //= s.controller.send_to_master

for i in range(s.num_tiles):
s.recv_waddr[i] //= s.tile[i].recv_waddr
s.recv_wopt[i] //= s.tile[i].recv_wopt

if i // width > 0:
s.tile[i].send_data[PORT_SOUTH] //= s.tile[i-width].recv_data[PORT_NORTH]

if i // width < height - 1:
s.tile[i].send_data[PORT_NORTH] //= s.tile[i+width].recv_data[PORT_SOUTH]

if i % width > 0:
s.tile[i].send_data[PORT_WEST] //= s.tile[i-1].recv_data[PORT_EAST]

if i % width < width - 1:
s.tile[i].send_data[PORT_EAST] //= s.tile[i+1].recv_data[PORT_WEST]

if i // width == 0:
s.tile[i].send_data[PORT_SOUTH].rdy //= 0
s.tile[i].recv_data[PORT_SOUTH].en //= 0
s.tile[i].recv_data[PORT_SOUTH].msg //= DataType(0, 0)

if i // width == height - 1:
s.tile[i].send_data[PORT_NORTH].rdy //= 0
s.tile[i].recv_data[PORT_NORTH].en //= 0
s.tile[i].recv_data[PORT_NORTH].msg //= DataType(0, 0)

if i % width == 0:
s.tile[i].send_data[PORT_WEST].rdy //= 0
s.tile[i].recv_data[PORT_WEST].en //= 0
s.tile[i].recv_data[PORT_WEST].msg //= DataType(0, 0)

if i % width == width - 1:
s.tile[i].send_data[PORT_EAST].rdy //= 0
s.tile[i].recv_data[PORT_EAST].en //= 0
s.tile[i].recv_data[PORT_EAST].msg //= DataType(0, 0)

if i % width == 0:
s.tile[i].to_mem_raddr //= s.data_mem.recv_raddr[i//width]
s.tile[i].from_mem_rdata //= s.data_mem.send_rdata[i//width]
s.tile[i].to_mem_waddr //= s.data_mem.recv_waddr[i//width]
s.tile[i].to_mem_wdata //= s.data_mem.recv_wdata[i//width]
else:
s.tile[i].to_mem_raddr.rdy //= 0
s.tile[i].from_mem_rdata.en //= 0
s.tile[i].from_mem_rdata.msg //= DataType(0, 0)
s.tile[i].to_mem_waddr.rdy //= 0
s.tile[i].to_mem_wdata.rdy //= 0


# Line trace
def line_trace( s ):
# str = "||".join([ x.element.line_trace() for x in s.tile ])
# str += " :: [" + s.data_mem.line_trace() + "]"
res = "||\n".join([ (("[tile"+str(i)+"]: ") + x.line_trace() + x.ctrl_mem.line_trace())
for (i,x) in enumerate(s.tile) ])
res += "\n :: [" + s.data_mem.line_trace() + "] \n"
return res
156 changes: 156 additions & 0 deletions cgra/test/CGRAWithControllerRTL_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
"""
==========================================================================
CGRAWithControllerRTL_test.py
==========================================================================
Test cases for CGRA with controller.
Author : Cheng Tan
Date : Dec 4, 2024
"""


from pymtl3 import *
from pymtl3.stdlib.test_utils import (run_sim,
config_model_with_cmdline_opts)
from pymtl3.passes.backends.verilog import (VerilogTranslationPass,
VerilogVerilatorImportPass)
from ..CGRAWithControllerRTL import CGRAWithControllerRTL
from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL
from ...fu.single.AdderRTL import AdderRTL
from ...fu.single.MemUnitRTL import MemUnitRTL
from ...fu.single.ShifterRTL import ShifterRTL
from ...lib.messages import *
from ...lib.opt_type import *
from ...lib.basic.en_rdy.test_srcs import TestSrcRTL


#-------------------------------------------------------------------------
# Test harness
#-------------------------------------------------------------------------

class TestHarness(Component):

def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType,
CtrlType, NocPktType, width, height, ctrl_mem_size,
data_mem_size, src_opt, ctrl_waddr):

s.num_tiles = width * height
AddrType = mk_bits(clog2(ctrl_mem_size))

s.src_opt = [TestSrcRTL(CtrlType, src_opt[i])
for i in range(s.num_tiles)]
s.ctrl_waddr = [TestSrcRTL(AddrType, ctrl_waddr[i])
for i in range(s.num_tiles)]

s.dut = DUT(DataType, PredicateType, CtrlType, NocPktType,
width, height, ctrl_mem_size, data_mem_size,
len(src_opt[0]), len(src_opt[0]), FunctionUnit, FuList)

# Connections
s.dut.send_to_other.rdy //= 0
s.dut.recv_from_other.val //= 0
s.dut.recv_from_other.msg //= NocPktType(0, 0, 0, 0, 0, 0)

for i in range(s.num_tiles):
connect(s.src_opt[i].send, s.dut.recv_wopt[i])
connect(s.ctrl_waddr[i].send, s.dut.recv_waddr[i])

def done(s):
done = True
for i in range(s.num_tiles):
if not s.src_opt[i].done():
done = False
break
return done

def line_trace(s):
return s.dut.line_trace()

def test_homo_2x2(cmdline_opts):
num_tile_inports = 4
num_tile_outports = 4
num_fu_inports = 4
num_fu_outports = 2
num_routing_outports = num_tile_outports + num_fu_inports
ctrl_mem_size = 6
data_mem_size = 8
width = 2
height = 2
TileInType = mk_bits(clog2(num_tile_inports + 1))
FuInType = mk_bits(clog2(num_fu_inports + 1))
FuOutType = mk_bits(clog2(num_fu_outports + 1))
AddrType = mk_bits(clog2(ctrl_mem_size))
num_tiles = width * height
DUT = CGRAWithControllerRTL
FunctionUnit = FlexibleFuRTL
FuList = [MemUnitRTL, AdderRTL]
DataType = mk_data(32, 1)
PredicateType = mk_predicate(1, 1)
CtrlType = mk_separate_ctrl(num_fu_inports, num_fu_outports,
num_tile_inports, num_tile_outports)
NocPktType = mk_ring_multi_cgra_pkt(nrouters = 4,
payload_nbits = 32,
predicate_nbits = 1)
pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)]
src_opt = [[
CtrlType(OPT_INC, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
# TODO: make below as TileInType(5) to double check.
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]),
CtrlType(OPT_INC, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]),

CtrlType(OPT_ADD, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]),

CtrlType(OPT_STR, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]),

CtrlType(OPT_ADD, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]),

CtrlType(OPT_ADD, b1(0),
pickRegister,
[TileInType(4), TileInType(3), TileInType(2), TileInType(1),
TileInType(0), TileInType(0), TileInType(0), TileInType(0)],

[FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0),
FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)])

] for _ in range(num_tiles)]
ctrl_waddr = [[AddrType(0), AddrType(1), AddrType(2), AddrType(3),
AddrType(4), AddrType(5)] for _ in range(num_tiles)]
th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType,
CtrlType, NocPktType, width, height, ctrl_mem_size,
data_mem_size, src_opt, ctrl_waddr)
th.elaborate()
th.dut.set_metadata(VerilogVerilatorImportPass.vl_Wno_list,
['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT',
'ALWCOMBORDER'])
th = config_model_with_cmdline_opts(th, cmdline_opts, duts=['dut'])
run_sim(th)

1 change: 1 addition & 0 deletions controller/ControllerRTL.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def construct(s, RingPktType, CGRADataType, CGRAAddrType):
# Connections
s.queue.recv //= s.recv_from_master


@update
def update_data():
s.pkt2data.payload @= s.recv_from_other.msg.payload
Expand Down
Loading

0 comments on commit a863769

Please sign in to comment.