From f0ee5ea63206677bd87b618ecbcb2e727c765070 Mon Sep 17 00:00:00 2001 From: tancheng Date: Tue, 3 Dec 2024 17:32:24 +0000 Subject: [PATCH] [feature] Simple controller --- controller/ControllerRTL.py | 94 +++++++++++++++++++ controller/__init__.py | 0 controller/test/ControllerRTL_test.py | 127 ++++++++++++++++++++++++++ controller/test/__init__.py | 0 4 files changed, 221 insertions(+) create mode 100644 controller/ControllerRTL.py create mode 100644 controller/__init__.py create mode 100644 controller/test/ControllerRTL_test.py create mode 100644 controller/test/__init__.py diff --git a/controller/ControllerRTL.py b/controller/ControllerRTL.py new file mode 100644 index 0000000..2412a9a --- /dev/null +++ b/controller/ControllerRTL.py @@ -0,0 +1,94 @@ +""" +========================================================================== +ControllerRTL.py +========================================================================== +Simple controller for CGRA. + +Author : Cheng Tan + Date : Dec 2, 2024 +""" + + +from pymtl3 import * +from pymtl3.stdlib.primitive import RegisterFile +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 * + + +class ControllerRTL(Component): + + def construct(s, RingPktType, CGRADataType, CGRAAddrType): + + # # Constant + + # AddrType = mk_bits( clog2( data_mem_size ) ) + + # Interface + + # # Read/write Data from local CGRA data memory. + # s.recv_raddr_from_local = RecvIfcRTL(AddrType) + # s.send_rdata_from_local = SendIfcRTL(DataType) + # s.recv_waddr_from_local = RecvIfcRTL(AddrType) + # s.recv_wdata_from_local = RecvIfcRTL(DataType) + + # # Read/write Data to local CGRA data memory. + # s.recv_raddr_to_local = RecvIfcRTL(CGRAAddrType) + # s.send_rdata_to_local = SendIfcRTL(CGRADataType) + # s.recv_waddr_to_local = RecvIfcRTL(CGRAAddrType) + # s.recv_wdata_to_local = RecvIfcRTL(CGRADataType) + + # Request from other CGRA. + s.recv_from_other = ValRdyRecvIfcRTL(RingPktType) + s.send_to_other = ValRdySendIfcRTL(RingPktType) + + # Request from master. + s.recv_from_master = RecvIfcRTL(CGRADataType) + s.send_to_master = SendIfcRTL(CGRADataType) + + + # # TODO: below ifcs should be connected through another NoC within + # # one CGRA, instead of per-tile and performing like a bus. + # # Configuration signals to be written into and read from per-tile + # # control memory. + # s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(s.num_tiles)] + # s.recv_wopt = [RecvIfcRTL(CtrlType) for _ in range(s.num_tiles)] + + # s.send_waddr = [SendIfcRTL(AddrType) for _ in range(s.num_tiles)] + # s.send_wopt = [SendIfcRTL(CtrlType) for _ in range(s.num_tiles)] + + # # Cmd to invoke/terminate tiles execution. + # s.recv_cmd = [RecvIfcRTL(b2) for _ in range(s.num_tiles)] + # s.send_cmd = [SendIfcRTL(b2) for _ in range(s.num_tiles)] + + + s.pkt2data = Wire(CGRADataType) + s.data2pkt = Wire(RingPktType) + + @update + def update_data(): + s.pkt2data.payload @= s.recv_from_other.msg.payload + s.data2pkt.payload @= s.recv_from_master.msg.payload + + + # Can also be @update instead of @update_ff + # @update + @update_ff + def update_controller(): + s.recv_from_other.rdy <<= s.send_to_master.rdy + s.send_to_master.en <<= s.recv_from_other.val & s.send_to_master.rdy + s.send_to_master.msg <<= s.pkt2data + + s.recv_from_master.rdy <<= s.send_to_other.rdy + s.send_to_other.val <<= s.recv_from_master.en + s.send_to_other.msg <<= s.data2pkt + + + def line_trace(s): + recv_from_master_str = "recv_from_master: " + str(s.recv_from_master.msg) + send_to_master_str = "send_to_master: " + str(s.send_to_master.msg) + recv_from_other_str = "recv_from_other: " + str(s.recv_from_other.msg) + send_to_other_str = "send_to_other: " + str(s.send_to_other.msg) + return f'{recv_from_master_str} || {send_to_master_str} || {recv_from_other_str} || {send_to_other_str}' + diff --git a/controller/__init__.py b/controller/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/controller/test/ControllerRTL_test.py b/controller/test/ControllerRTL_test.py new file mode 100644 index 0000000..b1324bf --- /dev/null +++ b/controller/test/ControllerRTL_test.py @@ -0,0 +1,127 @@ +''' +========================================================================= +ChannelRTL_test.py +========================================================================= +Simple test for Channel. + +Author : Cheng Tan + Date : Dec 2, 2024 +''' + + +from pymtl3 import * +from pymtl3.stdlib.test_utils import TestVectorSimulator +from ..ControllerRTL import ControllerRTL +from ...lib.basic.en_rdy.test_sinks import TestSinkRTL +from ...lib.basic.en_rdy.test_srcs import TestSrcRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestValRdySrcRTL +from ...lib.basic.val_rdy.ifcs import SendIfcRTL as ValRdySendIfcRTL +from ...lib.basic.val_rdy.ifcs import RecvIfcRTL as ValRdyRecvIfcRTL +from ...lib.messages import * +from ...noc.PyOCN.pymtl3_net.ocnlib.test.stream_sinks import NetSinkRTL as TestNetSinkRTL +import pytest + + +#------------------------------------------------------------------------- +# TestHarness +#------------------------------------------------------------------------- + +class TestHarness(Component): + + def construct(s, MsgType, PktType, AddrType, src_msgs, sink_msgs, src_pkts, sink_pkts): + + cmp_fn = lambda a, b : a.payload == b.payload + s.src_en_rdy = TestSrcRTL(MsgType, src_msgs) + s.sink_en_rdy = TestSinkRTL(MsgType, sink_msgs) + s.src_val_rdy = TestValRdySrcRTL(PktType, src_pkts) + s.sink_val_rdy = TestNetSinkRTL(PktType, sink_pkts, cmp_fn = cmp_fn) + + s.dut = ControllerRTL(PktType, MsgType, AddrType) + + # Connections + s.src_en_rdy.send //= s.dut.recv_from_master + s.dut.send_to_master //= s.sink_en_rdy.recv + s.src_val_rdy.send //= s.dut.recv_from_other + s.dut.send_to_other //= s.sink_val_rdy.recv + + def done(s): + return s.src_en_rdy.done() and s.sink_en_rdy.done() and \ + s.src_val_rdy.done() and s.sink_val_rdy.done() + + def line_trace( s ): + return s.dut.line_trace() + # return s.src.line_trace() + "-> | " + s.dut.line_trace() + # return s.src.line_trace() + "-> | " + s.dut.line_trace() + \ + # " | -> " + s.sink.line_trace() + +#------------------------------------------------------------------------- +# run_rtl_sim +#------------------------------------------------------------------------- + +def run_sim(test_harness, max_cycles=20): + + # Create a simulator + test_harness.elaborate() + test_harness.apply( DefaultPassGroup() ) + test_harness.sim_reset() + + # Run simulation + ncycles = 0 + print() + print( "{}:{}".format( ncycles, test_harness.line_trace() )) + while not test_harness.done() and ncycles < max_cycles: + test_harness.sim_tick() + ncycles += 1 + print( "{}:{}".format( ncycles, test_harness.line_trace() )) + + # Check timeout + assert ncycles < max_cycles + + test_harness.sim_tick() + test_harness.sim_tick() + test_harness.sim_tick() + +#------------------------------------------------------------------------- +# Test cases +#------------------------------------------------------------------------- + +def mk_src_pkts( nterminals, lst ): + src_pkts = [ [] for _ in range( nterminals ) ] + src = 0 + for pkt in lst: + if hasattr(pkt, 'fl_type'): + if pkt.fl_type == 0: + src = pkt.src + else: + src = pkt.src + src_pkts[ src ].append( pkt ) + return src_pkts + +DataType = mk_data(32, 1) +test_msgs = [DataType(7, 1, 1), DataType(2, 1), DataType(3, 1)] +sink_msgs = [DataType(0xdeadbeef, 0), DataType(0xbeefdead, 0), DataType(0xdeedbeed, 0)] + +nterminals = 4 +Pkt = mk_ring_multi_cgra_pkt(nterminals, payload_nbits = 32, + predicate_nbits = 1) +src_pkts = [ + # src dst opq vc payload predicate + Pkt(0, 0, 0, 0, 0xdeadbeef, 0), + Pkt(0, 0, 0, 0, 0xbeefdead, 0), + Pkt(0, 0, 0, 0, 0xdeedbeed, 0), +] + +sink_pkts = [ + # src dst opq vc payload predicate + Pkt(0, 0, 0, 0, 7, 0), + Pkt(0, 0, 0, 0, 2, 0), + Pkt(0, 0, 0, 0, 3, 0), +] + +ctrl_mem_size = 4 +AddrType = mk_bits(clog2(ctrl_mem_size)) + +def test_simple(): + th = TestHarness(DataType, Pkt, AddrType, test_msgs, sink_msgs, src_pkts, sink_pkts) + run_sim(th) + diff --git a/controller/test/__init__.py b/controller/test/__init__.py new file mode 100644 index 0000000..e69de29