From 37474876a4d59d399cae2ce6f25c76801cd2aa8b Mon Sep 17 00:00:00 2001 From: tancheng Date: Tue, 31 Dec 2024 04:39:13 +0000 Subject: [PATCH 01/10] [refactor] Replace en/rdy with val/rdy --- cgra/CGRAKingMeshRTL.py | 2 +- cgra/CgraCrossbarDataMemRingCtrlMemRTL.py | 155 +++---- cgra/CgraTemplateRTL.py | 151 +++++++ cgra/test/CGRA_custom_test.py | 190 --------- .../CgraCrossbarDataMemRingCtrlMemRTL_test.py | 202 +++++---- cgra/test/CgraTemplateRTL_test.py | 398 ++++++++++++++++++ cgra/test/VectorCGRAKingMeshRTL_test.py | 130 ------ cgra/translate/CgraTemplateRTL_test.py | 398 ++++++++++++++++++ controller/ControllerRTL.py | 37 +- controller/test/ControllerRTL_test.py | 32 +- fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py | 149 ++++--- .../test/ALUgenMACFU_test.py | 21 +- fu/basic/Fu.py | 81 ++-- fu/basic/ReduceMulUnit.py | 2 - fu/basic/SumUnit.py | 2 - fu/basic/ThreeCombo.py | 135 +++--- fu/basic/TwoPrlCombo.py | 72 ++-- fu/basic/TwoSeqCombo.py | 113 ++--- fu/double/PrlMulAdderRTL.py | 24 +- fu/double/SeqMulAdderRTL.py | 17 +- fu/double/SeqMulShifterRTL.py | 16 +- fu/double/test/TwoPrlComboRTL_test.py | 32 +- fu/double/test/TwoSeqComboRTL_test.py | 15 +- fu/flexible/FlexibleFuRTL.py | 115 ++--- fu/flexible/FuFL.py | 7 +- .../test/FlexibleFuRTL_hypothesis_test.py | 22 +- fu/flexible/test/FlexibleFuRTL_test.py | 140 +++--- fu/float/FpAddRTL.py | 153 ++++--- fu/float/FpMulRTL.py | 111 ++--- fu/float/test/FpAddRTL_test.py | 9 +- fu/float/test/FpMulRTL_test.py | 11 +- fu/single/AdderCL.py | 164 +++++--- fu/single/AdderRTL.py | 167 +++++--- fu/single/BranchRTL.py | 144 ++++--- fu/single/CompRTL.py | 168 ++++---- fu/single/LogicRTL.py | 144 ++++--- fu/single/MemUnitRTL.py | 303 ++++++------- fu/single/MulRTL.py | 128 +++--- fu/single/NahRTL.py | 46 ++ fu/single/PhiRTL.py | 198 +++++---- fu/single/RetRTL.py | 96 ++--- fu/single/SelRTL.py | 187 ++++---- fu/single/ShifterRTL.py | 127 +++--- fu/single/test/AdderCL_test.py | 121 +++--- fu/single/test/AdderRTL_test.py | 117 ++--- fu/single/test/AluRTL_test.py | 227 +++++----- fu/single/test/BranchRTL_test.py | 128 +++--- fu/single/test/CompRTL_test.py | 92 ++-- fu/single/test/MemRTL_test.py | 137 ------ fu/single/test/MemUnitRTL_test.py | 136 ++++++ fu/single/test/MulRTL_test.py | 135 +++--- fu/single/test/PhiRTL_test.py | 143 +++---- fu/single/test/RetRTL_test.py | 94 ++--- fu/single/test/SelRTL_test.py | 113 +++-- fu/triple/ThreeMulAdderShifterRTL.py | 38 +- fu/triple/test/ThreeMulAluShifterRTL_test.py | 49 +-- fu/vector/VectorAdderComboRTL.py | 90 ++-- fu/vector/VectorAdderRTL.py | 148 ++++--- fu/vector/VectorAllReduceRTL.py | 56 ++- fu/vector/VectorMulComboRTL.py | 113 +++-- fu/vector/VectorMulRTL.py | 114 ++--- fu/vector/test/VectorAdderComboRTL_test.py | 57 ++- fu/vector/test/VectorAdderRTL_test.py | 33 +- fu/vector/test/VectorAllReduceRTL_test.py | 61 ++- fu/vector/test/VectorMulComboRTL_test.py | 59 ++- fu/vector/test/VectorMulRTL_test.py | 25 +- mem/const/ConstQueueRTL.py | 45 +- mem/const/test/ConstQueueRTL_test.py | 78 ++-- mem/ctrl/CtrlMemCL.py | 54 ++- mem/ctrl/CtrlMemDynamicRTL.py | 15 +- mem/ctrl/CtrlMemRTL.py | 11 +- mem/ctrl/RingMultiCtrlMemDynamicRTL.py | 6 +- mem/ctrl/test/CtrlCL_test.py | 134 ------ mem/ctrl/test/CtrlMemCL_test.py | 130 ++++++ mem/ctrl/test/CtrlMemDynamicRTL_test.py | 40 +- ...rCL_test.py => CtrlMemRTL_AdderCL_test.py} | 9 +- .../{CtrlRTL_test.py => CtrlMemRTL_test.py} | 9 +- mem/ctrl/test/RingCtrlMemDynamicRTL_test.py | 7 +- mem/data/DataMemCL.py | 60 ++- mem/data/DataMemRTL.py | 69 ++- mem/data/DataMemScalableRTL.py | 39 +- mem/data/DataMemWithCrossbarRTL.py | 69 +-- mem/data/test/DataMemCL_test.py | 59 ++- mem/data/test/DataMemRTL_test.py | 62 ++- mem/data/test/DataMemScalableRTL_test.py | 13 +- mem/data/test/DataMemWithCrossbarRTL_test.py | 39 +- noc/ChannelNormalRTL.py | 58 +-- noc/CrossbarRTL.py | 29 +- noc/CrossbarSeparateRTL.py | 146 +++---- noc/LinkOrRTL.py | 39 +- noc/test/ChannelNormalRTL_test.py | 55 +-- noc/test/CrossbarRTL_test.py | 9 +- noc/test/LinkOrRTL_test.py | 63 +-- rf/RegFile.py | 6 +- rf/RegisterRTL.py | 50 +-- rf/test/RegFile_test.py | 10 +- rf/test/RegisterRTL_test.py | 43 +- tile/TileCL.py | 36 +- tile/TileSeparateCrossbarRTL.py | 77 ++-- tile/test/TileSeparateCrossbarRTL_test.py | 11 +- 100 files changed, 4680 insertions(+), 4000 deletions(-) create mode 100644 cgra/CgraTemplateRTL.py delete mode 100644 cgra/test/CGRA_custom_test.py create mode 100644 cgra/test/CgraTemplateRTL_test.py delete mode 100644 cgra/test/VectorCGRAKingMeshRTL_test.py create mode 100644 cgra/translate/CgraTemplateRTL_test.py create mode 100644 fu/single/NahRTL.py delete mode 100644 fu/single/test/MemRTL_test.py create mode 100644 fu/single/test/MemUnitRTL_test.py delete mode 100644 mem/ctrl/test/CtrlCL_test.py create mode 100644 mem/ctrl/test/CtrlMemCL_test.py rename mem/ctrl/test/{CtrlRTL_AdderCL_test.py => CtrlMemRTL_AdderCL_test.py} (95%) rename mem/ctrl/test/{CtrlRTL_test.py => CtrlMemRTL_test.py} (95%) diff --git a/cgra/CGRAKingMeshRTL.py b/cgra/CGRAKingMeshRTL.py index e9e37b0..bbe4bfb 100644 --- a/cgra/CGRAKingMeshRTL.py +++ b/cgra/CGRAKingMeshRTL.py @@ -27,8 +27,8 @@ def construct( s, DataType, PredicateType, CtrlType, width, height, FunctionUnit, FuList, preload_data = None, preload_const = None ): - s.num_tiles = width * height s.num_mesh_ports = 8 + s.num_tiles = width * height AddrType = mk_bits( clog2( ctrl_mem_size ) ) # Interfaces diff --git a/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py b/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py index ab7df25..7d390ba 100644 --- a/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py +++ b/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py @@ -13,9 +13,8 @@ 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 ValRdySendIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL from ..noc.ChannelNormalRTL import ChannelNormalRTL @@ -25,54 +24,55 @@ from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL class CgraCrossbarDataMemRingCtrlMemRTL(Component): + def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, ControllerIdType, controller_id, width, height, ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, num_banks_per_cgra, num_ctrl, - total_steps, FunctionUnit, FuList, controller2addr_map, - preload_data = None, preload_const = None): + total_steps, FunctionUnit, FuList, topology, + controller2addr_map, preload_data = None, + preload_const = None): + + # Other topology can simply modify the tiles connections, or + # leverage the template for modeling. + assert(topology == "Mesh" or topology == "KingMesh") + s.num_mesh_ports = 4 + if topology == "Mesh": + s.num_mesh_ports = 4 + elif topology == "KingMesh": + s.num_mesh_ports = 8 s.num_tiles = width * height CtrlRingPos = mk_ring_pos(s.num_tiles) - s.num_mesh_ports = 4 CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) DataAddrType = mk_bits(clog2(data_mem_size_global)) assert(data_mem_size_per_bank * num_banks_per_cgra <= \ data_mem_size_global) # Interfaces - # s.recv_waddr = [RecvIfcRTL(CtrlAddrType) for _ in range(s.num_tiles)] - # s.recv_wopt = [RecvIfcRTL(CtrlSignalType) for _ in range(s.num_tiles)] - s.recv_from_cpu_ctrl_pkt = ValRdyRecvIfcRTL(CtrlPktType) - - # Explicitly provides the ValRdyRecvIfcRTL in the library, as the - # translation pass sometimes not able to distinguish the - # EnRdyRecvIfcRTL from it. - s.recv_from_noc = ValRdyRecvIfcRTL(NocPktType) - s.send_to_noc = ValRdySendIfcRTL(NocPktType) + s.recv_from_cpu_ctrl_pkt = RecvIfcRTL(CtrlPktType) + s.recv_from_noc = RecvIfcRTL(NocPktType) + s.send_to_noc = SendIfcRTL(NocPktType) # Interfaces on the boundary of the CGRA. - s.recv_data_on_boundary_south = [RecvIfcRTL(DataType) for _ in range(width)] - s.send_data_on_boundary_south = [SendIfcRTL(DataType) for _ in range(width)] - s.recv_data_on_boundary_north = [RecvIfcRTL(DataType) for _ in range(width)] - s.send_data_on_boundary_north = [SendIfcRTL(DataType) for _ in range(width)] - - s.recv_data_on_boundary_east = [RecvIfcRTL(DataType) for _ in range(height)] - s.send_data_on_boundary_east = [SendIfcRTL(DataType) for _ in range(height)] - s.recv_data_on_boundary_west = [RecvIfcRTL(DataType) for _ in range(height)] - s.send_data_on_boundary_west = [SendIfcRTL(DataType) for _ in range(height)] + s.recv_data_on_boundary_south = [RecvIfcRTL(DataType) for _ in range(width )] + s.send_data_on_boundary_south = [SendIfcRTL(DataType) for _ in range(width )] + s.recv_data_on_boundary_north = [RecvIfcRTL(DataType) for _ in range(width )] + s.send_data_on_boundary_north = [SendIfcRTL(DataType) for _ in range(width )] - # s.recv_towards_controller = RecvIfcRTL(DataType) - # s.send_from_controller = SendIfcRTL(DataType) + s.recv_data_on_boundary_east = [RecvIfcRTL(DataType) for _ in range(height)] + s.send_data_on_boundary_east = [SendIfcRTL(DataType) for _ in range(height)] + s.recv_data_on_boundary_west = [RecvIfcRTL(DataType) for _ in range(height)] + s.send_data_on_boundary_west = [SendIfcRTL(DataType) for _ in range(height)] # Components if preload_const == None: - preload_const = [[DataType(0, 0)] for _ in range(width*height)] + preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] s.tile = [TileSeparateCrossbarRTL( DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, data_mem_size_global, 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)] + const_list = preload_const[i]) for i in range(s.num_tiles)] s.data_mem = DataMemWithCrossbarRTL(NocPktType, DataType, data_mem_size_global, data_mem_size_per_bank, @@ -86,16 +86,10 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # 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 - - # The last `recv_raddr` is reserved to connect the controller. s.data_mem.recv_raddr[height] //= s.controller.send_to_master_load_request_addr s.data_mem.recv_waddr[height] //= s.controller.send_to_master_store_request_addr s.data_mem.recv_wdata[height] //= s.controller.send_to_master_store_request_data - # Reserved ... s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data - # Reserved ... s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt @@ -106,9 +100,6 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Connects the ctrl interface between CPU and controller. s.recv_from_cpu_ctrl_pkt //= s.controller.recv_from_cpu_ctrl_pkt - # s.recv_towards_controller //= s.controller.recv_from_master - # s.send_from_controller //= s.controller.send_to_master - # Connects ring with each control memory. for i in range(s.num_tiles): s.ctrl_ring.send[i] //= s.tile[i].recv_ctrl_pkt @@ -119,8 +110,6 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.ctrl_ring.recv[i].msg //= CtrlPktType() 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] @@ -134,6 +123,52 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, if i % width < width - 1: s.tile[i].send_data[PORT_EAST] //= s.tile[i+1].recv_data[PORT_WEST] + if topology == "KingMesh": + if i % width > 0 and i // width < height - 1: + s.tile[i].send_data[PORT_NORTHWEST] //= s.tile[i+width-1].recv_data[PORT_SOUTHEAST] + s.tile[i+width-1].send_data[PORT_SOUTHEAST] //= s.tile[i].recv_data[PORT_NORTHWEST] + + if i % width < width - 1 and i // width < height - 1: + s.tile[i].send_data[PORT_NORTHEAST] //= s.tile[i+width+1].recv_data[PORT_SOUTHWEST] + s.tile[i+width+1].send_data[PORT_SOUTHWEST] //= s.tile[i].recv_data[PORT_NORTHEAST] + + if i // width == 0: + s.tile[i].send_data[PORT_SOUTHWEST].rdy //= 0 + s.tile[i].recv_data[PORT_SOUTHWEST].val //= 0 + s.tile[i].recv_data[PORT_SOUTHWEST].msg //= DataType( 0, 0 ) + s.tile[i].send_data[PORT_SOUTHEAST].rdy //= 0 + s.tile[i].recv_data[PORT_SOUTHEAST].val //= 0 + s.tile[i].recv_data[PORT_SOUTHEAST].msg //= DataType( 0, 0 ) + + if i // width == height - 1: + s.tile[i].send_data[PORT_NORTHWEST].rdy //= 0 + s.tile[i].recv_data[PORT_NORTHWEST].val //= 0 + s.tile[i].recv_data[PORT_NORTHWEST].msg //= DataType( 0, 0 ) + s.tile[i].send_data[PORT_NORTHEAST].rdy //= 0 + s.tile[i].recv_data[PORT_NORTHEAST].val //= 0 + s.tile[i].recv_data[PORT_NORTHEAST].msg //= DataType( 0, 0 ) + + if i % width == 0 and i // width > 0: + s.tile[i].send_data[PORT_SOUTHWEST].rdy //= 0 + s.tile[i].recv_data[PORT_SOUTHWEST].val //= 0 + s.tile[i].recv_data[PORT_SOUTHWEST].msg //= DataType( 0, 0 ) + + if i % width == 0 and i // width < height - 1: + s.tile[i].send_data[PORT_NORTHWEST].rdy //= 0 + s.tile[i].recv_data[PORT_NORTHWEST].val //= 0 + s.tile[i].recv_data[PORT_NORTHWEST].msg //= DataType( 0, 0 ) + + if i % width == width - 1 and i // width > 0: + s.tile[i].send_data[PORT_SOUTHEAST].rdy //= 0 + s.tile[i].recv_data[PORT_SOUTHEAST].val //= 0 + s.tile[i].recv_data[PORT_SOUTHEAST].msg //= DataType( 0, 0 ) + + if i % width == width - 1 and i // width < height - 1: + s.tile[i].send_data[PORT_NORTHEAST].rdy //= 0 + s.tile[i].recv_data[PORT_NORTHEAST].val //= 0 + s.tile[i].recv_data[PORT_NORTHEAST].msg //= DataType( 0, 0 ) + + if i // width == 0: s.tile[i].send_data[PORT_SOUTH] //= s.send_data_on_boundary_south[i % width] s.tile[i].recv_data[PORT_SOUTH] //= s.recv_data_on_boundary_south[i % width] @@ -150,44 +185,22 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.tile[i].send_data[PORT_EAST] //= s.send_data_on_boundary_east[i // width] s.tile[i].recv_data[PORT_EAST] //= s.recv_data_on_boundary_east[i // width] - # 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].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] + 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].to_mem_raddr.rdy //= 0 + s.tile[i].from_mem_rdata.val //= 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 + 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) ]) + def line_trace(s): + 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 diff --git a/cgra/CgraTemplateRTL.py b/cgra/CgraTemplateRTL.py new file mode 100644 index 0000000..cca1f94 --- /dev/null +++ b/cgra/CgraTemplateRTL.py @@ -0,0 +1,151 @@ +""" +========================================================================= +CgraTemplateRTL.py +========================================================================= + +Author : Cheng Tan + Date : Dec 30, 2024 +""" + +from pymtl3 import * +from ..controller.ControllerRTL import ControllerRTL +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.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ..lib.opt_type import * +from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL +from ..noc.ChannelNormalRTL import ChannelNormalRTL +from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL +from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos +from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL +from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL + +class CgraTemplateRTL(Component): + + def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, + NocPktType, CmdType, ControllerIdType, controller_id, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, num_ctrl, + total_steps, FunctionUnit, FuList, TileList, LinkList, + dataSPM, controller2addr_map, preload_data = None, + preload_const = None): + + s.num_mesh_ports = 8 + s.num_tiles = len(TileList) + CtrlRingPos = mk_ring_pos(s.num_tiles) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + DataAddrType = mk_bits(clog2(data_mem_size_global)) + assert(data_mem_size_per_bank * num_banks_per_cgra <= \ + data_mem_size_global) + + # Interfaces + s.recv_from_cpu_ctrl_pkt = RecvIfcRTL(CtrlPktType) + s.recv_from_noc = RecvIfcRTL(NocPktType) + s.send_to_noc = SendIfcRTL(NocPktType) + + # FIXME: Think about how to handle the boundary for the case of + # multi-cgra modeling. + # # Interfaces on the boundary of the CGRA. + # s.recv_data_on_boundary_south = [RecvIfcRTL(DataType) for _ in range(width )] + # s.send_data_on_boundary_south = [SendIfcRTL(DataType) for _ in range(width )] + # s.recv_data_on_boundary_north = [RecvIfcRTL(DataType) for _ in range(width )] + # s.send_data_on_boundary_north = [SendIfcRTL(DataType) for _ in range(width )] + + # s.recv_data_on_boundary_east = [RecvIfcRTL(DataType) for _ in range(height)] + # s.send_data_on_boundary_east = [SendIfcRTL(DataType) for _ in range(height)] + # s.recv_data_on_boundary_west = [RecvIfcRTL(DataType) for _ in range(height)] + # s.send_data_on_boundary_west = [SendIfcRTL(DataType) for _ in range(height)] + + # Components + if preload_const == None: + preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] + s.tile = [TileSeparateCrossbarRTL( + DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, + data_mem_size_global, 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)] + # FIXME: Need to enrish data-SPM-related user-controlled parameters, e.g., number of banks. + s.data_mem = DataMemWithCrossbarRTL(NocPktType, DataType, + data_mem_size_global, + data_mem_size_per_bank, + num_banks_per_cgra, + dataSPM.getNumOfValidReadPorts(), + dataSPM.getNumOfValidWritePorts(), + preload_data) + s.controller = ControllerRTL(ControllerIdType, CmdType, CtrlPktType, + NocPktType, DataType, DataAddrType, + controller_id, controller2addr_map) + s.ctrl_ring = RingNetworkRTL(CtrlPktType, CtrlRingPos, s.num_tiles, 0) + + # Connections + # Connects data memory with controller. + s.data_mem.recv_raddr[dataSPM.getNumOfValidReadPorts()] //= s.controller.send_to_master_load_request_addr + s.data_mem.recv_waddr[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_master_store_request_addr + s.data_mem.recv_wdata[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_master_store_request_data + s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data + s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt + s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt + s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt + + s.recv_from_noc //= s.controller.recv_from_noc + s.send_to_noc //= s.controller.send_to_noc + + # Connects the ctrl interface between CPU and controller. + s.recv_from_cpu_ctrl_pkt //= s.controller.recv_from_cpu_ctrl_pkt + + # Connects ring with each control memory. + for i in range(s.num_tiles): + s.ctrl_ring.send[i] //= s.tile[i].recv_ctrl_pkt + + s.ctrl_ring.recv[0] //= s.controller.send_to_ctrl_ring_ctrl_pkt + for i in range(1, s.num_tiles): + s.ctrl_ring.recv[i].val //= 0 + s.ctrl_ring.recv[i].msg //= CtrlPktType() + + for link in LinkList: + + if link.isFromMem(): + memPort = link.getMemReadPort() + dstTileIndex = link.dstTile.getIndex(TileList) + s.data_mem.recv_raddr[memPort] //= s.tile[dstTileIndex].to_mem_raddr + s.data_mem.send_rdata[memPort] //= s.tile[dstTileIndex].from_mem_rdata + + elif link.isToMem(): + memPort = link.getMemWritePort() + srcTileIndex = link.srcTile.getIndex(TileList) + s.tile[srcTileIndex].to_mem_waddr //= s.data_mem.recv_waddr[memPort] + s.tile[srcTileIndex].to_mem_wdata //= s.data_mem.recv_wdata[memPort] + + else: + srcTileIndex = link.srcTile.getIndex(TileList) + dstTileIndex = link.dstTile.getIndex(TileList) + s.tile[srcTileIndex].send_data[link.srcPort] //= s.tile[dstTileIndex].recv_data[link.dstPort] + + for i in range(s.num_tiles): + + for invalidInPort in TileList[i].getInvalidInPorts(): + s.tile[i].recv_data[invalidInPort].val //= 0 + s.tile[i].recv_data[invalidInPort].msg //= DataType(0, 0) + + for invalidOutPort in TileList[i].getInvalidOutPorts(): + s.tile[i].send_data[invalidOutPort].rdy //= 0 + + if not TileList[i].hasFromMem(): + s.tile[i].to_mem_raddr.rdy //= 0 + s.tile[i].from_mem_rdata.val //= 0 + s.tile[i].from_mem_rdata.msg //= DataType(0, 0) + + if not TileList[i].hasToMem(): + s.tile[i].to_mem_waddr.rdy //= 0 + s.tile[i].to_mem_wdata.rdy //= 0 + + # Line trace + def line_trace(s): + 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 + diff --git a/cgra/test/CGRA_custom_test.py b/cgra/test/CGRA_custom_test.py deleted file mode 100644 index 49c01b3..0000000 --- a/cgra/test/CGRA_custom_test.py +++ /dev/null @@ -1,190 +0,0 @@ -""" -========================================================================== -CGRA_custom_test.py -========================================================================== -FP units' test. - -Author : Cheng Tan & Ron Jokai - Date : Dec 24, 2023 -""" - - -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 ..CGRAKingMeshRTL import CGRAKingMeshRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.opt_type import * -from ...lib.messages import * -from ...fu.ALUgen_fusedALU_fixedp.ALUgenMACFU import ALUgenMACFU -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.float.FpAddRTL import FpAddRTL -from ...fu.pymtl3_hardfloat.HardFloat.AddFNRTL import AddFN -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.ShifterRTL import ShifterRTL - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - - 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 = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, ALUgenMACFU] #FPadd2nd]#, FPmult] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - for _ in range( num_tiles ) ] - ctrl_waddr = [[ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ), AddrType( 3 ), - AddrType( 4 ), AddrType( 5 ) ] for _ in range( num_tiles ) ] - - assert DataType.get_field_type( 'payload' ).nbits == 16 - - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, 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 ) - -def test_hetero_2x2( cmdline_opts ): - num_tile_inports = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - for _ in range( num_tiles ) ] - ctrl_waddr = [[ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ), AddrType( 3 ), - AddrType( 4 ), AddrType( 5 ) ] for _ in range( num_tiles ) ] - - assert DataType.get_field_type( 'payload' ).nbits == 16 - - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr ) - th.set_param("top.dut.tile[1].construct", FuList=[ShifterRTL]) - th.elaborate() - th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - 'ALWCOMBORDER'] ) - #th.set_param("top.dut.tile[1].construct", FuList=[MemUnitRTL,ShifterRTL]) - th = config_model_with_cmdline_opts( th, cmdline_opts, duts=['dut'] ) - run_sim( th ) - diff --git a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py b/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py index 9757073..4ea112e 100644 --- a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py +++ b/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py @@ -9,7 +9,6 @@ Date : Dec 22, 2024 """ - from pymtl3 import * from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) @@ -18,36 +17,41 @@ from ..CgraCrossbarDataMemRingCtrlMemRTL import CgraCrossbarDataMemRingCtrlMemRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ...fu.single.AdderRTL import AdderRTL +from ...fu.single.BranchRTL import BranchRTL +from ...fu.single.CompRTL import CompRTL +from ...fu.single.LogicRTL import LogicRTL from ...fu.single.MemUnitRTL import MemUnitRTL +from ...fu.single.MulRTL import MulRTL +from ...fu.single.PhiRTL import PhiRTL +from ...fu.single.SelRTL import SelRTL from ...fu.single.ShifterRTL import ShifterRTL +from ...fu.vector.VectorMulComboRTL import VectorMulComboRTL +from ...fu.vector.VectorAdderComboRTL import VectorAdderComboRTL from ...lib.messages import * from ...lib.cmd_type import * from ...lib.opt_type import * -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- class TestHarness(Component): - def construct(s, DUT, FunctionUnit, FuList, DataType, - PredicateType, CtrlPktType, CtrlSignalType, NocPktType, - CmdType, ControllerIdType, controller_id, width, height, + def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, width, height, ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, num_banks_per_cgra, - src_ctrl_pkt, ctrl_steps, controller2addr_map): + src_ctrl_pkt, ctrl_steps, topology, controller2addr_map): s.num_tiles = width * height - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - DataAddrType = mk_bits(clog2(data_mem_size_global)) - s.src_ctrl_pkt = ValRdyTestSrcRTL(CtrlPktType, src_ctrl_pkt) + s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, ControllerIdType, controller_id, width, height, ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, num_banks_per_cgra, ctrl_steps, ctrl_steps, FunctionUnit, FuList, - controller2addr_map) + topology, controller2addr_map) # Connections s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt @@ -58,20 +62,20 @@ def construct(s, DUT, FunctionUnit, FuList, DataType, for tile_col in range(width): s.dut.send_data_on_boundary_north[tile_col].rdy //= 0 - s.dut.recv_data_on_boundary_north[tile_col].en //= 0 + s.dut.recv_data_on_boundary_north[tile_col].val //= 0 s.dut.recv_data_on_boundary_north[tile_col].msg //= DataType() s.dut.send_data_on_boundary_south[tile_col].rdy //= 0 - s.dut.recv_data_on_boundary_south[tile_col].en //= 0 + s.dut.recv_data_on_boundary_south[tile_col].val //= 0 s.dut.recv_data_on_boundary_south[tile_col].msg //= DataType() for tile_row in range(height): s.dut.send_data_on_boundary_west[tile_row].rdy //= 0 - s.dut.recv_data_on_boundary_west[tile_row].en //= 0 + s.dut.recv_data_on_boundary_west[tile_row].val //= 0 s.dut.recv_data_on_boundary_west[tile_row].msg //= DataType() s.dut.send_data_on_boundary_east[tile_row].rdy //= 0 - s.dut.recv_data_on_boundary_east[tile_row].en //= 0 + s.dut.recv_data_on_boundary_east[tile_row].val //= 0 s.dut.recv_data_on_boundary_east[tile_row].msg //= DataType() def done(s): @@ -80,9 +84,15 @@ def done(s): def line_trace(s): return s.dut.line_trace() -def test_homo_2x2(cmdline_opts): - num_tile_inports = 4 - num_tile_outports = 4 +def init_param(topology, FuList = [MemUnitRTL, AdderRTL]): + tile_ports = 4 + assert(topology == "Mesh" or topology == "KingMesh") + if topology == "Mesh": + tile_ports = 4 + elif topology == "KingMesh": + tile_ports = 8 + num_tile_inports = tile_ports + num_tile_outports = tile_ports num_fu_inports = 4 num_fu_outports = 2 num_routing_outports = num_tile_outports + num_fu_inports @@ -104,10 +114,9 @@ def test_homo_2x2(cmdline_opts): num_tiles = width * height DUT = CgraCrossbarDataMemRingCtrlMemRTL FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] DataType = mk_data(32, 1) PredicateType = mk_predicate(1, 1) - + CmdType = mk_bits(4) ControllerIdType = mk_bits(clog2(num_terminals)) controller_id = 1 @@ -117,7 +126,7 @@ def test_homo_2x2(cmdline_opts): 2: [8, 11], 3: [12, 15], } - + CtrlPktType = \ mk_ring_across_tiles_pkt(width * height, num_ctrl_actions, @@ -127,79 +136,86 @@ def test_homo_2x2(cmdline_opts): num_fu_outports, num_tile_inports, num_tile_outports) - CtrlSignalType = \ mk_separate_ctrl(num_ctrl_operations, num_fu_inports, num_fu_outports, num_tile_inports, num_tile_outports) - + NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, addr_nbits = addr_nbits, data_nbits = 32, predicate_nbits = 1) - pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)] + pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] + tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] + fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] src_opt_per_tile = [[ # src dst vc_id opq cmd_type addr operation predicate CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, 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)]), + pick_register, tile_in_code, fu_out_code), + # [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)]), CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, 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)]), - + pick_register, tile_in_code, fu_out_code), + # 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)]), + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 2, 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)]), - + pick_register, tile_in_code, fu_out_code), + # 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)]), + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 3, 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)]), - + pick_register, tile_in_code, fu_out_code), + # 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)]), + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 4, 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)]), - + pick_register, tile_in_code, fu_out_code), + # 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)]), + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 5, 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)]), - + pick_register, tile_in_code, fu_out_code), + # 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)]), + # This last one is for launching kernel. CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, 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)]) + pick_register, tile_in_code, fu_out_code) + # 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 i in range(num_tiles)] - + src_ctrl_pkt = [] for opt_per_tile in src_opt_per_tile: src_ctrl_pkt.extend(opt_per_tile) @@ -209,7 +225,45 @@ def test_homo_2x2(cmdline_opts): ControllerIdType, controller_id, width, height, ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, num_banks_per_cgra, - src_ctrl_pkt, ctrl_mem_size, controller2addr_map) + src_ctrl_pkt, ctrl_mem_size, topology, + controller2addr_map) + return th + +def test_homogeneous_2x2(cmdline_opts): + topology = "Mesh" + th = init_param(topology) + 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) + +def test_heterogeneous_king_mesh_2x2(cmdline_opts): + topology = "KingMesh" + th = init_param(topology) + th.set_param("top.dut.tile[1].construct", FuList=[ShifterRTL]) + 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) + +def test_vector_king_mesh_2x2(cmdline_opts): + topology = "KingMesh" + FuList = [AdderRTL, + MulRTL, + LogicRTL, + ShifterRTL, + PhiRTL, + CompRTL, + BranchRTL, + MemUnitRTL, + SelRTL, + VectorMulComboRTL, + VectorAdderComboRTL] + th = init_param(topology, FuList) th.elaborate() th.dut.set_metadata(VerilogVerilatorImportPass.vl_Wno_list, ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', diff --git a/cgra/test/CgraTemplateRTL_test.py b/cgra/test/CgraTemplateRTL_test.py new file mode 100644 index 0000000..c18d3c7 --- /dev/null +++ b/cgra/test/CgraTemplateRTL_test.py @@ -0,0 +1,398 @@ +""" +========================================================================== +CgraTemplateRTL_test.py +========================================================================== +Translation for parameterizable CGRA based on the template. + +Author : Cheng Tan + Date : Dec 23, 2022 + +""" + +from pymtl3 import * +from pymtl3.passes.backends.verilog import (VerilogTranslationPass, + VerilogVerilatorImportPass) +from pymtl3.stdlib.test_utils import (run_sim, + config_model_with_cmdline_opts) +from ..CgraTemplateRTL import CgraTemplateRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ...lib.messages import * +from ...lib.cmd_type import * +from ...lib.opt_type import * +from ...lib.util.common import * +from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL +from ...fu.single.AdderRTL import AdderRTL +from ...fu.single.BranchRTL import BranchRTL +from ...fu.single.CompRTL import CompRTL +from ...fu.single.LogicRTL import LogicRTL +from ...fu.single.MemUnitRTL import MemUnitRTL +from ...fu.single.MulRTL import MulRTL +from ...fu.single.PhiRTL import PhiRTL +from ...fu.single.RetRTL import RetRTL +from ...fu.single.SelRTL import SelRTL +from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL +from ...fu.single.ShifterRTL import ShifterRTL + +fuType2RTL = {} +fuType2RTL["Phi" ] = PhiRTL +fuType2RTL["Add" ] = AdderRTL +fuType2RTL["Shift"] = ShifterRTL +fuType2RTL["Ld" ] = MemUnitRTL +fuType2RTL["St" ] = MemUnitRTL +fuType2RTL["Sel" ] = SelRTL +fuType2RTL["Cmp" ] = CompRTL +fuType2RTL["MAC" ] = SeqMulAdderRTL +fuType2RTL["Ret" ] = RetRTL +fuType2RTL["Mul" ] = MulRTL +fuType2RTL["Logic"] = LogicRTL +fuType2RTL["Br" ] = BranchRTL + +#------------------------------------------------------------------------- +# Test harness +#------------------------------------------------------------------------- + +class TestHarness(Component): + + def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, ctrl_mem_size, + data_mem_size_global, data_mem_size_per_bank, + num_banks_per_cgra, src_ctrl_pkt, ctrl_steps, TileList, + LinkList, dataSPM, controller2addr_map): + + s.num_tiles = len(TileList) + s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) + + s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, + NocPktType, CmdType, ControllerIdType, controller_id, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + ctrl_steps, ctrl_steps, FunctionUnit, FuList, + TileList, LinkList, dataSPM, controller2addr_map) + + # Connections + s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt + + s.dut.send_to_noc.rdy //= 0 + s.dut.recv_from_noc.val //= 0 + s.dut.recv_from_noc.msg //= NocPktType(0, 0, 0, 0, 0, 0) + + def done(s): + return s.src_ctrl_pkt.done() + + def line_trace(s): + return s.dut.line_trace() + +class Tile: + def __init__(s, dimX, dimY): + s.disabled = False + s.dimX = dimX + s.dimY = dimY + s.toMem = False + s.fromMem = False + s.invalidOutPorts = set() + s.invalidInPorts = set() + for i in range(PORT_DIRECTION_COUNTS): + s.invalidOutPorts.add(i) + s.invalidInPorts.add(i) + + def getInvalidInPorts(s): + return s.invalidInPorts + + def getInvalidOutPorts(s): + return s.invalidOutPorts + + def hasToMem(s): + return s.toMem + + def hasFromMem(s): + return s.fromMem + + def getIndex(s, TileList): + if s.disabled: + return -1 + index = 0 + for tile in TileList: + if tile.dimY < s.dimY and not tile.disabled: + index += 1 + elif tile.dimY == s.dimY and tile.dimX < s.dimX and not tile.disabled: + index += 1 + return index + +class DataSPM: + def __init__(s, numOfReadPorts, numOfWritePorts): + s.numOfReadPorts = numOfReadPorts + s.numOfWritePorts = numOfWritePorts + + def getNumOfValidReadPorts(s): + return s.numOfReadPorts + + def getNumOfValidWritePorts(s): + return s.numOfWritePorts + +class Link: + def __init__(s, srcTile, dstTile, srcPort, dstPort): + s.srcTile = srcTile + s.dstTile = dstTile + s.srcPort = srcPort + s.dstPort = dstPort + s.disabled = False + s.toMem = False + s.fromMem = False + s.memPort = -1 + + def getMemReadPort(s): + return s.memPort + + def getMemWritePort(s): + return s.memPort + + def isToMem(s): + return s.toMem + + def isFromMem(s): + return s.fromMem + + def validatePorts(s): + if not s.toMem and not s.fromMem: + s.srcTile.invalidOutPorts.remove(s.srcPort) + s.dstTile.invalidInPorts.remove(s.dstPort) + if s.toMem: + s.srcTile.toMem = True + if s.fromMem: + s.dstTile.fromMem = True + + +import platform +import pytest + +def test_cgra_universal(cmdline_opts, paramCGRA = None): + num_tile_inports = 8 + num_tile_outports = 8 + num_fu_inports = 4 + num_fu_outports = 2 + num_routing_outports = num_tile_outports + num_fu_inports + ctrl_mem_size = paramCGRA.configMemSize if paramCGRA != None else 6 + width = paramCGRA.rows if paramCGRA != None else 2 + height = paramCGRA.columns if paramCGRA != None else 2 + data_mem_size_global = 512 + data_mem_size_per_bank = 32 + num_banks_per_cgra = 2 + num_terminals = 4 + num_ctrl_actions = 6 + num_ctrl_operations = 64 + TileInType = mk_bits(clog2(num_tile_inports + 1)) + FuInType = mk_bits(clog2(num_fu_inports + 1)) + FuOutType = mk_bits(clog2(num_fu_outports + 1)) + addr_nbits = clog2(data_mem_size_global) + AddrType = mk_bits(addr_nbits) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + num_tiles = width * height + DUT = CgraTemplateRTL + FunctionUnit = FlexibleFuRTL + # FuList = [MemUnitRTL, AdderRTL] + FuList = [PhiRTL, AdderRTL, ShifterRTL, MemUnitRTL, SelRTL, CompRTL, SeqMulAdderRTL, RetRTL, MulRTL, LogicRTL, BranchRTL] + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) + + CmdType = mk_bits(4) + ControllerIdType = mk_bits(clog2(num_terminals)) + controller_id = 1 + controller2addr_map = { + 0: [0, 3], + 1: [4, 7], + 2: [8, 11], + 3: [12, 15], + } + + CtrlPktType = \ + mk_ring_across_tiles_pkt(width * height, + num_ctrl_actions, + ctrl_mem_size, + num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + CtrlSignalType = \ + mk_separate_ctrl(num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + + NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, + addr_nbits = addr_nbits, + data_nbits = 32, + predicate_nbits = 1) + pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] + tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] + fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] + src_opt_per_tile = [[ + # src dst vc_id opq cmd_type addr operation predicate + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, OPT_INC, b1(0), + pick_register, tile_in_code, fu_out_code), + # This last one is for launching kernel. + CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), + pick_register, tile_in_code, fu_out_code) + ] for i in range(num_tiles)] + + src_ctrl_pkt = [] + for opt_per_tile in src_opt_per_tile: + src_ctrl_pkt.extend(opt_per_tile) + + dataSPM = None + tiles = [] + links = None + if paramCGRA != None: + tiles = paramCGRA.getValidTiles() + links = paramCGRA.getValidLinks() + dataSPM = paramCGRA.dataSPM + else: + dataSPM = DataSPM(2, 2) + for r in range(2): + tiles.append([]) + for c in range(2): + tiles[r].append(Tile(c, r)) + + links = [Link(None, None, 0, 0) for _ in range(16)] + + links[0].srcTile = None + links[0].dstTile = tiles[0][0] + links[0].srcPort = 0 + links[0].dstPort = PORT_WEST + links[0].fromMem = True + links[0].memPort = 0 + links[0].validatePorts() + + links[1].srcTile = tiles[0][0] + links[1].dstTile = None + links[1].srcPort = PORT_WEST + links[1].dstPort = 0 + links[1].toMem = True + links[1].memPort = 0 + links[1].validatePorts() + + links[2].srcTile = None + links[2].dstTile = tiles[1][0] + links[2].srcPort = 1 + links[2].dstPort = PORT_WEST + links[2].fromMem = True + links[2].memPort = 1 + links[2].validatePorts() + + links[3].srcTile = tiles[1][0] + links[3].dstTile = None + links[3].srcPort = PORT_WEST + links[3].dstPort = 1 + links[3].toMem = True + links[3].memPort = 1 + links[3].validatePorts() + + links[4].srcTile = tiles[0][0] + links[4].dstTile = tiles[0][1] + links[4].srcPort = PORT_EAST + links[4].dstPort = PORT_WEST + links[4].validatePorts() + + links[5].srcTile = tiles[0][1] + links[5].dstTile = tiles[0][0] + links[5].srcPort = PORT_WEST + links[5].dstPort = PORT_EAST + links[5].validatePorts() + + links[6].srcTile = tiles[1][0] + links[6].dstTile = tiles[1][1] + links[6].srcPort = PORT_EAST + links[6].dstPort = PORT_WEST + links[6].validatePorts() + + links[7].srcTile = tiles[1][1] + links[7].dstTile = tiles[1][0] + links[7].srcPort = PORT_WEST + links[7].dstPort = PORT_EAST + links[7].validatePorts() + + links[8].srcTile = tiles[0][0] + links[8].dstTile = tiles[1][0] + links[8].srcPort = PORT_NORTH + links[8].dstPort = PORT_SOUTH + links[8].validatePorts() + + links[9].srcTile = tiles[1][0] + links[9].dstTile = tiles[0][0] + links[9].srcPort = PORT_SOUTH + links[9].dstPort = PORT_NORTH + links[9].validatePorts() + + links[10].srcTile = tiles[0][1] + links[10].dstTile = tiles[1][1] + links[10].srcPort = PORT_NORTH + links[10].dstPort = PORT_SOUTH + links[10].validatePorts() + + links[11].srcTile = tiles[1][1] + links[11].dstTile = tiles[0][1] + links[11].srcPort = PORT_SOUTH + links[11].dstPort = PORT_NORTH + links[11].validatePorts() + + links[12].srcTile = tiles[0][0] + links[12].dstTile = tiles[1][1] + links[12].srcPort = PORT_NORTHEAST + links[12].dstPort = PORT_SOUTHWEST + links[12].validatePorts() + + links[13].srcTile = tiles[1][1] + links[13].dstTile = tiles[0][0] + links[13].srcPort = PORT_SOUTHWEST + links[13].dstPort = PORT_NORTHEAST + links[13].validatePorts() + + links[14].srcTile = tiles[0][1] + links[14].dstTile = tiles[1][0] + links[14].srcPort = PORT_NORTHWEST + links[14].dstPort = PORT_SOUTHEAST + links[14].validatePorts() + + links[15].srcTile = tiles[1][0] + links[15].dstTile = tiles[0][1] + links[15].srcPort = PORT_SOUTHEAST + links[15].dstPort = PORT_NORTHWEST + links[15].validatePorts() + + def handleReshape( t_tiles ): + tiles = [] + for row in t_tiles: + for t in row: + tiles.append(t) + return tiles + + tiles = handleReshape(tiles) + + th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + src_ctrl_pkt, ctrl_mem_size, tiles, links, dataSPM, + controller2addr_map) + + th.elaborate() + th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, + f'CgraTemplateRTL') + th.dut.set_metadata(VerilogVerilatorImportPass.vl_Wno_list, + ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', + 'ALWCOMBORDER']) + th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut']) + + if paramCGRA != None: + for tile in tiles: + if not tile.isDefaultFus(): + targetFuList = [] + for fuType in tile.getAllValidFuTypes(): + targetFuList.append(fuType2RTL[fuType]) + targetTile = "top.dut.tile[" + str(tile.getIndex(tiles)) + "].construct" + th.set_param(targetTile, FuList=targetFuList) + + run_sim(th) diff --git a/cgra/test/VectorCGRAKingMeshRTL_test.py b/cgra/test/VectorCGRAKingMeshRTL_test.py deleted file mode 100644 index 2019af5..0000000 --- a/cgra/test/VectorCGRAKingMeshRTL_test.py +++ /dev/null @@ -1,130 +0,0 @@ -""" -========================================================================== -VectorCGRAKingMeshRTL_test.py -========================================================================== -Test cases for CGRAs with different configurations. - -Author : Cheng Tan - Date : April 1, 2023 -""" - - -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 ..CGRAKingMeshRTL import CGRAKingMeshRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.vector.VectorMulComboRTL import VectorMulComboRTL -from ...fu.vector.VectorAdderComboRTL import VectorAdderComboRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - - 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_4x4( cmdline_opts ): - num_tile_inports = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 4 - height = 4 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - # FuList = [MemUnitRTL, AdderRTL] - FuList = [ AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL, SelRTL, VectorMulComboRTL, VectorAdderComboRTL ] - DataType = mk_data( 64, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, 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 ) - diff --git a/cgra/translate/CgraTemplateRTL_test.py b/cgra/translate/CgraTemplateRTL_test.py new file mode 100644 index 0000000..c18d3c7 --- /dev/null +++ b/cgra/translate/CgraTemplateRTL_test.py @@ -0,0 +1,398 @@ +""" +========================================================================== +CgraTemplateRTL_test.py +========================================================================== +Translation for parameterizable CGRA based on the template. + +Author : Cheng Tan + Date : Dec 23, 2022 + +""" + +from pymtl3 import * +from pymtl3.passes.backends.verilog import (VerilogTranslationPass, + VerilogVerilatorImportPass) +from pymtl3.stdlib.test_utils import (run_sim, + config_model_with_cmdline_opts) +from ..CgraTemplateRTL import CgraTemplateRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ...lib.messages import * +from ...lib.cmd_type import * +from ...lib.opt_type import * +from ...lib.util.common import * +from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL +from ...fu.single.AdderRTL import AdderRTL +from ...fu.single.BranchRTL import BranchRTL +from ...fu.single.CompRTL import CompRTL +from ...fu.single.LogicRTL import LogicRTL +from ...fu.single.MemUnitRTL import MemUnitRTL +from ...fu.single.MulRTL import MulRTL +from ...fu.single.PhiRTL import PhiRTL +from ...fu.single.RetRTL import RetRTL +from ...fu.single.SelRTL import SelRTL +from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL +from ...fu.single.ShifterRTL import ShifterRTL + +fuType2RTL = {} +fuType2RTL["Phi" ] = PhiRTL +fuType2RTL["Add" ] = AdderRTL +fuType2RTL["Shift"] = ShifterRTL +fuType2RTL["Ld" ] = MemUnitRTL +fuType2RTL["St" ] = MemUnitRTL +fuType2RTL["Sel" ] = SelRTL +fuType2RTL["Cmp" ] = CompRTL +fuType2RTL["MAC" ] = SeqMulAdderRTL +fuType2RTL["Ret" ] = RetRTL +fuType2RTL["Mul" ] = MulRTL +fuType2RTL["Logic"] = LogicRTL +fuType2RTL["Br" ] = BranchRTL + +#------------------------------------------------------------------------- +# Test harness +#------------------------------------------------------------------------- + +class TestHarness(Component): + + def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, ctrl_mem_size, + data_mem_size_global, data_mem_size_per_bank, + num_banks_per_cgra, src_ctrl_pkt, ctrl_steps, TileList, + LinkList, dataSPM, controller2addr_map): + + s.num_tiles = len(TileList) + s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) + + s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, + NocPktType, CmdType, ControllerIdType, controller_id, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + ctrl_steps, ctrl_steps, FunctionUnit, FuList, + TileList, LinkList, dataSPM, controller2addr_map) + + # Connections + s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt + + s.dut.send_to_noc.rdy //= 0 + s.dut.recv_from_noc.val //= 0 + s.dut.recv_from_noc.msg //= NocPktType(0, 0, 0, 0, 0, 0) + + def done(s): + return s.src_ctrl_pkt.done() + + def line_trace(s): + return s.dut.line_trace() + +class Tile: + def __init__(s, dimX, dimY): + s.disabled = False + s.dimX = dimX + s.dimY = dimY + s.toMem = False + s.fromMem = False + s.invalidOutPorts = set() + s.invalidInPorts = set() + for i in range(PORT_DIRECTION_COUNTS): + s.invalidOutPorts.add(i) + s.invalidInPorts.add(i) + + def getInvalidInPorts(s): + return s.invalidInPorts + + def getInvalidOutPorts(s): + return s.invalidOutPorts + + def hasToMem(s): + return s.toMem + + def hasFromMem(s): + return s.fromMem + + def getIndex(s, TileList): + if s.disabled: + return -1 + index = 0 + for tile in TileList: + if tile.dimY < s.dimY and not tile.disabled: + index += 1 + elif tile.dimY == s.dimY and tile.dimX < s.dimX and not tile.disabled: + index += 1 + return index + +class DataSPM: + def __init__(s, numOfReadPorts, numOfWritePorts): + s.numOfReadPorts = numOfReadPorts + s.numOfWritePorts = numOfWritePorts + + def getNumOfValidReadPorts(s): + return s.numOfReadPorts + + def getNumOfValidWritePorts(s): + return s.numOfWritePorts + +class Link: + def __init__(s, srcTile, dstTile, srcPort, dstPort): + s.srcTile = srcTile + s.dstTile = dstTile + s.srcPort = srcPort + s.dstPort = dstPort + s.disabled = False + s.toMem = False + s.fromMem = False + s.memPort = -1 + + def getMemReadPort(s): + return s.memPort + + def getMemWritePort(s): + return s.memPort + + def isToMem(s): + return s.toMem + + def isFromMem(s): + return s.fromMem + + def validatePorts(s): + if not s.toMem and not s.fromMem: + s.srcTile.invalidOutPorts.remove(s.srcPort) + s.dstTile.invalidInPorts.remove(s.dstPort) + if s.toMem: + s.srcTile.toMem = True + if s.fromMem: + s.dstTile.fromMem = True + + +import platform +import pytest + +def test_cgra_universal(cmdline_opts, paramCGRA = None): + num_tile_inports = 8 + num_tile_outports = 8 + num_fu_inports = 4 + num_fu_outports = 2 + num_routing_outports = num_tile_outports + num_fu_inports + ctrl_mem_size = paramCGRA.configMemSize if paramCGRA != None else 6 + width = paramCGRA.rows if paramCGRA != None else 2 + height = paramCGRA.columns if paramCGRA != None else 2 + data_mem_size_global = 512 + data_mem_size_per_bank = 32 + num_banks_per_cgra = 2 + num_terminals = 4 + num_ctrl_actions = 6 + num_ctrl_operations = 64 + TileInType = mk_bits(clog2(num_tile_inports + 1)) + FuInType = mk_bits(clog2(num_fu_inports + 1)) + FuOutType = mk_bits(clog2(num_fu_outports + 1)) + addr_nbits = clog2(data_mem_size_global) + AddrType = mk_bits(addr_nbits) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + num_tiles = width * height + DUT = CgraTemplateRTL + FunctionUnit = FlexibleFuRTL + # FuList = [MemUnitRTL, AdderRTL] + FuList = [PhiRTL, AdderRTL, ShifterRTL, MemUnitRTL, SelRTL, CompRTL, SeqMulAdderRTL, RetRTL, MulRTL, LogicRTL, BranchRTL] + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) + + CmdType = mk_bits(4) + ControllerIdType = mk_bits(clog2(num_terminals)) + controller_id = 1 + controller2addr_map = { + 0: [0, 3], + 1: [4, 7], + 2: [8, 11], + 3: [12, 15], + } + + CtrlPktType = \ + mk_ring_across_tiles_pkt(width * height, + num_ctrl_actions, + ctrl_mem_size, + num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + CtrlSignalType = \ + mk_separate_ctrl(num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + + NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, + addr_nbits = addr_nbits, + data_nbits = 32, + predicate_nbits = 1) + pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] + tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] + fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] + src_opt_per_tile = [[ + # src dst vc_id opq cmd_type addr operation predicate + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, OPT_INC, b1(0), + pick_register, tile_in_code, fu_out_code), + # This last one is for launching kernel. + CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), + pick_register, tile_in_code, fu_out_code) + ] for i in range(num_tiles)] + + src_ctrl_pkt = [] + for opt_per_tile in src_opt_per_tile: + src_ctrl_pkt.extend(opt_per_tile) + + dataSPM = None + tiles = [] + links = None + if paramCGRA != None: + tiles = paramCGRA.getValidTiles() + links = paramCGRA.getValidLinks() + dataSPM = paramCGRA.dataSPM + else: + dataSPM = DataSPM(2, 2) + for r in range(2): + tiles.append([]) + for c in range(2): + tiles[r].append(Tile(c, r)) + + links = [Link(None, None, 0, 0) for _ in range(16)] + + links[0].srcTile = None + links[0].dstTile = tiles[0][0] + links[0].srcPort = 0 + links[0].dstPort = PORT_WEST + links[0].fromMem = True + links[0].memPort = 0 + links[0].validatePorts() + + links[1].srcTile = tiles[0][0] + links[1].dstTile = None + links[1].srcPort = PORT_WEST + links[1].dstPort = 0 + links[1].toMem = True + links[1].memPort = 0 + links[1].validatePorts() + + links[2].srcTile = None + links[2].dstTile = tiles[1][0] + links[2].srcPort = 1 + links[2].dstPort = PORT_WEST + links[2].fromMem = True + links[2].memPort = 1 + links[2].validatePorts() + + links[3].srcTile = tiles[1][0] + links[3].dstTile = None + links[3].srcPort = PORT_WEST + links[3].dstPort = 1 + links[3].toMem = True + links[3].memPort = 1 + links[3].validatePorts() + + links[4].srcTile = tiles[0][0] + links[4].dstTile = tiles[0][1] + links[4].srcPort = PORT_EAST + links[4].dstPort = PORT_WEST + links[4].validatePorts() + + links[5].srcTile = tiles[0][1] + links[5].dstTile = tiles[0][0] + links[5].srcPort = PORT_WEST + links[5].dstPort = PORT_EAST + links[5].validatePorts() + + links[6].srcTile = tiles[1][0] + links[6].dstTile = tiles[1][1] + links[6].srcPort = PORT_EAST + links[6].dstPort = PORT_WEST + links[6].validatePorts() + + links[7].srcTile = tiles[1][1] + links[7].dstTile = tiles[1][0] + links[7].srcPort = PORT_WEST + links[7].dstPort = PORT_EAST + links[7].validatePorts() + + links[8].srcTile = tiles[0][0] + links[8].dstTile = tiles[1][0] + links[8].srcPort = PORT_NORTH + links[8].dstPort = PORT_SOUTH + links[8].validatePorts() + + links[9].srcTile = tiles[1][0] + links[9].dstTile = tiles[0][0] + links[9].srcPort = PORT_SOUTH + links[9].dstPort = PORT_NORTH + links[9].validatePorts() + + links[10].srcTile = tiles[0][1] + links[10].dstTile = tiles[1][1] + links[10].srcPort = PORT_NORTH + links[10].dstPort = PORT_SOUTH + links[10].validatePorts() + + links[11].srcTile = tiles[1][1] + links[11].dstTile = tiles[0][1] + links[11].srcPort = PORT_SOUTH + links[11].dstPort = PORT_NORTH + links[11].validatePorts() + + links[12].srcTile = tiles[0][0] + links[12].dstTile = tiles[1][1] + links[12].srcPort = PORT_NORTHEAST + links[12].dstPort = PORT_SOUTHWEST + links[12].validatePorts() + + links[13].srcTile = tiles[1][1] + links[13].dstTile = tiles[0][0] + links[13].srcPort = PORT_SOUTHWEST + links[13].dstPort = PORT_NORTHEAST + links[13].validatePorts() + + links[14].srcTile = tiles[0][1] + links[14].dstTile = tiles[1][0] + links[14].srcPort = PORT_NORTHWEST + links[14].dstPort = PORT_SOUTHEAST + links[14].validatePorts() + + links[15].srcTile = tiles[1][0] + links[15].dstTile = tiles[0][1] + links[15].srcPort = PORT_SOUTHEAST + links[15].dstPort = PORT_NORTHWEST + links[15].validatePorts() + + def handleReshape( t_tiles ): + tiles = [] + for row in t_tiles: + for t in row: + tiles.append(t) + return tiles + + tiles = handleReshape(tiles) + + th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + src_ctrl_pkt, ctrl_mem_size, tiles, links, dataSPM, + controller2addr_map) + + th.elaborate() + th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, + f'CgraTemplateRTL') + th.dut.set_metadata(VerilogVerilatorImportPass.vl_Wno_list, + ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', + 'ALWCOMBORDER']) + th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut']) + + if paramCGRA != None: + for tile in tiles: + if not tile.isDefaultFus(): + targetFuList = [] + for fuType in tile.getAllValidFuTypes(): + targetFuList.append(fuType2RTL[fuType]) + targetTile = "top.dut.tile[" + str(tile.getIndex(tiles)) + "].construct" + th.set_param(targetTile, FuList=targetFuList) + + run_sim(th) diff --git a/controller/ControllerRTL.py b/controller/ControllerRTL.py index 68ed0b5..08691b5 100644 --- a/controller/ControllerRTL.py +++ b/controller/ControllerRTL.py @@ -10,9 +10,8 @@ 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.basic.val_rdy.ifcs import SendIfcRTL as SendIfcRTL +from ..lib.basic.val_rdy.ifcs import RecvIfcRTL as RecvIfcRTL from ..lib.basic.val_rdy.queues import NormalQueueRTL from ..noc.ChannelNormalRTL import ChannelNormalRTL from ..noc.PyOCN.pymtl3_net.xbar.XbarBypassQueueRTL import XbarBypassQueueRTL @@ -27,11 +26,11 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, # Interface # Request from/to other CGRA via NoC. - s.recv_from_noc = ValRdyRecvIfcRTL(NocPktType) - s.send_to_noc = ValRdySendIfcRTL(NocPktType) + s.recv_from_noc = RecvIfcRTL(NocPktType) + s.send_to_noc = SendIfcRTL(NocPktType) - s.recv_from_cpu_ctrl_pkt = ValRdyRecvIfcRTL(CtrlPktType) - s.send_to_ctrl_ring_ctrl_pkt = ValRdySendIfcRTL(CtrlPktType) + s.recv_from_cpu_ctrl_pkt = RecvIfcRTL(CtrlPktType) + s.send_to_ctrl_ring_ctrl_pkt = SendIfcRTL(CtrlPktType) # Request from/to master. s.recv_from_master_load_request_pkt = RecvIfcRTL(NocPktType) @@ -127,7 +126,7 @@ def update_received_msg(): kStoreRequestInportIdx = 2 # For the load request from master. - s.crossbar.recv[kLoadRequestInportIdx].val @= s.recv_from_master_load_request_pkt_queue.send.en + s.crossbar.recv[kLoadRequestInportIdx].val @= s.recv_from_master_load_request_pkt_queue.send.val s.recv_from_master_load_request_pkt_queue.send.rdy @= s.crossbar.recv[kLoadRequestInportIdx].rdy s.crossbar.recv[kLoadRequestInportIdx].msg @= \ NocPktType(controller_id, @@ -140,7 +139,7 @@ def update_received_msg(): 1) # For the store request from master. - s.crossbar.recv[kStoreRequestInportIdx].val @= s.recv_from_master_store_request_pkt_queue.send.en + s.crossbar.recv[kStoreRequestInportIdx].val @= s.recv_from_master_store_request_pkt_queue.send.val s.recv_from_master_store_request_pkt_queue.send.rdy @= s.crossbar.recv[kStoreRequestInportIdx].rdy s.crossbar.recv[kStoreRequestInportIdx].msg @= \ NocPktType(controller_id, @@ -154,7 +153,7 @@ def update_received_msg(): # For the load response (i.e., the data towards other) from master. s.crossbar.recv[kLoadResponseInportIdx].val @= \ - s.recv_from_master_load_response_pkt_queue.send.en + s.recv_from_master_load_response_pkt_queue.send.val s.recv_from_master_load_response_pkt_queue.send.rdy @= s.crossbar.recv[kLoadResponseInportIdx].rdy s.crossbar.recv[kLoadResponseInportIdx].msg @= \ NocPktType(controller_id, @@ -174,10 +173,10 @@ def update_received_msg(): # def update_received_msg_from_noc(): # Initiates the signals. - s.send_to_master_load_request_addr_queue.recv.en @= 0 - s.send_to_master_store_request_addr_queue.recv.en @= 0 - s.send_to_master_store_request_data_queue.recv.en @= 0 - s.send_to_master_load_response_data_queue.recv.en @= 0 + s.send_to_master_load_request_addr_queue.recv.val @= 0 + s.send_to_master_store_request_addr_queue.recv.val @= 0 + s.send_to_master_store_request_data_queue.recv.val @= 0 + s.send_to_master_load_response_data_queue.recv.val @= 0 s.send_to_master_load_request_addr_queue.recv.msg @= CGRAAddrType() s.send_to_master_store_request_addr_queue.recv.msg @= CGRAAddrType() s.send_to_master_store_request_data_queue.recv.msg @= CGRADataType() @@ -192,7 +191,7 @@ def update_received_msg(): s.recv_from_noc.rdy @= 1 s.send_to_master_load_request_addr_queue.recv.msg @= \ CGRAAddrType(received_pkt.addr) - s.send_to_master_load_request_addr_queue.recv.en @= 1 + s.send_to_master_load_request_addr_queue.recv.val @= 1 elif s.recv_from_noc.msg.cmd == CMD_STORE_REQUEST: if s.send_to_master_store_request_addr_queue.recv.rdy & \ @@ -202,15 +201,15 @@ def update_received_msg(): CGRAAddrType(received_pkt.addr) s.send_to_master_store_request_data_queue.recv.msg @= \ CGRADataType(received_pkt.data, received_pkt.predicate, 0, 0) - s.send_to_master_store_request_addr_queue.recv.en @= 1 - s.send_to_master_store_request_data_queue.recv.en @= 1 + s.send_to_master_store_request_addr_queue.recv.val @= 1 + s.send_to_master_store_request_data_queue.recv.val @= 1 elif s.recv_from_noc.msg.cmd == CMD_LOAD_RESPONSE: if s.send_to_master_load_response_data_queue.recv.rdy: s.recv_from_noc.rdy @= 1 s.send_to_master_load_response_data_queue.recv.msg @= \ CGRADataType(received_pkt.data, received_pkt.predicate, 0, 0) - s.send_to_master_load_response_data_queue.recv.en @= 1 + s.send_to_master_load_response_data_queue.recv.val @= 1 # else: # # TODO: Handle other cmd types. @@ -232,8 +231,6 @@ def update_sending_to_noc_msg(): s.crossbar.send[0].msg.data, s.crossbar.send[0].msg.predicate) - - def line_trace(s): recv_from_master_load_request_pkt_str = "recv_from_master_load_request_pkt: " + str(s.recv_from_master_load_request_pkt.msg) recv_from_master_load_response_pkt_str = "recv_from_master_load_response_pkt: " + str(s.recv_from_master_load_response_pkt.msg) diff --git a/controller/test/ControllerRTL_test.py b/controller/test/ControllerRTL_test.py index 57b78e2..a0e9173 100644 --- a/controller/test/ControllerRTL_test.py +++ b/controller/test/ControllerRTL_test.py @@ -12,17 +12,15 @@ 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.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL from ...lib.messages import * from ...lib.cmd_type import * from ...noc.PyOCN.pymtl3_net.ocnlib.test.stream_sinks import NetSinkRTL as TestNetSinkRTL import pytest - #------------------------------------------------------------------------- # TestHarness #------------------------------------------------------------------------- @@ -53,7 +51,7 @@ def construct(s, ControllerIdType, CtrlPktType, CmdType, MsgType, s.sink_to_master_store_request_addr_en_rdy = TestSinkRTL(AddrType, expected_to_master_store_request_addr_msgs) s.sink_to_master_store_request_data_en_rdy = TestSinkRTL(MsgType, expected_to_master_store_request_data_msgs) - s.src_from_noc_val_rdy = TestValRdySrcRTL(PktType, from_noc_pkts) + s.src_from_noc_val_rdy = TestSrcRTL(PktType, from_noc_pkts) s.sink_to_noc_val_rdy = TestNetSinkRTL(PktType, expected_to_noc_pkts, cmp_fn = cmp_func) s.dut = ControllerRTL(ControllerIdType, CmdType, CtrlPktType, @@ -88,15 +86,14 @@ def done(s): s.src_from_noc_val_rdy.done() and \ s.sink_to_noc_val_rdy.done() - - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() #------------------------------------------------------------------------- # run_rtl_sim #------------------------------------------------------------------------- -def run_sim(test_harness, max_cycles=20): +def run_sim(test_harness, max_cycles = 20): # Create a simulator test_harness.elaborate() @@ -106,11 +103,11 @@ def run_sim(test_harness, max_cycles=20): # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -123,8 +120,8 @@ def run_sim(test_harness, max_cycles=20): # Test cases #------------------------------------------------------------------------- -def mk_src_pkts( nterminals, lst ): - src_pkts = [ [] for _ in range( nterminals ) ] +def mk_src_pkts(nterminals, lst): + src_pkts = [[] for _ in range(nterminals)] src = 0 for pkt in lst: if hasattr(pkt, 'fl_type'): @@ -132,7 +129,7 @@ def mk_src_pkts( nterminals, lst ): src = pkt.src else: src = pkt.src - src_pkts[ src ].append( pkt ) + src_pkts[src].append(pkt) return src_pkts data_nbits = 32 @@ -176,11 +173,6 @@ def mk_src_pkts( nterminals, lst ): data_nbits = data_nbits, predicate_nbits = predicate_nbits) -# from_master_load_request_addr_msgs = [AddrType(1), AddrType(4), AddrType(12)] -# from_master_load_response_data_msgs = [DataType(1, 1), DataType(4, 1), DataType(12, 1)] -# from_master_store_request_addr_msgs = [AddrType(4), AddrType(12)] -# from_master_store_request_data_msgs = [DataType(40, 1), DataType(120, 1)] - from_master_load_request_pkts = [ # src dst opq vc cmd addr data predicate Pkt(0, 0, 0, 0, CMD_LOAD_REQUEST, 1, 0, 1), diff --git a/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py b/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py index 26ec95a..8a6fb5b 100644 --- a/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py +++ b/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py @@ -8,23 +8,20 @@ Date : Jan 6, 2024 """ - from pymtl3 import * from ..basic.Fu import Fu from ..pymtl3_fusedALU_fixedp.ALUgenMACRTL import ALUgenMAC -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * - -class ALUgenMACFU( Fu ): - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size): - super( ALUgenMACFU, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size ) +class ALUgenMACFU(Fu): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): + super(ALUgenMACFU, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) # Local parameters - assert DataType.get_field_type( 'payload' ).nbits == 16 + assert DataType.get_field_type('payload').nbits == 16 num_entries = 3 FuInType = mk_bits( clog2( num_inports + 1 ) ) @@ -55,81 +52,93 @@ def construct( s, DataType, PredicateType, CtrlType, s.in1_idx //= s.in1[0:idx_nbits] s.in2_idx //= s.in2[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 s.in2 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 - if s.recv_opt.en: + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[2] != 0: s.in2 @= zext(s.recv_opt.msg.fu_in[2] - 1, FuInType) - s.recv_in[s.in2_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate & \ - s.recv_in[s.in2_idx].msg.predicate - - # TODO RJ Here we need to block predicate propagation for the third port if ctrl != MAC. - #if s.recv_opt.msg.ctrl == OPT_FADD: - s.fALU.rhs_0 @= s.recv_in[s.in0_idx].msg.payload - s.fALU.rhs_1 @= s.recv_in[s.in1_idx].msg.payload - s.fALU.rhs_1b @= s.recv_in[s.in2_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate & \ - s.recv_in[s.in2_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) | \ - (s.recv_in_count[s.in2_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.recv_in[s.in2_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - #elif s.recv_opt.msg.ctrl == OPT_FADD_CONST: - # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload - # s.fadd.rhs_1 @= s.recv_const.msg.payload - # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - #elif s.recv_opt.msg.ctrl == OPT_FINC: - # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload - # s.fadd.rhs_1 @= s.FLOATING_ONE - # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - #elif s.recv_opt.msg.ctrl == OPT_FSUB: - # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload - # s.fadd.rhs_1 @= s.recv_in[s.in1_idx].msg.payload - # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - # if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - # (s.recv_in_count[s.in1_idx] == 0) ): - # s.recv_in[s.in0_idx].rdy @= b1( 0 ) - # s.recv_in[s.in1_idx].rdy @= b1( 0 ) - # s.send_out[0].msg.predicate @= b1( 0 ) - #else: - # for j in range( num_outports ): - # s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - - s.send_out[0].msg.payload @= s.fALU.lhs_0 + + if s.recv_opt.val: + # FIXME: Handle recv_all_val for different cases, e.g., some ops do not need + # 3 operands, some ops do not need const. + if (s.recv_opt.msg.ctrl == OPT_ADD ) | \ + (s.recv_opt.msg.ctrl == OPT_SUB ) | \ + (s.recv_opt.msg.ctrl == OPT_LT ) | \ + (s.recv_opt.msg.ctrl == OPT_GTE ) | \ + (s.recv_opt.msg.ctrl == OPT_GT ) | \ + (s.recv_opt.msg.ctrl == OPT_LTE ) | \ + (s.recv_opt.msg.ctrl == OPT_MUL ) | \ + (s.recv_opt.msg.ctrl == OPT_MUL_ADD): + s.fALU.rhs_0 @= s.recv_in[s.in0_idx].msg.payload + s.fALU.rhs_1 @= s.recv_in[s.in1_idx].msg.payload + s.fALU.rhs_1b @= s.recv_in[s.in2_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + s.recv_in[s.in2_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + s.recv_in[s.in1_idx].val & \ + s.recv_in[s.in2_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in2_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + #elif s.recv_opt.msg.ctrl == OPT_FADD_CONST: + # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload + # s.fadd.rhs_1 @= s.recv_const.msg.payload + # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate + + #elif s.recv_opt.msg.ctrl == OPT_FINC: + # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload + # s.fadd.rhs_1 @= s.FLOATING_ONE + # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate + + #elif s.recv_opt.msg.ctrl == OPT_FSUB: + # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload + # s.fadd.rhs_1 @= s.recv_in[s.in1_idx].msg.payload + # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate + # if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ + # (s.recv_in_count[s.in1_idx] == 0) ): + # s.recv_in[s.in0_idx].rdy @= b1( 0 ) + # s.recv_in[s.in1_idx].rdy @= b1( 0 ) + # s.send_out[0].msg.predicate @= b1( 0 ) + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + s.recv_in[s.in2_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + + s.send_out[0].msg.payload @= s.fALU.lhs_0 diff --git a/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py b/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py index 46f7f8a..9656d18 100644 --- a/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py +++ b/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py @@ -12,8 +12,8 @@ from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) from ..ALUgenMACFU import ALUgenMACFU -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL @@ -63,9 +63,6 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, s.dut = FunctionUnit( DataType, PredicateType, ConfigType, num_inports, num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_in2.send, s.dut.recv_in[2] ) @@ -99,13 +96,13 @@ def test_add_basic(cmdline_opts): src_predicate = [ PredicateType(1, 1), PredicateType(1, 1), PredicateType(1, 1) ] src_const = [ DataType(1, 1), DataType(2, 1), DataType(3, 1) ] sink_out = [ DataType(2, 1), DataType(0, 1), DataType(0, 1),DataType(1, 1),DataType(0, 1),DataType(1, 1), DataType(20, 1), DataType(12, 1) ] - src_opt = [ ConfigType( OPT_ADD, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_LT, b1( 1 ), pickRegister ), - ConfigType( OPT_LTE, b1( 1 ), pickRegister ), - ConfigType( OPT_GT, b1( 1 ), pickRegister ), - ConfigType( OPT_GTE, b1( 1 ), pickRegister ), - ConfigType( OPT_MUL, b1( 1 ), pickRegister ), + src_opt = [ ConfigType( OPT_ADD, b1( 1 ), pickRegister ), + ConfigType( OPT_SUB, b1( 1 ), pickRegister ), + ConfigType( OPT_LT, b1( 1 ), pickRegister ), + ConfigType( OPT_LTE, b1( 1 ), pickRegister ), + ConfigType( OPT_GT, b1( 1 ), pickRegister ), + ConfigType( OPT_GTE, b1( 1 ), pickRegister ), + ConfigType( OPT_MUL, b1( 1 ), pickRegister ), ConfigType( OPT_MUL_ADD, b1( 1 ), pickRegister ) ] th = TestHarness( FU, DataType, PredicateType, ConfigType, num_inports, num_outports, data_mem_size, diff --git a/fu/basic/Fu.py b/fu/basic/Fu.py index 3b76723..655a458 100644 --- a/fu/basic/Fu.py +++ b/fu/basic/Fu.py @@ -11,7 +11,8 @@ from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * @@ -22,66 +23,62 @@ def construct( s, DataType, PredicateType, CtrlType, latency = 1 ): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) - s.const_zero = DataType(0, 0) - num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - LatencyType = mk_bits( clog2( latency + 1 ) ) + num_entries = 2 + AddrType = mk_bits(clog2(data_mem_size)) + s.const_zero = DataType(0, 0) + CountType = mk_bits(clog2(num_entries + 1)) + FuInType = mk_bits(clog2(num_inports + 1)) + LatencyType = mk_bits(clog2(latency + 1)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_predicate = RecvIfcRTL(PredicateType) + s.recv_const = RecvIfcRTL(DataType) + s.recv_opt = RecvIfcRTL(CtrlType) + s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] # Redundant interfaces for MemUnit - s.to_mem_raddr = SendIfcRTL( AddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( AddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) + s.to_mem_raddr = SendIfcRTL(AddrType) + s.from_mem_rdata = RecvIfcRTL(DataType) + s.to_mem_waddr = SendIfcRTL(AddrType) + s.to_mem_wdata = SendIfcRTL(DataType) # Components - s.recv_rdy_vector = Wire( num_outports ) - s.latency = Wire( LatencyType ) + s.latency = Wire(LatencyType) @update_ff def proceed_latency(): if s.recv_opt.msg.ctrl == OPT_START: - s.latency <<= LatencyType( 0 ) + s.latency <<= LatencyType(0) elif s.latency == latency - 1: - s.latency <<= LatencyType( 0 ) + s.latency <<= LatencyType(0) else: - s.latency <<= s.latency + LatencyType( 1 ) + s.latency <<= s.latency + LatencyType(1) - @update - def update_signal(): - for j in range( num_outports ): - s.recv_rdy_vector[j] @= s.send_out[j].rdy - s.recv_const.rdy @= reduce_or( s.recv_rdy_vector ) & ( s.latency == latency - 1 ) - # OPT_NAH doesn't require consuming any input. - s.recv_opt.rdy @= (( s.recv_opt.msg.ctrl == OPT_NAH ) | \ - reduce_or( s.recv_rdy_vector ) ) & \ - ( s.latency == latency - 1 ) + # @update + # def update_signal(): + # for j in range(num_outports): + # s.send_rdy_vector[j] @= s.send_out[j].rdy + # s.recv_const.rdy @= reduce_and(s.send_rdy_vector) & (s.latency == latency - 1) + # # OPT_NAH doesn't require consuming any input. + # s.recv_opt.rdy @= ((s.recv_opt.msg.ctrl == OPT_NAH) | \ + # reduce_and(s.send_rdy_vector)) & \ + # (s.latency == latency - 1) @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) - s.to_mem_wdata.msg @= s.const_zero - s.to_mem_waddr.msg @= AddrType( 0 ) - s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) - s.from_mem_rdata.rdy @= b1( 0 ) + s.to_mem_waddr.val @= b1(0) + s.to_mem_wdata.val @= b1(0) + s.to_mem_wdata.msg @= s.const_zero + s.to_mem_waddr.msg @= AddrType(0) + s.to_mem_raddr.msg @= AddrType(0) + s.to_mem_raddr.val @= b1(0) + s.from_mem_rdata.rdy @= b1(0) def line_trace( s ): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.en: {s.recv_opt.en}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(opt_predicate:{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' diff --git a/fu/basic/ReduceMulUnit.py b/fu/basic/ReduceMulUnit.py index 9bfe385..670e1af 100644 --- a/fu/basic/ReduceMulUnit.py +++ b/fu/basic/ReduceMulUnit.py @@ -13,10 +13,8 @@ Date : Jul 30, 2023 ''' - from pymtl3 import * - class ReduceMulUnit( Component ): def construct( s, DataType, num_inputs ): diff --git a/fu/basic/SumUnit.py b/fu/basic/SumUnit.py index b1374b7..273d60a 100644 --- a/fu/basic/SumUnit.py +++ b/fu/basic/SumUnit.py @@ -12,10 +12,8 @@ Date : Jul 30, 2023 ''' - from pymtl3 import * - class SumUnit( Component ): def construct( s, DataType, num_inputs ): diff --git a/fu/basic/ThreeCombo.py b/fu/basic/ThreeCombo.py index 892ee49..7686986 100644 --- a/fu/basic/ThreeCombo.py +++ b/fu/basic/ThreeCombo.py @@ -9,72 +9,86 @@ Date : November 28, 2019 """ - from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class ThreeCombo(Component): -class ThreeCombo( Component ): - - def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, Fu2, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, Fu2, + num_inports, num_outports, data_mem_size): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) - s.const_zero = DataType(0, 0) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + AddrType = mk_bits(clog2(data_mem_size)) + s.const_zero = DataType(0, 0) + CountType = mk_bits(clog2(num_entries + 1)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_predicate = RecvIfcRTL(PredicateType) + s.recv_const = RecvIfcRTL(DataType) + s.recv_opt = RecvIfcRTL(CtrlType) + s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] # Redundant interfaces for MemUnit - s.to_mem_raddr = SendIfcRTL( AddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( AddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) + s.to_mem_raddr = SendIfcRTL(AddrType) + s.from_mem_rdata = RecvIfcRTL(DataType) + s.to_mem_waddr = SendIfcRTL(AddrType) + s.to_mem_wdata = SendIfcRTL(DataType) # Components - s.Fu0 = Fu0( DataType, PredicateType, CtrlType, 4, 2, data_mem_size ) - s.Fu1 = Fu1( DataType, PredicateType, CtrlType, 4, 2, data_mem_size ) - s.Fu2 = Fu2( DataType, PredicateType, CtrlType, 4, 2, data_mem_size ) + s.Fu0 = Fu0(DataType, PredicateType, CtrlType, 4, 2, data_mem_size) + s.Fu1 = Fu1(DataType, PredicateType, CtrlType, 4, 2, data_mem_size) + s.Fu2 = Fu2(DataType, PredicateType, CtrlType, 4, 2, data_mem_size) # Connections - s.recv_in[0].msg //= s.Fu0.recv_in[0].msg - s.recv_in[1].msg //= s.Fu0.recv_in[1].msg - s.recv_in[2].msg //= s.Fu1.recv_in[0].msg - s.recv_in[3].msg //= s.Fu1.recv_in[1].msg + s.recv_in[0].msg //= s.Fu0.recv_in[0].msg + s.recv_in[1].msg //= s.Fu0.recv_in[1].msg + s.recv_in[2].msg //= s.Fu1.recv_in[0].msg + s.recv_in[3].msg //= s.Fu1.recv_in[1].msg s.Fu0.send_out[0].msg //= s.Fu2.recv_in[0].msg s.Fu1.send_out[0].msg //= s.Fu2.recv_in[1].msg s.Fu2.send_out[0].msg //= s.send_out[0].msg s.Fu2.send_out[0].msg //= s.send_out[1].msg - # TODO: use & instead of and @update def update_signal(): - s.recv_in[0].rdy @= s.send_out[0].rdy - s.recv_in[1].rdy @= s.send_out[0].rdy - s.recv_in[2].rdy @= s.send_out[0].rdy - s.recv_in[3].rdy @= s.send_out[0].rdy - s.Fu0.recv_opt.en @= s.recv_opt.en - s.Fu1.recv_opt.en @= s.recv_opt.en - s.Fu2.recv_opt.en @= s.recv_opt.en - s.recv_opt.rdy @= s.send_out[0].rdy -# s.send_out[0].en = s.recv_in[0].en and s.recv_in[1].en and\ -# s.recv_in[2].en and s.recv_in[3].en and\ -# s.recv_opt.en -# s.send_out[1].en = s.recv_in[0].en and s.recv_in[1].en and\ -# s.recv_in[2].en and s.recv_in[3].en and\ -# s.recv_opt.en + all_rdy = s.Fu0.recv_in[0].rdy & \ + s.Fu0.recv_in[1].rdy & \ + s.Fu1.recv_in[0].rdy & \ + s.Fu1.recv_in[1].rdy & \ + s.Fu2.recv_in[0].rdy & \ + s.Fu2.recv_in[1].rdy + + s.recv_in[0].rdy @= all_rdy + s.recv_in[1].rdy @= all_rdy + s.recv_in[2].rdy @= all_rdy + s.recv_in[3].rdy @= all_rdy + + s.Fu0.recv_in[0].val @= s.recv_in[0].val + s.Fu0.recv_in[1].val @= s.recv_in[1].val + s.Fu1.recv_in[0].val @= s.recv_in[2].val + s.Fu1.recv_in[1].val @= s.recv_in[3].val + s.Fu2.recv_in[0].val @= s.Fu0.send_out[0].val + s.Fu2.recv_in[1].val @= s.Fu1.send_out[0].val + + s.Fu0.recv_opt.val @= s.recv_opt.val + s.Fu1.recv_opt.val @= s.recv_opt.val + s.Fu2.recv_opt.val @= s.recv_opt.val + + s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & \ + s.Fu1.recv_opt.rdy & \ + s.Fu2.recv_opt.rdy & \ + all_rdy + + s.send_out[0].val @= s.Fu2.send_out[0].val + + s.Fu0.send_out[0].rdy @= s.Fu2.recv_in[0].rdy + s.Fu1.send_out[0].rdy @= s.Fu2.recv_in[1].rdy + s.Fu2.send_out[0].rdy @= s.send_out[0].rdy # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. @@ -82,36 +96,29 @@ def update_signal(): s.Fu1.recv_opt.msg.predicate @= s.recv_opt.msg.predicate s.Fu2.recv_opt.msg.predicate @= s.recv_opt.msg.predicate - s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy and\ - s.Fu1.recv_predicate.rdy and\ - s.Fu2.recv_predicate.rdy + s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ + s.Fu1.recv_predicate.rdy & \ + s.Fu2.recv_predicate.rdy & \ + all_rdy - s.Fu0.recv_predicate.en @= s.recv_predicate.en - s.Fu1.recv_predicate.en @= s.recv_predicate.en - s.Fu2.recv_predicate.en @= s.recv_predicate.en + s.Fu0.recv_predicate.val @= s.recv_predicate.val + s.Fu1.recv_predicate.val @= s.recv_predicate.val + s.Fu2.recv_predicate.val @= s.recv_predicate.val s.Fu0.recv_predicate.msg @= s.recv_predicate.msg s.Fu1.recv_predicate.msg @= s.recv_predicate.msg s.Fu2.recv_predicate.msg @= s.recv_predicate.msg - # Connect count. - s.Fu0.recv_in_count[0] @= s.recv_in_count[0] - s.Fu0.recv_in_count[1] @= s.recv_in_count[1] - s.Fu1.recv_in_count[0] @= s.recv_in_count[2] - s.Fu1.recv_in_count[1] @= s.recv_in_count[3] - s.Fu2.recv_in_count[0] @= s.recv_in_count[0] - s.Fu2.recv_in_count[1] @= s.recv_in_count[2] - @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) + s.to_mem_waddr.val @= b1(0) + s.to_mem_wdata.val @= b1(0) s.to_mem_wdata.msg @= s.const_zero - s.to_mem_waddr.msg @= AddrType( 0 ) - s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) - s.from_mem_rdata.rdy @= b1( 0 ) + s.to_mem_waddr.msg @= AddrType(0) + s.to_mem_raddr.msg @= AddrType(0) + s.to_mem_raddr.val @= b1(0) + s.from_mem_rdata.rdy @= b1(0) - def line_trace( s ): + def line_trace(s): return s.Fu0.line_trace() + " ; " + s.Fu1.line_trace() + " ; " + s.Fu2.line_trace() diff --git a/fu/basic/TwoPrlCombo.py b/fu/basic/TwoPrlCombo.py index 420378d..dabfb48 100644 --- a/fu/basic/TwoPrlCombo.py +++ b/fu/basic/TwoPrlCombo.py @@ -8,25 +8,23 @@ Date : November 28, 2019 """ - from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class TwoPrlCombo(Component): -class TwoPrlCombo( Component ): - - def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, + num_inports, num_outports, data_mem_size): # Constants - AddrType = mk_bits( clog2( data_mem_size ) ) num_entries = 2 + AddrType = mk_bits( clog2( data_mem_size ) ) CountType = mk_bits( clog2( num_entries + 1 ) ) # Interface s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] s.recv_predicate = RecvIfcRTL( PredicateType ) s.recv_opt = RecvIfcRTL( CtrlType ) s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] @@ -36,8 +34,6 @@ def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, s.from_mem_rdata = RecvIfcRTL( DataType ) s.to_mem_waddr = SendIfcRTL( AddrType ) s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) # Components s.Fu0 = Fu0( DataType, PredicateType, CtrlType, 2, 1, data_mem_size ) @@ -52,41 +48,49 @@ def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, s.Fu0.send_out[0].msg //= s.send_out[0].msg s.Fu1.send_out[0].msg //= s.send_out[1].msg - # TODO: use & instead of and @update def update_signal(): - s.recv_in[0].rdy @= s.send_out[0].rdy and s.send_out[1].rdy - s.recv_in[1].rdy @= s.send_out[0].rdy and s.send_out[1].rdy - s.recv_in[2].rdy @= s.send_out[0].rdy and s.send_out[1].rdy - s.recv_in[3].rdy @= s.send_out[0].rdy and s.send_out[1].rdy - - s.Fu0.recv_opt.en @= s.recv_opt.en - s.Fu1.recv_opt.en @= s.recv_opt.en - s.recv_opt.rdy @= s.send_out[0].rdy and s.send_out[1].rdy - s.send_out[0].en @= s.recv_in[0].en and s.recv_in[1].en and\ - s.recv_in[2].en and s.recv_in[3].en and\ - s.recv_opt.en - s.send_out[1].en @= s.recv_in[0].en and s.recv_in[1].en and\ - s.recv_in[2].en and s.recv_in[3].en and\ - s.recv_opt.en + all_rdy = s.Fu0.recv_in[0].rdy & \ + s.Fu0.recv_in[1].rdy & \ + s.Fu1.recv_in[0].rdy & \ + s.Fu1.recv_in[1].rdy + + s.recv_in[0].rdy @= all_rdy + s.recv_in[1].rdy @= all_rdy + s.recv_in[2].rdy @= all_rdy + s.recv_in[3].rdy @= all_rdy + + s.Fu0.recv_in[0].val @= s.recv_in[0].val + s.Fu0.recv_in[1].val @= s.recv_in[1].val + s.Fu1.recv_in[0].val @= s.recv_in[2].val + s.Fu1.recv_in[1].val @= s.recv_in[3].val + + s.Fu0.recv_opt.val @= s.recv_opt.val + s.Fu1.recv_opt.val @= s.recv_opt.val + + s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy & all_rdy + + s.send_out[0].val @= s.Fu0.send_out[0].val + s.send_out[1].val @= s.Fu1.send_out[0].val + + s.Fu0.send_out[0].rdy @= s.send_out[0].rdy + s.Fu1.send_out[0].rdy @= s.send_out[1].rdy # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. s.Fu0.recv_opt.msg.predicate @= s.recv_opt.msg.predicate s.Fu1.recv_opt.msg.predicate @= s.recv_opt.msg.predicate - s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy and\ - s.Fu1.recv_predicate.rdy - s.Fu0.recv_predicate.en @= s.recv_predicate.en - s.Fu1.recv_predicate.en @= s.recv_predicate.en + s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ + s.Fu1.recv_predicate.rdy & \ + all_rdy + + s.Fu0.recv_predicate.val @= s.recv_predicate.val + s.Fu1.recv_predicate.val @= s.recv_predicate.val s.Fu0.recv_predicate.msg @= s.recv_predicate.msg s.Fu1.recv_predicate.msg @= s.recv_predicate.msg - # Connect count. - for i in range( 2 ): - s.Fu0.recv_in_count[i] @= s.recv_in_count[i] - s.Fu1.recv_in_count[i] @= s.recv_in_count[i] - def line_trace( s ): return s.Fu0.line_trace() + " ; " + s.Fu1.line_trace() + diff --git a/fu/basic/TwoSeqCombo.py b/fu/basic/TwoSeqCombo.py index 32ae75f..f195b7b 100644 --- a/fu/basic/TwoSeqCombo.py +++ b/fu/basic/TwoSeqCombo.py @@ -8,50 +8,44 @@ Date : November 28, 2019 """ - from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class TwoSeqCombo(Component): -class TwoSeqCombo( Component ): - - def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, + num_inports, num_outports, data_mem_size): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) - s.const_zero = DataType(0, 0) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + AddrType = mk_bits(clog2(data_mem_size)) + s.const_zero = DataType(0, 0) + CountType = mk_bits(clog2(num_entries + 1)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_in_count = [InPort(CountType) for _ in range(num_inports)] + s.recv_predicate = RecvIfcRTL(PredicateType) + s.recv_const = RecvIfcRTL(DataType) + s.recv_opt = RecvIfcRTL(CtrlType) + s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] # Redundant interfaces for MemUnit - s.to_mem_raddr = SendIfcRTL( AddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( AddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) + s.to_mem_raddr = SendIfcRTL(AddrType) + s.from_mem_rdata = RecvIfcRTL(DataType) + s.to_mem_waddr = SendIfcRTL(AddrType) + s.to_mem_wdata = SendIfcRTL(DataType) # Components - s.Fu0 = Fu0( DataType, PredicateType, CtrlType, 4, 2, data_mem_size ) - s.Fu1 = Fu1( DataType, PredicateType, CtrlType, 4, 2, data_mem_size ) + s.Fu0 = Fu0(DataType, PredicateType, CtrlType, 4, 2, data_mem_size) + s.Fu1 = Fu1(DataType, PredicateType, CtrlType, 4, 2, data_mem_size) # Connections - s.recv_in[0].msg //= s.Fu0.recv_in[0].msg - s.recv_in[1].msg //= s.Fu0.recv_in[1].msg - s.recv_in[2].msg //= s.Fu1.recv_in[1].msg - -# s.Fu0.recv_opt.msg //= s.recv_opt.msg -# s.Fu1.recv_opt.msg //= s.recv_opt.msg + s.recv_in[0].msg //= s.Fu0.recv_in[0].msg + s.recv_in[1].msg //= s.Fu0.recv_in[1].msg + s.recv_in[2].msg //= s.Fu1.recv_in[1].msg s.Fu0.send_out[0].msg //= s.Fu1.recv_in[0].msg s.Fu1.send_out[0].msg //= s.send_out[0].msg @@ -60,15 +54,29 @@ def construct( s, DataType, PredicateType, CtrlType, Fu0, Fu1, @update def update_signal(): - s.recv_in[0].rdy @= s.send_out[0].rdy - s.recv_in[1].rdy @= s.send_out[0].rdy - s.recv_in[2].rdy @= s.send_out[0].rdy - s.Fu0.recv_opt.en @= s.recv_opt.en - s.Fu1.recv_opt.en @= s.recv_opt.en - s.recv_opt.rdy @= s.send_out[0].rdy -# s.send_out[0].en = s.recv_in[0].en and s.recv_in[1].en and\ -# s.recv_in[2].en and s.recv_opt.en - s.send_out[0].en @= s.recv_in[0].en & s.recv_opt.en + all_rdy = s.Fu0.recv_in[0].rdy & \ + s.Fu0.recv_in[1].rdy & \ + s.Fu1.recv_in[0].rdy & \ + s.Fu1.recv_in[1].rdy + + s.recv_in[0].rdy @= all_rdy + s.recv_in[1].rdy @= all_rdy + s.recv_in[2].rdy @= all_rdy + + s.Fu0.recv_in[0].val @= s.recv_in[0].val + s.Fu0.recv_in[1].val @= s.recv_in[1].val + s.Fu1.recv_in[0].val @= s.Fu0.send_out[0].val + s.Fu1.recv_in[1].val @= s.recv_in[2].val + + s.Fu0.recv_opt.val @= s.recv_opt.val + s.Fu1.recv_opt.val @= s.recv_opt.val + + s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy & all_rdy + + s.send_out[0].val @= s.Fu1.send_out[0].val + + s.Fu0.send_out[0].rdy @= s.Fu1.recv_in[0].rdy + s.Fu1.send_out[0].rdy @= s.send_out[0].rdy # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. @@ -76,30 +84,25 @@ def update_signal(): s.Fu1.recv_opt.msg.predicate @= s.recv_opt.msg.predicate s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ - s.Fu1.recv_predicate.rdy - s.Fu0.recv_predicate.en @= s.recv_predicate.en - s.Fu1.recv_predicate.en @= s.recv_predicate.en + s.Fu1.recv_predicate.rdy & \ + all_rdy + + s.Fu0.recv_predicate.val @= s.recv_predicate.val + s.Fu1.recv_predicate.val @= s.recv_predicate.val - # FIXME:should work, though two fields... s.Fu0.recv_predicate.msg @= s.recv_predicate.msg s.Fu1.recv_predicate.msg @= s.recv_predicate.msg - # Connect count. - s.Fu0.recv_in_count[0] @= s.recv_in_count[0] - s.Fu0.recv_in_count[1] @= s.recv_in_count[1] - s.Fu1.recv_in_count[0] @= s.recv_in_count[0] - s.Fu1.recv_in_count[1] @= s.recv_in_count[2] - @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) + s.to_mem_waddr.val @= b1(0) + s.to_mem_wdata.val @= b1(0) s.to_mem_wdata.msg @= s.const_zero - s.to_mem_waddr.msg @= AddrType( 0 ) - s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) - s.from_mem_rdata.rdy @= b1( 0 ) + s.to_mem_waddr.msg @= AddrType(0) + s.to_mem_raddr.msg @= AddrType(0) + s.to_mem_raddr.val @= b1(0) + s.from_mem_rdata.rdy @= b1(0) - def line_trace( s ): + def line_trace(s): return s.Fu0.line_trace() + " ; " + s.Fu1.line_trace() + " ; s.recv_predicate.msg: " + str(s.recv_predicate.msg) diff --git a/fu/double/PrlMulAdderRTL.py b/fu/double/PrlMulAdderRTL.py index 4ba88e8..6432542 100644 --- a/fu/double/PrlMulAdderRTL.py +++ b/fu/double/PrlMulAdderRTL.py @@ -13,29 +13,23 @@ from ..basic.TwoPrlCombo import TwoPrlCombo from ..single.MulRTL import MulRTL from ..single.AdderRTL import AdderRTL -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class PrlMulAdderRTL(TwoPrlCombo): -class PrlMulAdderRTL( TwoPrlCombo ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + super(PrlMulAdderRTL, s).construct(DataType, PredicateType, CtrlType, + MulRTL, AdderRTL, num_inports, + num_outports, data_mem_size) - super( PrlMulAdderRTL, s ).construct( DataType, PredicateType, CtrlType, - MulRTL, AdderRTL, num_inports, - num_outports, data_mem_size ) - - FuInType = mk_bits( clog2( num_inports + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) @update def update_opt(): -# if s.recv_opt.msg.ctrl == OPT_MUL_ADD: -# s.Fu0.recv_opt.msg = CtrlType( OPT_MUL, s.recv_opt.msg.predicate, [ Bits2(1), Bits2(2) ] ) -# s.Fu1.recv_opt.msg = CtrlType( OPT_ADD, s.recv_opt.msg.predicate, [ Bits2(1), Bits2(2) ] ) -# elif s.recv_opt.msg.ctrl == OPT_MUL_SUB: -# s.Fu0.recv_opt.msg = CtrlType( OPT_MUL, s.recv_opt.msg.predicate, [ Bits2(1), Bits2(2) ] ) -# s.Fu1.recv_opt.msg = CtrlType( OPT_SUB, s.recv_opt.msg.predicate, [ Bits2(1), Bits2(2) ] ) s.Fu0.recv_opt.msg.fu_in[0] @= 1 s.Fu0.recv_opt.msg.fu_in[1] @= 2 diff --git a/fu/double/SeqMulAdderRTL.py b/fu/double/SeqMulAdderRTL.py index c8953ed..669da7d 100644 --- a/fu/double/SeqMulAdderRTL.py +++ b/fu/double/SeqMulAdderRTL.py @@ -8,25 +8,22 @@ Date : November 28, 2019 """ - from pymtl3 import * from ..basic.TwoSeqCombo import TwoSeqCombo from ..single.MulRTL import MulRTL from ..single.AdderRTL import AdderRTL -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class SeqMulAdderRTL(TwoSeqCombo): -class SeqMulAdderRTL( TwoSeqCombo ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( SeqMulAdderRTL, s ).construct( DataType, PredicateType, CtrlType, - MulRTL, AdderRTL, num_inports, - num_outports, data_mem_size ) + super(SeqMulAdderRTL, s).construct(DataType, PredicateType, CtrlType, + MulRTL, AdderRTL, num_inports, + num_outports, data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) @update def update_opt(): diff --git a/fu/double/SeqMulShifterRTL.py b/fu/double/SeqMulShifterRTL.py index 1cccac1..034f488 100644 --- a/fu/double/SeqMulShifterRTL.py +++ b/fu/double/SeqMulShifterRTL.py @@ -8,7 +8,6 @@ Date : November 28, 2019 """ - from pymtl3 import * from ..basic.TwoSeqCombo import TwoSeqCombo from ..single.MulRTL import MulRTL @@ -16,16 +15,15 @@ from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class SeqMulShifterRTL(TwoSeqCombo): -class SeqMulShifterRTL( TwoSeqCombo ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( SeqMulShifterRTL, s ).construct( DataType, PredicateType, - CtrlType, MulRTL, ShifterRTL, - num_inports, num_outports, - data_mem_size ) + super(SeqMulShifterRTL, s).construct(DataType, PredicateType, + CtrlType, MulRTL, ShifterRTL, + num_inports, num_outports, + data_mem_size) @update def update_opt(): diff --git a/fu/double/test/TwoPrlComboRTL_test.py b/fu/double/test/TwoPrlComboRTL_test.py index ab2d66f..1231993 100644 --- a/fu/double/test/TwoPrlComboRTL_test.py +++ b/fu/double/test/TwoPrlComboRTL_test.py @@ -8,11 +8,10 @@ Date : November 29, 2019 """ - from pymtl3 import * from ..PrlMulAdderRTL import PrlMulAdderRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * @@ -20,28 +19,25 @@ # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src2_msgs, src3_msgs, src_predicate, - ctrl_msgs, sink_msgs0, sink_msgs1 ): + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src0_msgs, + src1_msgs, src2_msgs, src3_msgs, src_predicate, + ctrl_msgs, sink_msgs0, sink_msgs1): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_in2 = TestSrcRTL( DataType, src2_msgs ) - s.src_in3 = TestSrcRTL( DataType, src3_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_in2 = TestSrcRTL ( DataType, src2_msgs ) + s.src_in3 = TestSrcRTL ( DataType, src3_msgs ) + s.src_predicate = TestSrcRTL ( PredicateType, src_predicate ) + s.src_opt = TestSrcRTL ( CtrlType, ctrl_msgs ) s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) s.sink_out1 = TestSinkRTL( DataType, sink_msgs1 ) s.dut = FunctionUnit( DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size ) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_in2.send, s.dut.recv_in[2] ) @@ -59,7 +55,7 @@ def done( s ): def line_trace( s ): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=1000 ): +def run_sim( test_harness, max_cycles=40 ): test_harness.elaborate() test_harness.apply( DefaultPassGroup() ) test_harness.sim_reset() diff --git a/fu/double/test/TwoSeqComboRTL_test.py b/fu/double/test/TwoSeqComboRTL_test.py index 8626744..89c5716 100644 --- a/fu/double/test/TwoSeqComboRTL_test.py +++ b/fu/double/test/TwoSeqComboRTL_test.py @@ -8,16 +8,14 @@ Date : November 27, 2019 """ - from pymtl3 import * from ..SeqMulAdderRTL import SeqMulAdderRTL from ..SeqMulShifterRTL import SeqMulShifterRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- @@ -40,11 +38,6 @@ def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, s.dut = FunctionUnit( DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size ) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 - s.dut.recv_in_count[2] //= 1 - s.dut.recv_in_count[3] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_in2.send, s.dut.recv_in[2] ) @@ -54,13 +47,13 @@ def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, connect( s.dut.send_out[0], s.sink_out.recv ) def done( s ): - return s.src_in0.done() and s.src_in1.done() and s.src_in2.done() and\ + return s.src_in0.done() and s.src_in1.done() and s.src_in2.done() and \ s.src_opt.done() and s.sink_out.done() def line_trace( s ): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=1000 ): +def run_sim( test_harness, max_cycles = 30 ): test_harness.elaborate() test_harness.apply( DefaultPassGroup() ) test_harness.sim_reset() diff --git a/fu/flexible/FlexibleFuRTL.py b/fu/flexible/FlexibleFuRTL.py index 2fdbadd..c5c1ad5 100644 --- a/fu/flexible/FlexibleFuRTL.py +++ b/fu/flexible/FlexibleFuRTL.py @@ -12,110 +12,111 @@ from pymtl3 import * from ...fu.single.MemUnitRTL import MemUnitRTL from ...fu.single.AdderRTL import AdderRTL -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...fu.single.NahRTL import NahRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * -class FlexibleFuRTL( Component ): +class FlexibleFuRTL(Component): - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, FuList ):#=[MemUnitRTL,AdderRTL] ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, FuList): # Constant - s.fu_list_size = len( FuList ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - AddrType = mk_bits( clog2( data_mem_size ) ) + if NahRTL not in FuList: + FuList.append(NahRTL) + s.fu_list_size = len(FuList) + CountType = mk_bits(clog2( num_entries + 1)) + AddrType = mk_bits(clog2( data_mem_size)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] - - s.to_mem_raddr = [ SendIfcRTL( AddrType ) for _ in range( s.fu_list_size ) ] - s.from_mem_rdata = [ RecvIfcRTL( DataType ) for _ in range( s.fu_list_size ) ] - s.to_mem_waddr = [ SendIfcRTL( AddrType ) for _ in range( s.fu_list_size ) ] - s.to_mem_wdata = [ SendIfcRTL( DataType ) for _ in range( s.fu_list_size ) ] + s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_predicate = RecvIfcRTL(PredicateType) + s.recv_const = RecvIfcRTL(DataType) + s.recv_opt = RecvIfcRTL(CtrlType) + s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] + + s.to_mem_raddr = [SendIfcRTL(AddrType) for _ in range(s.fu_list_size)] + s.from_mem_rdata = [RecvIfcRTL(DataType) for _ in range(s.fu_list_size)] + s.to_mem_waddr = [SendIfcRTL(AddrType) for _ in range(s.fu_list_size)] + s.to_mem_wdata = [SendIfcRTL(DataType) for _ in range(s.fu_list_size)] # Components - s.fu = [ FuList[i]( DataType, PredicateType, CtrlType, num_inports, num_outports, - data_mem_size ) for i in range( s.fu_list_size ) ] + s.fu = [FuList[i](DataType, PredicateType, CtrlType, num_inports, num_outports, + data_mem_size) for i in range(s.fu_list_size)] - s.fu_recv_const_rdy_vector = Wire( s.fu_list_size ) - s.fu_recv_predicate_rdy_vector = Wire( s.fu_list_size ) - s.fu_recv_opt_rdy_vector = Wire( s.fu_list_size ) - s.fu_recv_in_rdy_vector = [ Wire( s.fu_list_size ) for i in range( num_inports ) ] + s.fu_recv_const_rdy_vector = Wire(s.fu_list_size) + s.fu_recv_predicate_rdy_vector = Wire(s.fu_list_size) + s.fu_recv_opt_rdy_vector = Wire(s.fu_list_size) + s.fu_recv_in_rdy_vector = [Wire(s.fu_list_size) for i in range(num_inports)] # Connection - for i in range( len( FuList ) ): - s.to_mem_raddr[i] //= s.fu[i].to_mem_raddr + for i in range(len(FuList)): + s.to_mem_raddr[i] //= s.fu[i].to_mem_raddr s.from_mem_rdata[i] //= s.fu[i].from_mem_rdata - s.to_mem_waddr[i] //= s.fu[i].to_mem_waddr - s.to_mem_wdata[i] //= s.fu[i].to_mem_wdata + s.to_mem_waddr[i] //= s.fu[i].to_mem_waddr + s.to_mem_wdata[i] //= s.fu[i].to_mem_wdata @update def comb_logic(): - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + for j in range(num_outports): + s.send_out[j].val @= b1(0) s.send_out[j].msg @= DataType() - for i in range( s.fu_list_size ): + for i in range(s.fu_list_size): # const connection s.fu[i].recv_const.msg @= s.recv_const.msg - s.fu[i].recv_const.en @= s.recv_const.en - # s.recv_const.rdy @= s.recv_const.rdy | s.fu[i].recv_const.rdy + s.fu[i].recv_const.val @= s.recv_const.val s.fu_recv_const_rdy_vector[i] @= s.fu[i].recv_const.rdy - for j in range( num_inports): - s.fu[i].recv_in_count[j] @= s.recv_in_count[j] - # opt connection s.fu[i].recv_opt.msg @= s.recv_opt.msg - s.fu[i].recv_opt.en @= s.recv_opt.en - # s.recv_opt.rdy @= s.fu[i].recv_opt.rdy | s.recv_opt.rdy + s.fu[i].recv_opt.val @= s.recv_opt.val s.fu_recv_opt_rdy_vector[i] @= s.fu[i].recv_opt.rdy # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. s.fu[i].recv_opt.msg.predicate @= s.recv_opt.msg.predicate - s.fu[i].recv_predicate.en @= s.recv_predicate.en - # s.recv_predicate.rdy @= s.fu[i].recv_predicate.rdy | s.recv_predicate.rdy + s.fu[i].recv_predicate.val @= s.recv_predicate.val s.fu_recv_predicate_rdy_vector[i] @= s.fu[i].recv_predicate.rdy - s.fu[i].recv_predicate.msg @= s.recv_predicate.msg + s.fu[i].recv_predicate.msg @= s.recv_predicate.msg # send_out connection - for j in range( num_outports ): - if s.fu[i].send_out[j].en: - s.send_out[j].msg @= s.fu[i].send_out[j].msg - s.send_out[j].en @= s.fu[i].send_out[j].en + for j in range(num_outports): + # FIXME: need reduce_or here: https://github.com/tancheng/VectorCGRA/issues/51 + if s.fu[i].send_out[j].val: + s.send_out[j].msg @= s.fu[i].send_out[j].msg + s.send_out[j].val @= s.fu[i].send_out[j].val s.fu[i].send_out[j].rdy @= s.send_out[j].rdy - s.recv_const.rdy @= reduce_or( s.fu_recv_const_rdy_vector ) - s.recv_predicate.rdy @= reduce_or( s.fu_recv_predicate_rdy_vector ) - s.recv_opt.rdy @= reduce_or( s.fu_recv_opt_rdy_vector ) + s.recv_const.rdy @= reduce_or(s.fu_recv_const_rdy_vector) + s.recv_predicate.rdy @= reduce_or(s.fu_recv_predicate_rdy_vector) + # FIXME: Operation might be performed more than once due to the set of + # recv_opt.rdy is done separately: https://github.com/tancheng/VectorCGRA/issues/10 & + # https://github.com/tancheng/VectorCGRA/issues/53. + s.recv_opt.rdy @= reduce_or(s.fu_recv_opt_rdy_vector) - for j in range( num_inports ): - s.recv_in[j].rdy @= b1( 0 ) + for j in range(num_inports): + s.recv_in[j].rdy @= b1(0) # recv_in connection - for port in range( num_inports ): - for i in range( s.fu_list_size ): + for port in range(num_inports): + for i in range(s.fu_list_size): s.fu[i].recv_in[port].msg @= s.recv_in[port].msg - s.fu[i].recv_in[port].en @= s.recv_in[port].en + s.fu[i].recv_in[port].val @= s.recv_in[port].val # s.recv_in[j].rdy @= s.fu[i].recv_in[j].rdy | s.recv_in[j].rdy s.fu_recv_in_rdy_vector[port][i] @= s.fu[i].recv_in[port].rdy - s.recv_in[port].rdy @= reduce_or( s.fu_recv_in_rdy_vector[port] ) + s.recv_in[port].rdy @= reduce_or(s.fu_recv_in_rdy_vector[port]) - def line_trace( s ): + def line_trace(s): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}, en: {s.recv_const.en}) ] = [out: {out_str}] (recv_opt.rdy: {s.recv_opt.rdy}, recv_in[0].rdy: {s.recv_in[0].rdy}, recv_in[1].rdy: {s.recv_in[1].rdy}, recv_predicate.msg: {s.recv_predicate.msg}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.en: {s.recv_opt.en}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}, val: {s.recv_const.val}) ] = [out: {out_str}] (recv_opt.rdy: {s.recv_opt.rdy}, recv_in[0].rdy: {s.recv_in[0].rdy}, recv_in[1].rdy: {s.recv_in[1].rdy}, recv_predicate.msg: {s.recv_predicate.msg}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' diff --git a/fu/flexible/FuFL.py b/fu/flexible/FuFL.py index c06d8d7..9bf3b32 100644 --- a/fu/flexible/FuFL.py +++ b/fu/flexible/FuFL.py @@ -23,9 +23,10 @@ def FuFL( DataType, input_a, input_b, opt ): out_list = [] for i in range( len( input_a ) ): if( opt[i].ctrl == OPT_ADD): - out = input_a[i].payload + input_b[i].payload + out_list.append(DataType(input_a[i].payload + input_b[i].payload)) + elif( opt[i].ctrl == OPT_SUB): + out_list.append(DataType(input_a[i].payload - input_b[i].payload)) elif( opt[i].ctrl == OPT_MUL): - out = input_a[i].payload * input_b[i].payload - out_list.append( DataType( out ) ) + out_list.append(DataType(input_a[i].payload * input_b[i].payload)) return out_list diff --git a/fu/flexible/test/FlexibleFuRTL_hypothesis_test.py b/fu/flexible/test/FlexibleFuRTL_hypothesis_test.py index ff9c7b6..cc7a391 100644 --- a/fu/flexible/test/FlexibleFuRTL_hypothesis_test.py +++ b/fu/flexible/test/FlexibleFuRTL_hypothesis_test.py @@ -19,17 +19,15 @@ from ...single.LogicRTL import LogicRTL from ...single.MemUnitRTL import MemUnitRTL from ...single.MulRTL import MulRTL +from ...single.NahRTL import NahRTL from ...single.PhiRTL import PhiRTL from ...single.ShifterRTL import ShifterRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.opt_type import * from ....lib.messages import * import hypothesis - -#from pymtl3.passes.backends.verilog import TranslationImportPass - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- @@ -52,9 +50,6 @@ def construct( s, FunctionUnit, FuList, DataType, PredicateType, CtrlType, s.dut = FunctionUnit( DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size, FuList ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - connect( s.src_const.send, s.dut.recv_const ) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) @@ -68,20 +63,20 @@ def construct( s, FunctionUnit, FuList, DataType, PredicateType, CtrlType, s.to_mem_waddr = [ TestSinkRTL( AddrType, [] ) for _ in FuList ] s.to_mem_wdata = [ TestSinkRTL( DataType, [] ) for _ in FuList ] - for i in range( len( FuList ) ): + for i in range( s.dut.fu_list_size ): s.to_mem_raddr[i].recv //= s.dut.to_mem_raddr[i] s.from_mem_rdata[i].send //= s.dut.from_mem_rdata[i] s.to_mem_waddr[i].recv //= s.dut.to_mem_waddr[i] s.to_mem_wdata[i].recv //= s.dut.to_mem_wdata[i] def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out0.done() + return s.src_in0.done() and s.src_in1.done() and \ + s.src_opt.done() and s.sink_out0.done() def line_trace( s ): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim( test_harness, max_cycles=20 ): test_harness.elaborate() test_harness.apply( DefaultPassGroup() ) test_harness.sim_reset() @@ -104,6 +99,7 @@ def run_sim( test_harness, max_cycles=100 ): func_opt = { AdderRTL : OPT_ADD, + NahRTL : OPT_ADD, MulRTL : OPT_MUL } @st.composite @@ -115,7 +111,7 @@ def inputs_strat( draw, functions ): @hypothesis.settings( deadline=None, max_examples=50 ) @hypothesis.given( - functions = st.sampled_from( [ [AdderRTL], [ AdderRTL, MulRTL ]] ), + functions = st.sampled_from( [ [ AdderRTL], [ AdderRTL, MulRTL ]] ), inputs = st.data(), ) def test_hypothesis( functions, inputs ): diff --git a/fu/flexible/test/FlexibleFuRTL_test.py b/fu/flexible/test/FlexibleFuRTL_test.py index 8de7144..4effb07 100644 --- a/fu/flexible/test/FlexibleFuRTL_test.py +++ b/fu/flexible/test/FlexibleFuRTL_test.py @@ -8,7 +8,6 @@ Date : Dec 14, 2019 """ - from pymtl3 import * from ..FlexibleFuRTL import FlexibleFuRTL from ...single.AdderRTL import AdderRTL @@ -19,12 +18,11 @@ from ...single.MulRTL import MulRTL from ...single.PhiRTL import PhiRTL from ...single.ShifterRTL import ShifterRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.opt_type import * from ....lib.messages import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- @@ -36,60 +34,58 @@ def construct( s, FunctionUnit, FuList, DataType, PredicateType, src0_msgs, src1_msgs, src_predicate, ctrl_msgs, sink0_msgs, sink1_msgs ): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_const = TestSrcRTL( DataType, src1_msgs ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) - s.sink_out0 = TestSinkRTL( DataType, sink0_msgs ) - # s.sink_out1 = TestSinkRTL( DataType, sink1_msgs ) - - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - FuList ) - - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - - connect( s.src_const.send, s.dut.recv_const ) - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out0.recv ) - - AddrType = mk_bits( clog2( data_mem_size ) ) - s.to_mem_raddr = [ TestSinkRTL( AddrType, [] ) for _ in FuList ] - s.from_mem_rdata = [ TestSrcRTL( DataType, [] ) for _ in FuList ] - s.to_mem_waddr = [ TestSinkRTL( AddrType, [] ) for _ in FuList ] - s.to_mem_wdata = [ TestSinkRTL( DataType, [] ) for _ in FuList ] - - for i in range( len( FuList ) ): - s.to_mem_raddr[i].recv //= s.dut.to_mem_raddr[i] + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_const = TestSrcRTL(DataType, src1_msgs) + s.src_opt = TestSrcRTL(CtrlType, ctrl_msgs) + s.sink_out0 = TestSinkRTL(DataType, sink0_msgs) + s.sink_out1 = TestSinkRTL( DataType, sink1_msgs) + + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, FuList) + + connect(s.src_const.send, s.dut.recv_const) + connect(s.src_in0.send, s.dut.recv_in[0]) + connect(s.src_in1.send, s.dut.recv_in[1]) + connect(s.src_predicate.send, s.dut.recv_predicate) + connect(s.src_opt.send, s.dut.recv_opt) + connect(s.dut.send_out[0], s.sink_out0.recv) + connect(s.dut.send_out[1], s.sink_out1.recv) + + AddrType = mk_bits(clog2(data_mem_size)) + s.to_mem_raddr = [TestSinkRTL(AddrType, []) for _ in FuList] + s.from_mem_rdata = [TestSrcRTL( DataType, []) for _ in FuList] + s.to_mem_waddr = [TestSinkRTL(AddrType, []) for _ in FuList] + s.to_mem_wdata = [TestSinkRTL(DataType, []) for _ in FuList] + + for i in range(len(FuList)): + s.to_mem_raddr[i].recv //= s.dut.to_mem_raddr[i] s.from_mem_rdata[i].send //= s.dut.from_mem_rdata[i] - s.to_mem_waddr[i].recv //= s.dut.to_mem_waddr[i] - s.to_mem_wdata[i].recv //= s.dut.to_mem_wdata[i] + s.to_mem_waddr[i].recv //= s.dut.to_mem_waddr[i] + s.to_mem_wdata[i].recv //= s.dut.to_mem_wdata[i] - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out0.done() + def done(s): + return s.src_in0.done() and s.src_in1.done() and \ + s.src_opt.done() and s.sink_out0.done() and \ + s.sink_out1.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 100): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -99,28 +95,29 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() def test_flexible_alu(): - FU = FlexibleFuRTL - FuList = [AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() + FU = FlexibleFuRTL + FuList = [AdderRTL] + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() data_mem_size = 8 - num_inports = 2 - num_outports = 2 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(9, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 0) ] - sink_out = [ DataType(3, 0), DataType(5, 1), DataType(8, 0) ] - src_opt = [ CtrlType( OPT_ADD, b1( 1 ), pickRegister ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister ), - CtrlType( OPT_SUB, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, FuList, DataType, PredicateType, CtrlType, - data_mem_size, num_inports, num_outports, - src_in0, src_in1, src_predicate, src_opt, - sink_out, sink_out ) - run_sim( th ) + num_inports = 2 + num_outports = 2 + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(2, 1), DataType(9, 1)] + src_in1 = [DataType(2, 1), DataType(3, 1), DataType(1, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 0)] + sink_out0 = [DataType(3, 0), DataType(5, 1), DataType(8, 0)] + sink_out1 = [] + src_opt = [CtrlType(OPT_ADD, b1(1), pickRegister), + CtrlType(OPT_ADD, b1(0), pickRegister), + CtrlType(OPT_SUB, b1(1), pickRegister)] + th = TestHarness(FU, FuList, DataType, PredicateType, CtrlType, + data_mem_size, num_inports, num_outports, + src_in0, src_in1, src_predicate, src_opt, + sink_out0, sink_out1) + run_sim(th) def test_flexible_mul(): FU = FlexibleFuRTL @@ -136,14 +133,15 @@ def test_flexible_mul(): src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(9, 1) ] src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(2, 1) ] src_predicate = [ PredicateType(1, 0), PredicateType(1, 1), PredicateType(1, 1) ] - sink_out = [ DataType(2, 0), DataType(6, 1), DataType(18, 1) ] + sink_out0 = [ DataType(2, 0), DataType(6, 1), DataType(18, 1) ] + sink_out1 = [ ] src_opt = [ CtrlType( OPT_MUL, b1( 1 ), pickRegister ), CtrlType( OPT_MUL, b1( 1 ), pickRegister ), CtrlType( OPT_MUL, b1( 1 ), pickRegister ) ] th = TestHarness( FU, FuList, DataType, PredicateType, CtrlType, data_mem_size, num_inports, num_outports, src_in0, src_in1, src_predicate, src_opt, - sink_out, sink_out ) + sink_out0, sink_out1) run_sim( th ) def test_flexible_universal(): @@ -156,12 +154,12 @@ def test_flexible_universal(): num_inports = 2 num_outports = 2 FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(2, 1), DataType(1, 1), DataType(3, 0) ] - src_in1 = [ DataType(2, 1), DataType(0, 1), DataType(2, 1) ] src_predicate = [ PredicateType(1, 0), PredicateType(1, 1), PredicateType(1, 0) ] + pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] + src_in0 = [ DataType(2, 1), DataType(1, 1), DataType(3, 0) ] + src_in1 = [ DataType(2, 1), DataType(2, 1) ] sink_out0 = [ DataType(1, 0), DataType(0, 0), DataType(2, 1) ] - sink_out1 = [ DataType(0, 0), DataType(0, 1), DataType(0, 0) ] + sink_out1 = [ DataType(0, 1) ] src_opt = [ CtrlType( OPT_EQ , b1( 1 ), pickRegister ), CtrlType( OPT_BRH, b1( 1 ), pickRegister ), CtrlType( OPT_PHI, b1( 0 ), pickRegister ) ] diff --git a/fu/float/FpAddRTL.py b/fu/float/FpAddRTL.py index e3e23b0..12964e5 100644 --- a/fu/float/FpAddRTL.py +++ b/fu/float/FpAddRTL.py @@ -16,29 +16,26 @@ Date : Aug 8, 2023 """ - from pymtl3 import * from ..basic.Fu import Fu from ..pymtl3_hardfloat.HardFloat.AddFNRTL import AddFN -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class FpAddRTL(Fu): -class FpAddRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, exp_nbits = 4, - sig_nbits = 11 ): - super( FpAddRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size ) + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, exp_nbits = 4, + sig_nbits = 11): + super(FpAddRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) # Local parameters - assert DataType.get_field_type( 'payload' ).nbits == exp_nbits + sig_nbits + 1 + assert DataType.get_field_type('payload').nbits == exp_nbits + sig_nbits + 1 num_entries = 2 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) # TODO: parameterize rounding mode s.rounding_mode = 0b000 s.FLOATING_ONE = concat( @@ -61,70 +58,94 @@ def construct( s, DataType, PredicateType, CtrlType, s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 - if s.recv_opt.en: + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - - if s.recv_opt.msg.ctrl == OPT_FADD: - s.fadd.a @= s.recv_in[s.in0_idx].msg.payload - s.fadd.b @= s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - elif s.recv_opt.msg.ctrl == OPT_FADD_CONST: - s.fadd.a @= s.recv_in[s.in0_idx].msg.payload - s.fadd.b @= s.recv_const.msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - elif s.recv_opt.msg.ctrl == OPT_FINC: - s.fadd.a @= s.recv_in[s.in0_idx].msg.payload - s.fadd.b @= s.FLOATING_ONE - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - elif s.recv_opt.msg.ctrl == OPT_FSUB: - s.fadd.a @= s.recv_in[s.in0_idx].msg.payload - s.fadd.b @= s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - - s.send_out[0].msg.payload @= s.fadd.out + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_FADD: + s.fadd.a @= s.recv_in[s.in0_idx].msg.payload + s.fadd.b @= s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_FADD_CONST: + s.fadd.a @= s.recv_in[s.in0_idx].msg.payload + s.fadd.b @= s.recv_const.msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_FINC: + s.fadd.a @= s.recv_in[s.in0_idx].msg.payload + s.fadd.b @= s.FLOATING_ONE + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_FSUB: + s.fadd.a @= s.recv_in[s.in0_idx].msg.payload + s.fadd.b @= s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + else: + for j in range( num_outports ): + s.send_out[j].en @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + + s.send_out[0].msg.payload @= s.fadd.out + diff --git a/fu/float/FpMulRTL.py b/fu/float/FpMulRTL.py index 4194a19..0d1f627 100644 --- a/fu/float/FpMulRTL.py +++ b/fu/float/FpMulRTL.py @@ -16,49 +16,48 @@ Date : August 9, 2023 """ - from pymtl3 import * from ..basic.Fu import Fu from ..pymtl3_hardfloat.HardFloat.MulFNRTL import MulFN -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class FpMulRTL(Fu): -class FpMulRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, exp_nbits = 4, - sig_nbits = 11 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, exp_nbits = 4, + sig_nbits = 11): - super( FpMulRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size ) + super(FpMulRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) # Local parameters - assert DataType.get_field_type( 'payload' ).nbits == exp_nbits + sig_nbits + 1 + assert DataType.get_field_type('payload').nbits == exp_nbits + sig_nbits + 1 - FuInType = mk_bits( clog2( num_inports + 1) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) # TODO: parameterize rounding mode s.rounding_mode = 0b000 # Components - s.fmul = MulFN( exp_nbits+1, sig_nbits ) + s.fmul = MulFN(exp_nbits+1, sig_nbits) s.fmul.roundingMode //= s.rounding_mode # Wires - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): @@ -66,49 +65,61 @@ def comb_logic(): s.in0 @= 0 s.in1 @= 0 for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + s.recv_in[i].rdy @= b1(0) for i in range( num_outports ): s.send_out[i].en @= s.recv_opt.en s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 if s.recv_opt.en: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.msg.ctrl == OPT_FMUL: - s.fmul.a @= s.recv_in[s.in0_idx].msg.payload - s.fmul.b @= s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - elif s.recv_opt.msg.ctrl == OPT_FMUL_CONST: - s.fmul.a @= s.recv_in[s.in0_idx].msg.payload - s.fmul.b @= s.recv_const.msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - - s.send_out[0].msg.payload @= s.fmul.out + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_FMUL: + s.fmul.a @= s.recv_in[s.in0_idx].msg.payload + s.fmul.b @= s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_FMUL_CONST: + s.fmul.a @= s.recv_in[s.in0_idx].msg.payload + s.fmul.b @= s.recv_const.msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range( num_outports ): + s.send_out[j].en @= b1( 0 ) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + + s.send_out[0].msg.payload @= s.fmul.out diff --git a/fu/float/test/FpAddRTL_test.py b/fu/float/test/FpAddRTL_test.py index 292fa4a..85b3a97 100644 --- a/fu/float/test/FpAddRTL_test.py +++ b/fu/float/test/FpAddRTL_test.py @@ -15,14 +15,14 @@ from ..FpAddRTL import FpAddRTL from ...pymtl3_hardfloat.HardFloat.converter_funcs import (floatToFN, fNToFloat) -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL -round_near_even = 0b000 +round_near_even = 0b000 def test_elaborate( cmdline_opts ): DataType = mk_data( 16, 1 ) @@ -66,9 +66,6 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, s.dut = FunctionUnit( DataType, PredicateType, ConfigType, num_inports, num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_predicate.send, s.dut.recv_predicate ) diff --git a/fu/float/test/FpMulRTL_test.py b/fu/float/test/FpMulRTL_test.py index ad65198..e4af298 100644 --- a/fu/float/test/FpMulRTL_test.py +++ b/fu/float/test/FpMulRTL_test.py @@ -8,7 +8,6 @@ Date : August 10, 2023 """ - from pymtl3 import * from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) @@ -21,8 +20,7 @@ from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL - -round_near_even = 0b000 +round_near_even = 0b000 def test_elaborate( cmdline_opts ): DataType = mk_data( 16, 1 ) @@ -66,9 +64,6 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, s.dut = FunctionUnit( DataType, PredicateType, ConfigType, num_inports, num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_predicate.send, s.dut.recv_predicate ) @@ -76,11 +71,11 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out.recv ) - def done( s ): + def done(s): return s.src_in0.done() and s.src_in1.done() and \ s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() def mk_float_to_bits_fn( DataType, exp_nbits = 4, sig_nbits = 11 ): diff --git a/fu/single/AdderCL.py b/fu/single/AdderCL.py index 19cd19e..6ab2e7c 100644 --- a/fu/single/AdderCL.py +++ b/fu/single/AdderCL.py @@ -8,100 +8,134 @@ Date : Aug 5, 2023 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class AdderCL(Fu): -class AdderCL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, latency = 1 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, latency = 1): - super( AdderCL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size, latency ) + super(AdderCL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size, latency) # Constant s.const_one = DataType(1, 1) - FuInType = mk_bits( clog2( num_inports + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - idx_nbits = clog2( num_inports ) - LatencyType = mk_bits( clog2( latency + 1 ) ) + CountType = mk_bits(clog2(num_entries + 1)) + idx_nbits = clog2(num_inports) + LatencyType = mk_bits(clog2(latency + 1)) # Component - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 s.in0 @= 0 s.in1 @= 0 s.recv_predicate.rdy @= 0 # For pick input register - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= b1(0) + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 - if s.recv_opt.en: + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - - -# s.send_out[0].en = s.recv_opt.en - - if s.recv_opt.msg.ctrl == OPT_ADD: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_const.msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - elif s.recv_opt.msg.ctrl == OPT_INC: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.const_one.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - elif s.recv_opt.msg.ctrl == OPT_SUB: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_PAS: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_ADD: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_const.msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_INC: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.const_one.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_SUB: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_PAS: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + diff --git a/fu/single/AdderRTL.py b/fu/single/AdderRTL.py index cba43b9..c279b47 100644 --- a/fu/single/AdderRTL.py +++ b/fu/single/AdderRTL.py @@ -8,98 +8,131 @@ Date : November 27, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class AdderRTL(Fu): -class AdderRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( AdderRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size ) + super(AdderRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) s.const_one = DataType(1, 1) - FuInType = mk_bits( clog2( num_inports + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + CountType = mk_bits(clog2(num_entries + 1)) - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 s.in0 @= 0 s.in1 @= 0 - s.recv_predicate.rdy @= 0 # For pick input register - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 - if s.recv_opt.en: + # Though different operations might not need to consume + # all the operands, as long as the opcode indicating it + # is an operand, the data would disappear from the register. + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - - -# s.send_out[0].en = s.recv_opt.en - - if s.recv_opt.msg.ctrl == OPT_ADD: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_const.msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - elif s.recv_opt.msg.ctrl == OPT_INC: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.const_one.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - elif s.recv_opt.msg.ctrl == OPT_SUB: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_PAS: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_ADD: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_const.msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_const.rdy @= s.send_out[0].rdy + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_INC: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.const_one.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_SUB: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_PAS: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + diff --git a/fu/single/BranchRTL.py b/fu/single/BranchRTL.py index bb0c6cf..d4cc886 100644 --- a/fu/single/BranchRTL.py +++ b/fu/single/BranchRTL.py @@ -8,102 +8,111 @@ Date : December 1, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class BranchRTL(Fu): -class BranchRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( BranchRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(BranchRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - s.first = Wire( b1 ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) + s.first = Wire(b1) - ZeroType = mk_bits( s.const_zero.payload.nbits ) + ZeroType = mk_bits(s.const_zero.payload.nbits) - # TODO: declare in0 as wire - s.in0 = Wire( FuInType ) + s.in0 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 - # in1 = FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) - - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) -# if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): -# in1 = s.recv_opt.msg.fu_in[1] - FuInType( 1 ) -# s.recv_in[in1].rdy = b1( 1 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - if s.recv_opt.msg.ctrl == OPT_BRH: - # Branch is only used to set predication rather than delivering value. - s.send_out[0].msg @= DataType(ZeroType( 0 ), b1( 0 ), b1( 0 ), b1( 0 ) ) - s.send_out[1].msg @= DataType(ZeroType( 0 ), b1( 0 ), b1( 0 ), b1( 0 ) ) - if s.recv_in[s.in0_idx].msg.payload == s.const_zero.payload: - s.send_out[0].msg.predicate @= Bits1( 1 ) - s.send_out[1].msg.predicate @= Bits1( 0 ) - else: - s.send_out[0].msg.predicate @= Bits1( 0 ) - s.send_out[1].msg.predicate @= Bits1( 1 ) - elif s.recv_opt.msg.ctrl == OPT_BRH_START: - s.send_out[0].msg @= DataType(ZeroType( 0 ), b1( 0 ), b1( 0 ), b1( 0 ) ) - s.send_out[1].msg @= DataType(ZeroType( 0 ), b1( 0 ), b1( 0 ), b1( 0 ) ) - if s.first: - s.send_out[0].msg.predicate @= Bits1( 1 ) - s.send_out[1].msg.predicate @= Bits1( 0 ) - else: - s.send_out[0].msg.predicate @= Bits1( 0 ) - s.send_out[1].msg.predicate @= Bits1( 1 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy & s.send_out[1].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_BRH: + # Branch is only used to set predication rather than delivering value. + s.send_out[0].msg @= DataType(ZeroType(0), b1(0), b1(0), b1(0)) + s.send_out[1].msg @= DataType(ZeroType(0), b1(0), b1(0), b1(0)) + if s.recv_in[s.in0_idx].msg.payload == s.const_zero.payload: + s.send_out[0].msg.predicate @= (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.send_out[1].msg.predicate @= Bits1(0) + else: + s.send_out[0].msg.predicate @= Bits1(0) + s.send_out[1].msg.predicate @= (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.send_out[1].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy & s.send_out[1].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy & s.send_out[1].rdy + + elif s.recv_opt.msg.ctrl == OPT_BRH_START: + s.send_out[0].msg @= DataType(ZeroType(0), b1(0), b1(0), b1(0)) + s.send_out[1].msg @= DataType(ZeroType(0), b1(0), b1(0), b1(0)) + # branch_start could be the entry of a function, which runs + # only once. + if s.first: + s.send_out[0].msg.predicate @= Bits1(1) + s.send_out[1].msg.predicate @= Bits1(0) + else: + s.send_out[0].msg.predicate @= Bits1(0) + s.send_out[1].msg.predicate @= Bits1(1) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.send_out[1].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy & s.send_out[1].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy & s.send_out[1].rdy - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + else: + for j in range( num_outports ): + s.send_out[j].val @= b1( 0 ) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 - if (s.recv_opt.msg.predicate == 1) & (s.recv_opt.msg.ctrl != OPT_BRH_START): - # The operation executed on the first cycle gets no input predicate. - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - s.send_out[1].msg.predicate @= s.send_out[1].msg.predicate & \ - s.recv_predicate.msg.predicate + if (s.recv_opt.msg.predicate == 1) & \ + (s.recv_opt.msg.ctrl != OPT_BRH_START): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy & s.send_out[1].rdy # branch_start could be the entry of a function, which is executed by # only once. @update_ff def br_start_once(): if s.reset: - s.first <<= b1( 1 ) + s.first <<= b1(1) if s.recv_opt.msg.ctrl == OPT_BRH_START: - s.first <<= b1( 0 ) - - + s.first <<= b1(0) def line_trace( s ): symbol0 = "?" @@ -121,4 +130,5 @@ def line_trace( s ): symbol0 = " " symbol1 = "*" winner = " true " - return f'[{s.recv_in[0].msg}|{s.recv_in[1].msg}] => ([{s.send_out[0].msg} {symbol0}] ({winner}) [{s.send_out[1].msg}(first:{s.first}) {symbol1}])' + return f'[{s.recv_in[0].msg}|{s.recv_in[1].msg}] => ([{s.send_out[0].msg} {symbol0}] (wnner: {winner}) [{s.send_out[1].msg}(first:{s.first}) {symbol1}])' + diff --git a/fu/single/CompRTL.py b/fu/single/CompRTL.py index 978d683..d086aef 100644 --- a/fu/single/CompRTL.py +++ b/fu/single/CompRTL.py @@ -8,104 +8,116 @@ Date : December 2, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class CompRTL(Fu): -class CompRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size): - super( CompRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size ) + super(CompRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) - s.const_one = DataType(1, 0) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + num_entries = 2 + s.const_one = DataType(1, 0) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) # data: s.recv_in[0] # reference: s.recv_in[1] (or recv_const) - # TODO: declare in0 and in1 as wires - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def read_reg(): + s.recv_all_val @= 0 # For pick input register - s.in0 @= FuInType( 0 ) - s.in1 @= FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - s.recv_predicate.rdy @= b1( 0 ) - if s.recv_opt.en: + s.in0 @= FuInType(0) + s.in1 @= FuInType(0) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 + s.send_out[i].msg @= DataType() + + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - predicate = s.recv_in[s.in0_idx].msg.predicate & s.recv_in[s.in1_idx].msg.predicate - s.send_out[0].msg @= s.const_one - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en - - if s.recv_opt.msg.ctrl == OPT_EQ: - if s.recv_in[s.in0_idx].msg.payload == s.recv_in[s.in1_idx].msg.payload: - s.send_out[0].msg @= s.const_one - s.send_out[0].msg.predicate @= predicate - else: - s.send_out[0].msg @= s.const_zero - s.send_out[0].msg.predicate @= predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - elif s.recv_opt.msg.ctrl == OPT_EQ_CONST: - if s.recv_in[s.in0_idx].msg.payload == s.recv_const.msg.payload: - s.send_out[0].msg @= s.const_one - s.send_out[0].msg.predicate @= b1( 1 ) - else: - s.send_out[0].msg @= s.const_zero - s.send_out[0].msg.predicate @= b1( 1 ) + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_EQ: + if s.recv_in[s.in0_idx].msg.payload == s.recv_in[s.in1_idx].msg.payload: + s.send_out[0].msg @= s.const_one + else: + s.send_out[0].msg @= s.const_zero + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_EQ_CONST: + if s.recv_in[s.in0_idx].msg.payload == s.recv_const.msg.payload: + s.send_out[0].msg @= s.const_one + else: + s.send_out[0].msg @= s.const_zero + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_LT: + if s.recv_in[s.in0_idx].msg.payload < s.recv_in[s.in1_idx].msg.payload: + s.send_out[0].msg @= s.const_one + else: + s.send_out[0].msg @= s.const_zero + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy - elif s.recv_opt.msg.ctrl == OPT_LT: - if s.recv_in[s.in0_idx].msg.payload < s.recv_in[s.in1_idx].msg.payload: - s.send_out[0].msg @= s.const_one - s.send_out[0].msg.predicate @= predicate else: - s.send_out[0].msg @= s.const_zero - s.send_out[0].msg.predicate @= predicate - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - # TODO: and -> & - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + diff --git a/fu/single/LogicRTL.py b/fu/single/LogicRTL.py index 466c45f..cb6722b 100644 --- a/fu/single/LogicRTL.py +++ b/fu/single/LogicRTL.py @@ -8,82 +8,114 @@ Date : November 28, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * -class LogicRTL( Fu ): +class LogicRTL(Fu): - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size): - super( LogicRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(LogicRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) - # TODO: declare in0 and in1 as wire - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) for i in range( num_outports ): - s.send_out[i].en @= b1( 0 ) + s.send_out[i].val @= b1(0) s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) - - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en - if s.recv_opt.msg.ctrl == OPT_OR: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload | s.recv_in[s.in1_idx].msg.payload - elif s.recv_opt.msg.ctrl == OPT_AND: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload & s.recv_in[s.in1_idx].msg.payload - elif s.recv_opt.msg.ctrl == OPT_NOT: - s.send_out[0].msg.payload @= ~ s.recv_in[s.in0_idx].msg.payload - elif s.recv_opt.msg.ctrl == OPT_XOR: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload ^ s.recv_in[s.in1_idx].msg.payload - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if ( (s.recv_opt.msg.ctrl == OPT_OR) | (s.recv_opt.msg.ctrl == OPT_AND) | \ - (s.recv_opt.msg.ctrl == OPT_XOR) ) & s.recv_opt.en & \ - ( (s.recv_in_count[s.in0_idx] == 0) | (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_OR: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload | s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_AND: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload & s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_NOT: + s.send_out[0].msg.payload @= ~ s.recv_in[s.in0_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_XOR: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload ^ s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.send_out[0].rdy & (s.recv_opt.msg.predicate == b1(1)): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + diff --git a/fu/single/MemUnitRTL.py b/fu/single/MemUnitRTL.py index 8e8a37d..d1adf91 100644 --- a/fu/single/MemUnitRTL.py +++ b/fu/single/MemUnitRTL.py @@ -2,188 +2,195 @@ ========================================================================== MemUnitRTL.py ========================================================================== -Scratchpad memory access unit for (the left most) CGRA tiles. +Scratchpad memory access unit for CGRA tiles. Author : Cheng Tan Date : November 29, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL, ValRdyRecvIfcRTL from ...lib.opt_type import * +class MemUnitRTL(Component): -class MemUnitRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) - num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) + num_entries = 2 + AddrType = mk_bits(clog2(data_mem_size)) + CountType = mk_bits(clog2(num_entries + 1)) + FuInType = mk_bits(clog2(num_inports + 1)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [ValRdyRecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_predicate = ValRdyRecvIfcRTL(PredicateType) + s.recv_const = ValRdyRecvIfcRTL(DataType) + s.recv_opt = ValRdyRecvIfcRTL(CtrlType) + s.send_out = [ValRdySendIfcRTL(DataType) for _ in range(num_outports)] # Interface to the data sram, need to interface them with # the data memory module in top level - s.to_mem_raddr = SendIfcRTL( AddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( AddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) + s.to_mem_raddr = ValRdySendIfcRTL(AddrType) + s.from_mem_rdata = ValRdyRecvIfcRTL(DataType) + s.to_mem_waddr = ValRdySendIfcRTL(AddrType) + s.to_mem_wdata = ValRdySendIfcRTL(DataType) - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] # Components - s.recv_rdy_vector = Wire( num_outports ) - s.recv_in_en_vector = Wire( num_inports ) + s.recv_in_val_vector = Wire(num_inports) + s.recv_all_val = Wire(1) @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register - s.in0 @= FuInType( 0 ) - s.in1 @= FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - - s.recv_predicate.rdy @= b1( 0 ) - - if s.recv_opt.en: + s.in0 @= FuInType(0) + s.in1 @= FuInType(0) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 + s.send_out[i].msg @= DataType() + + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: - s.in0 @= zext( s.recv_opt.msg.fu_in[0] - 1, FuInType ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) + s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) if s.recv_opt.msg.fu_in[1] != 0: - s.in1 @= zext( s.recv_opt.msg.fu_in[1] - 1, FuInType ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - for j in range( num_outports ): - # s.recv_const.rdy @= s.send_out[j].rdy | s.recv_const.rdy - s.recv_rdy_vector[j] @= s.send_out[j].rdy - - # for j in range( num_outports ): - # s.recv_opt.rdy @= s.send_out[j].rdy | s.recv_opt.rdy - s.recv_const.rdy @= reduce_or( s.recv_rdy_vector ) - s.recv_opt.rdy @= reduce_or( s.recv_rdy_vector ) - - # for j in range( num_outports ): - # for i in range( num_inports ): - # s.send_out[j].en @= s.recv_in[i].en | s.send_out[j].en - # s.send_out[j].en @= s.send_out[j].en & s.recv_opt.en - - for i in range( num_inports ): - s.recv_in_en_vector[i] @= s.recv_in[i].en - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en & reduce_or( s.recv_in_en_vector) - - s.send_out[0].msg @= s.from_mem_rdata.msg - - s.to_mem_waddr.en @= 0 - s.to_mem_waddr.msg @= AddrType() - s.to_mem_wdata.en @= 0 - s.to_mem_wdata.msg @= DataType() - s.to_mem_raddr.en @= 0 - s.to_mem_raddr.msg @= AddrType() - s.from_mem_rdata.rdy @= 0 - - if s.recv_opt.msg.ctrl == OPT_LD: - s.recv_in[s.in0_idx].rdy @= s.to_mem_raddr.rdy - s.recv_in[s.in1_idx].rdy @= s.from_mem_rdata.rdy - # s.to_mem_raddr.msg @= AddrType( s.recv_in[s.in0_idx].msg.payload ) - s.to_mem_raddr.msg @= AddrType( s.recv_in[s.in0_idx].msg.payload[0:AddrType.nbits] ) - s.to_mem_raddr.en @= s.recv_in[s.in0_idx].en - s.from_mem_rdata.rdy @= s.send_out[0].rdy - s.send_out[0].msg @= s.from_mem_rdata.msg - s.send_out[0].en @= s.recv_opt.en - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - - # LD_CONST indicates the address is a const. - elif s.recv_opt.msg.ctrl == OPT_LD_CONST: - for i in range( num_inports): - s.recv_in[i].rdy @= b1( 0 ) - s.recv_const.rdy @= s.to_mem_raddr.rdy - s.to_mem_raddr.msg @= AddrType( s.recv_const.msg.payload[0:AddrType.nbits] ) - s.to_mem_raddr.en @= s.recv_const.en - s.from_mem_rdata.rdy @= s.send_out[0].rdy - s.send_out[0].msg @= s.from_mem_rdata.msg - s.send_out[0].en @= s.recv_opt.en - # Const's predicate will always be true. - s.send_out[0].msg.predicate @= b1( 1 ) - - elif s.recv_opt.msg.ctrl == OPT_STR: - # s.send_out[0].en @= s.from_mem_rdata.en & s.recv_in[s.in0_idx].en & s.recv_in[s.in1_idx].en - s.recv_in[s.in0_idx].rdy @= s.to_mem_waddr.rdy - s.recv_in[s.in1_idx].rdy @= s.to_mem_wdata.rdy - # s.to_mem_waddr.msg @= AddrType( s.recv_in[0].msg.payload ) - s.to_mem_waddr.msg @= AddrType( s.recv_in[0].msg.payload[0:AddrType.nbits] ) - s.to_mem_waddr.en @= s.recv_in[s.in0_idx].en - s.to_mem_wdata.msg @= s.recv_in[s.in1_idx].msg - s.to_mem_wdata.en @= s.recv_in[s.in1_idx].en - - # `send_out` is meaningless for store operation. - s.send_out[0].en @= b1( 0 ) - s.send_out[0].msg @= s.to_mem_wdata.msg - # s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - # s.recv_in[s.in1_idx].msg.predicate - s.send_out[0].msg.predicate @= b1(0) - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - # s.send_out[0].msg.predicate @= b1( 0 ) - - # STR_CONST indicates the address is a const. - elif s.recv_opt.msg.ctrl == OPT_STR_CONST: - s.recv_const.rdy @= s.to_mem_waddr.rdy - - # Only needs one input register to indicate the storing data. - s.recv_in[s.in0_idx].rdy @= s.to_mem_wdata.rdy - s.to_mem_waddr.msg @= AddrType( s.recv_const.msg.payload[0:AddrType.nbits] ) - s.to_mem_waddr.en @= s.recv_const.en - s.to_mem_wdata.msg @= s.recv_in[s.in0_idx].msg - s.to_mem_wdata.en @= s.recv_in[s.in0_idx].en - - # `send_out` is meaningless for store operation. - s.send_out[0].en @= b1( 0 ) - s.send_out[0].msg @= s.to_mem_wdata.msg - s.send_out[0].msg.predicate @= b1(0) - if s.recv_opt.en & (s.recv_in_count[s.in0_idx] == 0): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) + + s.to_mem_waddr.val @= 0 + s.to_mem_waddr.msg @= AddrType() + s.to_mem_wdata.val @= 0 + s.to_mem_wdata.msg @= DataType() + s.to_mem_raddr.val @= 0 + s.to_mem_raddr.msg @= AddrType() + s.from_mem_rdata.rdy @= 0 + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_LD: + # s.recv_in[s.in0_idx].rdy @= s.to_mem_raddr.rdy + # s.recv_in[s.in1_idx].rdy @= s.from_mem_rdata.rdy + # s.to_mem_raddr.val @= s.recv_in[s.in0_idx].val + # s.from_mem_rdata.rdy @= s.send_out[0].rdy + # s.send_out[0].val @= s.recv_opt.val & \ + # s.recv_in[s.in0_idx].val & \ + # s.recv_in[s.in1_idx].val & \ + # s.from_mem_rdata.val & \ + # s.to_mem_raddr.val + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) # FIXME: Use ~ after checking translation + # FIXME: to_mem_raddr shouldn't be ready if the existing request not yet returned. + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.to_mem_raddr.rdy + s.to_mem_raddr.msg @= AddrType(s.recv_in[s.in0_idx].msg.payload[0:AddrType.nbits]) + s.to_mem_raddr.val @= s.recv_all_val + s.from_mem_rdata.rdy @= s.send_out[0].rdy + # FIXME: As the memory access might take more than one cycle, + # the send_out valid no need to depend on recv_all_val. + s.send_out[0].val @= s.from_mem_rdata.val + s.send_out[0].msg @= s.from_mem_rdata.msg + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.from_mem_rdata.msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_opt.rdy @= s.send_out[0].rdy & s.from_mem_rdata.val + if s.recv_opt.msg.predicate == 1: + s.recv_predicate.rdy @= s.from_mem_rdata.val & s.send_out[0].rdy + + # LD_CONST indicates the address is a const. + elif s.recv_opt.msg.ctrl == OPT_LD_CONST: + s.recv_all_val @= s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.recv_const.rdy @= s.recv_all_val & s.to_mem_raddr.rdy + s.to_mem_raddr.msg @= AddrType(s.recv_const.msg.payload[0:AddrType.nbits]) + s.to_mem_raddr.val @= s.recv_all_val + s.from_mem_rdata.rdy @= s.send_out[0].rdy + s.send_out[0].val @= s.from_mem_rdata.val + s.send_out[0].msg @= s.from_mem_rdata.msg + s.send_out[0].msg.predicate @= s.recv_const.msg.predicate & \ + s.from_mem_rdata.msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_opt.rdy @= s.send_out[0].rdy & s.from_mem_rdata.val + if s.recv_opt.msg.predicate == 1: + s.recv_predicate.rdy @= s.from_mem_rdata.val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_STR: + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + s.to_mem_waddr.msg @= AddrType(s.recv_in[0].msg.payload[0:AddrType.nbits]) + s.to_mem_waddr.val @= s.recv_all_val + s.to_mem_wdata.msg @= s.recv_in[s.in1_idx].msg + s.to_mem_wdata.msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.to_mem_wdata.val @= s.recv_all_val + + # `send_out` is meaningless for store operation. + s.send_out[0].val @= b1(0) + + s.recv_opt.rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + + if s.recv_opt.msg.predicate == 1: + s.recv_predicate.rdy @= s.recv_all_val + + # STR_CONST indicates the address is a const. + elif s.recv_opt.msg.ctrl == OPT_STR_CONST: + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.recv_const.rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + # Only needs one input register to indicate the storing data. + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + s.to_mem_waddr.msg @= AddrType(s.recv_const.msg.payload[0:AddrType.nbits]) + s.to_mem_waddr.val @= s.recv_all_val + s.to_mem_wdata.msg @= s.recv_in[s.in0_idx].msg + s.to_mem_wdata.msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_const.msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.to_mem_wdata.val @= s.recv_all_val + + # `send_out` is meaningless for store operation. + s.send_out[0].val @= b1(0) + + s.recv_opt.rdy @= s.recv_all_val & s.to_mem_waddr.rdy & s.to_mem_wdata.rdy + + if s.recv_opt.msg.predicate == 1: + s.recv_predicate.rdy @= s.recv_all_val + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 def line_trace( s ): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].en: {s.send_out[0].en}) <{s.recv_const.en}|{s.recv_const.msg}>' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].val: {s.send_out[0].val}) <{s.recv_const.val}|{s.recv_const.msg}>' + diff --git a/fu/single/MulRTL.py b/fu/single/MulRTL.py index 466aff9..111f0a3 100644 --- a/fu/single/MulRTL.py +++ b/fu/single/MulRTL.py @@ -8,87 +8,103 @@ Date : November 28, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class MulRTL(Fu): -class MulRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( MulRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(MulRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) - - # TOOD: declare in0 in1 as wires - # use & | instead of and or + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 - if s.recv_opt.en: + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) - s.recv_in[s.in0_idx].rdy @= b1(1) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1(1): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - - if s.recv_opt.msg.ctrl == OPT_MUL: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload * s.recv_in[s.in1_idx].msg.payload - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_MUL_CONST: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload * s.recv_const.msg.payload - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate - elif s.recv_opt.msg.ctrl == OPT_DIV: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload / s.recv_in[s.in1_idx].msg.payload - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_MUL: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload * s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_MUL_CONST: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload * s.recv_const.msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_DIV: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload / s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.send_out[0].rdy & (s.recv_opt.msg.predicate == b1(1)): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy diff --git a/fu/single/NahRTL.py b/fu/single/NahRTL.py new file mode 100644 index 0000000..aadcf9b --- /dev/null +++ b/fu/single/NahRTL.py @@ -0,0 +1,46 @@ +""" +========================================================================== +NahRTL.py +========================================================================== +Handling nothing, but proceeding ctrl index. + +Author : Cheng Tan + Date : Dec 28, 2024 +""" + +from pymtl3 import * +from ..basic.Fu import Fu +from ...lib.opt_type import * + +class NahRTL(Fu): + + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): + + super(NahRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) + + @update + def comb_logic(): + + s.recv_const.rdy @= 0 + s.recv_opt.rdy @= 0 + # For pick input register + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + + for i in range( num_outports ): + # s.send_out[i].val @= s.recv_opt.val + s.send_out[i].val @= 0 + s.send_out[i].msg @= DataType() + + s.recv_predicate.rdy @= b1(0) + + if s.recv_opt.msg.ctrl == OPT_NAH: + s.recv_opt.rdy @= 1 + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + diff --git a/fu/single/PhiRTL.py b/fu/single/PhiRTL.py index e770a18..bfca4cb 100644 --- a/fu/single/PhiRTL.py +++ b/fu/single/PhiRTL.py @@ -8,116 +8,144 @@ Date : November 30, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * import copy +class PhiRTL(Fu): -class PhiRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size): - super( PhiRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(PhiRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) + s.first = Wire(b1) - # TODO: declare in0 in1 as wires - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) - - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - if s.recv_opt.msg.ctrl == OPT_PHI: - if s.recv_in[s.in0_idx].msg.predicate == Bits1( 1 ): - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.send_out[0].msg.predicate @= Bits1( 1 ) - elif s.recv_in[s.in1_idx].msg.predicate == Bits1( 1 ): - s.send_out[0].msg.payload @= s.recv_in[s.in1_idx].msg.payload - s.send_out[0].msg.predicate @= Bits1( 1 ) - else: # No predecessor is active. - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload - s.send_out[0].msg.predicate @= Bits1( 0 ) - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.recv_predicate.rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - if (s.recv_opt.msg.predicate == b1( 1 )) & \ - (s.recv_predicate.msg.payload == b1( 0 )): - s.recv_predicate.rdy @= b1( 0 ) - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - - elif s.recv_opt.msg.ctrl == OPT_PHI_CONST: - - s.send_out[0].msg.predicate @= Bits1( 1 ) - if s.recv_in[s.in0_idx].msg.predicate == Bits1( 1 ): - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_PHI: + if s.recv_in[s.in0_idx].msg.predicate == Bits1(1): + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.send_out[0].msg.predicate @= (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + elif s.recv_in[s.in1_idx].msg.predicate == Bits1(1): + s.send_out[0].msg.payload @= s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + else: # No predecessor is active. + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + s.send_out[0].msg.predicate @= Bits1(0) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + + # if (s.recv_opt.msg.predicate == b1(1)) & \ + # (s.recv_predicate.msg.payload == b1(0)): + # s.recv_predicate.rdy @= b1(0) + # s.recv_in[s.in0_idx].rdy @= b1(0) + # s.recv_in[s.in1_idx].rdy @= b1(0) + # s.recv_opt.rdy @= 0 + # s.send_out[0].val @= 0 + + elif s.recv_opt.msg.ctrl == OPT_PHI_CONST: + if s.recv_in[s.in0_idx].msg.predicate == Bits1(1): + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload + else: + s.send_out[0].msg.payload @= s.recv_const.msg.payload + + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val & \ + ((s.recv_opt.msg.predicate == b1(0)) | \ + (s.recv_predicate.val & ~s.first) | s.first) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + # Predication signal not arrive yet. + #if ~s.first & \ + # (s.recv_opt.msg.predicate == b1(1)) & \ + # (s.recv_predicate.msg.payload == b1(0)): + # s.recv_in[s.in0_idx].rdy @= b1(0) + # s.recv_opt.rdy @= 0 + # s.recv_const.rdy @= 0 + # s.send_out[0].val @= 0 + # No need to consume predication signal if opcode doesn't indicate that. + if s.first: + s.send_out[0].msg.predicate @= Bits1(1) + s.recv_predicate.rdy @= 0 + elif ~s.first & (s.recv_opt.msg.predicate == 0): + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate + s.recv_predicate.rdy @= 0 + elif s.recv_opt.msg.predicate == 1: + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (s.recv_predicate.msg.payload == 1) + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + else: - s.send_out[0].msg.payload @= s.recv_const.msg.payload - - # Predication signal not arrive yet. - if (s.recv_opt.msg.predicate == b1( 1 )) & \ - (s.recv_predicate.msg.payload == b1( 0 )): - #s.recv_predicate.rdy = b1( 0 ) - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - # The PHI_CONST operation executed an the first time does not need predication signal. - if s.recv_opt.msg.ctrl == OPT_PHI_CONST: - if s.recv_predicate.msg.payload == b1( 0 ): - s.send_out[0].msg.predicate @= b1( 1 ) -# ( s.recv_predicate.msg.payload == b1( 0 ) ) - - def line_trace( s ): + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + # branch_start could be the entry of a function, which is executed by + # only once. + @update_ff + def br_start_once(): + if s.reset: + s.first <<= b1(1) + if s.recv_opt.msg.ctrl == OPT_PHI_CONST: + s.first <<= b1(0) + + def line_trace(s): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].val: {s.send_out[0].val}) ' + diff --git a/fu/single/RetRTL.py b/fu/single/RetRTL.py index 6256e9a..a56d5f5 100644 --- a/fu/single/RetRTL.py +++ b/fu/single/RetRTL.py @@ -8,79 +8,79 @@ Date : September 21, 2021 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class RetRTL(Fu): -class RetRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size ): - super( RetRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(RetRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) - idx_nbits = clog2( num_inports ) + idx_nbits = clog2(num_inports) - s.in0 = Wire( FuInType ) - s.in0_idx = Wire( idx_nbits ) + s.in0 = Wire(FuInType) + s.in0_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] - s.send_out_predicate = Wire( 1 ) - # TODO: declare in0 as wire + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) - s.recv_predicate.rdy @= b1( 0 ) - s.send_out_predicate @= b1( 0 ) - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en + for j in range(num_outports): + s.send_out[j].val @= 0 s.send_out[j].msg @= DataType() - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - if s.recv_opt.msg.ctrl == OPT_RET: - # Branch is only used to set predication rather than delivering value. - # payload, predicate, bypass, delay - s.send_out[0].msg @= DataType(s.recv_in[s.in0_idx].msg.payload, b1(0), b1(0), b1(0)) - if s.recv_in[s.in0_idx].msg.predicate == b1( 0 ):#s.const_zero.payload: - s.send_out_predicate @= 0 + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_RET: + # Branch is only used to set predication rather than delivering value. + # payload, predicate, bypass, delay + s.send_out[0].msg @= DataType(s.recv_in[s.in0_idx].msg.payload, b1(0), b1(0), b1(0)) + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy else: - s.send_out_predicate @= 1 - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out_predicate & \ - s.recv_predicate.msg.predicate + if s.send_out[0].rdy & s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy - - def line_trace( s ): + def line_trace(s): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].val: {s.send_out[0].val}) ' + diff --git a/fu/single/SelRTL.py b/fu/single/SelRTL.py index 85eeab7..f153b3e 100644 --- a/fu/single/SelRTL.py +++ b/fu/single/SelRTL.py @@ -8,129 +8,124 @@ Date : May 23, 2020 """ - from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL, ValRdyRecvIfcRTL from ...lib.opt_type import * +class SelRTL(Component): -class SelRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size=4 ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size = 4): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) - s.const_zero = DataType(0, 0) - s.true = DataType(1, 1) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + num_entries = 2 + AddrType = mk_bits(clog2(data_mem_size)) + s.const_zero = DataType(0, 0) + s.true = DataType(1, 1) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_predicate = RecvIfcRTL( PredicateType ) - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [ValRdyRecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_predicate = ValRdyRecvIfcRTL(PredicateType) + s.recv_const = ValRdyRecvIfcRTL(DataType) + s.recv_opt = ValRdyRecvIfcRTL(CtrlType) + s.send_out = [ValRdySendIfcRTL(DataType) for _ in range(num_outports)] # Redundant interfaces for MemUnit - s.to_mem_raddr = SendIfcRTL( AddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( AddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) - - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) - s.in2 = Wire( FuInType ) - - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) - s.in2_idx = Wire( idx_nbits ) + s.to_mem_raddr = ValRdySendIfcRTL(AddrType) + s.from_mem_rdata = ValRdyRecvIfcRTL(DataType) + s.to_mem_waddr = ValRdySendIfcRTL(AddrType) + s.to_mem_wdata = ValRdySendIfcRTL(DataType) + + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) + s.in2 = Wire(FuInType) + + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) + s.in2_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] s.in2_idx //= s.in2[0:idx_nbits] # Components - s.recv_rdy_vector = Wire( num_outports ) + s.recv_all_val = Wire(1) @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) - s.to_mem_wdata.msg @= s.const_zero - s.to_mem_waddr.msg @= AddrType( 0 ) - s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) - s.from_mem_rdata.rdy @= b1( 0 ) - - # TODO: declare in0 in1 in2 as wires + s.to_mem_waddr.val @= b1(0) + s.to_mem_wdata.val @= b1(0) + s.to_mem_wdata.msg @= s.const_zero + s.to_mem_waddr.msg @= AddrType(0) + s.to_mem_raddr.msg @= AddrType(0) + s.to_mem_raddr.val @= b1(0) + s.from_mem_rdata.rdy @= b1(0) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register, Selector needs at least 3 inputs - s.in0 @= FuInType( 0 ) - s.in1 @= FuInType( 0 ) - s.in2 @= FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - - s.recv_predicate.rdy @= b1( 0 ) - for i in range( num_outports ): - s.send_out[i].en @= 0 + s.in0 @= FuInType(0) + s.in1 @= FuInType(0) + s.in2 @= FuInType(0) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= s.send_out[0].rdy + + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[2] != FuInType( 0 ): - s.in2 @= s.recv_opt.msg.fu_in[2] - FuInType( 1 ) - s.recv_in[s.in2_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - for j in range( num_outports ): - # s.recv_const.rdy @= s.send_out[j].rdy | s.recv_const.rdy - # s.recv_opt.rdy @= s.send_out[j].rdy | s.recv_opt.rdy - s.recv_rdy_vector[j] @= s.send_out[j].rdy - s.recv_const.rdy @= reduce_or( s.recv_rdy_vector ) - s.recv_opt.rdy @= reduce_or( s.recv_rdy_vector ) - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en - if s.recv_opt.msg.ctrl == OPT_SEL: - if s.recv_in[s.in0_idx].msg.payload == s.true.payload: - s.send_out[0].msg @= s.recv_in[s.in1_idx].msg + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + if s.recv_opt.msg.fu_in[2] != FuInType(0): + s.in2 @= s.recv_opt.msg.fu_in[2] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_SEL: + if s.recv_in[s.in0_idx].msg.payload == s.true.payload: + s.send_out[0].msg @= s.recv_in[s.in1_idx].msg + else: + s.send_out[0].msg @= s.recv_in[s.in2_idx].msg + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + s.recv_in[s.in2_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ + s.recv_in[s.in1_idx].val & \ + s.recv_in[s.in2_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in2_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy else: - s.send_out[0].msg @= s.recv_in[s.in2_idx].msg - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) | \ - (s.recv_in_count[s.in2_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.recv_in[s.in2_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate - - def line_trace( s ): + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + s.recv_in[s.in2_idx].rdy @= 0 + + if s.send_out[0].rdy & (s.recv_opt.msg.predicate == b1(1)): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + + def line_trace(s): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}, predicate_reg: {s.recv_predicate.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, send[0].val: {s.send_out[0].val}) ' diff --git a/fu/single/ShifterRTL.py b/fu/single/ShifterRTL.py index ed3e0fd..5c28ea8 100644 --- a/fu/single/ShifterRTL.py +++ b/fu/single/ShifterRTL.py @@ -8,79 +8,92 @@ Date : November 28, 2019 """ - from pymtl3 import * from ..basic.Fu import Fu -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * +class ShifterRTL(Fu): -class ShifterRTL( Fu ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size): - super( ShifterRTL, s ).construct( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + super(ShifterRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) - FuInType = mk_bits( clog2( num_inports + 1 ) ) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) - # TODO: replace `and` `or` with & | - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] + + s.recv_all_val = Wire(1) + @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register - s.in0 @= FuInType( 0 ) - s.in1 @= FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + s.in0 @= FuInType(0) + s.in1 @= FuInType(0) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() - s.recv_predicate.rdy @= b1( 0 ) - - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) - - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.msg.ctrl == OPT_LLS: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload << s.recv_in[s.in1_idx].msg.payload - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - elif s.recv_opt.msg.ctrl == OPT_LRS: - s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload >> s.recv_in[s.in1_idx].msg.payload - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if s.recv_opt.msg.predicate == b1( 1 ): - s.send_out[0].msg.predicate @= s.send_out[0].msg.predicate & \ - s.recv_predicate.msg.predicate + s.recv_const.rdy @= 0 + s.recv_predicate.rdy @= b1(0) + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_LLS: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload << s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_LRS: + s.send_out[0].msg.payload @= s.recv_in[s.in0_idx].msg.payload >> s.recv_in[s.in1_idx].msg.payload + s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ + s.recv_in[s.in1_idx].msg.predicate & \ + (~s.recv_opt.msg.predicate | \ + s.recv_predicate.msg.predicate) + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range(num_outports): + s.send_out[j].val @= b1(0) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 + + if s.send_out[0].rdy & s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= s.recv_all_val & s.send_out[0].rdy + diff --git a/fu/single/test/AdderCL_test.py b/fu/single/test/AdderCL_test.py index e4e0842..02283a3 100644 --- a/fu/single/test/AdderCL_test.py +++ b/fu/single/test/AdderCL_test.py @@ -11,8 +11,8 @@ from pymtl3 import * from ..AdderCL import AdderCL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL @@ -22,54 +22,52 @@ # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src2_msgs, src_const, - ctrl_msgs, sink_msgs, latency ): - - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src2_msgs ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) - - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - latency ) - - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.dut.recv_const, s.const_queue.send_const ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) - - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out.done() - - def line_trace( s ): +class TestHarness(Component): + + def construct(s, FunctionUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src2_msgs, src_const, + ctrl_msgs, sink_msgs, latency): + + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_predicate = TestSrcRTL(PredicateType, src2_msgs) + s.src_opt = TestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = TestSinkRTL(DataType, sink_msgs) + + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + latency) + + connect(s.src_in0.send, s.dut.recv_in[0]) + connect(s.src_in1.send, s.dut.recv_in[1]) + connect(s.src_predicate.send, s.dut.recv_predicate) + connect(s.dut.recv_const, s.const_queue.send_const) + connect(s.src_opt.send, s.dut.recv_opt) + connect(s.dut.send_out[0], s.sink_out.recv) + + def done(s): + return s.src_in0.done() and \ + s.src_opt.done() and \ + s.sink_out.done() + + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -79,27 +77,28 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() def test_alu(): - FU = AdderCL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() + FU = AdderCL + DataType = mk_data(16, 1) + PredType = mk_predicate(1, 1) + ConfigType = mk_ctrl() data_mem_size = 8 - num_inports = 2 - num_outports = 1 - latency = 4 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ DataType(6, 0), DataType(4, 0), DataType(11, 1) ] - src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out, latency ) - run_sim( th ) + num_inports = 2 + num_outports = 1 + latency = 4 + FuInType = mk_bits(clog2(num_inports + 1)) + + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_predicate = [PredType(1, 0), PredType(1, 0), PredType(1, 1)] + src_in0 = [DataType(1, 1), DataType(7, 1), DataType(4, 1)] + src_in1 = [ DataType(3, 1), DataType(1, 1)] + src_const = [DataType(5, 1), DataType(2, 1), DataType(7, 1)] + sink_out = [DataType(6, 0), DataType(4, 0), DataType(6, 1)] + src_opt = [ConfigType(OPT_ADD_CONST, b1(1), pickRegister), + ConfigType(OPT_SUB, b1(1), pickRegister), + ConfigType(OPT_ADD_CONST, b1(1), pickRegister)] + + th = TestHarness(FU, DataType, PredType, ConfigType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_predicate, src_const, src_opt, sink_out, latency) + run_sim(th) diff --git a/fu/single/test/AdderRTL_test.py b/fu/single/test/AdderRTL_test.py index cd30f50..8e21789 100644 --- a/fu/single/test/AdderRTL_test.py +++ b/fu/single/test/AdderRTL_test.py @@ -8,67 +8,66 @@ Date : November 27, 2019 """ - from pymtl3 import * from ..AdderRTL import AdderRTL -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 ValRdyTestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src2_msgs, src_const, - ctrl_msgs, sink_msgs ): + def construct(s, FunctionUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src2_msgs, src_const, + ctrl_msgs, sink_msgs): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src2_msgs ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + s.src_in0 = ValRdyTestSrcRTL(DataType, src0_msgs) + s.src_in1 = ValRdyTestSrcRTL(DataType, src1_msgs) + s.src_predicate = ValRdyTestSrcRTL(PredicateType, src2_msgs) + s.src_opt = ValRdyTestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = ValRdyTestSinkRTL(DataType, sink_msgs) - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + # for i in range(num_inports): + # s.dut.recv_in_count[i] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.dut.recv_const, s.const_queue.send_const ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) + connect(s.src_in0.send, s.dut.recv_in[0]) + connect(s.src_in1.send, s.dut.recv_in[1]) + connect(s.src_predicate.send, s.dut.recv_predicate) + connect(s.dut.recv_const, s.const_queue.send_const) + connect(s.src_opt.send, s.dut.recv_opt) + connect(s.dut.send_out[0], s.sink_out.recv) - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out.done() + def done(s): + return s.src_in0.done() and \ + s.src_opt.done() and \ + s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -78,26 +77,36 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() def test_alu(): - FU = AdderRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() + FU = AdderRTL + DataType = mk_data(16, 1) + PredType = mk_predicate(1, 1) + ConfigType = mk_ctrl() data_mem_size = 8 - num_inports = 2 - num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ DataType(6, 0), DataType(4, 0), DataType(11, 1) ] - src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + num_inports = 2 + num_outports = 1 + FuInType = mk_bits(clog2(num_inports + 1)) + # pickRegister = [FuInType(x + 1) for x in range(num_inports)] + # src_in0 = [DataType(1, 1), DataType(7, 1), DataType(4, 1)] + # src_in1 = [DataType(2, 1), DataType(3, 1), DataType(1, 1)] + # src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + # src_const = [DataType(5, 1), DataType(4, 0), DataType(7, 1)] + # sink_out = [DataType(6, 0), DataType(4, 0), DataType(8, 1)] + # src_opt = [ConfigType( OPT_ADD_CONST, b1(1), pickRegister), + # ConfigType(OPT_SUB, b1(1), pickRegister), + # ConfigType(OPT_ADD_CONST, b1(1), pickRegister)] + + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_predicate = [PredType(1, 0), PredType(1, 0), PredType(1, 1)] + src_in0 = [DataType(1, 1), DataType(7, 1), DataType(4, 1)] + src_in1 = [ DataType(3, 1), DataType(1, 1)] + src_const = [DataType(5, 1), DataType(2, 1), DataType(7, 1)] + sink_out = [DataType(6, 0), DataType(4, 0), DataType(6, 1)] + src_opt = [ConfigType(OPT_ADD_CONST, b1(1), pickRegister), + ConfigType(OPT_SUB, b1(1), pickRegister), + ConfigType(OPT_ADD_CONST, b1(1), pickRegister)] + + th = TestHarness(FU, DataType, PredType, ConfigType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_predicate, src_const, src_opt, sink_out) + run_sim(th) diff --git a/fu/single/test/AluRTL_test.py b/fu/single/test/AluRTL_test.py index 23aca44..400a570 100644 --- a/fu/single/test/AluRTL_test.py +++ b/fu/single/test/AluRTL_test.py @@ -8,70 +8,65 @@ Date : November 27, 2019 """ - from pymtl3 import * from ..AdderRTL import AdderRTL from ..LogicRTL import LogicRTL from ..MulRTL import MulRTL from ..ShifterRTL import ShifterRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src2_msgs, src_const, - ctrl_msgs, sink_msgs ): +class TestHarness(Component): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src2_msgs ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + def construct(s, FunctionUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, src0_msgs, + src1_msgs, src2_msgs, src_const, ctrl_msgs, sink_msgs): - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_predicate = TestSrcRTL(PredicateType, src2_msgs) + s.src_opt = TestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = TestSinkRTL(DataType, sink_msgs) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredicateType, ConfigType, num_inports, + num_outports, data_mem_size) - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.dut.recv_const, s.const_queue.send_const ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) + s.src_in0.send //= s.dut.recv_in[0] + s.src_in1.send //= s.dut.recv_in[1] + s.src_predicate.send //= s.dut.recv_predicate + s.dut.recv_const //= s.const_queue.send_const + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink_out.recv - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out.done() + def done(s): + return s.src_in0.done() and \ + s.src_opt.done() and \ + s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -80,100 +75,98 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() test_harness.sim_tick() -def test_alu(): - FU = AdderRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() +def test_add_sub(): + FU = AdderRTL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() data_mem_size = 8 - num_inports = 2 - num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ DataType(6, 0), DataType(4, 0), DataType(11, 1) ] - src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + num_inports = 2 + num_outports = 1 + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(7, 1), DataType(4, 1)] + src_in1 = [DataType(2, 1), DataType(3, 1), DataType(1, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + src_const = [DataType(5, 1), DataType(1, 0), DataType(7, 1)] + sink_out = [DataType(6, 0), DataType(5, 0), DataType(5, 1)] + src_opt = [ConfigType(OPT_ADD_CONST, b1(1), pickRegister), + ConfigType(OPT_SUB, b1(1), pickRegister), + ConfigType(OPT_ADD_CONST, b1(1), pickRegister)] + th = TestHarness(FU, DataType, PredicateType, ConfigType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_predicate, src_const, src_opt, sink_out) + run_sim(th) def test_logic(): FU = LogicRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(4, 1), DataType(1, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(3, 1), DataType(2, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ DataType(3, 0), DataType(2, 1), DataType(0xfffb, 1), DataType(3, 1) ] - src_opt = [ ConfigType( OPT_OR , b1( 1 ), pickRegister ), - ConfigType( OPT_AND, b1( 0 ), pickRegister ), - ConfigType( OPT_NOT, b1( 0 ), pickRegister ), - ConfigType( OPT_XOR, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(2, 1), DataType(4, 1), DataType(1, 1)] + src_in1 = [DataType(2, 1), DataType(3, 1), DataType(3, 1), DataType(2, 1)] + src_const = [DataType(5, 1), DataType(0, 0), DataType(7, 1)] + sink_out = [DataType(3, 0), DataType(2, 1), DataType(0xfffb, 1), DataType(2, 1)] + src_opt = [ConfigType(OPT_OR , b1(1), pickRegister), + ConfigType(OPT_AND, b1(0), pickRegister), + ConfigType(OPT_NOT, b1(0), pickRegister), + ConfigType(OPT_XOR, b1(0), pickRegister)] + th = TestHarness(FU, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_predicate, src_const, src_opt, + sink_out ) + run_sim(th) def test_shifter(): FU = ShifterRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - sink_out = [ DataType(4, 1), DataType(16, 1), DataType(2, 1) ] - src_opt = [ ConfigType( OPT_LLS, b1( 0 ), pickRegister ), - ConfigType( OPT_LLS, b1( 0 ), pickRegister ), - ConfigType( OPT_LRS, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(2, 1), DataType(4, 1)] + src_in1 = [DataType(2, 1), DataType(3, 1), DataType(1, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + src_const = [DataType(2, 1), DataType(3, 1), DataType(1, 1)] + sink_out = [DataType(4, 1), DataType(16, 1), DataType(2, 1)] + src_opt = [ConfigType(OPT_LLS, b1(0), pickRegister), + ConfigType(OPT_LLS, b1(0), pickRegister), + ConfigType(OPT_LRS, b1(0), pickRegister)] + th = TestHarness(FU, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_predicate, src_const, src_opt, + sink_out ) + run_sim(th) def test_mul(): FU = MulRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(3, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(2, 1), DataType(3, 1), DataType(3, 1) ] - sink_out = [ DataType(2, 1), DataType(6, 1), DataType(12, 1) ] - src_opt = [ ConfigType( OPT_MUL, b1( 0 ), pickRegister ), - ConfigType( OPT_MUL, b1( 0 ), pickRegister ), - ConfigType( OPT_MUL, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(2, 1), DataType(4, 1)] + src_in1 = [DataType(2, 1), DataType(3, 1), DataType(3, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + src_const = [DataType(2, 1), DataType(3, 1), DataType(3, 1)] + sink_out = [DataType(2, 1), DataType(6, 1), DataType(12, 1)] + src_opt = [ConfigType(OPT_MUL, b1(0), pickRegister), + ConfigType(OPT_MUL, b1(0), pickRegister), + ConfigType(OPT_MUL, b1(0), pickRegister)] + th = TestHarness(FU, DataType, PredicateType, ConfigType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_predicate, src_const, src_opt, sink_out) + run_sim(th) diff --git a/fu/single/test/BranchRTL_test.py b/fu/single/test/BranchRTL_test.py index d724f45..5b25339 100644 --- a/fu/single/test/BranchRTL_test.py +++ b/fu/single/test/BranchRTL_test.py @@ -8,66 +8,60 @@ Date : November 27, 2019 """ - from pymtl3 import * from ..BranchRTL import BranchRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_comp, src_predicate, src_opt, sink_if, sink_else ): + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src_comp, + src_predicate, src_opt, sink_if, sink_else): - s.src_comp = TestSrcRTL( DataType, src_comp ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.sink_if = TestSinkRTL( DataType, sink_if ) - s.sink_else = TestSinkRTL( DataType, sink_else ) + s.src_comp = TestSrcRTL(DataType, src_comp) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_opt = TestSrcRTL(CtrlType, src_opt) + s.sink_if = TestSinkRTL(DataType, sink_if) + s.sink_else = TestSinkRTL(DataType, sink_else) - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.src_comp.send //= s.dut.recv_in[0] + s.src_predicate.send //= s.dut.recv_predicate + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink_if.recv + s.dut.send_out[1] //= s.sink_else.recv - connect( s.src_comp.send, s.dut.recv_in[0] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_if.recv ) - connect( s.dut.send_out[1], s.sink_else.recv ) + def done(s): + return s.src_opt.done() and s.sink_if.done() and s.sink_else.done() - def done( s ): - return s.src_opt.done() and s.sink_if.done() and s.sink_else.done() - - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout - assert ncycles < max_cycles test_harness.sim_tick() @@ -75,44 +69,44 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() def test_Branch(): - FU = BranchRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 2 + FU = BranchRTL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 2 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - src_comp = [ DataType(0, 1), DataType(1, 1), DataType(0, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1,0), PredicateType(1,1) ] - src_opt = [ CtrlType( OPT_BRH, b1( 1 ), [FuInType(1), FuInType(2)] ), - CtrlType( OPT_BRH, b1( 0 ), [FuInType(1), FuInType(2)] ), - CtrlType( OPT_BRH, b1( 0 ), [FuInType(1), FuInType(2)] ) ] - sink_if = [ DataType(0, 0), DataType(0, 0), DataType(0, 1) ] - sink_else = [ DataType(0, 0), DataType(0, 1), DataType(0, 0) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_comp, src_predicate, src_opt, sink_if, sink_else ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + src_comp = [DataType(0, 1), DataType(1, 1), DataType(0, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1)] + src_opt = [CtrlType( OPT_BRH, b1( 1 ), [FuInType(1), FuInType(2)]), + CtrlType( OPT_BRH, b1( 0 ), [FuInType(1), FuInType(2)]), + CtrlType( OPT_BRH, b1( 0 ), [FuInType(1), FuInType(2)])] + sink_if = [DataType(0, 0), DataType(0, 0), DataType(0, 1)] + sink_else = [DataType(0, 0), DataType(0, 1), DataType(0, 0)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_comp, src_predicate, + src_opt, sink_if, sink_else) + run_sim(th) def test_Branch_Start(): - FU = BranchRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 2 + FU = BranchRTL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 2 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - src_comp = [ DataType(0, 1), DataType(1, 1), DataType(0, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1,0), PredicateType(1,1) ] - src_opt = [ CtrlType( OPT_BRH_START, b1( 0 ), [FuInType(0), FuInType(0)] ), - CtrlType( OPT_BRH_START, b1( 0 ), [FuInType(0), FuInType(0)] ), - CtrlType( OPT_BRH_START, b1( 0 ), [FuInType(0), FuInType(0)] ) ] - sink_if = [ DataType(0, 1), DataType(0, 0), DataType(0, 0) ] - sink_else = [ DataType(0, 0), DataType(0, 1), DataType(0, 1) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_comp, src_predicate, src_opt, sink_if, sink_else ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + src_comp = [DataType(0, 1), DataType(1, 1), DataType(0, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1,0), PredicateType(1,1) ] + src_opt = [CtrlType(OPT_BRH_START, b1(0), [FuInType(0), FuInType(0)]), + CtrlType(OPT_BRH_START, b1(0), [FuInType(0), FuInType(0)]), + CtrlType(OPT_BRH_START, b1(0), [FuInType(0), FuInType(0)])] + sink_if = [DataType(0, 1), DataType(0, 0), DataType(0, 0)] + sink_else = [DataType(0, 0), DataType(0, 1), DataType(0, 1)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_comp, src_predicate, + src_opt, sink_if, sink_else) + run_sim(th) diff --git a/fu/single/test/CompRTL_test.py b/fu/single/test/CompRTL_test.py index d5b62f6..3cb606c 100644 --- a/fu/single/test/CompRTL_test.py +++ b/fu/single/test/CompRTL_test.py @@ -8,65 +8,57 @@ Date : November 27, 2019 """ - from pymtl3 import * -# TODO: use `config_model_with_cmdline_opts` -# from pymtl3.stdlib.test_utils import config_model_with_cmdline_opts - from ..CompRTL import CompRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_data, src_ref, src_predicate, src_opt, sink_msgs ): +class TestHarness(Component): - s.src_data = TestSrcRTL( DataType, src_data ) - s.src_ref = TestSrcRTL( DataType, src_ref ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src_data, + src_ref, src_predicate, src_opt, sink_msgs): - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.src_data = TestSrcRTL(DataType, src_data) + s.src_ref = TestSrcRTL(DataType, src_ref) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_opt = TestSrcRTL(CtrlType, src_opt) + s.sink_out = TestSinkRTL(DataType, sink_msgs) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size) - connect( s.src_data.send, s.dut.recv_in[0] ) - connect( s.src_ref.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) + s.src_data.send //= s.dut.recv_in[0] + s.src_ref.send //= s.dut.recv_in[1] + s.src_predicate.send //= s.dut.recv_predicate + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink_out.recv - def done( s ): + def done(s): return s.src_data.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -77,23 +69,23 @@ def run_sim( test_harness, max_cycles=100 ): def test_Comp(): FU = CompRTL - DataType = mk_data( 32, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_data = [ DataType(9, 1), DataType(3, 1), DataType(3, 1) ] - src_ref = [ DataType(9, 1), DataType(5, 1), DataType(2, 1) ] - src_predicate = [ PredicateType(1,0), PredicateType(1,0), PredicateType(1,1) ] - src_opt = [ CtrlType( OPT_EQ, b1( 0 ), pickRegister ), - CtrlType( OPT_LT, b1( 0 ), pickRegister ), - CtrlType( OPT_EQ, b1( 0 ), pickRegister ) ] - sink_out = [ DataType(1, 1), DataType(1, 1), DataType(0, 1) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_data, src_ref, src_predicate, src_opt, sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_data = [DataType(9, 1), DataType(3, 1), DataType(3, 1)] + src_ref = [DataType(9, 1), DataType(5, 1), DataType(2, 1)] + src_predicate = [PredicateType(1,0), PredicateType(1,0), PredicateType(1,1)] + src_opt = [CtrlType(OPT_EQ, b1(0), pickRegister), + CtrlType(OPT_LT, b1(0), pickRegister), + CtrlType(OPT_EQ, b1(0), pickRegister)] + sink_out = [DataType(1, 1), DataType(1, 1), DataType(0, 1)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_data, src_ref, + src_predicate, src_opt, sink_out) + run_sim(th) diff --git a/fu/single/test/MemRTL_test.py b/fu/single/test/MemRTL_test.py deleted file mode 100644 index dc9f36d..0000000 --- a/fu/single/test/MemRTL_test.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -========================================================================== -Mem_test.py -========================================================================== -Test cases for functional unit. - -Author : Cheng Tan - Date : November 27, 2019 -""" - - -from pymtl3 import * - -from ..MemUnitRTL import MemUnitRTL -from ....lib.messages import * -from ....lib.opt_type import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL -from ....mem.data.DataMemCL import DataMemCL -from ....mem.data.DataMemRTL import DataMemRTL - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- -# TODO: connect recv_const - -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataUnit, DataType, PredicateType, - ConfigType, num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_predicate, ctrl_msgs, - sink_msgs ): - - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) - - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) - s.data_mem = DataUnit( DataType, data_mem_size ) - - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - - connect( s.dut.to_mem_raddr, s.data_mem.recv_raddr[0] ) - connect( s.dut.from_mem_rdata, s.data_mem.send_rdata[0] ) - connect( s.dut.to_mem_waddr, s.data_mem.recv_waddr[0] ) - connect( s.dut.to_mem_wdata, s.data_mem.recv_wdata[0] ) - - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) - - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out.done() - - def line_trace( s ): - # return s.dut.line_trace() - return s.data_mem.line_trace() + ' | ' + s.dut.line_trace() - -def run_sim( test_harness, max_cycles=100 ): - 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() - -def test_Mem(): - FU = MemUnitRTL - DataUnit = DataMemRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() - data_mem_size = 8 - num_inports = 2 - num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(3, 1), DataType(3, 1), DataType(3, 1) ] # addr - src_in1 = [ DataType(9, 1) ] # data - src_predicate = [ PredicateType(1, 0), PredicateType(1,1), PredicateType(1,0), PredicateType(0,0) ] - sink_out = [ DataType(0, 0), DataType(9, 1), DataType(9, 1) ] - src_opt = [ ConfigType( OPT_LD, b1( 1 ), pickRegister ), - ConfigType( OPT_STR, b1( 0 ), pickRegister ), - ConfigType( OPT_LD, b1( 0 ), pickRegister ), - ConfigType( OPT_LD, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, DataUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_opt, sink_out ) - run_sim( th ) - -def test_PseudoMem(): - FU = MemUnitRTL - DataUnit = DataMemCL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - ConfigType = mk_ctrl() - data_mem_size = 8 - num_inports = 2 - num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(0, 1), DataType(0, 1) ] - src_in1 = [ DataType(9, 1) ] - src_predicate = [ PredicateType(1, 1), PredicateType(0, 0), PredicateType(1, 0), - PredicateType(0, 0), PredicateType(0, 0), PredicateType(0, 0) ] - sink_out = [ DataType(0, 1), DataType(9, 1), DataType(9, 1), DataType(9, 1) ] - src_opt = [ ConfigType( OPT_LD , b1( 0 ), pickRegister ), - ConfigType( OPT_STR , b1( 0 ), pickRegister ), - ConfigType( OPT_LD_CONST, b1( 0 ), pickRegister ), - ConfigType( OPT_LD , b1( 0 ), pickRegister ), - ConfigType( OPT_LD_CONST, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, DataUnit, DataType, PredicateType, ConfigType, num_inports, - num_outports, data_mem_size, src_in0, src_in1, - src_predicate, src_opt, sink_out ) - run_sim( th ) - diff --git a/fu/single/test/MemUnitRTL_test.py b/fu/single/test/MemUnitRTL_test.py new file mode 100644 index 0000000..595761c --- /dev/null +++ b/fu/single/test/MemUnitRTL_test.py @@ -0,0 +1,136 @@ +""" +========================================================================== +MemUnitRTL_test.py +========================================================================== +Test cases for functional unit. + +Author : Cheng Tan + Date : November 27, 2019 +""" + +from pymtl3 import * + +from ..MemUnitRTL import MemUnitRTL +from ....lib.messages import * +from ....lib.opt_type import * +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....mem.data.DataMemCL import DataMemCL +from ....mem.data.DataMemRTL import DataMemRTL + +#------------------------------------------------------------------------- +# Test harness +#------------------------------------------------------------------------- +# TODO: connect recv_const + +class TestHarness(Component): + + def construct(s, FunctionUnit, DataUnit, DataType, PredicateType, + ConfigType, num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_const_msgs, src_predicate, + ctrl_msgs, sink_msgs): + + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_const = TestSrcRTL(DataType, src_const_msgs) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_opt = TestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = TestSinkRTL(DataType, sink_msgs) + + s.dut = FunctionUnit(DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size) + s.data_mem = DataUnit(DataType, data_mem_size) + + connect(s.dut.to_mem_raddr, s.data_mem.recv_raddr[0]) + connect(s.dut.from_mem_rdata, s.data_mem.send_rdata[0]) + connect(s.dut.to_mem_waddr, s.data_mem.recv_waddr[0]) + connect(s.dut.to_mem_wdata, s.data_mem.recv_wdata[0]) + + connect(s.src_in0.send, s.dut.recv_in[0]) + connect(s.src_in1.send, s.dut.recv_in[1]) + connect(s.src_const.send, s.dut.recv_const) + connect(s.src_predicate.send, s.dut.recv_predicate) + connect(s.src_opt.send, s.dut.recv_opt) + connect(s.dut.send_out[0], s.sink_out.recv) + + def done(s): + return s.src_in0.done() and s.src_in1.done() and \ + s.src_opt.done() and s.sink_out.done() + + def line_trace(s): + return s.data_mem.line_trace() + ' || ' + s.dut.line_trace() + +def run_sim(test_harness, max_cycles = 20): + 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() + +def test_Mem(): + FU = MemUnitRTL + DataUnit = DataMemRTL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() + data_mem_size = 8 + num_inports = 2 + num_outports = 1 + FuInType = mk_bits( clog2( num_inports + 1 ) ) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(3, 1), DataType(3, 1), DataType(3, 1)] # addr + src_in1 = [DataType(9, 1)] # data + src_const = [DataType(0, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1,1), PredicateType(1,0), PredicateType(0,0)] + sink_out = [DataType(0, 0), DataType(9, 1), DataType(9, 1)] + src_opt = [ConfigType(OPT_LD, b1(1), pickRegister), + ConfigType(OPT_STR, b1(0), pickRegister), + ConfigType(OPT_LD, b1(0), pickRegister), + ConfigType(OPT_LD, b1(0), pickRegister)] + th = TestHarness(FU, DataUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_const, src_predicate, + src_opt, sink_out) + run_sim(th) + +def test_PseudoMem(): + FU = MemUnitRTL + DataUnit = DataMemCL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + ConfigType = mk_ctrl() + data_mem_size = 8 + num_inports = 2 + num_outports = 1 + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 1), DataType(0, 1), DataType(0, 1)] + src_in1 = [DataType(9, 1)] + src_const = [DataType(0, 1), DataType(1, 1)] + src_predicate = [PredicateType(1, 1), PredicateType(0, 0), PredicateType(1, 0), + PredicateType(0, 0), PredicateType(0, 0), PredicateType(0, 0)] + sink_out = [DataType(0, 0), DataType(9, 1), DataType(9, 1), DataType(0, 0)] + src_opt = [ConfigType(OPT_LD , b1(0), pickRegister), + ConfigType(OPT_STR , b1(0), pickRegister), + ConfigType(OPT_LD_CONST, b1(0), pickRegister), + ConfigType(OPT_LD , b1(0), pickRegister), + ConfigType(OPT_LD_CONST, b1(0), pickRegister)] + th = TestHarness(FU, DataUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, src_in0, + src_in1, src_const, src_predicate, src_opt, sink_out) + run_sim(th) + diff --git a/fu/single/test/MulRTL_test.py b/fu/single/test/MulRTL_test.py index c3320e6..ff6ccf5 100644 --- a/fu/single/test/MulRTL_test.py +++ b/fu/single/test/MulRTL_test.py @@ -8,79 +8,68 @@ Date : November 27, 2019 """ - -from pymtl3 import * - -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..AdderRTL import AdderRTL -from ..ShifterRTL import ShifterRTL -from ..MulRTL import MulRTL -from ..LogicRTL import LogicRTL -from ....mem.const.ConstQueueRTL import ConstQueueRTL -from ....lib.opt_type import * -from ....lib.messages import * - import pytest -from itertools import product - import hypothesis from hypothesis import strategies as st +from itertools import product +from pymtl3 import * +from ..MulRTL import MulRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * +from ....mem.const.ConstQueueRTL import ConstQueueRTL #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_predicate, src_const, - ctrl_msgs, sink_msgs ): - - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_in2 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) - - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) - - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_in2.send, s.dut.recv_in[2] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.dut.recv_const, s.const_queue.send_const ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) - - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ +class TestHarness(Component): + + def construct(s, FunctionUnit, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_predicate, src_const, + ctrl_msgs, sink_msgs): + + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_in2 = TestSrcRTL(DataType, src1_msgs) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_opt = TestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = TestSinkRTL(DataType, sink_msgs) + + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size) + + connect(s.src_in0.send, s.dut.recv_in[0]) + connect(s.src_in1.send, s.dut.recv_in[1]) + connect(s.src_in2.send, s.dut.recv_in[2]) + connect(s.src_predicate.send, s.dut.recv_predicate) + connect(s.dut.recv_const, s.const_queue.send_const) + connect(s.src_opt.send, s.dut.recv_opt) + connect(s.dut.send_out[0], s.sink_out.recv) + + def done(s): + return s.src_in0.done() and s.src_in2.done() and \ s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -91,27 +80,27 @@ def run_sim( test_harness, max_cycles=100 ): @pytest.mark.parametrize( 'input_a, input_b', - product( range( 3, 4 ), range( 2, 3 ) ) + product(range(3, 5), range(2, 4)) ) -def test_mul0( input_a, input_b ): - FU = MulRTL - DataType = mk_data( 32, 1 ) - PredicateType = mk_predicate( 1, 1 ) - num_inports = 4 - num_outports = 1 - ConfigType = mk_ctrl(num_inports) - FuInType = mk_bits( clog2( num_inports + 1 ) ) +def test_mul0(input_a, input_b): + FU = MulRTL + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) + num_inports = 4 + num_outports = 1 + ConfigType = mk_ctrl(num_inports) + FuInType = mk_bits(clog2(num_inports + 1)) data_mem_size = 8 - src_in0 = [ DataType( input_a, 1 ) ] - src_in1 = [ DataType( input_b, 1 ) ] - src_predicate = [ PredicateType(1,1) ] - src_const = [ DataType( 0, 1) ] - sink_out = [ DataType( input_a * input_b, 1 ) ] - src_opt = [ ConfigType( OPT_MUL, b1( 0 ), - [FuInType(1), FuInType(3), FuInType(0), FuInType(0)] ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, - src_opt, sink_out ) - run_sim( th ) + src_in0 = [DataType(input_a, 1)] + src_in1 = [DataType(input_b, 1)] + src_predicate = [PredicateType(1,1)] + src_const = [DataType(0, 1) ] + sink_out = [DataType(input_a * input_b, 1)] + src_opt = [ConfigType(OPT_MUL, b1(0), + [FuInType(1), FuInType(3), FuInType(0), FuInType(0)])] + th = TestHarness(FU, DataType, PredicateType, ConfigType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_predicate, src_const, + src_opt, sink_out) + run_sim(th) diff --git a/fu/single/test/PhiRTL_test.py b/fu/single/test/PhiRTL_test.py index 215ad9b..de1cfb1 100644 --- a/fu/single/test/PhiRTL_test.py +++ b/fu/single/test/PhiRTL_test.py @@ -8,66 +8,60 @@ Date : November 27, 2019 """ - from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - from ..PhiRTL import PhiRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.opt_type import * from ....lib.messages import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_const, src_predicate, src_opt, - sink_msgs ): +class TestHarness(Component): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_const = TestSrcRTL( DataType, src_const ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_const, src_predicate, src_opt, + sink_msgs): - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.src_in0 = TestSrcRTL(DataType, src0_msgs) + s.src_in1 = TestSrcRTL(DataType, src1_msgs) + s.src_const = TestSrcRTL(DataType, src_const) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate ) + s.src_opt = TestSrcRTL(CtrlType, src_opt) + s.sink_out = TestSinkRTL(DataType, sink_msgs) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size) - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_const.send, s.dut.recv_const ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) + s.src_in0.send //= s.dut.recv_in[0] + s.src_in1.send //= s.dut.recv_in[1] + s.src_const.send //= s.dut.recv_const + s.src_predicate.send //= s.dut.recv_predicate + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink_out.recv - def done( s ): + def done(s): return s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -78,49 +72,52 @@ def run_sim( test_harness, max_cycles=100 ): def test_Phi(): FU = PhiRTL - DataType = mk_data( 16, 1, 1) - PredicateType = mk_predicate( 1, 1) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(16, 1, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 0), DataType(3, 1), DataType(6, 0) ] - src_in1 = [ DataType(0, 0), DataType(5, 0), DataType(2, 1) ] - src_const = [ DataType(0, 0), DataType(5, 0), DataType(2, 1) ] - src_predicate = [ PredicateType(1, 1), PredicateType(1, 0), PredicateType(1, 1) ] - src_opt = [ CtrlType( OPT_PHI, b1( 1 ), pickRegister ), - CtrlType( OPT_PHI, b1( 1 ), pickRegister ), - CtrlType( OPT_PHI, b1( 1 ), pickRegister ) ] - sink_out = [ DataType(1, 0), DataType(3, 0), DataType(2, 1) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_const, src_predicate, - src_opt, sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 0), DataType(3, 1), DataType(6, 0)] + src_in1 = [DataType(0, 0), DataType(5, 0), DataType(2, 1)] + src_const = [DataType(0, 0), DataType(5, 0), DataType(2, 1)] + src_predicate = [PredicateType(1, 1), PredicateType(1, 0), PredicateType(1, 1)] + src_opt = [CtrlType(OPT_PHI, b1(1), pickRegister), + CtrlType(OPT_PHI, b1(1), pickRegister), + CtrlType(OPT_PHI, b1(1), pickRegister)] + sink_out = [DataType(1, 0), DataType(3, 0), DataType(2, 1)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_const, src_predicate, src_opt, sink_out) + run_sim(th) def test_Phi_const(): FU = PhiRTL - DataType = mk_data( 16, 1, 1) - PredicateType = mk_predicate( 1, 1) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 1 + DataType = mk_data(16, 1, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 0), DataType(3, 1), DataType(6, 0) ] - src_in1 = [ DataType(3, 0), DataType(5, 1), DataType(2, 1) ] - src_const = [ DataType(3, 0), DataType(5, 1), DataType(2, 1) ] - src_predicate = [ PredicateType(0, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_opt = [ CtrlType( OPT_PHI_CONST, b1( 1 ), pickRegister ), - CtrlType( OPT_PHI_CONST, b1( 1 ), pickRegister ), - CtrlType( OPT_PHI_CONST, b1( 1 ), pickRegister ) ] - sink_out = [ DataType(3, 1), DataType(5, 0), DataType(3, 1) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_const, src_predicate, - src_opt, sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_in0 = [DataType(1, 0), DataType(4, 1), DataType(7, 0)] + src_in1 = [DataType(2, 0), DataType(5, 1), DataType(8, 1)] + # The const predicate doesn't matter, as long as the predicate + # in the src_in0 is 0, the const value would be picked up, and + # the predicate is set as 1. + # TODO: Need to change following for multi-op predicate support: + # https://github.com/tancheng/VectorCGRA/issues/27. + src_const = [DataType(3, 0), DataType(6, 1), DataType(9, 1)] + src_predicate = [PredicateType(0, 1), PredicateType(1, 0), PredicateType(1, 1)] + src_opt = [CtrlType(OPT_PHI_CONST, b1(1), pickRegister), + CtrlType(OPT_PHI_CONST, b1(1), pickRegister), + CtrlType(OPT_PHI_CONST, b1(1), pickRegister) ] + sink_out = [DataType(3, 1), DataType(4, 0), DataType(9, 0)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_in0, src_in1, + src_const, src_predicate, src_opt, sink_out) + run_sim(th) diff --git a/fu/single/test/RetRTL_test.py b/fu/single/test/RetRTL_test.py index 5c0ee2b..c8bd3ae 100644 --- a/fu/single/test/RetRTL_test.py +++ b/fu/single/test/RetRTL_test.py @@ -8,65 +8,57 @@ Date : September 21, 2021 """ -from pymtl3 import * - -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..RetRTL import RetRTL -from ....lib.opt_type import * -from ....lib.messages import * - +from pymtl3 import * +from ..RetRTL import RetRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.opt_type import * +from ....lib.messages import * #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_in, src_predicate, src_opt, sink ): + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src_in, + src_predicate, src_opt, sink): - s.src_in = TestSrcRTL( DataType, src_in ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.sink = TestSinkRTL( DataType, sink ) + s.src_in = TestSrcRTL(DataType, src_in) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_opt = TestSrcRTL(CtrlType, src_opt) + s.sink = TestSinkRTL(DataType, sink) - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.src_in.send //= s.dut.recv_in[0] + s.src_predicate.send //= s.dut.recv_predicate + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink.recv - connect( s.src_in.send, s.dut.recv_in[0] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink.recv ) - - def done( s ): + def done(s): return s.src_opt.done() and s.sink.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation - ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout - assert ncycles < max_cycles test_harness.sim_tick() @@ -74,22 +66,22 @@ def run_sim( test_harness, max_cycles=100 ): test_harness.sim_tick() def test_Ret(): - FU = RetRTL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - num_inports = 2 - num_outports = 2 + FU = RetRTL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + num_inports = 2 + num_outports = 2 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - src_in = [ DataType(1, 1), DataType(2, 1), DataType(3, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1,0), PredicateType(1,1) ] - src_opt = [ CtrlType( OPT_RET, b1( 1 ), [FuInType(1), FuInType(0)] ), - CtrlType( OPT_RET, b1( 0 ), [FuInType(1), FuInType(0)] ), - CtrlType( OPT_RET, b1( 1 ), [FuInType(1), FuInType(0)] ) ] - sink = [ DataType(1, 0), DataType(2, 0), DataType(3, 0) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_in, src_predicate, src_opt, sink ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + src_in = [DataType(1, 1), DataType(2, 1), DataType(3, 1)] + src_predicate = [PredicateType(1, 0), PredicateType(1,0), PredicateType(1,1)] + src_opt = [CtrlType(OPT_RET, b1(1), [FuInType(1), FuInType(0)]), + CtrlType(OPT_RET, b1(0), [FuInType(1), FuInType(0)]), + CtrlType(OPT_RET, b1(1), [FuInType(1), FuInType(0)])] + sink = [DataType(1, 0), DataType(2, 1), DataType(3, 0)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_in, src_predicate, + src_opt, sink) + run_sim(th) diff --git a/fu/single/test/SelRTL_test.py b/fu/single/test/SelRTL_test.py index 191f15e..61fc0d7 100644 --- a/fu/single/test/SelRTL_test.py +++ b/fu/single/test/SelRTL_test.py @@ -8,71 +8,61 @@ Date : November 27, 2019 """ - -from pymtl3 import * - -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL -from ....lib.opt_type import * -from ....lib.messages import * - -from ..SelRTL import SelRTL -from ....lib.opt_type import * -from ....lib.messages import * - -from pymtl3.passes.PassGroups import * +from pymtl3 import * +from pymtl3.passes.PassGroups import * +from ..SelRTL import SelRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.messages import * +from ....lib.opt_type import * #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_data1, src_data2, src_predicate, - src_ref0, src_opt, sink_msgs ): +class TestHarness(Component): - s.src_data1 = TestSrcRTL( DataType, src_data1 ) - s.src_data2 = TestSrcRTL( DataType, src_data2 ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_ref0 = TestSrcRTL( DataType, src_ref0 ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src_data1, + src_data2, src_predicate, src_ref0, src_opt, sink_msgs): - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.src_data1 = TestSrcRTL(DataType, src_data1) + s.src_data2 = TestSrcRTL(DataType, src_data2) + s.src_predicate = TestSrcRTL(PredicateType, src_predicate) + s.src_ref0 = TestSrcRTL(DataType, src_ref0) + s.src_opt = TestSrcRTL(CtrlType, src_opt) + s.sink_out = TestSinkRTL( DataType, sink_msgs) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size) - connect( s.src_data1.send, s.dut.recv_in[1] ) - connect( s.src_data2.send, s.dut.recv_in[2] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_ref0.send, s.dut.recv_in[0] ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out.recv ) + s.src_data1.send //= s.dut.recv_in[1] + s.src_data2.send //= s.dut.recv_in[2] + s.src_predicate.send //= s.dut.recv_predicate + s.src_ref0.send //= s.dut.recv_in[0] + s.src_opt.send //= s.dut.recv_opt + s.dut.send_out[0] //= s.sink_out.recv - def done( s ): - return s.src_data1.done() and s.src_data2.done() and\ + def done(s): + return s.src_data1.done() and s.src_data2.done() and \ s.src_ref0.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -83,26 +73,25 @@ def run_sim( test_harness, max_cycles=100 ): def test_Select(): FU = SelRTL - DataType = mk_data( 32, 1 ) - PredicateType = mk_predicate( 1, 1 ) + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) # Selector needs more than 2 inputs - CtrlType = mk_ctrl(num_fu_in = 4) - num_inports = 4 - num_outports = 1 + CtrlType = mk_ctrl(num_fu_in = 4) + num_inports = 4 + num_outports = 1 data_mem_size = 8 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_data1 = [ DataType(9, 1), DataType(3, 1), DataType(4, 1) ] - src_data2 = [ DataType(2, 1), DataType(7, 1), DataType(5, 1) ] - src_predicate = [ PredicateType(1,1), PredicateType(1,1), PredicateType(1,1) ] - src_ref0 = [ DataType(1, 1), DataType(0, 1), DataType(1, 1) ] - src_opt = [ CtrlType( OPT_SEL, b1( 0 ), pickRegister ), - CtrlType( OPT_SEL, b1( 0 ), pickRegister ), - CtrlType( OPT_SEL, b1( 0 ), pickRegister ) ] - sink_out = [ DataType(9, 1), DataType(7, 1), DataType(4, 1) ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src_data1, src_data2, src_predicate, - src_ref0, src_opt, sink_out ) - run_sim( th ) + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_data1 = [DataType(9, 1), DataType(3, 1), DataType(4, 1)] + src_data2 = [DataType(2, 1), DataType(7, 1), DataType(5, 1)] + src_predicate = [PredicateType(1,1), PredicateType(1,1), PredicateType(1,1)] + src_ref0 = [DataType(1, 1), DataType(0, 1), DataType(1, 1)] + src_opt = [CtrlType(OPT_SEL, b1(0), pickRegister), + CtrlType(OPT_SEL, b1(0), pickRegister), + CtrlType(OPT_SEL, b1(0), pickRegister)] + sink_out = [DataType(9, 1), DataType(7, 1), DataType(4, 1)] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, src_data1, src_data2, + src_predicate, src_ref0, src_opt, sink_out) + run_sim(th) diff --git a/fu/triple/ThreeMulAdderShifterRTL.py b/fu/triple/ThreeMulAdderShifterRTL.py index 5370898..7800d40 100644 --- a/fu/triple/ThreeMulAdderShifterRTL.py +++ b/fu/triple/ThreeMulAdderShifterRTL.py @@ -8,37 +8,33 @@ Date : November 28, 2019 """ - from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ...lib.opt_type import * from ..basic.ThreeCombo import ThreeCombo from ..single.MulRTL import MulRTL from ..single.AdderRTL import AdderRTL from ..single.ShifterRTL import ShifterRTL +class ThreeMulAdderShifterRTL(ThreeCombo): -class ThreeMulAdderShifterRTL( ThreeCombo ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size): - super( ThreeMulAdderShifterRTL, s ).construct( DataType, PredicateType, - CtrlType, MulRTL, - AdderRTL, ShifterRTL, - num_inports, num_outports, - data_mem_size ) + super(ThreeMulAdderShifterRTL, s).construct(DataType, PredicateType, + CtrlType, MulRTL, + AdderRTL, ShifterRTL, + num_inports, num_outports, + data_mem_size) - # TODO: use & instead of and @update def update_opt(): - s.send_out[0].en @= s.recv_in[0].en and s.recv_in[1].en and\ - s.recv_in[2].en and s.recv_in[3].en and\ - s.recv_opt.en - s.send_out[1].en @= s.recv_in[0].en and s.recv_in[1].en and\ - s.recv_in[2].en and s.recv_in[3].en and\ - s.recv_opt.en + # s.send_out[0].en @= s.recv_in[0].en and s.recv_in[1].en and\ + # s.recv_in[2].en and s.recv_in[3].en and\ + # s.recv_opt.en + # s.send_out[1].en @= s.recv_in[0].en and s.recv_in[1].en and\ + # s.recv_in[2].en and s.recv_in[3].en and\ + # s.recv_opt.en s.Fu0.recv_opt.msg.fu_in[0] @= 1 s.Fu0.recv_opt.msg.fu_in[1] @= 2 @@ -59,9 +55,9 @@ def update_opt(): s.Fu0.recv_opt.msg.ctrl @= OPT_MUL s.Fu1.recv_opt.msg.ctrl @= OPT_SUB s.Fu2.recv_opt.msg.ctrl @= OPT_LRS - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + # else: + # for j in range(num_outports): + # s.send_out[j].val @= b1(0) # TODO: need to handle the other cases diff --git a/fu/triple/test/ThreeMulAluShifterRTL_test.py b/fu/triple/test/ThreeMulAluShifterRTL_test.py index 010b0fc..e140f07 100644 --- a/fu/triple/test/ThreeMulAluShifterRTL_test.py +++ b/fu/triple/test/ThreeMulAluShifterRTL_test.py @@ -9,14 +9,12 @@ Date : November 29, 2019 """ - from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ....lib.opt_type import * -from ....lib.messages import * +from ..ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * #------------------------------------------------------------------------- # Test harness @@ -29,22 +27,17 @@ def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, src1_msgs, src2_msgs, src3_msgs, src_predicate, ctrl_msgs, sink_msgs ): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_in2 = TestSrcRTL( DataType, src2_msgs ) - s.src_in3 = TestSrcRTL( DataType, src3_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_in2 = TestSrcRTL ( DataType, src2_msgs ) + s.src_in3 = TestSrcRTL ( DataType, src3_msgs ) + s.src_predicate = TestSrcRTL ( PredicateType, src_predicate ) + s.src_opt = TestSrcRTL ( CtrlType, ctrl_msgs ) s.sink_out = TestSinkRTL( DataType, sink_msgs ) s.dut = FunctionUnit( DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size ) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 - s.dut.recv_in_count[2] //= 1 - s.dut.recv_in_count[3] //= 1 - connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) connect( s.src_in2.send, s.dut.recv_in[2] ) @@ -53,27 +46,27 @@ def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, connect( s.src_opt.send , s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out.recv ) - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_in2.done() and s.src_in3.done() and\ - s.src_opt.done() and s.sink_out.done() + def done(s): + return s.src_in0.done() and s.src_in1.done() and \ + s.src_in2.done() and s.src_in3.done() and \ + s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=1000 ): +def run_sim(test_harness, max_cycles= 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -92,7 +85,7 @@ def test_mul_alu_shifter(): CtrlType = mk_ctrl( num_fu_in=num_inports ) FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] + pickRegister = [ FuInType(x + 1) for x in range(num_inports) ] src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(4, 1) ] src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(3, 1) ] diff --git a/fu/vector/VectorAdderComboRTL.py b/fu/vector/VectorAdderComboRTL.py index a024a90..95e69a3 100644 --- a/fu/vector/VectorAdderComboRTL.py +++ b/fu/vector/VectorAdderComboRTL.py @@ -12,45 +12,40 @@ Date : March 28, 2022 """ +from pymtl3 import * +from .VectorAdderRTL import VectorAdderRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.opt_type import * -from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from .VectorAdderRTL import VectorAdderRTL -from ...lib.opt_type import * +class VectorAdderComboRTL(Component): -class VectorAdderComboRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - num_lanes = 4, data_bandwidth = 64 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, + num_lanes = 4, data_bandwidth = 64): # Constants assert(data_bandwidth % num_lanes == 0) + num_entries = 2 s.const_zero = DataType(0, 0) sub_bw = data_bandwidth // num_lanes - num_entries = 2 CountType = mk_bits( clog2( num_entries + 1 ) ) # Interface s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] s.recv_const = RecvIfcRTL( DataType ) s.recv_predicate = RecvIfcRTL( PredicateType ) s.recv_opt = RecvIfcRTL( CtrlType ) s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] - # s.initial_carry_in = InPort( b1 ) - # s.initial_carry_out = OutPort( b1 ) # Components s.Fu = [ VectorAdderRTL( sub_bw, CtrlType, 4, 2, data_mem_size ) for _ in range( num_lanes ) ] # Connection: for carry-in/out - # s.Fu[0].carry_in //= s.initial_carry_in # b1( 0 ) s.Fu[0].carry_in //= 0 for i in range( 1, num_lanes ): s.Fu[i].carry_in //= s.Fu[i-1].carry_out - # s.initial_carry_out //= s.Fu[num_lanes-1].carry_out for i in range( num_lanes ): # Connection: split into vectorized FUs @@ -70,38 +65,38 @@ def construct( s, DataType, PredicateType, CtrlType, @update def update_signal(): - s.recv_in[0].rdy @= s.send_out[0].rdy - s.recv_in[1].rdy @= s.send_out[0].rdy + s.recv_in[0].rdy @= s.Fu[0].recv_in[0].rdy + s.recv_in[1].rdy @= s.Fu[0].recv_in[1].rdy + + for i in range(num_lanes): + s.Fu[i].recv_opt.val @= s.recv_opt.val + + for j in range(num_outports): + s.Fu[i].send_out[j].rdy @= s.send_out[j].rdy - for i in range( num_lanes ): - s.Fu[i].recv_opt.en @= s.recv_opt.en + s.Fu[i].recv_in[0].val @= s.recv_in[0].val + s.Fu[i].recv_in[1].val @= s.recv_in[1].val + s.Fu[i].recv_const.val @= s.recv_const.val # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. # s.Fu[i].recv_opt.msg.predicate = s.recv_opt.msg.predicate + s.recv_const.rdy @= s.Fu[0].recv_const.rdy + s.recv_opt.rdy @= s.Fu[0].recv_opt.rdy - # Connect count - s.Fu[i].recv_in_count[0] @= s.recv_in_count[0] - s.Fu[i].recv_in_count[1] @= s.recv_in_count[1] - - s.recv_opt.rdy @= s.send_out[0].rdy - - # TODO: use & | instead of and or @update def update_opt(): for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - s.send_out[j].msg.predicate @= b1( 0 ) + s.send_out[j].val @= b1(0) + s.send_out[j].msg.predicate @= b1(0) - s.send_out[0].en @= s.recv_in[0].en & \ - s.recv_in[1].en & \ - s.recv_opt.en + s.send_out[0].val @= s.Fu[0].send_out[0].val & \ + s.recv_opt.val - s.recv_predicate.rdy @= b1( 0 ) - s.recv_const.rdy @= b1( 0 ) + s.recv_predicate.rdy @= b1(0) - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.fu_in[0] @= 1 s.Fu[i].recv_opt.msg.fu_in[1] @= 2 s.Fu[i].recv_opt.msg.ctrl @= OPT_NAH @@ -111,49 +106,42 @@ def update_opt(): if ( s.recv_opt.msg.ctrl == OPT_VEC_ADD ) | \ ( s.recv_opt.msg.ctrl == OPT_ADD ): - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.ctrl @= OPT_ADD s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate & s.recv_in[1].msg.predicate elif ( s.recv_opt.msg.ctrl == OPT_VEC_SUB ) | \ ( s.recv_opt.msg.ctrl == OPT_SUB ): - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.ctrl @= OPT_SUB s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate & s.recv_in[1].msg.predicate elif ( s.recv_opt.msg.ctrl == OPT_VEC_ADD_CONST ) | \ ( s.recv_opt.msg.ctrl == OPT_ADD_CONST ): - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.ctrl @= OPT_ADD_CONST s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate elif (s.recv_opt.msg.ctrl == OPT_VEC_SUB_CONST ) | \ (s.recv_opt.msg.ctrl == OPT_SUB_CONST ): - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.ctrl @= OPT_SUB_CONST s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate else: for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - - if ( s.recv_opt.msg.ctrl == OPT_VEC_ADD_CONST ) | \ - ( s.recv_opt.msg.ctrl == OPT_VEC_SUB_CONST ) | \ - ( s.recv_opt.msg.ctrl == OPT_ADD_CONST ) | \ - ( s.recv_opt.msg.ctrl == OPT_SUB_CONST ): - s.recv_const.rdy @= s.recv_opt.en + s.send_out[j].val @= b1( 0 ) @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) + s.to_mem_waddr.val @= b1( 0 ) + s.to_mem_wdata.val @= b1( 0 ) s.to_mem_wdata.msg @= s.const_zero s.to_mem_waddr.msg @= AddrType( 0 ) s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) + s.to_mem_raddr.val @= b1( 0 ) s.from_mem_rdata.rdy @= b1( 0 ) - def line_trace( s ): + def line_trace(s): return str(s.recv_in[0].msg) + OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] + str(s.recv_in[1].msg) + " -> " + str(s.send_out[0].msg) - # return s.Fu[0].line_trace() + " ; " + s.Fu[1].line_trace() + " ; " +\ - # s.Fu[2].line_trace() + " ; " + s.Fu[3].line_trace() + diff --git a/fu/vector/VectorAdderRTL.py b/fu/vector/VectorAdderRTL.py index a0c8610..ac416e4 100644 --- a/fu/vector/VectorAdderRTL.py +++ b/fu/vector/VectorAdderRTL.py @@ -12,18 +12,19 @@ """ -from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ...lib.opt_type import * +from pymtl3 import * +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.opt_type import * -class VectorAdderRTL( Component ): +class VectorAdderRTL(Component): - def construct( s, bw, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, bw, CtrlType, num_inports, num_outports, + data_mem_size): # DataType should be 1-bit more due to the carry-out - DataType = mk_bits( bw+1 ) num_entries = 2 + DataType = mk_bits( bw+1 ) FuInType = mk_bits( clog2( num_inports + 1 ) ) CountType = mk_bits( clog2( num_entries + 1 ) ) FuInType = mk_bits( clog2( num_inports + 1 ) ) @@ -34,7 +35,6 @@ def construct( s, bw, CtrlType, # Interface s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] s.recv_const = RecvIfcRTL( DataType ) s.recv_opt = RecvIfcRTL( CtrlType ) s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] @@ -52,82 +52,98 @@ def construct( s, bw, CtrlType, s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] - # Components - s.recv_rdy_vector = Wire( num_outports ) + s.recv_all_val = Wire(1) - @update - def update_signal(): - for j in range( num_outports ): - # s.recv_const.rdy @= s.send_out[j].rdy | s.recv_const.rdy - # s.recv_opt.rdy @= s.send_out[j].rdy | s.recv_opt.rdy - s.recv_rdy_vector[j] @= s.send_out[j].rdy - s.recv_const.rdy @= reduce_or( s.recv_rdy_vector ) - s.recv_opt.rdy @= reduce_or( s.recv_rdy_vector ) - - # TODO: declare in0 in1 as wires @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 for i in range( num_inports ): s.recv_in[i].rdy @= b1( 0 ) - s.carry_in_temp[0] @= s.carry_in - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != FuInType( 0 ): - s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType( 1 ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != FuInType( 0 ): - s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType( 1 ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en - s.send_out[j].msg @= DataType() - - if s.recv_opt.msg.ctrl == OPT_ADD: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.recv_in[s.in1_idx].msg + s.carry_in_temp - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range( num_outports ): + s.send_out[i].val @= b1(0) + s.send_out[i].msg @= DataType() - elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.recv_const.msg + s.carry_in_temp + s.recv_const.rdy @= 0 + s.recv_opt.rdy @= 0 - elif s.recv_opt.msg.ctrl == OPT_INC: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.const_one - - elif s.recv_opt.msg.ctrl == OPT_SUB: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg - s.recv_in[s.in1_idx].msg - s.carry_in_temp - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - - elif s.recv_opt.msg.ctrl == OPT_SUB_CONST: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg - s.recv_const.msg - s.carry_in_temp - - elif s.recv_opt.msg.ctrl == OPT_PAS: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + s.carry_in_temp[0] @= s.carry_in + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_ADD: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.recv_in[s.in1_idx].msg + s.carry_in_temp + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_ADD_CONST: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.recv_const.msg + s.carry_in_temp + s.recv_const.rdy @= s.send_out[0].rdy + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_INC: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.const_one + s.recv_all_val @= s.recv_in[s.in0_idx].val + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_SUB: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg - s.recv_in[s.in1_idx].msg - s.carry_in_temp + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_SUB_CONST: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg - s.recv_const.msg - s.carry_in_temp + s.recv_const.rdy @= s.send_out[0].rdy + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_const.val + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + elif s.recv_opt.msg.ctrl == OPT_PAS: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg + s.recv_all_val @= s.recv_in[s.in0_idx].val + s.send_out[0].val @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range( num_outports ): + s.send_out[j].val @= b1( 0 ) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 s.carry_out @= s.send_out[0].msg[bw:bw+1] - # if s.recv_opt.msg.predicate == b1( 1 ): - # s.send_out[0].msg.predicate = s.send_out[0].msg.predicate - def line_trace( s ): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.en: {s.recv_opt.en}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' + diff --git a/fu/vector/VectorAllReduceRTL.py b/fu/vector/VectorAllReduceRTL.py index 7b30e00..b3af1e0 100644 --- a/fu/vector/VectorAllReduceRTL.py +++ b/fu/vector/VectorAllReduceRTL.py @@ -8,17 +8,18 @@ """ -from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ...lib.opt_type import * -from ..basic.SumUnit import SumUnit +from pymtl3 import * +from ..basic.SumUnit import SumUnit from ..basic.ReduceMulUnit import ReduceMulUnit +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.opt_type import * -class VectorAllReduceRTL( Component ): +class VectorAllReduceRTL(Component): - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - num_lanes = 4, data_bandwidth = 16 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, + num_lanes = 4, data_bandwidth = 16): # Constants assert(data_bandwidth % num_lanes == 0) @@ -47,13 +48,13 @@ def construct( s, DataType, PredicateType, CtrlType, s.to_mem_wdata = SendIfcRTL( DataType ) # Reduction units - s.reduce_add = SumUnit( TempDataType, num_lanes ) - for i in range( num_lanes ): + s.reduce_add = SumUnit(TempDataType, num_lanes) + for i in range(num_lanes): s.reduce_add.in_[i] //= lambda: (s.temp_result[i] if s.recv_opt.msg.ctrl == OPT_VEC_REDUCE_ADD else 0) - s.reduce_mul = ReduceMulUnit( TempDataType, num_lanes ) - for i in range( num_lanes ): + s.reduce_mul = ReduceMulUnit(TempDataType, num_lanes) + for i in range(num_lanes): s.reduce_mul.in_[i] //= lambda: (s.temp_result[i] if s.recv_opt.msg.ctrl == OPT_VEC_REDUCE_MUL else 0) @@ -61,8 +62,8 @@ def construct( s, DataType, PredicateType, CtrlType, def update_result(): # Connection: split data into vectorized wires s.send_out[0].msg.payload @= 0 - for i in range( num_lanes ): - s.temp_result[i] @= TempDataType( 0 ) + for i in range(num_lanes): + s.temp_result[i] @= TempDataType(0) s.temp_result[i][0:sub_bw] @= s.recv_in[0].msg.payload[i*sub_bw:(i+1)*sub_bw] if s.recv_opt.msg.ctrl == OPT_VEC_REDUCE_ADD: @@ -73,38 +74,35 @@ def update_result(): @update def update_signal(): - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) s.recv_in[0].rdy @= s.send_out[0].rdy # s.recv_in[1].rdy = s.send_out[0].rdy s.recv_opt.rdy @= s.send_out[0].rdy - s.send_out[0].en @= s.recv_in[0].en & s.recv_opt.en + s.send_out[0].val @= s.recv_in[0].val & s.recv_opt.val @update def update_predicate(): - s.recv_predicate.rdy @= b1( 0 ) + s.recv_predicate.rdy @= b1(0) s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= b1(1) # else: # s.send_out[0].msg.predicate @= b1( 0 ) if s.recv_opt.msg.ctrl != OPT_VEC_REDUCE_ADD | s.recv_opt.msg.ctrl != OPT_VEC_REDUCE_MUL: - s.send_out[0].msg.predicate @= b1( 0 ) # s.recv_in[0].msg.predicate + s.send_out[0].msg.predicate @= b1(0) # s.recv_in[0].msg.predicate @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) + s.to_mem_waddr.val @= b1( 0 ) + s.to_mem_wdata.val @= b1( 0 ) s.to_mem_wdata.msg @= s.const_zero s.to_mem_waddr.msg @= AddrType( 0 ) s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) + s.to_mem_raddr.val @= b1( 0 ) s.from_mem_rdata.rdy @= b1( 0 ) - def line_trace( s ): + def line_trace(s): return str(s.recv_in[0].msg) + OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] + " -> " + str(s.send_out[0].msg) - # return s.Fu[0].line_trace() + " ; " + s.Fu[1].line_trace() + " ; " +\ - # s.Fu[2].line_trace() + " ; " + s.Fu[3].line_trace() + " ; " +\ - # s.Fu[4].line_trace() + " ; " + s.Fu[5].line_trace() + " ; " +\ - # s.Fu[6].line_trace() + " ; " + s.Fu[7].line_trace() + diff --git a/fu/vector/VectorMulComboRTL.py b/fu/vector/VectorMulComboRTL.py index ea27fdc..1263e5e 100644 --- a/fu/vector/VectorMulComboRTL.py +++ b/fu/vector/VectorMulComboRTL.py @@ -10,26 +10,26 @@ Date : April 17, 2022 """ +from pymtl3 import * +from .VectorMulRTL import VectorMulRTL +from ..basic.SumUnit import SumUnit +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.opt_type import * -from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from .VectorMulRTL import VectorMulRTL -from ...lib.opt_type import * -from ..basic.SumUnit import SumUnit +class VectorMulComboRTL(Component): -class VectorMulComboRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - num_lanes = 4, data_bandwidth = 64 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, + num_lanes = 4, data_bandwidth = 64): # Constants assert(data_bandwidth % num_lanes == 0) # currently only support 4 due to the shift logic assert(num_lanes % 4 == 0) - s.const_zero = DataType(0, 0) num_entries = 2 - CountType = mk_bits( clog2( num_entries + 1 ) ) + s.const_zero = DataType(0, 0) + CountType = mk_bits(clog2(num_entries + 1)) # By default 16-bit indicates both input and output. For a Mul, # if output is no longer than 16-bit, it means the # input is no longer than 8-bit. Here, the sub_bw is by default @@ -42,7 +42,6 @@ def construct( s, DataType, PredicateType, CtrlType, # Interface s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] s.recv_const = RecvIfcRTL( DataType ) s.recv_predicate = RecvIfcRTL( PredicateType ) s.recv_opt = RecvIfcRTL( CtrlType ) @@ -64,10 +63,9 @@ def construct( s, DataType, PredicateType, CtrlType, s.to_mem_waddr = SendIfcRTL( AddrType ) s.to_mem_wdata = SendIfcRTL( DataType ) - # Reduction units s.reduce_add = SumUnit( TempDataType, num_lanes ) - for i in range( num_lanes ): + for i in range(num_lanes): s.reduce_add.in_[i] //= lambda: (s.temp_result[i] if s.recv_opt.msg.ctrl == OPT_VEC_MUL else 0) @@ -75,23 +73,19 @@ def construct( s, DataType, PredicateType, CtrlType, def update_input_output(): # Initialization to avoid latches - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + for j in range(num_outports): + s.send_out[j].val @= b1(0) - s.send_out[0].en @= s.recv_in[0].en & \ - s.recv_in[1].en & \ - s.recv_opt.en + s.send_out[0].val @= s.Fu[0].send_out[0].val & \ + s.recv_opt.val s.send_out[0].msg.payload @= 0 - for i in range( num_lanes ): - s.temp_result[i] @= TempDataType( 0 ) + for i in range(num_lanes): + s.temp_result[i] @= TempDataType(0) s.Fu[i].recv_in[0].msg[0:sub_bw] @= FuDataType() s.Fu[i].recv_in[1].msg[0:sub_bw] @= FuDataType() if s.recv_opt.msg.ctrl == OPT_VEC_MUL: - - # s.send_out[0].msg.payload[0:data_bandwidth] @= TempDataType( 0 ) - # Connection: split into vectorized FUs s.Fu[0].recv_in[0].msg[0:sub_bw] @= s.recv_in[0].msg.payload[0:sub_bw] s.Fu[0].recv_in[1].msg[0:sub_bw] @= s.recv_in[1].msg.payload[0:sub_bw] @@ -102,19 +96,13 @@ def update_input_output(): s.Fu[3].recv_in[0].msg[0:sub_bw] @= s.recv_in[0].msg.payload[sub_bw_3:sub_bw_4] s.Fu[3].recv_in[1].msg[0:sub_bw] @= s.recv_in[1].msg.payload[sub_bw_3:sub_bw_4] - for i in range( num_lanes ): - - s.temp_result[i] @= TempDataType( 0 ) - # s.temp_result[i][0:sub_bw_2] @= s.Fu[i].send_out[0].msg[0:sub_bw_2] + for i in range(num_lanes): + s.temp_result[i] @= TempDataType(0) s.temp_result[i][0:sub_bw_2] @= s.Fu[i].send_out[0].msg[0:sub_bw_2] << (sub_bw * i) - # s.send_out[0].msg.payload[0:data_bandwidth] @= s.send_out[0].msg.payload[0:data_bandwidth] + (s.temp_result[i] << (sub_bw * i)); - # s.send_out[0].msg.payload[0:data_bandwidth] @= s.send_out[0].msg.payload[0:data_bandwidth] + s.temp_result[i]; - # s.send_out[0].msg.payload[sub_bw*i:sub_bw*(i+1)] @= s.Fu[i].send_out[0].msg[0:sub_bw]; s.send_out[0].msg.payload[0:data_bandwidth] @= s.reduce_add.out elif s.recv_opt.msg.ctrl == OPT_MUL: # with highest precision - s.Fu[0].recv_in[0].msg[0:sub_bw] @= s.recv_in[0].msg.payload[0:sub_bw] s.Fu[0].recv_in[1].msg[0:sub_bw] @= s.recv_in[1].msg.payload[0:sub_bw] s.Fu[1].recv_in[0].msg[0:sub_bw] @= s.recv_in[0].msg.payload[0:sub_bw] @@ -124,70 +112,71 @@ def update_input_output(): s.Fu[3].recv_in[0].msg[0:sub_bw] @= s.recv_in[0].msg.payload[sub_bw:sub_bw_2] s.Fu[3].recv_in[1].msg[0:sub_bw] @= s.recv_in[1].msg.payload[sub_bw:sub_bw_2] - for i in range( num_lanes ): + for i in range(num_lanes): s.temp_result[i] @= TempDataType( 0 ) s.temp_result[i][0:sub_bw_2] @= s.Fu[i].send_out[0].msg[0:sub_bw_2] - s.send_out[0].msg.payload[0:data_bandwidth] @= s.temp_result[0] + (s.temp_result[1] << sub_bw) + (s.temp_result[2] << sub_bw) + (s.temp_result[3] << (sub_bw*2)) + s.send_out[0].msg.payload[0:data_bandwidth] @= \ + s.temp_result[0] + \ + (s.temp_result[1] << sub_bw) + \ + (s.temp_result[2] << sub_bw) + \ + (s.temp_result[3] << (sub_bw*2)) else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) - + for j in range(num_outports): + s.send_out[j].val @= b1(0) @update def update_signal(): - s.recv_in[0].rdy @= s.send_out[0].rdy - s.recv_in[1].rdy @= s.send_out[0].rdy + s.recv_in[0].rdy @= s.Fu[0].recv_in[0].rdy + s.recv_in[1].rdy @= s.Fu[0].recv_in[1].rdy - for i in range( num_lanes ): - s.Fu[i].recv_opt.en @= s.recv_opt.en + for i in range(num_lanes): + s.Fu[i].recv_opt.val @= s.recv_opt.val # Note that the predication for a combined FU should be identical/shareable, # which means the computation in different basic block cannot be combined. # s.Fu[i].recv_opt.msg.predicate = s.recv_opt.msg.predicate - # Connect count - s.Fu[i].recv_in_count[0] @= s.recv_in_count[0] - s.Fu[i].recv_in_count[1] @= s.recv_in_count[1] + s.Fu[i].recv_in[0].val @= s.recv_in[0].val + s.Fu[i].recv_in[1].val @= s.recv_in[1].val + s.Fu[i].recv_const.val @= s.recv_const.val - s.recv_opt.rdy @= s.send_out[0].rdy + for j in range(num_outports): + s.Fu[i].send_out[j].rdy @= s.send_out[j].rdy - FuInType = mk_bits( clog2( num_inports + 1 ) ) + s.recv_const.rdy @= s.Fu[0].recv_const.rdy + s.recv_opt.rdy @= s.send_out[0].rdy @update def update_opt(): + s.recv_predicate.rdy @= b1(0) + s.send_out[0].msg.predicate @= b1(0) - s.recv_predicate.rdy @= b1( 0 ) - s.send_out[0].msg.predicate @= b1( 0 ) - - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.fu_in[0] @= 1 s.Fu[i].recv_opt.msg.fu_in[1] @= 2 s.Fu[i].recv_opt.msg.ctrl @= OPT_NAH - if s.recv_opt.msg.predicate == b1( 1 ): - s.recv_predicate.rdy @= b1( 1 ) + if s.recv_opt.msg.predicate == b1(1): + s.recv_predicate.rdy @= b1(1) if (s.recv_opt.msg.ctrl == OPT_VEC_MUL) | \ (s.recv_opt.msg.ctrl == OPT_MUL): - for i in range( num_lanes ): + for i in range(num_lanes): s.Fu[i].recv_opt.msg.ctrl @= OPT_MUL s.send_out[0].msg.predicate @= s.recv_in[0].msg.predicate & s.recv_in[1].msg.predicate @update def update_mem(): - s.to_mem_waddr.en @= b1( 0 ) - s.to_mem_wdata.en @= b1( 0 ) + s.to_mem_waddr.val @= b1( 0 ) + s.to_mem_wdata.val @= b1( 0 ) s.to_mem_wdata.msg @= s.const_zero s.to_mem_waddr.msg @= AddrType( 0 ) s.to_mem_raddr.msg @= AddrType( 0 ) - s.to_mem_raddr.en @= b1( 0 ) + s.to_mem_raddr.val @= b1( 0 ) s.from_mem_rdata.rdy @= b1( 0 ) - def line_trace( s ): + def line_trace(s): return str(s.recv_in[0].msg) + OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] + str(s.recv_in[1].msg) + " -> " + str(s.send_out[0].msg) - # return s.Fu[0].line_trace() + " ; " + s.Fu[1].line_trace() + " ; " +\ - # s.Fu[2].line_trace() + " ; " + s.Fu[3].line_trace() + " ; " +\ - # s.Fu[4].line_trace() + " ; " + s.Fu[5].line_trace() + " ; " +\ - # s.Fu[6].line_trace() + " ; " + s.Fu[7].line_trace() + diff --git a/fu/vector/VectorMulRTL.py b/fu/vector/VectorMulRTL.py index e52d105..9fdaaea 100644 --- a/fu/vector/VectorMulRTL.py +++ b/fu/vector/VectorMulRTL.py @@ -12,19 +12,20 @@ """ -from pymtl3 import * -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ...lib.opt_type import * +from pymtl3 import * +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.opt_type import * -class VectorMulRTL( Component ): +class VectorMulRTL(Component): - def construct( s, bw, CtrlType, - num_inports, num_outports, data_mem_size ): + def construct(s, bw, CtrlType, num_inports, num_outports, + data_mem_size): # DataType should be 2 times due to the longer output - DataType = mk_bits( bw * 2 ) num_entries = 2 + DataType = mk_bits( bw * 2 ) FuInType = mk_bits( clog2( num_inports + 1 ) ) CountType = mk_bits( clog2( num_entries + 1 ) ) FuInType = mk_bits( clog2( num_inports + 1 ) ) @@ -34,65 +35,66 @@ def construct( s, bw, CtrlType, s.const_one = DataType(1) # Interface - s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] - s.recv_const = RecvIfcRTL( DataType ) - s.recv_opt = RecvIfcRTL( CtrlType ) - s.send_out = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] + s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] + s.recv_in_count = [InPort(CountType) for _ in range(num_inports)] + s.recv_const = RecvIfcRTL(DataType) + s.recv_opt = RecvIfcRTL(CtrlType) + s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] # Components - s.recv_rdy_vector = Wire( num_outports ) - - @update - def update_signal(): - for j in range( num_outports ): - # s.recv_const.rdy @= s.send_out[j].rdy | s.recv_const.rdy - # s.recv_opt.rdy @= s.send_out[j].rdy | s.recv_opt.rdy - s.recv_rdy_vector[j] @= s.send_out[j].rdy - s.recv_const.rdy @= reduce_or( s.recv_rdy_vector ) - s.recv_opt.rdy @= reduce_or( s.recv_rdy_vector ) + s.recv_all_val = Wire(1) @update def comb_logic(): + s.recv_all_val @= 0 # Pick input register - s.in0 @= FuInType( 0 ) - s.in1 @= FuInType( 0 ) - for i in range( num_inports ): - s.recv_in[i].rdy @= b1( 0 ) - - if s.recv_opt.en: - if s.recv_opt.msg.fu_in[0] != 0: - s.in0 @= zext( s.recv_opt.msg.fu_in[0] - 1, FuInType ) - s.recv_in[s.in0_idx].rdy @= b1( 1 ) - if s.recv_opt.msg.fu_in[1] != 0: - s.in1 @= zext( s.recv_opt.msg.fu_in[1] - 1, FuInType ) - s.recv_in[s.in1_idx].rdy @= b1( 1 ) - - for j in range( num_outports ): - s.send_out[j].en @= s.recv_opt.en - s.send_out[j].msg @= DataType() - - if s.recv_opt.msg.ctrl == OPT_MUL: - s.send_out[0].msg @= s.recv_in[s.in0_idx].msg * s.recv_in[s.in1_idx].msg - if s.recv_opt.en & ( (s.recv_in_count[s.in0_idx] == 0) | \ - (s.recv_in_count[s.in1_idx] == 0) ): - s.recv_in[s.in0_idx].rdy @= b1( 0 ) - s.recv_in[s.in1_idx].rdy @= b1( 0 ) - - else: - for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + s.in0 @= FuInType(0) + s.in1 @= FuInType(0) + + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + + for i in range(num_inports): + s.recv_in[i].rdy @= b1(0) + for i in range( num_outports ): + s.send_out[i].val @= b1(0) + s.send_out[i].msg @= DataType() + + s.recv_const.rdy @= 0 + s.recv_opt.rdy @= 0 + + if s.recv_opt.val & s.send_out[0].rdy: + if s.recv_opt.msg.fu_in[0] != FuInType(0): + s.in0 @= s.recv_opt.msg.fu_in[0] - FuInType(1) + if s.recv_opt.msg.fu_in[1] != FuInType(0): + s.in1 @= s.recv_opt.msg.fu_in[1] - FuInType(1) + + if s.recv_opt.val: + if s.recv_opt.msg.ctrl == OPT_MUL: + s.send_out[0].msg @= s.recv_in[s.in0_idx].msg * s.recv_in[s.in1_idx].msg + s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val + s.send_out[0].val @= s.recv_all_val + s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + + else: + for j in range( num_outports ): + s.send_out[j].val @= b1( 0 ) + s.recv_opt.rdy @= 0 + s.recv_in[s.in0_idx].rdy @= 0 + s.recv_in[s.in1_idx].rdy @= 0 # if s.recv_opt.msg.predicate == b1( 1 ): # s.send_out[0].msg.predicate = s.send_out[0].msg.predicate @@ -100,8 +102,8 @@ def comb_logic(): def line_trace( s ): opt_str = " #" - if s.recv_opt.en: + if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] out_str = ",".join([str(x.msg) for x in s.send_out]) recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.en: {s.recv_opt.en}, send[0].en: {s.send_out[0].en}) ' + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const_reg: {s.recv_const.msg}) ] = [out: {out_str}] (s.recv_opt.rdy: {s.recv_opt.rdy}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' diff --git a/fu/vector/test/VectorAdderComboRTL_test.py b/fu/vector/test/VectorAdderComboRTL_test.py index 195904e..c0a0749 100644 --- a/fu/vector/test/VectorAdderComboRTL_test.py +++ b/fu/vector/test/VectorAdderComboRTL_test.py @@ -8,14 +8,12 @@ Date : April 17, 2022 """ - -from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..VectorAdderComboRTL import VectorAdderComboRTL -from ....lib.opt_type import * -from ....lib.messages import * +from pymtl3 import * +from ..VectorAdderComboRTL import VectorAdderComboRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * #------------------------------------------------------------------------- # Test harness @@ -23,23 +21,21 @@ class TestHarness( Component ): - def construct( s, FunctionUnit, DataType, data_bw, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_const_msgs, - src_predicate, ctrl_msgs, sink_msgs0 ): + def construct(s, FunctionUnit, DataType, data_bw, PredicateType, + CtrlType, num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_const_msgs, src_predicate, + ctrl_msgs, sink_msgs0): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_const = TestSrcRTL( DataType, src_const_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_const = TestSrcRTL ( DataType, src_const_msgs ) + s.src_predicate = TestSrcRTL ( PredicateType, src_predicate ) + s.src_opt = TestSrcRTL ( CtrlType, ctrl_msgs ) s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, 4, data_bw ) + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports, data_mem_size, 4, data_bw) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 # s.dut.initial_carry_in //= 0 connect( s.src_in0.send, s.dut.recv_in[0] ) @@ -49,26 +45,27 @@ def construct( s, FunctionUnit, DataType, data_bw, PredicateType, CtrlType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out0.recv ) - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out0.done() + def done(s): + return s.src_in0.done() and \ + s.src_opt.done() and \ + s.sink_out0.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -103,5 +100,5 @@ def test_vector_adder_combo(): num_inports, num_outports, data_mem_size, src_in0, src_in1, src_const, src_predicate, src_opt, sink_out0 ) - run_sim( th ) + run_sim(th) diff --git a/fu/vector/test/VectorAdderRTL_test.py b/fu/vector/test/VectorAdderRTL_test.py index 096cb52..9b9e7e4 100644 --- a/fu/vector/test/VectorAdderRTL_test.py +++ b/fu/vector/test/VectorAdderRTL_test.py @@ -9,14 +9,13 @@ """ -from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..VectorAdderRTL import VectorAdderRTL -from ....mem.const.ConstQueueRTL import ConstQueueRTL -from ....lib.opt_type import * -from ....lib.messages import * +from pymtl3 import * +from ..VectorAdderRTL import VectorAdderRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * +from ....mem.const.ConstQueueRTL import ConstQueueRTL #------------------------------------------------------------------------- # Test harness @@ -41,24 +40,18 @@ def construct( s, FunctionUnit, bandwidth, ConfigType, num_inports, num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - s.src_in0.send.rdy //= s.dut.recv_in[0].rdy - s.src_in0.send.en //= s.dut.recv_in[0].en + s.src_in0.send.val //= s.dut.recv_in[0].val s.src_in0.send.msg //= s.dut.recv_in[0].msg[0:bandwidth] s.src_in1.send.rdy //= s.dut.recv_in[1].rdy - s.src_in1.send.en //= s.dut.recv_in[1].en + s.src_in1.send.val //= s.dut.recv_in[1].val s.src_in1.send.msg //= s.dut.recv_in[1].msg[0:bandwidth] s.const_queue.send_const.rdy //= s.dut.recv_const.rdy - s.const_queue.send_const.en //= s.dut.recv_const.en + s.const_queue.send_const.val //= s.dut.recv_const.val s.const_queue.send_const.msg //= s.dut.recv_const.msg[0:bandwidth] - # connect( s.src_in0.send, s.dut.recv_in[0] ) - # connect( s.src_in1.send, s.dut.recv_in[1] ) - # connect( s.dut.recv_const, s.const_queue.send_const ) connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out.recv ) @@ -103,9 +96,9 @@ def test_vadder(): FuInType = mk_bits( clog2( num_inports + 1 ) ) pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] src_in0 = [ InDataType(1), InDataType(7), InDataType(4) ] - src_in1 = [ InDataType(2), InDataType(3), InDataType(1) ] - src_const = [ InDataType(5), InDataType(0), InDataType(7) ] - sink_out = [ OutDataType(6), OutDataType(4), OutDataType(11) ] + src_in1 = [ InDataType(2) ] + src_const = [ InDataType(5), InDataType(7) ] + sink_out = [ OutDataType(6), OutDataType(5), OutDataType(11) ] src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), ConfigType( OPT_SUB, b1( 1 ), pickRegister ), ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] diff --git a/fu/vector/test/VectorAllReduceRTL_test.py b/fu/vector/test/VectorAllReduceRTL_test.py index 6fe86fb..bd015fb 100644 --- a/fu/vector/test/VectorAllReduceRTL_test.py +++ b/fu/vector/test/VectorAllReduceRTL_test.py @@ -8,37 +8,32 @@ Date : April 23, 2022 """ - -from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..VectorAllReduceRTL import VectorAllReduceRTL -from ....lib.opt_type import * -from ....lib.messages import * +from pymtl3 import * +from ..VectorAllReduceRTL import VectorAllReduceRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_predicate, - ctrl_msgs, sink_msgs0 ): +class TestHarness(Component): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) - s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) + def construct(s, FunctionUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_predicate, + ctrl_msgs, sink_msgs0): - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_predicate = TestSrcRTL ( PredicateType, src_predicate ) + s.src_opt = TestSrcRTL ( CtrlType, ctrl_msgs ) + s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) @@ -46,25 +41,25 @@ def construct( s, FunctionUnit, DataType, PredicateType, CtrlType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out0.recv ) - def done( s ): + def done(s): return s.src_in0.done() and s.src_opt.done() and s.sink_out0.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -93,8 +88,8 @@ def test_vector_all_reduce(): CtrlType( OPT_VEC_REDUCE_MUL, b1( 0 ), pickRegister ), CtrlType( OPT_VEC_REDUCE_MUL, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredType, CtrlType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_pred, src_opt, sink_out ) - run_sim( th ) + th = TestHarness(FU, DataType, PredType, CtrlType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_pred, src_opt, sink_out) + run_sim(th) diff --git a/fu/vector/test/VectorMulComboRTL_test.py b/fu/vector/test/VectorMulComboRTL_test.py index ee78a9b..b092b1f 100644 --- a/fu/vector/test/VectorMulComboRTL_test.py +++ b/fu/vector/test/VectorMulComboRTL_test.py @@ -8,36 +8,31 @@ Date : April 17, 2022 """ -from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..VectorMulComboRTL import VectorMulComboRTL -from ....lib.opt_type import * -from ....lib.messages import * +from pymtl3 import * +from ..VectorMulComboRTL import VectorMulComboRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, FunctionUnit, DataType, bw, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_predicate, - ctrl_msgs, sink_msgs0 ): +class TestHarness(Component): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) - s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) + def construct(s, FunctionUnit, DataType, bw, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, src0_msgs, + src1_msgs, src_predicate, ctrl_msgs, sink_msgs0): - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, 4, bw ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_predicate = TestSrcRTL ( PredicateType, src_predicate ) + s.src_opt = TestSrcRTL ( CtrlType, ctrl_msgs ) + s.sink_out0 = TestSinkRTL( DataType, sink_msgs0 ) - s.dut.recv_in_count[0] //= 1 - s.dut.recv_in_count[1] //= 1 + s.dut = FunctionUnit(DataType, PredicateType, CtrlType, + num_inports, num_outports, data_mem_size, 4, bw) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) @@ -45,26 +40,26 @@ def construct( s, FunctionUnit, DataType, bw, PredicateType, CtrlType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out0.recv ) - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out0.done() + def done(s): + return s.src_in0.done() and s.src_in1.done() and \ + s.src_opt.done() and s.sink_out0.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -78,7 +73,7 @@ def test_vector_mul_combo(): bw = 64 DataType = mk_data( bw, 1 ) PredType = mk_predicate( 1, 1 ) - num_inports = 2 + num_inports = 4 num_outports = 1 data_mem_size = 8 CtrlType = mk_ctrl( num_fu_in=num_inports ) @@ -97,5 +92,5 @@ def test_vector_mul_combo(): th = TestHarness( FU, DataType, bw, PredType, CtrlType, num_inports, num_outports, data_mem_size, src_in0, src_in1, src_pred, src_opt, sink_out ) - run_sim( th ) + run_sim(th) diff --git a/fu/vector/test/VectorMulRTL_test.py b/fu/vector/test/VectorMulRTL_test.py index 10b789d..ad3f244 100644 --- a/fu/vector/test/VectorMulRTL_test.py +++ b/fu/vector/test/VectorMulRTL_test.py @@ -8,15 +8,13 @@ Date : March 13, 2022 """ - -from pymtl3 import * -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..VectorMulRTL import VectorMulRTL -from ....mem.const.ConstQueueRTL import ConstQueueRTL -from ....lib.opt_type import * -from ....lib.messages import * +from pymtl3 import * +from ..VectorMulRTL import VectorMulRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * +from ....mem.const.ConstQueueRTL import ConstQueueRTL #------------------------------------------------------------------------- # Test harness @@ -41,19 +39,16 @@ def construct( s, FunctionUnit, bandwidth, ConfigType, num_inports, num_outports, data_mem_size ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - s.src_in0.send.rdy //= s.dut.recv_in[0].rdy - s.src_in0.send.en //= s.dut.recv_in[0].en + s.src_in0.send.val //= s.dut.recv_in[0].val s.src_in0.send.msg //= s.dut.recv_in[0].msg[0:bandwidth] s.src_in1.send.rdy //= s.dut.recv_in[1].rdy - s.src_in1.send.en //= s.dut.recv_in[1].en + s.src_in1.send.val //= s.dut.recv_in[1].val s.src_in1.send.msg //= s.dut.recv_in[1].msg[0:bandwidth] s.const_queue.send_const.rdy //= s.dut.recv_const.rdy - s.const_queue.send_const.en //= s.dut.recv_const.en + s.const_queue.send_const.val //= s.dut.recv_const.val s.const_queue.send_const.msg //= s.dut.recv_const.msg[0:bandwidth] # connect( s.src_in0.send, s.dut.recv_in[0] ) diff --git a/mem/const/ConstQueueRTL.py b/mem/const/ConstQueueRTL.py index 253b5ee..1dbb669 100644 --- a/mem/const/ConstQueueRTL.py +++ b/mem/const/ConstQueueRTL.py @@ -8,51 +8,48 @@ Date : Jan 20, 2020 """ - 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class ConstQueueRTL(Component): -class ConstQueueRTL( Component ): - - def construct( s, DataType, const_list=None ): + def construct(s, DataType, const_list = None): # Constant - num_const = len( const_list ) - AddrType = mk_bits( clog2( num_const+1 ) ) - TimeType = mk_bits( clog2( num_const+1 ) ) + num_const = len(const_list) + AddrType = mk_bits(clog2(num_const + 1)) + TimeType = mk_bits(clog2(num_const + 1)) # Interface - - s.send_const = SendIfcRTL( DataType ) + s.send_const = SendIfcRTL(DataType) # Component + s.const_queue = [Wire(DataType) for _ in range(num_const)] + for i, const_value in enumerate(const_list): + s.const_queue[i] //= const_value - s.const_queue = [ Wire( DataType ) for _ in range( num_const ) ] - for i, const_value in enumerate( const_list ): - s.const_queue[ i ] //= const_value - - s.cur = Wire( AddrType ) + s.cur = Wire(AddrType) @update def load(): - s.send_const.msg @= s.const_queue[ s.cur ] + s.send_const.msg @= s.const_queue[s.cur] @update - def update_en(): - s.send_const.en @= s.send_const.rdy + def const_queue_val(): + s.send_const.val @= (num_const > 0) # s.send_const.rdy @update_ff def update_raddr(): if s.send_const.rdy: - if s.cur + AddrType( 1 ) >= AddrType( num_const ): - s.cur <<= AddrType( 0 ) + if s.cur + AddrType(1) >= AddrType(num_const): + s.cur <<= AddrType(0) else: - s.cur <<= s.cur + AddrType( 1 ) + s.cur <<= s.cur + AddrType(1) - def line_trace( s ): - out_str = "||".join([ str(data) for data in s.const_queue ]) - return f'[{out_str}] : {s.send_const.msg}({s.send_const.en})' + def line_trace(s): + out_str = "||".join([str(data) for data in s.const_queue]) + return f'[{out_str}] : {s.send_const.msg}(val: {s.send_const.val})' diff --git a/mem/const/test/ConstQueueRTL_test.py b/mem/const/test/ConstQueueRTL_test.py index f468186..073079f 100644 --- a/mem/const/test/ConstQueueRTL_test.py +++ b/mem/const/test/ConstQueueRTL_test.py @@ -12,60 +12,56 @@ from pymtl3 import * from ..ConstQueueRTL import ConstQueueRTL from ....fu.single.AdderRTL import AdderRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +# 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 ValRdyTestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ....lib.opt_type import * from ....lib.messages import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): - - def construct( s, DataType, PredicateType, ConfigType, src0_msgs, - src_const, ctrl_msgs, sink_msgs ): +class TestHarness(Component): - s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) - s.src_opt = TestSrcRTL ( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + def construct(s, DataType, PredicateType, ConfigType, src0_msgs, + src_const, ctrl_msgs, sink_msgs): - s.alu = AdderRTL( DataType, PredicateType, ConfigType, - 2, 1, 8 ) - s.const_queue = ConstQueueRTL( DataType, src_const ) + s.src_in0 = ValRdyTestSrcRTL(DataType, src0_msgs) + s.src_opt = ValRdyTestSrcRTL(ConfigType, ctrl_msgs) + s.sink_out = ValRdyTestSinkRTL(DataType, sink_msgs) - s.alu.recv_in_count[0] //= 1 - s.alu.recv_in_count[1] //= 1 + s.alu = AdderRTL(DataType, PredicateType, ConfigType, 2, 1, 8) + s.const_queue = ConstQueueRTL(DataType, src_const) - connect( s.src_in0.send, s.alu.recv_in[0] ) - connect( s.alu.recv_in[1], s.const_queue.send_const ) - connect( s.src_opt.send, s.alu.recv_opt ) - connect( s.alu.send_out[0], s.sink_out.recv ) + connect(s.src_in0.send, s.alu.recv_in[0]) + connect(s.alu.recv_in[1], s.const_queue.send_const) + connect(s.src_opt.send, s.alu.recv_opt) + connect(s.alu.send_out[0], s.sink_out.recv) - def done( s ): + def done(s): return s.src_in0.done() and s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.const_queue.line_trace() + s.alu.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout - assert ncycles < max_cycles test_harness.sim_tick() @@ -73,19 +69,19 @@ def run_sim( test_harness, max_cycles=10 ): test_harness.sim_tick() def test_const_queue(): - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - num_inports = 2 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - ConfigType = mk_ctrl(num_inports) - src_in0 = [ DataType(1, 1), DataType(3, 1), DataType(9, 1) ] - src_const = [ DataType(9, 1), DataType(8, 1), DataType(7, 1) ] - sink_out = [ DataType(10, 1), DataType(11, 1), DataType(2, 1) ] - src_opt = [ ConfigType( OPT_ADD, b1( 0 ), pickRegister ), - ConfigType( OPT_ADD, b1( 0 ), pickRegister ), - ConfigType( OPT_SUB, b1( 0 ), pickRegister ) ] - th = TestHarness( DataType, PredicateType, ConfigType, src_in0, - src_const, src_opt, sink_out ) - run_sim( th ) + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + num_inports = 2 + FuInType = mk_bits(clog2(num_inports + 1)) + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + ConfigType = mk_ctrl(num_inports) + src_in0 = [DataType(1, 1), DataType(3, 1), DataType(9, 1)] + src_const = [DataType(9, 1), DataType(8, 1), DataType(7, 1)] + sink_out = [DataType(10, 1), DataType(11, 1), DataType(2, 1)] + src_opt = [ConfigType(OPT_ADD, b1(0), pickRegister), + ConfigType(OPT_ADD, b1(0), pickRegister), + ConfigType(OPT_SUB, b1(0), pickRegister)] + th = TestHarness(DataType, PredicateType, ConfigType, src_in0, + src_const, src_opt, sink_out) + run_sim(th) diff --git a/mem/ctrl/CtrlMemCL.py b/mem/ctrl/CtrlMemCL.py index 49579fb..9c71712 100644 --- a/mem/ctrl/CtrlMemCL.py +++ b/mem/ctrl/CtrlMemCL.py @@ -8,62 +8,60 @@ Date : Dec 27, 2019 """ - 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class CtrlMemCL(Component): -class CtrlMemCL( Component ): - - def construct( s, CtrlType, ctrl_mem_size, ctrl_count_per_iter = 4, - total_ctrl_steps = 4, opt_list = None, id = 0 ): + def construct(s, CtrlType, ctrl_mem_size, ctrl_count_per_iter = 4, + total_ctrl_steps = 4, opt_list = None, id = 0): # Constant s.id = id - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - PCType = mk_bits( clog2( ctrl_count_per_iter + 1 ) ) - TimeType = mk_bits( clog2( total_ctrl_steps + 2 ) ) + PCType = mk_bits(clog2(ctrl_count_per_iter + 1)) + AddrType = mk_bits(clog2(ctrl_mem_size)) + TimeType = mk_bits(clog2(total_ctrl_steps + 2)) # Interface - s.send_ctrl = SendIfcRTL( CtrlType ) + s.send_ctrl = SendIfcRTL(CtrlType) # Component - s.sram = [ CtrlType( 0 ) for _ in range( ctrl_mem_size ) ] - for i in range( len( opt_list ) ): - s.sram[ i ] = opt_list[i] - s.times = Wire( TimeType ) - s.cur = Wire( AddrType ) + s.sram = [CtrlType(0) for _ in range(ctrl_mem_size)] + for i in range(len(opt_list)): + s.sram[i] = opt_list[i] + s.times = Wire(TimeType) + s.cur = Wire(AddrType) @update def load(): if s.times != 0: - s.send_ctrl.msg @= s.sram[ s.cur ] + s.send_ctrl.msg @= s.sram[s.cur] @update def update_signal(): if s.times == 0: - s.send_ctrl.en @= b1( 0 ) - elif s.times == TimeType( total_ctrl_steps ) or s.sram[s.cur].ctrl == OPT_START: - s.send_ctrl.en @= b1( 0 ) + s.send_ctrl.val @= b1(0) + elif s.times == TimeType(total_ctrl_steps) or s.sram[s.cur].ctrl == OPT_START: + s.send_ctrl.val @= b1(0) else: - s.send_ctrl.en @= s.send_ctrl.rdy + s.send_ctrl.val @= 1 @update_ff def update_raddr(): - if s.times < TimeType( total_ctrl_steps ): - s.times <<= s.times + TimeType( 1 ) + if s.times < TimeType(total_ctrl_steps): + s.times <<= s.times + TimeType(1) if s.send_ctrl.rdy: - if zext(s.cur + 1, PCType) == PCType( ctrl_count_per_iter ): - s.cur <<= AddrType( 0 ) + if zext(s.cur + 1, PCType) == PCType(ctrl_count_per_iter): + s.cur <<= AddrType(0) else: - s.cur <<= s.cur + AddrType( 1 ) - + s.cur <<= s.cur + AddrType(1) - def line_trace( s ): - out_str = "||".join([ str(data) for data in s.sram ]) + def line_trace(s): + out_str = "||".join([str(data) for data in s.sram]) return f'[{out_str}] : {OPT_SYMBOL_DICT[s.send_ctrl.msg.ctrl]}' diff --git a/mem/ctrl/CtrlMemDynamicRTL.py b/mem/ctrl/CtrlMemDynamicRTL.py index 9a96fa1..65dd59d 100644 --- a/mem/ctrl/CtrlMemDynamicRTL.py +++ b/mem/ctrl/CtrlMemDynamicRTL.py @@ -12,7 +12,7 @@ from pymtl3 import * from pymtl3.stdlib.primitive import RegisterFile from ...lib.basic.en_rdy.ifcs import SendIfcRTL -from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL, ValRdySendIfcRTL from ...lib.basic.val_rdy.queues import NormalQueueRTL from ...lib.cmd_type import * from ...lib.opt_type import * @@ -37,7 +37,7 @@ def construct(s, CtrlPktType, CtrlSignalType, ctrl_mem_size, num_routing_outports = num_tile_outports + num_fu_inports # Interface - s.send_ctrl = SendIfcRTL(CtrlSignalType) + s.send_ctrl = ValRdySendIfcRTL(CtrlSignalType) s.recv_pkt = ValRdyRecvIfcRTL(CtrlPktType) # Component @@ -96,23 +96,24 @@ def update_msg(): @update def update_send_out_signal(): - s.send_ctrl.en @= 0 + s.send_ctrl.val @= 0 if s.start_iterate_ctrl == b1(1): if ((total_ctrl_steps > 0) & \ (s.times == TimeType(total_ctrl_steps))) | \ (s.reg_file.rdata[0].ctrl == OPT_START): - s.send_ctrl.en @= b1(0) + s.send_ctrl.val @= b1(0) else: - s.send_ctrl.en @= s.send_ctrl.rdy + s.send_ctrl.val @= 1 if s.recv_pkt_queue.send.val & \ ((s.recv_pkt_queue.send.msg.ctrl_action == CMD_PAUSE) | \ (s.recv_pkt_queue.send.msg.ctrl_action == CMD_TERMINATE)): - s.send_ctrl.en @= b1(0) + s.send_ctrl.val @= b1(0) @update_ff def update_whether_we_can_iterate_ctrl(): if s.recv_pkt_queue.send.val: - # @yo96? data is still there, not released yet? + # if (s.recv_pkt_queue.send.msg.ctrl_action == CMD_LAUNCH) | \ + # (s.recv_pkt_queue.send.msg.ctrl_action == CMD_CONFIG): if s.recv_pkt_queue.send.msg.ctrl_action == CMD_LAUNCH: s.start_iterate_ctrl <<= 1 elif s.recv_pkt_queue.send.msg.ctrl_action == CMD_TERMINATE: diff --git a/mem/ctrl/CtrlMemRTL.py b/mem/ctrl/CtrlMemRTL.py index 644882f..45f38e3 100644 --- a/mem/ctrl/CtrlMemRTL.py +++ b/mem/ctrl/CtrlMemRTL.py @@ -8,13 +8,12 @@ Date : Dec 21, 2019 """ - 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * - class CtrlMemRTL( Component ): def construct( s, CtrlType, ctrl_mem_size, ctrl_count_per_iter = 4, @@ -45,16 +44,16 @@ def construct( s, CtrlType, ctrl_mem_size, ctrl_count_per_iter = 4, s.send_ctrl.msg //= s.reg_file.rdata[0] s.reg_file.waddr[0] //= s.recv_waddr.msg s.reg_file.wdata[0] //= s.recv_ctrl.msg - s.reg_file.wen[0] //= lambda: s.recv_ctrl.en & s.recv_waddr.en + s.reg_file.wen[0] //= lambda: s.recv_ctrl.val & s.recv_waddr.val @update def update_signal(): if ( ( total_ctrl_steps > 0 ) & \ ( s.times == TimeType( total_ctrl_steps ) ) ) | \ (s.reg_file.rdata[0].ctrl == OPT_START): - s.send_ctrl.en @= b1( 0 ) + s.send_ctrl.val @= b1( 0 ) else: - s.send_ctrl.en @= s.send_ctrl.rdy # s.recv_raddr[i].rdy + s.send_ctrl.val @= 1 # s.send_ctrl.rdy # s.recv_raddr[i].rdy s.recv_waddr.rdy @= b1( 1 ) s.recv_ctrl.rdy @= b1( 1 ) diff --git a/mem/ctrl/RingMultiCtrlMemDynamicRTL.py b/mem/ctrl/RingMultiCtrlMemDynamicRTL.py index f01ea06..d82b576 100644 --- a/mem/ctrl/RingMultiCtrlMemDynamicRTL.py +++ b/mem/ctrl/RingMultiCtrlMemDynamicRTL.py @@ -11,8 +11,8 @@ from pymtl3 import * from pymtl3.stdlib.primitive import RegisterFile from .CtrlMemDynamicRTL import CtrlMemDynamicRTL -from ...lib.basic.en_rdy.ifcs import SendIfcRTL -from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * from ...noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ...noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL @@ -29,7 +29,7 @@ def construct(s, CtrlPktType, CtrlSignalType, width, height, # Interface s.send_ctrl = [SendIfcRTL(CtrlSignalType) for _ in range(s.num_terminals)] - s.recv_pkt_from_controller = ValRdyRecvIfcRTL(CtrlPktType) + s.recv_pkt_from_controller = RecvIfcRTL(CtrlPktType) # Components s.ctrl_memories = [ diff --git a/mem/ctrl/test/CtrlCL_test.py b/mem/ctrl/test/CtrlCL_test.py deleted file mode 100644 index 3200c4c..0000000 --- a/mem/ctrl/test/CtrlCL_test.py +++ /dev/null @@ -1,134 +0,0 @@ -""" -========================================================================== -CtrlCL_test.py -========================================================================== -Test cases for control memory. - -Author : Cheng Tan - Date : Dec 21, 2019 -""" - - -from pymtl3 import * -from ..CtrlMemCL import CtrlMemCL -from ....fu.single.AdderCL import AdderCL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL -from ....lib.opt_type import * -from ....lib.messages import * - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, MemUnit, DataType, PredicateType, ConfigType, - ctrl_mem_size, data_mem_size, src0_msgs, src1_msgs, - ctrl_msgs, sink_msgs, adder_latency, total_steps ): - - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - s.src_data0 = TestSrcRTL ( DataType, src0_msgs ) - s.src_data1 = TestSrcRTL ( DataType, src1_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) - - s.alu = AdderCL( DataType, PredicateType, ConfigType, 2, 2, - data_mem_size, adder_latency ) - s.ctrl_mem = MemUnit( ConfigType, ctrl_mem_size, len( ctrl_msgs ), - total_steps, ctrl_msgs ) - - s.alu.recv_in_count[0] //= 1; - s.alu.recv_in_count[1] //= 1; - - connect( s.alu.recv_opt, s.ctrl_mem.send_ctrl ) - - connect( s.src_data0.send, s.alu.recv_in[0] ) - connect( s.src_data1.send, s.alu.recv_in[1] ) - connect( s.alu.send_out[0], s.sink_out.recv ) - - def done( s ): - return s.src_data0.done() and s.src_data1.done() and\ - s.sink_out.done() - - def line_trace( s ): - return s.alu.line_trace() + " || " +s.ctrl_mem.line_trace() - -def run_sim( test_harness, max_cycles=100 ): - 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() - -def test_PseudoCtrl(): - MemUnit = CtrlMemCL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - ctrl_mem_size = 4 - data_mem_size = 8 - num_inports = 2 - adder_latency = 4 - cl_reset_latency = 3 - # The reset latency for CL simulation seems to be 3 cycles. - total_steps = ctrl_mem_size * adder_latency + cl_reset_latency - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - src_data0 = [ DataType(1,1), DataType(5,1), DataType(7,1), DataType(6,1) ] - src_data1 = [ DataType(6,1), DataType(1,1), DataType(2,1), DataType(3,1) ] - src_wdata = [ CtrlType( OPT_ADD, b1( 0 ), pickRegister ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister ) ] - sink_out = [ DataType(7,1),DataType(4,1),DataType(5,1),DataType(9,1)] - th = TestHarness( MemUnit, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, src_data0, src_data1, - src_wdata, sink_out, adder_latency, total_steps ) - run_sim( th ) - -def test_PseudoCtrl_variantLatency(): - MemUnit = CtrlMemCL - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl() - ctrl_mem_size = 4 - data_mem_size = 8 - num_inports = 2 - adder_latency = 4 - cl_reset_latency = 3 - # The reset latency for CL simulation seems to be 3 cycles. - total_steps = ctrl_mem_size * adder_latency + cl_reset_latency - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - src_data0 = [ DataType(1,1), DataType(5,1), DataType(7,1), DataType(6,1) ] - src_data1 = [ DataType(6,1), DataType(1,1), DataType(2,1), DataType(3,1) ] - src_wdata = [ CtrlType( OPT_ADD, b1( 0 ), pickRegister ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister ) ] - sink_out = [ DataType(7,1),DataType(4,1),DataType(5,1),DataType(9,1)] - th = TestHarness( MemUnit, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, src_data0, src_data1, - src_wdata, sink_out, adder_latency, total_steps ) - run_sim( th ) - diff --git a/mem/ctrl/test/CtrlMemCL_test.py b/mem/ctrl/test/CtrlMemCL_test.py new file mode 100644 index 0000000..b4ba679 --- /dev/null +++ b/mem/ctrl/test/CtrlMemCL_test.py @@ -0,0 +1,130 @@ +""" +========================================================================== +CtrlMemCL_test.py +========================================================================== +Test cases for control memory (cycle-level simulation). + +Author : Cheng Tan + Date : Dec 21, 2019 +""" + +from pymtl3 import * +from ..CtrlMemCL import CtrlMemCL +from ....fu.single.AdderCL import AdderCL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ....lib.opt_type import * +from ....lib.messages import * + +#------------------------------------------------------------------------- +# Test harness +#------------------------------------------------------------------------- + +class TestHarness(Component): + + def construct(s, MemUnit, DataType, PredicateType, ConfigType, + ctrl_mem_size, data_mem_size, src0_msgs, src1_msgs, + ctrl_msgs, sink_msgs, adder_latency, total_steps): + + AddrType = mk_bits(clog2(ctrl_mem_size)) + + s.src_data0 = TestSrcRTL(DataType, src0_msgs) + s.src_data1 = TestSrcRTL(DataType, src1_msgs) + s.sink_out = TestSinkRTL(DataType, sink_msgs) + + s.alu = AdderCL(DataType, PredicateType, ConfigType, 2, 2, + data_mem_size, adder_latency) + s.ctrl_mem = MemUnit(ConfigType, ctrl_mem_size, len(ctrl_msgs), + total_steps, ctrl_msgs) + + s.alu.recv_opt //= s.ctrl_mem.send_ctrl + s.src_data0.send //= s.alu.recv_in[0] + s.src_data1.send //= s.alu.recv_in[1] + s.alu.send_out[0] //= s.sink_out.recv + + def done(s): + return s.src_data0.done() and s.src_data1.done() and \ + s.sink_out.done() + + def line_trace(s): + return s.alu.line_trace() + " || " +s.ctrl_mem.line_trace() + +def run_sim(test_harness, max_cycles = 20): + 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() + +def test_PseudoCtrl(): + MemUnit = CtrlMemCL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + ctrl_mem_size = 4 + data_mem_size = 8 + num_inports = 2 + adder_latency = 4 + cl_reset_latency = 3 + # The reset latency for CL simulation seems to be 3 cycles. + total_steps = ctrl_mem_size * adder_latency + cl_reset_latency + FuInType = mk_bits(clog2(num_inports + 1)) + AddrType = mk_bits(clog2(ctrl_mem_size)) + + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_data0 = [DataType(1, 1), DataType(5, 1), DataType(7, 1), DataType(6, 1)] + src_data1 = [DataType(6, 1), DataType(1, 1), DataType(2, 1), DataType(3, 1)] + src_wdata = [CtrlType(OPT_ADD, b1(0), pickRegister), + CtrlType(OPT_SUB, b1(0), pickRegister), + CtrlType(OPT_SUB, b1(0), pickRegister), + CtrlType(OPT_ADD, b1(0), pickRegister) ] + sink_out = [DataType(7, 1), DataType(4, 1), DataType(5, 1),DataType(9, 1)] + + th = TestHarness(MemUnit, DataType, PredicateType, CtrlType, + ctrl_mem_size, data_mem_size, src_data0, src_data1, + src_wdata, sink_out, adder_latency, total_steps) + run_sim(th) + +def test_PseudoCtrl_variantLatency(): + MemUnit = CtrlMemCL + DataType = mk_data(16, 1) + PredicateType = mk_predicate(1, 1) + CtrlType = mk_ctrl() + ctrl_mem_size = 4 + data_mem_size = 8 + num_inports = 2 + adder_latency = 4 + cl_reset_latency = 3 + # The reset latency for CL simulation seems to be 3 cycles. + total_steps = ctrl_mem_size * adder_latency + cl_reset_latency + FuInType = mk_bits(clog2(num_inports + 1)) + AddrType = mk_bits(clog2(ctrl_mem_size)) + + pickRegister = [FuInType(x + 1) for x in range(num_inports)] + src_data0 = [DataType(1, 1), DataType(5, 1), DataType(7, 1), DataType(6, 1)] + src_data1 = [DataType(6, 1), DataType(1, 1), DataType(2, 1), DataType(3, 1)] + src_wdata = [CtrlType(OPT_ADD, b1(0), pickRegister), + CtrlType(OPT_SUB, b1(0), pickRegister), + CtrlType(OPT_SUB, b1(0), pickRegister), + CtrlType(OPT_ADD, b1(0), pickRegister)] + sink_out = [DataType(7, 1),DataType(4, 1),DataType(5, 1),DataType(9, 1)] + + th = TestHarness(MemUnit, DataType, PredicateType, CtrlType, + ctrl_mem_size, data_mem_size, src_data0, src_data1, + src_wdata, sink_out, adder_latency, total_steps) + run_sim(th) + diff --git a/mem/ctrl/test/CtrlMemDynamicRTL_test.py b/mem/ctrl/test/CtrlMemDynamicRTL_test.py index 5fab794..b592869 100644 --- a/mem/ctrl/test/CtrlMemDynamicRTL_test.py +++ b/mem/ctrl/test/CtrlMemDynamicRTL_test.py @@ -14,6 +14,7 @@ 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 ValRdyTestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ....lib.messages import * from ....lib.cmd_type import * from ....lib.opt_type import * @@ -22,45 +23,38 @@ # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, MemUnit, DataType, PredicateType, CtrlPktType, - CtrlSignalType, ctrl_mem_size, data_mem_size, - num_fu_inports, num_fu_outports, num_tile_inports, - num_tile_outports, src0_msgs, src1_msgs, ctrl_pkts, - sink_msgs): + def construct(s, MemUnit, DataType, PredicateType, CtrlPktType, + CtrlSignalType, ctrl_mem_size, data_mem_size, + num_fu_inports, num_fu_outports, num_tile_inports, + num_tile_outports, src0_msgs, src1_msgs, ctrl_pkts, + sink_msgs): AddrType = mk_bits(clog2(ctrl_mem_size)) - s.src_data0 = TestSrcRTL(DataType, src0_msgs) - s.src_data1 = TestSrcRTL(DataType, src1_msgs) + s.src_data0 = ValRdyTestSrcRTL(DataType, src0_msgs) + s.src_data1 = ValRdyTestSrcRTL(DataType, src1_msgs) # s.src_waddr = TestSrcRTL(AddrType, ctrl_waddr ) # s.src_wdata = TestSrcRTL(ConfigType, ctrl_msgs ) s.src_pkt = ValRdyTestSrcRTL(CtrlPktType, ctrl_pkts) - s.sink_out = TestSinkRTL(DataType, sink_msgs) + s.sink_out = ValRdyTestSinkRTL(DataType, sink_msgs) s.alu = AdderRTL(DataType, PredicateType, CtrlSignalType, 2, 2, - data_mem_size ) + data_mem_size) s.ctrl_mem = MemUnit(CtrlPktType, CtrlSignalType, ctrl_mem_size, num_fu_inports, num_fu_outports, num_tile_inports, num_tile_outports, len(ctrl_pkts), len(ctrl_pkts)) - s.alu.recv_in_count[0] //= 1 - s.alu.recv_in_count[1] //= 1 - - connect(s.alu.recv_opt, s.ctrl_mem.send_ctrl) - - # connect(s.src_waddr.send, s.ctrl_mem.recv_waddr) - # connect(s.src_wdata.send, s.ctrl_mem.recv_ctrl) - connect(s.src_pkt.send, s.ctrl_mem.recv_pkt) - - connect(s.src_data0.send, s.alu.recv_in[0]) - connect(s.src_data1.send, s.alu.recv_in[1]) - connect(s.alu.send_out[0], s.sink_out.recv) + s.alu.recv_opt //= s.ctrl_mem.send_ctrl + s.src_pkt.send //= s.ctrl_mem.recv_pkt + s.src_data0.send //= s.alu.recv_in[0] + s.src_data1.send //= s.alu.recv_in[1] + s.alu.send_out[0] //= s.sink_out.recv def done(s): return s.src_data0.done() and s.src_data1.done() and \ - s.src_pkt.done() and s.sink_out.done() + s.src_pkt.done() and s.sink_out.done() def line_trace(s): return s.alu.line_trace() + " || " +s.ctrl_mem.line_trace() diff --git a/mem/ctrl/test/CtrlRTL_AdderCL_test.py b/mem/ctrl/test/CtrlMemRTL_AdderCL_test.py similarity index 95% rename from mem/ctrl/test/CtrlRTL_AdderCL_test.py rename to mem/ctrl/test/CtrlMemRTL_AdderCL_test.py index 2ac1bbc..956f493 100644 --- a/mem/ctrl/test/CtrlRTL_AdderCL_test.py +++ b/mem/ctrl/test/CtrlMemRTL_AdderCL_test.py @@ -8,17 +8,15 @@ Date : Dec 21, 2019 """ - from pymtl3 import * from ..CtrlMemRTL import CtrlMemRTL from ..CtrlMemCL import CtrlMemCL from ....fu.single.AdderCL import AdderCL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- @@ -43,9 +41,6 @@ def construct( s, MemUnit, DataType, PredicateType, ConfigType, s.ctrl_mem = MemUnit( ConfigType, ctrl_mem_size, len( ctrl_msgs ), total_steps ) - s.alu.recv_in_count[0] //= 1 - s.alu.recv_in_count[1] //= 1 - connect( s.alu.recv_opt, s.ctrl_mem.send_ctrl ) connect( s.src_waddr.send, s.ctrl_mem.recv_waddr ) diff --git a/mem/ctrl/test/CtrlRTL_test.py b/mem/ctrl/test/CtrlMemRTL_test.py similarity index 95% rename from mem/ctrl/test/CtrlRTL_test.py rename to mem/ctrl/test/CtrlMemRTL_test.py index 049b62b..91ae385 100644 --- a/mem/ctrl/test/CtrlRTL_test.py +++ b/mem/ctrl/test/CtrlMemRTL_test.py @@ -8,17 +8,15 @@ Date : Dec 21, 2019 """ - from pymtl3 import * from ..CtrlMemCL import CtrlMemCL from ..CtrlMemRTL import CtrlMemRTL from ....fu.single.AdderRTL import AdderRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- @@ -42,9 +40,6 @@ def construct( s, MemUnit, DataType, PredicateType, ConfigType, s.ctrl_mem = MemUnit( ConfigType, ctrl_mem_size, len( ctrl_msgs ), len( ctrl_msgs ) ) - s.alu.recv_in_count[0] //= 1 - s.alu.recv_in_count[1] //= 1 - connect( s.alu.recv_opt, s.ctrl_mem.send_ctrl ) connect( s.src_waddr.send, s.ctrl_mem.recv_waddr ) diff --git a/mem/ctrl/test/RingCtrlMemDynamicRTL_test.py b/mem/ctrl/test/RingCtrlMemDynamicRTL_test.py index c6655b0..6cbba1d 100644 --- a/mem/ctrl/test/RingCtrlMemDynamicRTL_test.py +++ b/mem/ctrl/test/RingCtrlMemDynamicRTL_test.py @@ -11,9 +11,8 @@ from pymtl3 import * from ..RingMultiCtrlMemDynamicRTL import RingMultiCtrlMemDynamicRTL from ....fu.single.AdderRTL import AdderRTL -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 ValRdyTestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.cmd_type import * from ....lib.opt_type import * @@ -32,7 +31,7 @@ def construct( s, DUT, DataType, PredicateType, CtrlPktType, s.width = width s.height = height - s.src_pkt = ValRdyTestSrcRTL(CtrlPktType, ctrl_pkts) + s.src_pkt = TestSrcRTL(CtrlPktType, ctrl_pkts) s.sink_out = [TestSinkRTL(CtrlSignalType, sink_msgs[i]) for i in range(width * height)] diff --git a/mem/data/DataMemCL.py b/mem/data/DataMemCL.py index b06e4d2..940cd23 100644 --- a/mem/data/DataMemCL.py +++ b/mem/data/DataMemCL.py @@ -8,63 +8,57 @@ Date : Dec 27, 2019 """ - from copy import deepcopy 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class DataMemCL(Component): -class DataMemCL( Component ): - - def construct( s, DataType, data_mem_size, - rd_ports=1, wr_ports=1, preload_data=[] ): + def construct(s, DataType, data_mem_size, rd_ports = 1, wr_ports = 1, + preload_data=[]): # Constant - - AddrType = mk_bits( clog2( data_mem_size ) ) + AddrType = mk_bits(clog2(data_mem_size)) # Interface - - s.recv_raddr = [ RecvIfcRTL( AddrType ) for _ in range( rd_ports ) ] - s.send_rdata = [ SendIfcRTL( DataType ) for _ in range( rd_ports ) ] - s.recv_waddr = [ RecvIfcRTL( AddrType ) for _ in range( wr_ports ) ] - s.recv_wdata = [ RecvIfcRTL( DataType ) for _ in range( wr_ports ) ] + s.recv_raddr = [RecvIfcRTL(AddrType) for _ in range(rd_ports)] + s.send_rdata = [SendIfcRTL(DataType) for _ in range(rd_ports)] + s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(wr_ports)] + s.recv_wdata = [RecvIfcRTL(DataType) for _ in range(wr_ports)] # Component - - s.sram = [ DataType( 0, 0 ) for _ in range( data_mem_size ) ] - for i in range( len( preload_data ) ): + s.sram = [DataType(0, 0) for _ in range(data_mem_size)] + for i in range(len(preload_data)): s.sram[i] = preload_data[i] @update def load(): - for i in range( rd_ports ): - s.send_rdata[i].msg @= s.sram[ s.recv_raddr[i].msg ] + for i in range(rd_ports): + s.send_rdata[i].msg @= s.sram[s.recv_raddr[i].msg] - # TODO @update_once def store(): - for i in range( wr_ports ): - if s.recv_wdata[i].en and s.recv_waddr[i].en: - s.sram[ s.recv_waddr[i].msg ] = deepcopy(s.recv_wdata[i].msg) + for i in range(wr_ports): + if s.recv_wdata[i].val and s.recv_waddr[i].val: + s.sram[s.recv_waddr[i].msg] = deepcopy(s.recv_wdata[i].msg) @update def update_signal(): - for i in range( rd_ports ): + for i in range(rd_ports): s.recv_raddr[i].rdy @= s.send_rdata[i].rdy # b1( 1 ) # s.send_rdata[i].rdy - s.send_rdata[i].en @= s.recv_raddr[i].en + s.send_rdata[i].val @= s.recv_raddr[i].val # s.send_rdata[i].rdy # s.recv_raddr[i].en - for i in range( wr_ports ): - s.recv_waddr[i].rdy @= Bits1( 1 ) - s.recv_wdata[i].rdy @= Bits1( 1 ) - - def line_trace( s ): - recv_str = "|".join([ str(data.msg) for data in s.recv_wdata ]) - out_str = "|".join([ str(data) for data in s.sram ]) - send_str = "|".join([ str(data.msg) for data in s.send_rdata ]) + for i in range(wr_ports): + s.recv_waddr[i].rdy @= Bits1(1) + s.recv_wdata[i].rdy @= Bits1(1) + + def line_trace(s): + recv_str = "|".join([str(data.msg) for data in s.recv_wdata]) + out_str = "|".join([str(data) for data in s.sram]) + send_str = "|".join([str(data.msg) for data in s.send_rdata]) # return f'{recv_str} : [{out_str}] : {send_str}' sram_trace = f'{"|".join([str(x) for x in s.sram])}' return f'{s.recv_waddr[0]}<{s.recv_wdata[0]}({sram_trace}){s.recv_raddr[0]}>{s.send_rdata[0]}' diff --git a/mem/data/DataMemRTL.py b/mem/data/DataMemRTL.py index ac7bda0..5a09ef5 100644 --- a/mem/data/DataMemRTL.py +++ b/mem/data/DataMemRTL.py @@ -8,53 +8,52 @@ Date : Dec 20, 2019 """ - 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * +class DataMemRTL(Component): -class DataMemRTL( Component ): - - def construct( s, DataType, data_mem_size, rd_ports = 1, wr_ports = 1, - preload_data = None ): + def construct(s, DataType, data_mem_size, rd_ports = 1, wr_ports = 1, + preload_data = None): # Constant - AddrType = mk_bits( clog2( data_mem_size ) ) + AddrType = mk_bits(clog2(data_mem_size)) # Interface - s.recv_raddr = [ RecvIfcRTL( AddrType ) for _ in range( rd_ports ) ] - s.send_rdata = [ SendIfcRTL( DataType ) for _ in range( rd_ports ) ] - s.recv_waddr = [ RecvIfcRTL( AddrType ) for _ in range( wr_ports ) ] - s.recv_wdata = [ RecvIfcRTL( DataType ) for _ in range( wr_ports ) ] + s.recv_raddr = [RecvIfcRTL(AddrType) for _ in range(rd_ports)] + s.send_rdata = [SendIfcRTL(DataType) for _ in range(rd_ports)] + s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(wr_ports)] + s.recv_wdata = [RecvIfcRTL(DataType) for _ in range(wr_ports)] # Component - s.reg_file = RegisterFile( DataType, data_mem_size, rd_ports, wr_ports + rd_ports ) - s.initWrites = [ Wire( b1 ) for _ in range( data_mem_size ) ] + s.reg_file = RegisterFile(DataType, data_mem_size, rd_ports, wr_ports + rd_ports) + s.initWrites = [Wire(b1) for _ in range(data_mem_size)] if preload_data == None: @update def update_read_without_init(): - for i in range( rd_ports ): + for i in range(rd_ports): # s.reg_file.wen[wr_ports + i] @= b1(0) s.reg_file.raddr[i] @= s.recv_raddr[i].msg s.send_rdata[i].msg @= s.reg_file.rdata[i] for i in range( wr_ports ): - s.reg_file.wen[i] @= b1(0) + s.reg_file.wen[i] @= b1(0) s.reg_file.waddr[i] @= s.recv_waddr[i].msg s.reg_file.wdata[i] @= s.recv_wdata[i].msg - if s.recv_waddr[i].en == b1(1): - s.reg_file.wen[i] @= s.recv_wdata[i].en & s.recv_waddr[i].en + if s.recv_waddr[i].val == b1(1): + s.reg_file.wen[i] @= s.recv_wdata[i].val & s.recv_waddr[i].val else: - s.preloadData = [ Wire( DataType ) for _ in range( data_mem_size ) ] - for i in range( len( preload_data ) ): - s.preloadData[ i ] //= preload_data[i] + s.preloadData = [Wire(DataType) for _ in range(data_mem_size)] + for i in range(len(preload_data)): + s.preloadData[i] //= preload_data[i] @update def update_read_with_init(): @@ -65,38 +64,36 @@ def update_read_with_init(): s.send_rdata[i].msg @= s.preloadData[s.recv_raddr[i].msg] s.reg_file.waddr[wr_ports + i] @= s.recv_raddr[i].msg s.reg_file.wdata[wr_ports + i] @= s.preloadData[s.recv_raddr[i].msg] - s.reg_file.wen[wr_ports + i] @= b1(1) + s.reg_file.wen[wr_ports + i] @= b1(1) else: s.reg_file.raddr[i] @= s.recv_raddr[i].msg s.send_rdata[i].msg @= s.reg_file.rdata[i] - for i in range( wr_ports ): - if s.recv_waddr[i].en == b1(1): + for i in range(wr_ports): + if s.recv_waddr[i].val == b1(1): s.reg_file.waddr[i] @= s.recv_waddr[i].msg s.reg_file.wdata[i] @= s.recv_wdata[i].msg - s.reg_file.wen[i] @= s.recv_wdata[i].en & s.recv_waddr[i].en + s.reg_file.wen[i] @= s.recv_wdata[i].val & s.recv_waddr[i].val # Connections @update_ff def update_init(): for i in range( rd_ports ): - if s.recv_raddr[i].en == b1(1): + if s.recv_raddr[i].val == b1(1): s.initWrites[s.recv_raddr[i].msg] <<= s.initWrites[s.recv_raddr[i].msg] | b1(1) for i in range( wr_ports ): - if s.recv_waddr[i].en == b1(1): + if s.recv_waddr[i].val == b1(1): s.initWrites[s.recv_waddr[i].msg] <<= s.initWrites[s.recv_waddr[i].msg] | b1(1) @update def update_signal(): - for i in range( rd_ports ): + for i in range(rd_ports): s.recv_raddr[i].rdy @= s.send_rdata[i].rdy - # b1( 1 ) # s.send_rdata[i].rdy - s.send_rdata[i].en @= s.recv_raddr[i].en - # s.send_rdata[i].rdy # s.recv_raddr[i].en - for i in range( wr_ports ): - s.recv_waddr[i].rdy @= Bits1( 1 ) - s.recv_wdata[i].rdy @= Bits1( 1 ) + s.send_rdata[i].val @= s.recv_raddr[i].val + for i in range(wr_ports): + s.recv_waddr[i].rdy @= Bits1(1) + s.recv_wdata[i].rdy @= Bits1(1) def line_trace(s): recv_raddr_str = "recv_read_addr: " + "|".join([str(data.msg) for data in s.recv_raddr]) @@ -105,8 +102,4 @@ def line_trace(s): content_str = "content: " + "|".join([str(data) for data in s.reg_file.regs]) send_rdata_str = "send_read_data: " + "|".join([str(data.msg) for data in s.send_rdata]) return f'{recv_raddr_str} || {recv_waddr_str} || {recv_wdata_str} || [{content_str}] || {send_rdata_str}' - # return f'DataMem: {recv_str} : [{out_str}] : {send_str} initWrites: {s.initWrites}' - # return s.reg_file.line_trace() - # return f'<{s.reg_file.wen[0]}>{s.reg_file.waddr[0]}:{s.reg_file.wdata[0]}|{s.reg_file.raddr[0]}:{s.reg_file.rdata[0]}' - # rf_trace = f'<{s.reg_file.wen[0]}>{s.reg_file.waddr[0]}:{s.reg_file.wdata[0]}|{s.reg_file.raddr[0]}:{s.reg_file.rdata[0]}' - # return f'[{s.recv_wdata[0].en & s.recv_waddr[0].en}]{s.recv_waddr[0]}<{s.recv_wdata[0]}({rf_trace}){s.recv_raddr[0]}>{s.send_rdata[0]}' + diff --git a/mem/data/DataMemScalableRTL.py b/mem/data/DataMemScalableRTL.py index b23a739..6dc1594 100644 --- a/mem/data/DataMemScalableRTL.py +++ b/mem/data/DataMemScalableRTL.py @@ -9,24 +9,21 @@ Date : Dec 4, 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.opt_type import * - class DataMemScalableRTL(Component): def construct(s, DataType, data_mem_size, rd_ports = 1, wr_ports = 1, preload_data = None): # Constant - AddrType = mk_bits(clog2(data_mem_size)) # Interface - s.recv_raddr = [RecvIfcRTL(AddrType) for _ in range(rd_ports)] s.send_rdata = [SendIfcRTL(DataType) for _ in range(rd_ports)] s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(wr_ports)] @@ -42,7 +39,7 @@ def construct(s, DataType, data_mem_size, rd_ports = 1, wr_ports = 1, # FIXME: Following signals need to be set via some logic, i.e., # handling miss accesses. - s.send_to_noc.en //= 0 + s.send_to_noc.val //= 0 s.send_to_noc.msg //= DataType(0, 0) s.recv_from_noc.rdy //= 0 @@ -58,18 +55,18 @@ def update_read_without_init(): s.reg_file.wen[i] @= b1(0) s.reg_file.waddr[i] @= s.recv_waddr[i].msg s.reg_file.wdata[i] @= s.recv_wdata[i].msg - if s.recv_waddr[i].en == b1(1): - s.reg_file.wen[i] @= s.recv_wdata[i].en & s.recv_waddr[i].en + if s.recv_waddr[i].val == b1(1): + s.reg_file.wen[i] @= s.recv_wdata[i].val & s.recv_waddr[i].val else: - s.preloadData = [ Wire( DataType ) for _ in range( data_mem_size ) ] - for i in range( len( preload_data ) ): - s.preloadData[ i ] //= preload_data[i] + s.preloadData = [Wire(DataType) for _ in range(data_mem_size)] + for i in range(len( preload_data)): + s.preloadData[i] //= preload_data[i] @update def update_read_with_init(): - for i in range( rd_ports ): + for i in range(rd_ports): s.reg_file.wen[wr_ports + i] @= b1(0) if s.initWrites[s.recv_raddr[i].msg] == b1(0): s.send_rdata[i].msg @= s.preloadData[s.recv_raddr[i].msg] @@ -81,29 +78,27 @@ def update_read_with_init(): s.send_rdata[i].msg @= s.reg_file.rdata[i] for i in range( wr_ports ): - if s.recv_waddr[i].en == b1(1): + if s.recv_waddr[i].val == b1(1): s.reg_file.waddr[i] @= s.recv_waddr[i].msg s.reg_file.wdata[i] @= s.recv_wdata[i].msg - s.reg_file.wen[i] @= s.recv_wdata[i].en & s.recv_waddr[i].en + s.reg_file.wen[i] @= s.recv_wdata[i].val & s.recv_waddr[i].val # Connections @update_ff def update_init(): for i in range( rd_ports ): - if s.recv_raddr[i].en == b1(1): + if s.recv_raddr[i].val == b1(1): s.initWrites[s.recv_raddr[i].msg] <<= s.initWrites[s.recv_raddr[i].msg] | b1(1) for i in range( wr_ports ): - if s.recv_waddr[i].en == b1(1): + if s.recv_waddr[i].val == b1(1): s.initWrites[s.recv_waddr[i].msg] <<= s.initWrites[s.recv_waddr[i].msg] | b1(1) @update def update_signal(): for i in range( rd_ports ): s.recv_raddr[i].rdy @= s.send_rdata[i].rdy - # b1( 1 ) # s.send_rdata[i].rdy - s.send_rdata[i].en @= s.recv_raddr[i].en - # s.send_rdata[i].rdy # s.recv_raddr[i].en + s.send_rdata[i].val @= s.recv_raddr[i].val for i in range( wr_ports ): s.recv_waddr[i].rdy @= Bits1( 1 ) s.recv_wdata[i].rdy @= Bits1( 1 ) @@ -115,8 +110,4 @@ def line_trace(s): content_str = "content: " + "|".join([str(data) for data in s.reg_file.regs]) send_rdata_str = "send_read_data: " + "|".join([str(data.msg) for data in s.send_rdata]) return f'{recv_raddr_str} || {recv_waddr_str} || {recv_wdata_str} || [{content_str}] || {send_rdata_str}' - # return f'DataMem: {recv_str} : [{out_str}] : {send_str} initWrites: {s.initWrites}' - # return s.reg_file.line_trace() - # return f'<{s.reg_file.wen[0]}>{s.reg_file.waddr[0]}:{s.reg_file.wdata[0]}|{s.reg_file.raddr[0]}:{s.reg_file.rdata[0]}' - # rf_trace = f'<{s.reg_file.wen[0]}>{s.reg_file.waddr[0]}:{s.reg_file.wdata[0]}|{s.reg_file.raddr[0]}:{s.reg_file.rdata[0]}' - # return f'[{s.recv_wdata[0].en & s.recv_waddr[0].en}]{s.recv_waddr[0]}<{s.recv_wdata[0]}({rf_trace}){s.recv_raddr[0]}>{s.send_rdata[0]}' + diff --git a/mem/data/DataMemWithCrossbarRTL.py b/mem/data/DataMemWithCrossbarRTL.py index 5288a3f..88cd407 100644 --- a/mem/data/DataMemWithCrossbarRTL.py +++ b/mem/data/DataMemWithCrossbarRTL.py @@ -26,26 +26,23 @@ Date : Dec 5, 2024 """ - from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import BypassQueue from pymtl3.stdlib.primitive import RegisterFile from ...noc.PyOCN.pymtl3_net.xbar.XbarBypassQueueRTL import XbarBypassQueueRTL -from ...lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ...lib.basic.val_rdy.queues import BypassQueueRTL from ...lib.cmd_type import * from ...lib.opt_type import * from ...lib.messages import * - class DataMemWithCrossbarRTL(Component): - def construct(s, NocPktType, DataType, - data_mem_size_global, data_mem_size_per_bank, - num_banks = 4, num_rd_tiles = 4, num_wr_tiles = 4, - preload_data_per_bank = None): + def construct(s, NocPktType, DataType, data_mem_size_global, + data_mem_size_per_bank, num_banks = 4, num_rd_tiles = 4, + num_wr_tiles = 4, preload_data_per_bank = None): # Constant - global_addr_nbits = clog2(data_mem_size_global) per_bank_addr_nbits = clog2(data_mem_size_per_bank) assert(2 ** global_addr_nbits == data_mem_size_global) @@ -113,7 +110,7 @@ def construct(s, NocPktType, DataType, s.rd_pkt = [Wire(TileSramXbarRdPktType) for _ in range(num_xbar_in_rd_ports)] s.wr_pkt = [Wire(TileSramXbarWrPktType) for _ in range(num_xbar_in_wr_ports)] - s.recv_wdata_bypass_q = [BypassQueue(DataType) for _ in range(num_xbar_in_wr_ports)] + s.recv_wdata_bypass_q = [BypassQueueRTL(DataType, 1) for _ in range(num_xbar_in_wr_ports)] s.send_to_noc_load_pending = Wire(b1) @@ -160,15 +157,15 @@ def update_all(): for i in range(num_xbar_in_rd_ports): s.recv_raddr[i].rdy @= 0 s.recv_waddr[i].rdy @= 0 - s.recv_wdata_bypass_q[i].deq_en @= 0 + s.recv_wdata_bypass_q[i].send.rdy @= 0 for i in range(num_rd_tiles): - s.send_rdata[i].en @= 0 - s.send_to_noc_load_response_pkt.en @= 0 + s.send_rdata[i].val @= 0 + s.send_to_noc_load_response_pkt.val @= 0 for i in range(num_xbar_in_wr_ports): s.recv_wdata[i].rdy @= 0 - s.recv_wdata_bypass_q[i].enq_en @= 0 + s.recv_wdata_bypass_q[i].recv.val @= 0 if s.init_mem_done == b1(0): for b in range(num_banks): @@ -178,17 +175,17 @@ def update_all(): else: for i in range(num_xbar_in_wr_ports): - s.recv_wdata[i].rdy @= s.recv_wdata_bypass_q[i].enq_rdy - s.recv_wdata_bypass_q[i].enq_en @= s.recv_wdata[i].en - s.recv_wdata_bypass_q[i].enq_msg @= s.recv_wdata[i].msg + s.recv_wdata[i].rdy @= s.recv_wdata_bypass_q[i].recv.rdy + s.recv_wdata_bypass_q[i].recv.val @= s.recv_wdata[i].val + s.recv_wdata_bypass_q[i].recv.msg @= s.recv_wdata[i].msg for i in range(num_xbar_in_rd_ports): - s.read_crossbar.recv[i].val @= s.recv_raddr[i].en + s.read_crossbar.recv[i].val @= s.recv_raddr[i].val s.read_crossbar.recv[i].msg @= s.rd_pkt[i] s.recv_raddr[i].rdy @= s.read_crossbar.recv[i].rdy for i in range(num_xbar_in_wr_ports): - s.write_crossbar.recv[i].val @= s.recv_waddr[i].en + s.write_crossbar.recv[i].val @= s.recv_waddr[i].val s.write_crossbar.recv[i].msg @= s.wr_pkt[i] s.recv_waddr[i].rdy @= s.write_crossbar.recv[i].rdy @@ -202,7 +199,7 @@ def update_all(): (s.read_crossbar.packet_on_input_units[i].dst < num_banks): if i <= s.num_rd_tiles: s.send_rdata[RdTileIdType(i)].msg @= s.reg_file[trunc(s.read_crossbar.packet_on_input_units[i].dst, LocalBankIndexType)].rdata[0] - s.send_rdata[RdTileIdType(i)].en @= s.read_crossbar.send[s.read_crossbar.packet_on_input_units[i].dst].val + s.send_rdata[RdTileIdType(i)].val @= s.read_crossbar.send[s.read_crossbar.packet_on_input_units[i].dst].val # TODO: Check the translated Verilog to make sure the loop is flattened correctly with special out (NocPktType) towards NoC. else: s.send_to_noc_load_response_pkt.msg @= \ @@ -212,7 +209,7 @@ def update_all(): s.reg_file[trunc(s.read_crossbar.packet_on_input_units[i].dst, LocalBankIndexType)].rdata[0].payload, s.reg_file[trunc(s.read_crossbar.packet_on_input_units[i].dst, LocalBankIndexType)].rdata[0].predicate ) - s.send_to_noc_load_response_pkt.en @= \ + s.send_to_noc_load_response_pkt.val @= \ s.read_crossbar.send[s.read_crossbar.packet_on_input_units[i].dst].val # Handles the case the load requests going through the NoC towards remote SRAMs. @@ -224,9 +221,9 @@ def update_all(): # assert(i < num_banks) s.send_rdata[RdTileIdType(i)].msg @= s.recv_from_noc_rdata.msg # TODO: https://github.com/tancheng/VectorCGRA/issues/26 -- Modify this part for non-blocking access. - s.send_rdata[RdTileIdType(i)].en @= \ + s.send_rdata[RdTileIdType(i)].val @= \ s.read_crossbar.send[s.read_crossbar.packet_on_input_units[i].dst].val & \ - s.recv_from_noc_rdata.en + s.recv_from_noc_rdata.val # FIXME: The msg would come back one by one in order, so no # need to check the src_tile, which can be improved. # s.recv_from_noc_rdata.en & \ @@ -244,9 +241,10 @@ def update_all(): 0, # data 1) # predicate # 'send_to_noc_load_pending' avoids sending pending request multiple times. - s.send_to_noc_load_request_pkt.en @= s.read_crossbar.send[num_banks].val & \ - s.send_to_noc_load_request_pkt.rdy & \ - ~s.send_to_noc_load_pending + s.send_to_noc_load_request_pkt.val @= s.read_crossbar.send[num_banks].val & \ + s.recv_from_noc_rdata.val + # ~s.send_to_noc_load_pending + # s.send_to_noc_load_request_pkt.rdy & \ # Outstanding remote read access would block the inport (for read request) of the NoC. # TODO: https://github.com/tancheng/VectorCGRA/issues/26 -- Modify this part for non-blocking access. # 'val` indicates the data is arbitrated successfully. @@ -254,18 +252,20 @@ def update_all(): # Only allows releasing the pending request until the required load data is back, # i.e., though the request already sent out to NoC (the port is still blocked until # response is back). - s.read_crossbar.send[num_banks].rdy @= s.recv_from_noc_rdata.en + s.read_crossbar.send[num_banks].rdy @= s.recv_from_noc_rdata.val # Connects the write ports towards SRAM and NoC from the xbar. for b in range(num_banks): s.reg_file[b].wen[0] @= b1(0) s.reg_file[b].waddr[0] @= trunc(s.write_crossbar.send[b].msg.addr % data_mem_size_per_bank, PerBankAddrType) - s.reg_file[b].wdata[0] @= s.recv_wdata_bypass_q[s.write_crossbar.send[b].msg.src].deq_msg + s.reg_file[b].wdata[0] @= s.recv_wdata_bypass_q[s.write_crossbar.send[b].msg.src].send.msg s.write_crossbar.send[b].rdy @= 1 s.reg_file[b].wen[0] @= s.write_crossbar.send[b].val for i in range(num_xbar_in_wr_ports): - s.recv_wdata_bypass_q[i].deq_en @= s.recv_wdata_bypass_q[i].deq_rdy & \ + # s.recv_wdata_bypass_q[i].deq_en @= s.recv_wdata_bypass_q[i].deq_rdy & \ + # s.write_crossbar.send[s.write_crossbar.packet_on_input_units[i].dst].val + s.recv_wdata_bypass_q[i].send.rdy @= \ s.write_crossbar.send[s.write_crossbar.packet_on_input_units[i].dst].val # Handles the one connecting to the NoC. @@ -276,9 +276,9 @@ def update_all(): 0, # vc_id CMD_STORE_REQUEST, s.write_crossbar.send[num_banks].msg.addr, - s.recv_wdata_bypass_q[s.write_crossbar.send[num_banks].msg.src].deq_msg.payload, - s.recv_wdata_bypass_q[s.write_crossbar.send[num_banks].msg.src].deq_msg.predicate) - s.send_to_noc_store_pkt.en @= s.write_crossbar.send[num_banks].val & s.send_to_noc_store_pkt.rdy + s.recv_wdata_bypass_q[s.write_crossbar.send[num_banks].msg.src].send.msg.payload, + s.recv_wdata_bypass_q[s.write_crossbar.send[num_banks].msg.src].send.msg.predicate) + s.send_to_noc_store_pkt.val @= s.write_crossbar.send[num_banks].val # & s.send_to_noc_store_pkt.rdy s.write_crossbar.send[num_banks].rdy @= s.send_to_noc_store_pkt.rdy if preload_data_per_bank != None: @@ -301,7 +301,7 @@ def update_init_index_once(): # Indicates whether the remote (towards others via NoC) load is pending on response. @update_ff def update_remote_load_pending(): - s.send_to_noc_load_pending <<= s.recv_from_noc_rdata.en + s.send_to_noc_load_pending <<= s.recv_from_noc_rdata.val def line_trace(s): recv_raddr_str = "recv_from_tile_read_addr: {" @@ -324,7 +324,8 @@ def line_trace(s): recv_waddr_str += " bank[" + str(b) + "]: " + "|".join([str(data.msg) for data in s.recv_waddr]) + ";" recv_wdata_str += " bank[" + str(b) + "]: " + "|".join([str(data.msg) for data in s.recv_wdata]) + ";" content_str += " bank[" + str(b) + "]: " + "|".join([str(data) for data in s.reg_file[b].regs]) + ";" - send_to_noc_load_request_pkt_str += " bank[" + str(b) + "]: " + "|".join([str(data.msg) for data in s.send_rdata]) + ";" + send_rdata_str += " bank[" + str(b) + "]: " + "|".join([str(data.msg) for data in s.send_rdata]) + ";" + # send_to_noc_load_request_pkt_str += " bank[" + str(b) + "]: " + "|".join([str(data.msg) for data in s.send_rdata]) + ";" # send_to_noc_raddr_str += str(s.send_to_noc_raddr.msg) + ";" send_to_noc_load_request_pkt_str += str(s.send_to_noc_load_request_pkt.msg) + ";" diff --git a/mem/data/test/DataMemCL_test.py b/mem/data/test/DataMemCL_test.py index 1ab9456..304d5c8 100644 --- a/mem/data/test/DataMemCL_test.py +++ b/mem/data/test/DataMemCL_test.py @@ -8,62 +8,58 @@ Date : Nov 26, 2022 """ - from pymtl3 import * from ..DataMemCL import DataMemCL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, DataType, AddrType, data_mem_size, read_addr, - read_data, write_addr, write_data, preloadData ): + def construct(s, DataType, AddrType, data_mem_size, read_addr, + read_data, write_addr, write_data, preloadData): - s.read_addr = TestSrcRTL ( AddrType, read_addr ) - s.read_data = TestSinkRTL( DataType, read_data ) + s.read_addr = TestSrcRTL(AddrType, read_addr) + s.read_data = TestSinkRTL(DataType, read_data) - s.write_addr = TestSrcRTL( AddrType, write_addr ) - s.write_data = TestSrcRTL( DataType, write_data ) + s.write_addr = TestSrcRTL(AddrType, write_addr) + s.write_data = TestSrcRTL(DataType, write_data) - s.dataMem = DataMemCL( DataType, data_mem_size, - preload_data = preloadData ) + s.dataMem = DataMemCL(DataType, data_mem_size, + preload_data = preloadData) s.dataMem.recv_raddr[0] //= s.read_addr.send s.dataMem.send_rdata[0] //= s.read_data.recv s.dataMem.recv_waddr[0] //= s.write_addr.send s.dataMem.recv_wdata[0] //= s.write_data.send - def done( s ): + def done(s): return s.read_addr.done() and s.read_data.done() - def line_trace( s ): + def line_trace(s): return s.dataMem.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation - ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout - assert ncycles < max_cycles test_harness.sim_tick() @@ -71,16 +67,17 @@ def run_sim( test_harness, max_cycles=10 ): test_harness.sim_tick() def test_const_queue(): - DataType = mk_data( 16, 1 ) + DataType = mk_data(16, 1) data_mem_size = 100 - AddrType = mk_bits( clog2( data_mem_size) ) - preloadData = [ DataType(i, 1) for i in range(100) ] + AddrType = mk_bits(clog2(data_mem_size)) + preloadData = [DataType(i, 1) for i in range(100)] + + read_addr = [AddrType(2), AddrType(3), AddrType(0), AddrType(12)] + read_data = [DataType(2, 1), DataType(3, 1), DataType(0, 1), DataType(33, 1)] + write_addr = [AddrType(12), AddrType(23)] + write_data = [DataType(33, 1), DataType(44, 1)] - read_addr = [ AddrType(2), AddrType(3), AddrType(0), AddrType(12) ] - read_data = [ DataType(2, 1), DataType(3, 1), DataType(0, 1), DataType(33, 1) ] - write_addr = [ AddrType(12), AddrType(23) ] - write_data = [ DataType(33, 1), DataType(44, 1) ] + th = TestHarness(DataType, AddrType, data_mem_size, read_addr, + read_data, write_addr, write_data, preloadData) + run_sim(th) - th = TestHarness( DataType, AddrType, data_mem_size, read_addr, - read_data, write_addr, write_data, preloadData ) - run_sim( th ) diff --git a/mem/data/test/DataMemRTL_test.py b/mem/data/test/DataMemRTL_test.py index 8e8ba63..dbef8da 100644 --- a/mem/data/test/DataMemRTL_test.py +++ b/mem/data/test/DataMemRTL_test.py @@ -8,62 +8,58 @@ Date : Nov 26, 2022 """ - from pymtl3 import * from ..DataMemRTL import DataMemRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- class TestHarness( Component ): - def construct( s, DataType, AddrType, data_mem_size, read_addr, - read_data, write_addr, write_data, preloadData ): + def construct(s, DataType, AddrType, data_mem_size, read_addr, + read_data, write_addr, write_data, preloadData): - s.read_addr = TestSrcRTL ( AddrType, read_addr ) - s.read_data = TestSinkRTL( DataType, read_data ) + s.read_addr = TestSrcRTL(AddrType, read_addr) + s.read_data = TestSinkRTL(DataType, read_data) - s.write_addr = TestSrcRTL( AddrType, write_addr ) - s.write_data = TestSrcRTL( DataType, write_data ) + s.write_addr = TestSrcRTL(AddrType, write_addr) + s.write_data = TestSrcRTL(DataType, write_data) - s.dataMem = DataMemRTL( DataType, data_mem_size, - preload_data = preloadData ) + s.dataMem = DataMemRTL(DataType, data_mem_size, + preload_data = preloadData) s.dataMem.recv_raddr[0] //= s.read_addr.send s.dataMem.send_rdata[0] //= s.read_data.recv s.dataMem.recv_waddr[0] //= s.write_addr.send s.dataMem.recv_wdata[0] //= s.write_data.send - def done( s ): + def done(s): return s.read_addr.done() and s.read_data.done() - def line_trace( s ): + def line_trace(s): return s.dataMem.line_trace() -def run_sim( test_harness, max_cycles=10 ): +def run_sim(test_harness, max_cycles = 10): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation - ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format(ncycles, test_harness.line_trace())) # Check timeout - assert ncycles < max_cycles test_harness.sim_tick() @@ -71,17 +67,17 @@ def run_sim( test_harness, max_cycles=10 ): test_harness.sim_tick() def test_const_queue(): - DataType = mk_data( 16, 1 ) + DataType = mk_data(16, 1) data_mem_size = 20 - AddrType = mk_bits( clog2( data_mem_size) ) - preloadData = [ DataType(i, 1) for i in range( data_mem_size ) ] - - read_addr = [ AddrType(2), AddrType(3), AddrType(0), AddrType(12) ] - read_data = [ DataType(2, 1), DataType(3, 1), DataType(0, 1), DataType(13, 1) ] - # read_data = [ DataType(0, 0), DataType(0, 0), DataType(0, 0), DataType(13, 1) ] - write_addr = [ AddrType(12), AddrType(13) ] - write_data = [ DataType(13, 1), DataType(14, 1) ] - - th = TestHarness( DataType, AddrType, data_mem_size, read_addr, - read_data, write_addr, write_data, preloadData ) - run_sim( th ) + AddrType = mk_bits(clog2(data_mem_size)) + preloadData = [DataType(i, 1) for i in range(data_mem_size)] + + read_addr = [AddrType(2), AddrType(3), AddrType(0), AddrType(12)] + read_data = [DataType(2, 1), DataType(3, 1), DataType(0, 1), DataType(13, 1)] + write_addr = [AddrType(12), AddrType(13)] + write_data = [DataType(13, 1), DataType(14, 1)] + + th = TestHarness(DataType, AddrType, data_mem_size, read_addr, + read_data, write_addr, write_data, preloadData) + run_sim(th) + diff --git a/mem/data/test/DataMemScalableRTL_test.py b/mem/data/test/DataMemScalableRTL_test.py index 27db104..68ae0dd 100644 --- a/mem/data/test/DataMemScalableRTL_test.py +++ b/mem/data/test/DataMemScalableRTL_test.py @@ -8,20 +8,18 @@ Date : Dec 6, 2024 """ - from pymtl3 import * from ..DataMemScalableRTL import DataMemScalableRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): def construct(s, DataType, AddrType, data_mem_size, read_addr, read_data, write_addr, write_data, preloadData): @@ -72,8 +70,8 @@ def run_sim(test_harness, max_cycles=20): def test_const_queue(): DataType = mk_data(16, 1) data_mem_size = 20 - AddrType = mk_bits( clog2( data_mem_size) ) - preloadData = [ DataType(i, 1) for i in range( data_mem_size ) ] + AddrType = mk_bits(clog2(data_mem_size)) + preloadData = [DataType(i, 1) for i in range(data_mem_size)] read_addr = [AddrType(2), AddrType(3), AddrType(0), AddrType(12)] read_data = [DataType(2, 1), DataType(3, 1), DataType(0, 1), DataType(13, 1)] @@ -84,3 +82,4 @@ def test_const_queue(): th = TestHarness(DataType, AddrType, data_mem_size, read_addr, read_data, write_addr, write_data, preloadData) run_sim(th) + diff --git a/mem/data/test/DataMemWithCrossbarRTL_test.py b/mem/data/test/DataMemWithCrossbarRTL_test.py index f5700b7..98f8889 100644 --- a/mem/data/test/DataMemWithCrossbarRTL_test.py +++ b/mem/data/test/DataMemWithCrossbarRTL_test.py @@ -8,33 +8,30 @@ Date : Dec 6, 2024 """ - from pymtl3 import * from pymtl3.passes.backends.verilog import (VerilogTranslationPass, VerilogVerilatorImportPass) from pymtl3.stdlib.test_utils import config_model_with_cmdline_opts from ..DataMemWithCrossbarRTL import DataMemWithCrossbarRTL -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 TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.cmd_type import * from ....lib.messages import * from ....lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): def construct(s, NocPktType, DataType, AddrType, data_mem_size_global, data_mem_size_per_bank, num_banks, rd_tiles, wr_tiles, read_addr, read_data, write_addr, write_data, # noc_send_read_addr, noc_recv_read_data, # noc_send_write_addr, noc_send_write_data, - noc_recv_load_data, - send_to_noc_load_request_pkt, send_to_noc_store_pkt, - preload_data_per_bank): + noc_recv_load_data, send_to_noc_load_request_pkt, + send_to_noc_store_pkt, preload_data_per_bank): s.num_banks = num_banks s.rd_tiles = rd_tiles @@ -49,12 +46,8 @@ def construct(s, NocPktType, DataType, AddrType, data_mem_size_global, s.recv_wdata = [TestSrcRTL(DataType, write_data[i]) for i in range(wr_tiles)] - # s.send_to_noc_raddr = TestSinkRTL(AddrType, noc_send_read_addr) s.recv_from_noc_rdata = TestSrcRTL(DataType, noc_recv_load_data) - # s.send_to_noc_waddr = TestSinkRTL(AddrType, noc_send_write_addr) - # s.send_to_noc_wdata = TestSinkRTL(DataType, noc_send_write_data) - s.send_to_noc_load_request_pkt = TestSinkRTL(NocPktType, send_to_noc_load_request_pkt) s.send_to_noc_store_pkt = TestSinkRTL(NocPktType, send_to_noc_store_pkt) @@ -72,14 +65,10 @@ def construct(s, NocPktType, DataType, AddrType, data_mem_size_global, s.data_mem.recv_waddr[i] //= s.recv_waddr[i].send s.data_mem.recv_wdata[i] //= s.recv_wdata[i].send - # s.data_mem.send_to_noc_raddr //= s.send_to_noc_raddr.recv s.data_mem.recv_from_noc_rdata //= s.recv_from_noc_rdata.send - # s.data_mem.send_to_noc_waddr //= s.send_to_noc_waddr.recv - # s.data_mem.send_to_noc_wdata //= s.send_to_noc_wdata.recv s.data_mem.send_to_noc_load_request_pkt //= s.send_to_noc_load_request_pkt.recv s.data_mem.send_to_noc_store_pkt //= s.send_to_noc_store_pkt.recv - def done(s): for i in range(s.rd_tiles): if not s.recv_raddr[i].done() or not s.send_rdata[i].done(): @@ -89,26 +78,17 @@ def done(s): if not s.recv_waddr[i].done() or not s.recv_wdata[i].done(): return False - # if not s.send_to_noc_raddr.done() or \ - # not s.recv_from_noc_rdata.done() or \ - # not s.send_to_noc_waddr.done() or \ - # not s.send_to_noc_wdata.done(): - # return False - if not s.send_to_noc_load_request_pkt.done() or \ not s.send_to_noc_store_pkt.done() or \ not s.recv_from_noc_rdata.done(): return False - return True def line_trace(s): return s.data_mem.line_trace() - -def run_sim(test_harness, max_cycles=40): - # test_harness.elaborate() +def run_sim(test_harness, max_cycles = 40): test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() @@ -116,14 +96,13 @@ def run_sim(test_harness, max_cycles=40): ncycles = 0 print() - print( "{}:{}".format(ncycles, test_harness.line_trace())) + 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() @@ -200,8 +179,8 @@ def test_const_queue(cmdline_opts): # noc_send_write_data = [DataType(0xd040, 1), DataType(0xd545, 1)] send_to_noc_store_pkt = [ # src dst opq vc cmd addr data predicate - NocPktType(0, 0, 0, 0, CMD_STORE_REQUEST, 40, 0xd040, 1), - NocPktType(0, 0, 0, 0, CMD_STORE_REQUEST, 45, 0xd545, 1), + NocPktType(0, 0, 0, 0, CMD_STORE_REQUEST, 40, 0xd040, 1), + NocPktType(0, 0, 0, 0, CMD_STORE_REQUEST, 45, 0xd545, 1), ] th = TestHarness(NocPktType, DataType, AddrType, data_mem_size_global, diff --git a/noc/ChannelNormalRTL.py b/noc/ChannelNormalRTL.py index aacd6bb..ec210d7 100644 --- a/noc/ChannelNormalRTL.py +++ b/noc/ChannelNormalRTL.py @@ -1,23 +1,25 @@ -#========================================================================= -# ChannelNormalRTL.py -#========================================================================= -# RTL channel module for connecting basic components within a CGRA tile -# and across tiles. A channel normally takes single cycle while it could -# be parameterizable with a few cycles in case the NoC is a torus. -# -# This simple channel has latency insensitive send/recv interfaces. -# -# Author : Cheng Tan -# Date : Nov 26, 2024 +''' +========================================================================= +ChannelNormalRTL.py +========================================================================= +RTL channel module for connecting basic components within a CGRA tile +and across tiles. A channel normally takes single cycle while it could +be parameterizable with a few cycles in case the NoC is a torus. + +This simple channel has latency insensitive send/recv interfaces. + +Author : Cheng Tan + Date : Nov 26, 2024 +''' from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import NormalQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ..lib.basic.val_rdy.queues import NormalQueueRTL +class ChannelNormalRTL(Component): -class ChannelNormalRTL( Component ): def construct(s, DataType, latency = 1, num_entries = 2): - # Constant assert(latency > 0) s.latency = latency @@ -34,31 +36,17 @@ def construct(s, DataType, latency = 1, num_entries = 2): s.send = SendIfcRTL(DataType) # Component - s.queues = [NormalQueue(DataType, s.num_entries) + s.queues = [NormalQueueRTL(DataType, s.num_entries) for _ in range(s.latency)] - s.count //= s.queues[s.latency - 1].count # Connections - s.recv.rdy //= s.queues[0].enq_rdy - - @update - def process(): - for i in range(s.latency - 1): - s.queues[i+1].enq_msg @= s.queues[i].deq_msg - s.queues[i+1].enq_en @= s.queues[i].deq_rdy & s.queues[i+1].enq_rdy - s.queues[i].deq_en @= s.queues[i+1].enq_en - - s.queues[0].enq_msg @= s.recv.msg - s.queues[0].enq_en @= s.queues[0].enq_rdy & s.recv.en - - s.send.msg @= s.queues[s.latency-1].deq_msg - # s.send.msg.delay @= s.queues[s.latency-1].deq_msg.delay - s.send.en @= s.send.rdy & s.queues[s.latency-1].deq_rdy - s.queues[s.latency-1].deq_en @= s.send.en - # print("s.queues[0].deq_en: ", s.queues[0].deq_en) - # print("s.queues[0].enq_en: ", s.queues[0].enq_en) + s.count //= s.queues[s.latency - 1].count + for i in range(s.latency - 1): + s.queues[i+1].recv //= s.queues[i].send + s.queues[0].recv //= s.recv + s.queues[s.latency - 1].send //= s.send def line_trace( s ): trace = " -> ".join("channel_stage_" + str(i) + ": " + s.queues[i].line_trace() for i in range(s.latency)) diff --git a/noc/CrossbarRTL.py b/noc/CrossbarRTL.py index 546bfcb..654ebc6 100644 --- a/noc/CrossbarRTL.py +++ b/noc/CrossbarRTL.py @@ -9,15 +9,17 @@ """ from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * -class CrossbarRTL( Component ): +class CrossbarRTL(Component): - def construct( s, DataType, PredicateType, CtrlType, - num_inports=5, num_outports=5, bypass_point=4, id=0 ): + def construct(s, DataType, PredicateType, CtrlType, + num_inports = 5, num_outports = 5, bypass_point = 4, + id = 0): - InType = mk_bits( clog2( num_inports + 1 ) ) + InType = mk_bits(clog2(num_inports + 1)) s.bypass_point = bypass_point # Interface @@ -46,7 +48,7 @@ def construct( s, DataType, PredicateType, CtrlType, def update_signal(): s.out_rdy_vector @= 0 s.recv_predicate_vector @= 0 - s.send_predicate.en @= 0 + s.send_predicate.val @= 0 s.recv_blocked_vector @= 0 s.send_predicate.msg @= PredicateType() for i in range( num_inports ): @@ -54,7 +56,7 @@ def update_signal(): for i in range( num_outports ): s.in_dir[i] @= 0 s.in_dir_local[i] @= 0 - s.send_data[i].en @= 0 + s.send_data[i].val @= 0 s.send_data[i].msg @= DataType() # For predication register update. 'predicate' and 'predicate_in' no need @@ -68,8 +70,8 @@ def update_signal(): if s.recv_opt.msg.ctrl != OPT_START: for i in range( num_inports ): # Set predicate once the recv_data is stable (i.e., en == true). - if s.recv_opt.msg.predicate_in[i] & s.recv_data[i].en: - s.send_predicate.en @= b1( 1 ) + if s.recv_opt.msg.predicate_in[i] & s.recv_data[i].val: + s.send_predicate.val @= b1( 1 ) s.send_predicate.msg.payload @= b1( 1 ) s.recv_predicate_vector[i] @= s.recv_data[i].msg.predicate @@ -103,8 +105,8 @@ def update_signal(): ~s.recv_but_block_by_others[s.in_dir_local[i]] & \ ~s.send_but_block_by_others[i] - s.send_data[i].en @= s.recv_data[s.in_dir_local[i]].en - if s.send_data[i].en & s.recv_data[s.in_dir_local[i]].rdy: + s.send_data[i].val @= s.recv_data[s.in_dir_local[i]].val + if s.send_data[i].val & s.recv_data[s.in_dir_local[i]].rdy: s.send_data[i].msg.payload @= s.recv_data[s.in_dir_local[i]].msg.payload s.send_data[i].msg.predicate @= s.recv_data[s.in_dir_local[i]].msg.predicate s.send_data[i].msg.bypass @= s.recv_data[s.in_dir_local[i]].msg.bypass @@ -120,11 +122,11 @@ def update_signal(): else: s.send_data[i].msg.bypass @= b1( 0 ) else: - s.send_data[i].en @= b1( 0 ) + s.send_data[i].val @= b1( 0 ) else: for i in range( num_outports ): - s.send_data[i].en @= b1( 0 ) + s.send_data[i].val @= b1( 0 ) s.recv_opt.rdy @= reduce_and( s.out_rdy_vector ) & ~reduce_or( s.recv_blocked_vector ) s.send_predicate.msg.predicate @= reduce_or( s.recv_predicate_vector ) @@ -142,7 +144,6 @@ def update_blocked_by_others(): elif reduce_and( s.out_rdy_vector ): s.send_but_block_by_others[i] <<= 0 - # Line trace def line_trace( s ): recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) diff --git a/noc/CrossbarSeparateRTL.py b/noc/CrossbarSeparateRTL.py index 10aefc9..f8a0f7f 100644 --- a/noc/CrossbarSeparateRTL.py +++ b/noc/CrossbarSeparateRTL.py @@ -10,59 +10,46 @@ """ from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * class CrossbarSeparateRTL(Component): - - def construct(s, DataType, PredicateType, CtrlType, - num_inports = 5, num_outports = 5, bypass_point = 4, - id = 0): + def construct(s, DataType, PredicateType, CtrlType, num_inports = 5, + num_outports = 5, bypass_point = 4, id = 0): InType = mk_bits(clog2(num_inports + 1)) num_index = num_inports if num_inports != 1 else 2 NumInportType = mk_bits(clog2(num_index)) - s.bypass_point = bypass_point # Interface s.recv_opt = RecvIfcRTL(CtrlType) s.recv_data = [RecvIfcRTL(DataType) for _ in range(num_inports)] - - # Interfaces outports of the specific crossbar. - # s.xbar_outport = [RecvIfcRTL(InType) for _ in range(num_outports)] # s.recv_opt.msg.routing_xbar_outport[i] s.crossbar_outport = [InPort(InType) for _ in range(num_outports)] - s.send_data = [SendIfcRTL(DataType) for _ in range(num_outports)] - s.send_predicate = SendIfcRTL(PredicateType) - # TODO: should include position information or not - # s.pos = InPort( PositionType ) + s.send_predicate = SendIfcRTL(PredicateType) s.in_dir = [Wire(InType) for _ in range(num_outports)] s.in_dir_local = [Wire(NumInportType) for _ in range(num_outports)] - s.out_rdy_vector = Wire(num_outports) + s.send_rdy_vector = Wire(num_outports) s.recv_predicate_vector = Wire(num_inports) - # Used to indicate whether the recv_data could be popped. - s.recv_blocked_vector = Wire(num_inports) - # received or sent once but there are still some others pending. So the - # one already done should not proceed the next to avoid overwriting. - s.recv_but_block_by_others = [Wire(b1) for _ in range(num_inports)] - s.send_but_block_by_others = [Wire(b1) for _ in range(num_outports)] + s.recv_valid_vector = Wire(num_outports) + s.recv_required_vector = Wire(num_inports) + s.send_required_vector = Wire(num_outports) # Routing logic @update def update_signal(): - s.out_rdy_vector @= 0 + # s.out_rdy_vector @= 0 s.recv_predicate_vector @= 0 - s.send_predicate.en @= 0 - s.recv_blocked_vector @= 0 + s.send_predicate.val @= 0 + # s.recv_blocked_vector @= 0 s.send_predicate.msg @= PredicateType() for i in range(num_inports): s.recv_data[i].rdy @= 0 for i in range(num_outports): - s.in_dir[i] @= 0 - s.in_dir_local[i] @= 0 - s.send_data[i].en @= 0 + s.send_data[i].val @= 0 s.send_data[i].msg @= DataType() # For predication register update. 'predicate' and 'predicate_in' no need @@ -73,88 +60,57 @@ def update_signal(): if s.recv_opt.msg.predicate: s.send_predicate.msg @= PredicateType(b1(0), b1(0)) - if s.recv_opt.msg.ctrl != OPT_START: + if s.recv_opt.val & (s.recv_opt.msg.ctrl != OPT_START): for i in range(num_inports): # Set predicate once the recv_data is stable (i.e., en == true). - if s.recv_opt.msg.routing_predicate_in[i] & s.recv_data[i].en: - s.send_predicate.en @= b1(1) + # FIXME: Let's re-think the predicate support in next PR. + if s.recv_opt.msg.routing_predicate_in[i]: + s.send_predicate.val @= b1(1) s.send_predicate.msg.payload @= b1(1) s.recv_predicate_vector[i] @= s.recv_data[i].msg.predicate for i in range(num_inports): - s.recv_blocked_vector[i] @= (s.recv_data[i].msg.delay == 1) - - # The predicate_in might not be issued to other ports on the xbar, - # but it also needs to be drained from the recv_data, otherwise, - # it would block the recv_data channel/buffer. - if s.recv_opt.msg.routing_predicate_in[i] & \ - ~s.recv_blocked_vector[i] & \ - ~s.recv_but_block_by_others[i]: - s.recv_data[i].rdy @= 1 + s.recv_data[i].rdy @= reduce_and(s.recv_valid_vector) & \ + reduce_and(s.send_rdy_vector) & \ + s.recv_required_vector[i] for i in range(num_outports): - s.out_rdy_vector[i] @= s.send_data[i].rdy - # s.in_dir[i] @= s.recv_opt.msg.routing_xbar_outport[i] - s.in_dir[i] @= s.crossbar_outport[i] - # if s.in_dir[i] > 0: - # s.send_data[i].msg.delay @= s.recv_data[s.in_dir_local[i]].msg.delay - # else: - # s.out_rdy_vector[i] @= 1 - s.out_rdy_vector[i] @= 1 - - for i in range( num_outports ): - # s.in_dir[i] @= s.recv_opt.msg.routing_xbar_outport[i] - s.in_dir[i] @= s.crossbar_outport[i] - if (s.in_dir[i] > 0) & s.send_data[i].rdy: - s.in_dir_local[i] @= trunc(s.in_dir[i] - 1, NumInportType) - s.recv_data[s.in_dir_local[i]].rdy @= \ - s.send_data[i].rdy & \ - ~s.recv_blocked_vector[s.in_dir_local[i]] & \ - ~s.recv_but_block_by_others[s.in_dir_local[i]] & \ - ~s.send_but_block_by_others[i] - - s.send_data[i].en @= s.recv_data[s.in_dir_local[i]].en - if s.send_data[i].en & s.recv_data[s.in_dir_local[i]].rdy: - s.send_data[i].msg.payload @= s.recv_data[s.in_dir_local[i]].msg.payload - s.send_data[i].msg.predicate @= s.recv_data[s.in_dir_local[i]].msg.predicate - s.send_data[i].msg.bypass @= s.recv_data[s.in_dir_local[i]].msg.bypass - s.send_data[i].msg.delay @= 0 - # FIXME: Cleanup the commented logic. - # The generate one can be send to other tile without buffering, - # but buffering is still needed when 'other tile' is yourself - # (i.e., generating output to self input). Here we avoid self - # connecting by checking whether the inport belongs to FU and - # outport be towards to remote tiles to eliminate combinational - # loop. - # print("[cheng] s.in_dir_local[", i, "]: ", s.in_dir_local[i], "; s.bypass_point: ", s.bypass_point) - # if (s.in_dir_local[i] >= s.bypass_point) & (i < s.bypass_point): - # s.send_data[i].msg.bypass @= b1( 1 ) - # else: - # s.send_data[i].msg.bypass @= b1( 0 ) - s.send_data[i].msg.bypass @= b1(0) - else: - s.send_data[i].en @= b1(0) - - else: - for i in range(num_outports): - s.send_data[i].en @= b1(0) - s.recv_opt.rdy @= reduce_and(s.out_rdy_vector) & ~reduce_or(s.recv_blocked_vector) + s.send_data[i].val @= reduce_and(s.recv_valid_vector) & \ + reduce_and(s.send_rdy_vector) & \ + s.send_required_vector[i] + if reduce_and(s.recv_valid_vector) & \ + reduce_and(s.send_rdy_vector) & \ + s.send_required_vector[i]: + s.send_data[i].msg.payload @= s.recv_data[s.in_dir_local[i]].msg.payload + s.send_data[i].msg.predicate @= s.recv_data[s.in_dir_local[i]].msg.predicate + s.recv_opt.rdy @= reduce_and(s.send_rdy_vector) & reduce_and(s.recv_valid_vector) s.send_predicate.msg.predicate @= reduce_or(s.recv_predicate_vector) - @update_ff - def update_blocked_by_others(): - for i in range(num_inports): - if reduce_or(s.recv_blocked_vector) & ~s.recv_blocked_vector[i]: - s.recv_but_block_by_others[i] <<= 1 - elif ~reduce_or(s.recv_blocked_vector): - s.recv_but_block_by_others[i] <<= 0 + @update + def update_valid_rdy_vector(): + s.send_rdy_vector @= 0 + s.recv_valid_vector @= 0 for i in range(num_outports): - if ~reduce_and(s.out_rdy_vector) & s.out_rdy_vector[i]: - s.send_but_block_by_others[i] <<= 1 - elif reduce_and(s.out_rdy_vector): - s.send_but_block_by_others[i] <<= 0 + s.in_dir[i] @= 0 + s.in_dir_local[i] @= 0 + s.send_required_vector[i] @= 0 + + for i in range(num_inports): + s.recv_required_vector[i] @= 0 + for i in range(num_outports): + s.in_dir[i] @= s.crossbar_outport[i] + if s.in_dir[i] > 0: + s.in_dir_local[i] @= trunc(s.in_dir[i] - 1, NumInportType) + s.recv_valid_vector[i] @= s.recv_data[s.in_dir_local[i]].val + s.send_rdy_vector[i] @= s.send_data[i].rdy + # FIXME: @yo96, this might be a long critical path? + s.recv_required_vector[s.in_dir_local[i]] @= 1 + s.send_required_vector[i] @= 1 + else: + s.recv_valid_vector[i] @= 1 + s.send_rdy_vector[i] @= 1 # Line trace def line_trace(s): diff --git a/noc/LinkOrRTL.py b/noc/LinkOrRTL.py index a269ed9..5f382a1 100644 --- a/noc/LinkOrRTL.py +++ b/noc/LinkOrRTL.py @@ -1,20 +1,23 @@ -#========================================================================= -# LinkOrRTL.py -#========================================================================= -# RTL link module for taking two data and send out the one with valid -# predicate. -# The link is different from channel that it has no latency. The links -# are connected to the channels from crossbar and the outports from the -# FUs. -# -# Author : Cheng Tan -# Date : April 19, 2024 +""" +========================================================================= +LinkOrRTL.py +========================================================================= +RTL link module for taking two data and send out the one with valid +predicate. +The link is different from channel that it has no latency. The links +are connected to the channels from crossbar and the outports from the +FUs. + +Author : Cheng Tan + Date : April 19, 2024 +""" from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL class LinkOrRTL(Component): + def construct(s, DataType): # Interface @@ -37,14 +40,14 @@ def process(): else: s.send.msg.payload @= s.recv_xbar.msg.payload - # bypass won't be necessary any more with separate xbar design. - s.send.msg.bypass @= 0 - s.send.msg.delay @= s.recv_fu.msg.delay | s.recv_xbar.msg.delay + # FIXME: bypass won't be necessary any more with separate xbar design. + # s.send.msg.bypass @= 0 + # s.send.msg.delay @= s.recv_fu.msg.delay | s.recv_xbar.msg.delay - s.send.en @= s.send.rdy & ( s.recv_fu.en | s.recv_xbar.en ) + s.send.val @= s.send.rdy & (s.recv_fu.val | s.recv_xbar.val) s.recv_fu.rdy @= s.send.rdy s.recv_xbar.rdy @= s.send.rdy - def line_trace( s ): + def line_trace(s): return f"from_fu:{s.recv_fu.msg} or from_xbar:{s.recv_xbar.msg} => out:{s.send.msg} ## " diff --git a/noc/test/ChannelNormalRTL_test.py b/noc/test/ChannelNormalRTL_test.py index 93bcaef..8975ed6 100644 --- a/noc/test/ChannelNormalRTL_test.py +++ b/noc/test/ChannelNormalRTL_test.py @@ -1,18 +1,19 @@ -#========================================================================= -# ChannelNormalRTL_test.py -#========================================================================= -# Simple test for ChannelNormalRTL. There is no bypass functionality in -# the channel. -# -# Author : Cheng Tan -# Date : Nov 26, 2024 +""" +========================================================================= +ChannelNormalRTL_test.py +========================================================================= +Simple test for ChannelNormalRTL. There is no bypass functionality in +the channel. + +Author : Cheng Tan + Date : Nov 26, 2024 +""" import pytest from pymtl3 import * from pymtl3.stdlib.test_utils import TestVectorSimulator - -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.messages import * from ..ChannelNormalRTL import ChannelNormalRTL @@ -20,45 +21,45 @@ # TestHarness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, MsgType, src_msgs, sink_msgs, latency ): + def construct(s, MsgType, src_msgs, sink_msgs, latency): - s.src = TestSrcRTL ( MsgType, src_msgs ) - s.sink = TestSinkRTL( MsgType, sink_msgs ) - s.dut = ChannelNormalRTL( MsgType, latency ) + s.src = TestSrcRTL(MsgType, src_msgs) + s.sink = TestSinkRTL(MsgType, sink_msgs) + s.dut = ChannelNormalRTL(MsgType, latency) # Connections s.src.send //= s.dut.recv s.dut.send //= s.sink.recv - def done( s ): + def done(s): return s.src.done() and s.sink.done() - def line_trace( s ): + def line_trace(s): # return s.src.line_trace() + "-> | " + s.dut.line_trace() return s.src.line_trace() + "-> | " + s.dut.line_trace() + \ - " | -> " + s.sink.line_trace() + " | -> " + s.sink.line_trace() #------------------------------------------------------------------------- # run_rtl_sim #------------------------------------------------------------------------- -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 100): # Create a simulator test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # if ncycles >= 6: # test_harness.dut.send.rdy @= 1 @@ -79,10 +80,10 @@ def run_sim( test_harness, max_cycles=100 ): def test_simple(): latency = 1 - th = TestHarness( DataType, test_msgs, sink_msgs, latency) - run_sim( th ) + th = TestHarness(DataType, test_msgs, sink_msgs, latency) + run_sim(th) def test_latency(): latency = 2 - th = TestHarness( DataType, test_msgs, sink_msgs, latency) - run_sim( th ) + th = TestHarness(DataType, test_msgs, sink_msgs, latency) + run_sim(th) diff --git a/noc/test/CrossbarRTL_test.py b/noc/test/CrossbarRTL_test.py index 23938e0..faa5f79 100644 --- a/noc/test/CrossbarRTL_test.py +++ b/noc/test/CrossbarRTL_test.py @@ -9,11 +9,10 @@ """ -from pymtl3 import * -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..CrossbarRTL import CrossbarRTL +from pymtl3 import * +from ..CrossbarRTL import CrossbarRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ...lib.opt_type import * from ...lib.messages import * diff --git a/noc/test/LinkOrRTL_test.py b/noc/test/LinkOrRTL_test.py index 8d919f0..212b42a 100644 --- a/noc/test/LinkOrRTL_test.py +++ b/noc/test/LinkOrRTL_test.py @@ -1,64 +1,65 @@ -#========================================================================= -# LinkOrRTL_test.py -#========================================================================= -# Simple test for LinkOrRTL. -# -# Author : Cheng Tan -# Date : April 19, 2024 +''' +========================================================================== +LinkOrRTL_test.py +========================================================================== +Simple test for LinkOrRTL. + +Author : Cheng Tan + Date : April 19, 2024 +''' import pytest from pymtl3 import * from pymtl3.stdlib.test_utils import TestVectorSimulator from ..LinkOrRTL import LinkOrRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.messages import * #------------------------------------------------------------------------- # TestHarness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, MsgType, src_msgs_0, src_msgs_1, sink_msgs ): + def construct(s, MsgType, src_msgs_0, src_msgs_1, sink_msgs): - s.src0 = TestSrcRTL ( MsgType, src_msgs_0 ) - s.src1 = TestSrcRTL ( MsgType, src_msgs_1 ) - s.sink = TestSinkRTL ( MsgType, sink_msgs ) - s.dut = LinkOrRTL( MsgType ) + s.src0 = TestSrcRTL(MsgType, src_msgs_0) + s.src1 = TestSrcRTL(MsgType, src_msgs_1) + s.sink = TestSinkRTL(MsgType, sink_msgs) + s.dut = LinkOrRTL(MsgType) # Connections s.src0.send //= s.dut.recv_fu s.src1.send //= s.dut.recv_xbar - s.dut.send //= s.sink.recv + s.dut.send //= s.sink.recv - def done( s ): + def done(s): return s.src0.done() and s.src1.done() and s.sink.done() - def line_trace( s ): - # return s.src.line_trace() + "-> | " + s.dut.line_trace() - return s.src0.line_trace() + " or " + s.src1.line_trace() + "-> | " + \ - s.dut.line_trace() + " | -> " + s.sink.line_trace() + def line_trace(s): + return s.src0.line_trace() + " or " + s.src1.line_trace() + "-> | " + \ + s.dut.line_trace() + " | -> " + s.sink.line_trace() #------------------------------------------------------------------------- # run_rtl_sim #------------------------------------------------------------------------- -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 100): # Create a simulator test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print( "{}:{}".format(ncycles, test_harness.line_trace())) if ncycles >= 4: test_harness.dut.send.rdy @= 1 @@ -73,12 +74,12 @@ def run_sim( test_harness, max_cycles=100 ): # Test cases #------------------------------------------------------------------------- -DataType = mk_data( 16, 1 ) -test_msgs_0 = [ DataType(7,0,1), DataType(4,1), DataType(1,1), DataType(0,1), DataType(0,0) ] -test_msgs_1 = [ DataType(0,1,1), DataType(0,0), DataType(2,0), DataType(2,1), DataType(3,1) ] -sink_msgs = [ DataType(0,1), DataType(4,1), DataType(1,1), DataType(0,1), DataType(3,1) ] +DataType = mk_data(16, 1) +test_msgs_0 = [DataType(7,0,1), DataType(4,1), DataType(1,1), DataType(0,1), DataType(0,0)] +test_msgs_1 = [DataType(0,1,1), DataType(0,0), DataType(2,0), DataType(2,1), DataType(3,1)] +sink_msgs = [DataType(0,1), DataType(4,1), DataType(1,1), DataType(0,1), DataType(3,1)] def test_simple(): - th = TestHarness( DataType, test_msgs_0, test_msgs_1, sink_msgs ) - run_sim( th ) + th = TestHarness(DataType, test_msgs_0, test_msgs_1, sink_msgs) + run_sim(th) diff --git a/rf/RegFile.py b/rf/RegFile.py index 89e37f8..6598812 100644 --- a/rf/RegFile.py +++ b/rf/RegFile.py @@ -11,10 +11,10 @@ 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 ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * - class RegFile( Component ): def construct( s, DataType, nregs ): @@ -47,7 +47,7 @@ def update_signal(): s.recv_raddr.rdy @= s.send_rdata.rdy s.recv_waddr.rdy @= s.send_rdata.rdy s.recv_wdata.rdy @= s.send_rdata.rdy - s.send_rdata.en @= s.recv_raddr.en + s.send_rdata.val @= s.recv_raddr.val def line_trace( s ): out_str = "|".join([ str(data) for data in s.reg_file.regs ]) diff --git a/rf/RegisterRTL.py b/rf/RegisterRTL.py index d6f2e1f..ae10781 100644 --- a/rf/RegisterRTL.py +++ b/rf/RegisterRTL.py @@ -8,46 +8,38 @@ Date : Aug 22, 2021 ''' - from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import NormalQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ..lib.basic.val_rdy.queues import NormalQueueRTL -class RegisterRTL( Component ): +class RegisterRTL(Component): - def construct(s, DataType, latency = 1 ): + def construct(s, DataType, latency = 1): # Constant - s.latency = latency + s.latency = latency s.num_entries = 2 - s.data = DataType( 0 ) + s.data = DataType(0) # Interface - s.recv = RecvIfcRTL( DataType ) - s.send = SendIfcRTL( DataType ) + s.recv = RecvIfcRTL(DataType) + s.send = SendIfcRTL(DataType) # Component - s.queues = [ NormalQueue( DataType, s.num_entries ) - for _ in range( s.latency ) ] - - @update - def process(): - s.recv.rdy @= s.queues[0].enq_rdy - s.queues[0].enq_msg @= s.recv.msg - s.queues[0].enq_en @= s.recv.en & s.queues[0].enq_rdy - for i in range(s.latency - 1): - s.queues[i+1].enq_msg @= s.queues[i].deq_msg - s.queues[i+1].enq_en @= s.queues[i].deq_rdy & s.queues[i+1].enq_rdy - s.queues[i].deq_en @= s.queues[i+1].enq_en - - s.send.msg @= s.queues[s.latency-1].deq_msg - s.send.en @= s.send.rdy & s.queues[s.latency-1].deq_rdy - s.queues[s.latency-1].deq_en @= s.send.en - - def line_trace( s ): + s.queues = [NormalQueueRTL(DataType, s.num_entries) + for _ in range(s.latency)] + + # Connections + for i in range(s.latency - 1): + s.queues[i+1].recv //= s.queues[i].send + + s.queues[0].recv //= s.recv + s.queues[s.latency - 1].send //= s.send + + def line_trace(s): trace = '>' - for i in range( s.latency ): + for i in range(s.latency): trace += s.queues[i].line_trace() + '>' return f"{s.recv.msg}({trace}){s.send.msg} ## " diff --git a/rf/test/RegFile_test.py b/rf/test/RegFile_test.py index 14eabb1..9c55f8f 100644 --- a/rf/test/RegFile_test.py +++ b/rf/test/RegFile_test.py @@ -1,22 +1,20 @@ """ ========================================================================== -Phi_test.py +RegFile_test.py ========================================================================== -Test cases for functional unit Phi. +Test cases for RegFile. Author : Cheng Tan Date : November 27, 2019 """ - from pymtl3 import * from ..RegFile import RegFile -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.messages import * from ...lib.opt_type import * - #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- diff --git a/rf/test/RegisterRTL_test.py b/rf/test/RegisterRTL_test.py index 0b845d9..d8c9cd2 100644 --- a/rf/test/RegisterRTL_test.py +++ b/rf/test/RegisterRTL_test.py @@ -1,8 +1,8 @@ ''' ========================================================================= -ChannelRTL_test.py +RegisterFile_test.py ========================================================================= -Simple test for Channel +Simple test for RegisterFileRTL. Author : Cheng Tan Date : Dec 11, 2019 @@ -13,8 +13,8 @@ from pymtl3 import * from pymtl3.stdlib.test_utils import TestVectorSimulator from ..RegisterRTL import RegisterRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.messages import * @@ -22,44 +22,44 @@ # TestHarness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, MsgType, src_msgs, sink_msgs ): + def construct(s, MsgType, src_msgs, sink_msgs): - s.src = TestSrcRTL ( MsgType, src_msgs ) - s.sink = TestSinkRTL( MsgType, sink_msgs ) - s.dut = RegisterRTL( MsgType ) + s.src = TestSrcRTL(MsgType, src_msgs) + s.sink = TestSinkRTL(MsgType, sink_msgs) + s.dut = RegisterRTL(MsgType) # Connections s.src.send //= s.dut.recv s.dut.send //= s.sink.recv - def done( s ): + def done(s): return s.src.done() and s.sink.done() - def line_trace( s ): + def line_trace(s): return s.src.line_trace() + "-> | " + s.dut.line_trace() + \ - " | -> " + s.sink.line_trace() + " | -> " + s.sink.line_trace() #------------------------------------------------------------------------- # run_rtl_sim #------------------------------------------------------------------------- -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 100): # Create a simulator test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + print("{}:{}".format( ncycles, test_harness.line_trace())) # Check timeout assert ncycles < max_cycles @@ -72,10 +72,11 @@ def run_sim( test_harness, max_cycles=100 ): # Test cases #------------------------------------------------------------------------- -DataType = mk_bits(3) -test_msgs = [ DataType(1), DataType(2), DataType(3) ] -sink_msgs = [ DataType(1), DataType(2), DataType(3) ] +DataType = mk_bits(3) +test_msgs = [DataType(1), DataType(2), DataType(3)] +sink_msgs = [DataType(1), DataType(2), DataType(3)] def test_simple(): - th = TestHarness( DataType, test_msgs, sink_msgs) - run_sim( th ) + th = TestHarness(DataType, test_msgs, sink_msgs) + run_sim(th) + diff --git a/tile/TileCL.py b/tile/TileCL.py index 13c4b00..310bb1e 100644 --- a/tile/TileCL.py +++ b/tile/TileCL.py @@ -7,23 +7,22 @@ Date : Dec 28, 2019 """ - from pymtl3 import * from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ..fu.single.MemUnitRTL import MemUnitRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..mem.ctrl.CtrlMemCL import CtrlMemCL from ..mem.const.ConstQueueRTL import ConstQueueRTL from ..noc.ChannelRTL import ChannelRTL from ..noc.CrossbarRTL import CrossbarRTL from ..rf.RegisterRTL import RegisterRTL +class TileCL(Component): -class TileCL( Component ): - - def construct( s, Fu, FuList, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - const_list, opt_list, id=0 ): + def construct(s, Fu, FuList, DataType, PredicateType, CtrlType, + ctrl_mem_size, data_mem_size, num_ctrl, total_steps, + const_list, opt_list, id=0): # Constant num_xbar_inports = 6 @@ -32,18 +31,18 @@ def construct( s, Fu, FuList, DataType, PredicateType, CtrlType, num_fu_outports = 2 num_mesh_ports = 4 bypass_point = 4 - CtrlAddrType = mk_bits( clog2( ctrl_mem_size ) ) - DataAddrType = mk_bits( clog2( data_mem_size ) ) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + DataAddrType = mk_bits(clog2(data_mem_size)) # Interfaces - s.recv_data = [ RecvIfcRTL( DataType ) for _ in range ( num_mesh_ports ) ] - s.send_data = [ SendIfcRTL( DataType ) for _ in range ( num_mesh_ports ) ] + s.recv_data = [RecvIfcRTL(DataType) for _ in range (num_mesh_ports)] + s.send_data = [SendIfcRTL(DataType) for _ in range (num_mesh_ports)] # Data - s.to_mem_raddr = SendIfcRTL( DataAddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( DataAddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) + s.to_mem_raddr = SendIfcRTL(DataAddrType) + s.from_mem_rdata = RecvIfcRTL(DataType) + s.to_mem_waddr = SendIfcRTL(DataAddrType) + s.to_mem_wdata = SendIfcRTL(DataType) # Components s.element = FlexibleFuRTL( DataType, PredicateType, CtrlType, num_fu_inports, @@ -71,7 +70,7 @@ def construct( s, Fu, FuList, DataType, PredicateType, CtrlType, s.to_mem_wdata //= s.element.to_mem_wdata[i] else: s.element.to_mem_raddr[i].rdy //= 0 - s.element.from_mem_rdata[i].en //= 0 + s.element.from_mem_rdata[i].val //= 0 s.element.from_mem_rdata[i].msg //= DataType( 0, 0 ) s.element.to_mem_waddr[i].rdy //= 0 s.element.to_mem_wdata[i].rdy //= 0 @@ -91,7 +90,6 @@ def construct( s, Fu, FuList, DataType, PredicateType, CtrlType, for i in range( num_fu_inports ): s.channel[num_mesh_ports+i].send //= s.element.recv_in[i] - s.channel[num_mesh_ports+i].count //= s.element.recv_in_count[i] for i in range( num_fu_outports ): s.element.send_out[i] //= s.crossbar.recv_data[num_mesh_ports+i] @@ -100,8 +98,8 @@ def construct( s, Fu, FuList, DataType, PredicateType, CtrlType, def update_opt(): s.element.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg s.crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.element.recv_opt.en @= s.ctrl_mem.send_ctrl.en - s.crossbar.recv_opt.en @= s.ctrl_mem.send_ctrl.en + s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val + s.crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy or s.crossbar.recv_opt.rdy # Line trace diff --git a/tile/TileSeparateCrossbarRTL.py b/tile/TileSeparateCrossbarRTL.py index 0a6250d..daa70f3 100644 --- a/tile/TileSeparateCrossbarRTL.py +++ b/tile/TileSeparateCrossbarRTL.py @@ -14,9 +14,7 @@ Date : Nov 26, 2024 """ - from pymtl3 import * - from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ..fu.single.AdderRTL import AdderRTL from ..fu.single.BranchRTL import BranchRTL @@ -24,15 +22,14 @@ from ..fu.single.CompRTL import CompRTL from ..fu.single.MemUnitRTL import MemUnitRTL from ..fu.single.MulRTL import MulRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..mem.const.ConstQueueRTL import ConstQueueRTL from ..mem.ctrl.CtrlMemDynamicRTL import CtrlMemDynamicRTL from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL from ..noc.ChannelNormalRTL import ChannelNormalRTL from ..noc.LinkOrRTL import LinkOrRTL from ..rf.RegisterRTL import RegisterRTL -# from ..noc.BypassChannelRTL import BypassChannelRTL class TileSeparateCrossbarRTL(Component): @@ -54,15 +51,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, DataAddrType = mk_bits(clog2(data_mem_size)) # Interfaces. - s.recv_data = [RecvIfcRTL(DataType) for _ in range ( - num_tile_inports)] - s.send_data = [SendIfcRTL(DataType) for _ in range ( - num_tile_outports)] + s.recv_data = [RecvIfcRTL(DataType) + for _ in range (num_tile_inports)] + s.send_data = [SendIfcRTL(DataType) + for _ in range (num_tile_outports)] # Ctrl. - # s.recv_waddr = RecvIfcRTL(CtrlAddrType) - # s.recv_wopt = RecvIfcRTL(CtrlSignalType) - s.recv_ctrl_pkt = ValRdyRecvIfcRTL(CtrlPktType) + s.recv_ctrl_pkt = RecvIfcRTL(CtrlPktType) # Data. s.to_mem_raddr = SendIfcRTL(DataAddrType) @@ -74,42 +69,42 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.element = FlexibleFuRTL(DataType, PredicateType, CtrlSignalType, num_fu_inports, num_fu_outports, data_mem_size, FuList) - s.const_queue = ConstQueueRTL(DataType, const_list if const_list != None else [DataType(0)]) - s.routing_crossbar = CrossbarSeparateRTL(DataType, PredicateType, CtrlSignalType, + s.const_queue = ConstQueueRTL(DataType, const_list \ + if const_list != None else [DataType(0)]) + s.routing_crossbar = CrossbarSeparateRTL(DataType, PredicateType, + CtrlSignalType, num_routing_xbar_inports, num_routing_xbar_outports) - s.fu_crossbar = CrossbarSeparateRTL(DataType, PredicateType, CtrlSignalType, + s.fu_crossbar = CrossbarSeparateRTL(DataType, PredicateType, + CtrlSignalType, num_fu_xbar_inports, num_fu_xbar_outports) - s.ctrl_mem = CtrlMemDynamicRTL(CtrlPktType, CtrlSignalType, ctrl_mem_size, + s.ctrl_mem = CtrlMemDynamicRTL(CtrlPktType, CtrlSignalType, + ctrl_mem_size, num_fu_inports, num_fu_outports, num_tile_inports, num_tile_outports, num_ctrl, total_steps) # The `tile_out_channel` indicates the outport channels that are # connected to the next tiles. - s.tile_out_channel = [ChannelNormalRTL(DataType) for _ in range( - num_tile_outports)] + s.tile_out_channel = [ChannelNormalRTL(DataType) + for _ in range(num_tile_outports)] # The `fu_in_channel` indicates the inport channels that are # connected to the FUs. - s.fu_in_channel = [ChannelNormalRTL(DataType) for _ in range( - num_fu_inports)] + s.fu_in_channel = [ChannelNormalRTL(DataType) + for _ in range(num_fu_inports)] # The `tile_out_or_link` would "or" the outports of the # `tile_out_channel` and the FUs. - s.tile_out_or_link = [LinkOrRTL(DataType) for _ in range( - num_tile_outports)] + s.tile_out_or_link = [LinkOrRTL(DataType) + for _ in range(num_tile_outports)] # The `fu_in_or_link` would "or" the inports of the `fu_in_channel' # and the outports of the fu_crossbar. s.fu_in_or_link = [LinkOrRTL(DataType) for _ in range(num_fu_inports)] - # # Added to break the combinational loops - # s.bypass_channel = [ BypassChannelRTL( DataType ) for _ in range( num_fu_outports ) ] # Additional one register for partial predication s.reg_predicate = RegisterRTL(PredicateType) # Connections. # Ctrl. - # s.ctrl_mem.recv_waddr //= s.recv_waddr - # s.ctrl_mem.recv_ctrl //= s.recv_wopt s.ctrl_mem.recv_pkt //= s.recv_ctrl_pkt # Constant queue. @@ -123,7 +118,7 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.to_mem_wdata //= s.element.to_mem_wdata[i] else: s.element.to_mem_raddr[i].rdy //= 0 - s.element.from_mem_rdata[i].en //= 0 + s.element.from_mem_rdata[i].val //= 0 s.element.from_mem_rdata[i].msg //= DataType() s.element.to_mem_waddr[i].rdy //= 0 s.element.to_mem_wdata[i].rdy //= 0 @@ -136,9 +131,10 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # # Connects specific xbar control signals to the corresponding crossbar. for i in range(num_routing_xbar_outports): - s.routing_crossbar.crossbar_outport[i] //= s.ctrl_mem.send_ctrl.msg.routing_xbar_outport[i] - s.fu_crossbar.crossbar_outport[i] //= s.ctrl_mem.send_ctrl.msg.fu_xbar_outport[i] - + s.routing_crossbar.crossbar_outport[i] //= \ + s.ctrl_mem.send_ctrl.msg.routing_xbar_outport[i] + s.fu_crossbar.crossbar_outport[i] //= \ + s.ctrl_mem.send_ctrl.msg.fu_xbar_outport[i] # The data going out to the other tiles should be from # the `routing_crossbar`. Note that there are also data @@ -147,19 +143,18 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, for i in range(num_tile_outports): s.routing_crossbar.send_data[i] //= s.tile_out_channel[i].recv - # for i in range(num_fu_inports): - # s.routing_crossbar.send_data[num_tile_outports + i] //= s.fu_in_channel[i].recv - # One partial predication register for flow control. s.routing_crossbar.send_predicate //= s.reg_predicate.recv s.reg_predicate.send //= s.element.recv_predicate # Connects the FU's inport channels with the corresponding FU. + # FIXME: change element to use val/rdy ifcs. for i in range(num_fu_inports): s.fu_in_channel[i].send //= s.element.recv_in[i] - s.fu_in_channel[i].count //= s.element.recv_in_count[i] + # s.fu_in_channel[i].count //= s.element.recv_in_count[i] # Connections on the `fu_crossbar`. + # FIXME: change element to use val/rdy ifcs. for i in range(num_fu_outports): s.element.send_out[i] //= s.fu_crossbar.recv_data[i] @@ -177,7 +172,6 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.routing_crossbar.send_data[num_tile_outports + i] //= s.fu_in_or_link[i].recv_xbar s.fu_in_or_link[i].send //= s.fu_in_channel[i].recv - # Updates the configuration memory related signals. @update def update_opt(): @@ -186,15 +180,14 @@ def update_opt(): s.routing_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg s.fu_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.element.recv_opt.en @= s.ctrl_mem.send_ctrl.en - s.routing_crossbar.recv_opt.en @= s.ctrl_mem.send_ctrl.en - s.fu_crossbar.recv_opt.en @= s.ctrl_mem.send_ctrl.en + s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val + s.routing_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val + s.fu_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & \ s.routing_crossbar.recv_opt.rdy & \ s.fu_crossbar.recv_opt.rdy - # Line trace def line_trace( s ): recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) @@ -202,7 +195,7 @@ def line_trace( s ): tile_out_channel_send_str = "|".join([str(x.send.msg) for x in s.tile_out_channel]) fu_in_channel_recv_str = "|".join([str(x.recv.msg) for x in s.fu_in_channel]) fu_in_channel_send_str = "|".join([str(x.send.msg) for x in s.fu_in_channel]) - out_str = "|".join([ "("+str(x.msg.payload)+","+str(x.msg.predicate)+")" for x in s.send_data ]) - return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} ## " - # return f"{recv_str} => [{s.crossbar.recv_opt.msg}] ({s.element.line_trace()}) => {channel_recv_str} => {channel_send_str} => {out_str}" + out_str = "|".join([ "("+str(x.msg.payload)+","+str(x.msg.predicate)+",val:"+str(x.val)+",rdy:"+str(x.rdy)+")" for x in s.send_data ]) + ctrl_mem = s.ctrl_mem.line_trace() + return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} || ctrl_mem: {ctrl_mem} ## " diff --git a/tile/test/TileSeparateCrossbarRTL_test.py b/tile/test/TileSeparateCrossbarRTL_test.py index 6ee012b..b263882 100644 --- a/tile/test/TileSeparateCrossbarRTL_test.py +++ b/tile/test/TileSeparateCrossbarRTL_test.py @@ -10,7 +10,6 @@ Date : Nov 26, 2024 """ - from pymtl3 import * from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) @@ -20,11 +19,11 @@ from ...fu.single.AdderRTL import AdderRTL from ...fu.single.MemUnitRTL import MemUnitRTL from ...fu.single.MulRTL import MulRTL +from ...fu.single.NahRTL import NahRTL from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -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 ValRdyTestSrcRTL +from ...lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ...lib.messages import * from ...lib.cmd_type import * from ...lib.opt_type import * @@ -45,9 +44,9 @@ def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, s.num_tile_outports = num_tile_outports s.src_ctrl_pkt = ValRdyTestSrcRTL(CtrlPktType, src_ctrl_pkt) - s.src_data = [TestSrcRTL(DataType, src_data[i]) + s.src_data = [ValRdyTestSrcRTL(DataType, src_data[i]) for i in range(num_tile_inports)] - s.sink_out = [TestSinkRTL(DataType, sink_out[i]) + s.sink_out = [ValRdyTestSinkRTL(DataType, sink_out[i]) for i in range(num_tile_outports)] s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, @@ -64,7 +63,7 @@ def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, if MemUnitRTL in FuList: s.dut.to_mem_raddr.rdy //= 0 - s.dut.from_mem_rdata.en //= 0 + s.dut.from_mem_rdata.val //= 0 s.dut.from_mem_rdata.msg //= DataType(0, 0) s.dut.to_mem_waddr.rdy //= 0 s.dut.to_mem_wdata.rdy //= 0 From 74429e086e500b3c5a1213be405eebdac796fca0 Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 09:16:36 +0000 Subject: [PATCH 02/10] [feature&cleanup] Allow either fu or xbar to complete first and allow ctrl proceed till both done. Enable 2x2 matmul on 3x3 cgra_systolic_array --- .github/workflows/python-package.yml | 20 +- cgra/CGRACL.py | 95 --- cgra/CGRAKingMeshRTL.py | 159 ----- cgra/CGRARTL.py | 107 --- cgra/CGRATemplateRTL.py | 98 --- cgra/{CGRAFL.py => CgraFL.py} | 6 +- cgra/test/CGRACL_FIR_demo_test.py | 194 ----- cgra/test/CGRACL_test.py | 189 ----- cgra/test/CGRAKingMeshRTL_test.py | 181 ----- cgra/test/CGRARTL_test.py | 169 ----- .../CgraCrossbarDataMemRingCtrlMemRTL_test.py | 1 + cgra/test/{CGRAFL_test.py => CgraFL_test.py} | 8 +- ...t.py => CgraRTL_fir_demo_test.py.disabled} | 0 cgra/translate/CGRARTL_hetero_test.py | 86 --- cgra/translate/CGRARTL_test.py | 97 --- cgra/translate/CGRATemplateRTL_test.py | 374 ---------- .../CgraCrossbarDataMemRingCtrlMemRTL_test.py | 219 ------ cgra/translate/CgraTemplateRTL_test.py | 398 ----------- cgra/translate/VectorCGRAKingMeshRTL_test.py | 144 ---- cgra/translate/__init__.py | 0 controller/ControllerRTL.py | 3 +- fu/basic/ThreeCombo.py | 22 +- fu/basic/TwoPrlCombo.py | 17 +- fu/basic/TwoSeqCombo.py | 16 +- fu/flexible/FlexibleFuRTL.py | 6 +- fu/flexible/translate/FlexibleFuRTL_test.py | 3 - fu/float/FpAddRTL.py | 2 +- fu/float/FpMulRTL.py | 2 +- fu/vector/VectorAllReduceRTL.py | 1 - fu/vector/VectorMulRTL.py | 1 - lib/messages.py | 1 - mem/ctrl/CtrlMemDynamicRTL.py | 10 +- mem/ctrl/RingMultiCtrlMemDynamicRTL.py | 2 +- mem/data/DataMemWithCrossbarRTL.py | 2 +- noc/BlockChannelRTL.py | 80 --- noc/BypassChannelRTL.py | 44 -- noc/ChannelRTL.py | 93 --- noc/CrossbarRTL.py | 153 ---- noc/CrossbarSeparateRTL.py | 11 +- noc/DelayChannelRTL.py | 80 --- noc/LinkOrRTL.py | 3 +- noc/MulticasterRTL.py | 41 -- noc/test/BlockChannelRTL_test.py | 83 --- noc/test/ChannelRTL_test.py | 88 --- noc/test/CrossbarBlockRTL_test.py | 117 --- noc/test/CrossbarDelayRTL_test.py | 186 ----- noc/test/CrossbarRTL_test.py | 175 ++--- noc/test/Multicaster_test.py | 80 --- .../RingMultiCgraRingCtrlMemRTL_test.py | 218 ------ scale_out/translate/__init__.py | 0 systolic/CgraMemBottomRTL.py | 115 --- systolic/CgraMemRightAndBottomRTL.py | 25 +- systolic/CgraSystolicArrayRTL.py | 176 +++++ systolic/SystolicCL.py | 105 --- ...3x3MemRightAndBottomRTL_matmul_2x2_test.py | 666 ++++++++++++++++++ systolic/test/SystolicCL_test.py | 216 ------ .../CgraMemBottomRTL_matmul_2x2_test.py | 307 -------- ...graMemRightAndBottomRTL_matmul_2x2_test.py | 406 ----------- systolic/translate/__init__.py | 0 tile/TileCL.py | 113 --- tile/TileSeparateCrossbarRTL.py | 54 +- tile/test/TileCL_test.py | 136 ---- tile/test/TileRTL_test.py | 156 ---- tile/test/TileSeparateCrossbarRTL_test.py | 43 +- tile/translate/TileRTL_test.py | 78 -- tile/translate/TileVectorRTL_test.py | 88 --- 66 files changed, 1060 insertions(+), 5709 deletions(-) delete mode 100644 cgra/CGRACL.py delete mode 100644 cgra/CGRAKingMeshRTL.py delete mode 100644 cgra/CGRARTL.py delete mode 100644 cgra/CGRATemplateRTL.py rename cgra/{CGRAFL.py => CgraFL.py} (97%) delete mode 100644 cgra/test/CGRACL_FIR_demo_test.py delete mode 100644 cgra/test/CGRACL_test.py delete mode 100644 cgra/test/CGRAKingMeshRTL_test.py delete mode 100644 cgra/test/CGRARTL_test.py rename cgra/test/{CGRAFL_test.py => CgraFL_test.py} (89%) rename cgra/test/{CGRARTL_FIR_demo_test.py => CgraRTL_fir_demo_test.py.disabled} (100%) delete mode 100644 cgra/translate/CGRARTL_hetero_test.py delete mode 100644 cgra/translate/CGRARTL_test.py delete mode 100644 cgra/translate/CGRATemplateRTL_test.py delete mode 100644 cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py delete mode 100644 cgra/translate/CgraTemplateRTL_test.py delete mode 100644 cgra/translate/VectorCGRAKingMeshRTL_test.py delete mode 100644 cgra/translate/__init__.py delete mode 100644 noc/BlockChannelRTL.py delete mode 100644 noc/BypassChannelRTL.py delete mode 100644 noc/ChannelRTL.py delete mode 100644 noc/CrossbarRTL.py delete mode 100644 noc/DelayChannelRTL.py delete mode 100644 noc/MulticasterRTL.py delete mode 100644 noc/test/BlockChannelRTL_test.py delete mode 100644 noc/test/ChannelRTL_test.py delete mode 100644 noc/test/CrossbarBlockRTL_test.py delete mode 100644 noc/test/CrossbarDelayRTL_test.py delete mode 100644 noc/test/Multicaster_test.py delete mode 100644 scale_out/translate/RingMultiCgraRingCtrlMemRTL_test.py delete mode 100644 scale_out/translate/__init__.py delete mode 100644 systolic/CgraMemBottomRTL.py create mode 100644 systolic/CgraSystolicArrayRTL.py delete mode 100644 systolic/SystolicCL.py create mode 100644 systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py delete mode 100644 systolic/test/SystolicCL_test.py delete mode 100644 systolic/translate/CgraMemBottomRTL_matmul_2x2_test.py delete mode 100644 systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py delete mode 100644 systolic/translate/__init__.py delete mode 100644 tile/TileCL.py delete mode 100644 tile/test/TileCL_test.py delete mode 100644 tile/test/TileRTL_test.py delete mode 100644 tile/translate/TileRTL_test.py delete mode 100644 tile/translate/TileVectorRTL_test.py diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 24255b1..7769ff4 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -61,23 +61,17 @@ jobs: # Simulation across all tests. pytest .. -v --tb=short # Tile translation. - pytest ../tile/translate/TileRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd - # Kingmesh topology CGRA translation. - pytest ../cgra/translate/VectorCGRAKingMeshRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd - # Separate crossbars CGRA simulation/translation. - pytest ../cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd - # 3x2 CGRA performs 2x2 matmul translation. - pytest ../systolic/translate/CgraMemBottomRTL_matmul_2x2_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../tile/test/TileSeparateCrossbarRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + # CGRA template translation. + pytest ../cgra/test/CgraTemplateRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + # CGRA simulation/translation (including heterogeneous, kingmesh, vector). + pytest ../cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd # 3x3 CGRA performs 2x2 matmul simulation/translation. - pytest ../systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py -xvs --tb=short - pytest ../systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd # Ring network simulation. pytest ../noc/PyOCN/pymtl3_net/ringnet/test/RingNetworkRTL_test.py --tb=short -sv - # CGRA with separate crossbars (for tiles and FUs), crossbar-based data - # memory (for multi-bank), ring-based control memories, and controller. - pytest --tb=short -sv ../cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py --test-verilog --dump-vtb --dump-vcd # CGRAs are interconnected with ring topology. The CGRA contains # separate crossbars (for tiles and FUs), crossbar-based data memory (for # multi-bank), and controller. - pytest --tb=short -sv ../scale_out/translate/RingMultiCgraRingCtrlMemRTL_test.py --test-verilog --dump-vtb --dump-vcd + pytest --tb=short -sv ../scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py --test-verilog --dump-vtb --dump-vcd diff --git a/cgra/CGRACL.py b/cgra/CGRACL.py deleted file mode 100644 index ff6d09c..0000000 --- a/cgra/CGRACL.py +++ /dev/null @@ -1,95 +0,0 @@ -""" -========================================================================= -CGRACL.py -========================================================================= - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - -from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..noc.CrossbarRTL import CrossbarRTL -from ..noc.ChannelRTL import ChannelRTL -from ..mem.data.DataMemCL import DataMemCL -from ..tile.TileCL import TileCL - - -class CGRACL( Component ): - - def construct( s, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - num_ctrl, total_steps, preload_ctrl, preload_data, - preload_const ): - - s.num_tiles = width * height - s.num_mesh_ports = 4 - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - # Components - - s.tile = [ TileCL( FunctionUnit, FuList, DataType, PredicateType, - CtrlType, ctrl_mem_size, data_mem_size, - num_ctrl, total_steps, preload_const[i], - preload_ctrl[i], i ) - for i in range( s.num_tiles ) ] - s.data_mem = DataMemCL( DataType, data_mem_size, height, height, - preload_data ) - - # Connections - - for i in range( s.num_tiles): - - 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 ): - 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 - diff --git a/cgra/CGRAKingMeshRTL.py b/cgra/CGRAKingMeshRTL.py deleted file mode 100644 index bbe4bfb..0000000 --- a/cgra/CGRAKingMeshRTL.py +++ /dev/null @@ -1,159 +0,0 @@ -""" -========================================================================= -CGRARTL.py -========================================================================= -Author : Cheng Tan - Date : Dec 15, 2019 -""" - -from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..noc.CrossbarRTL import CrossbarRTL -from ..noc.ChannelRTL import ChannelRTL -from ..tile.TileRTL import TileRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..mem.data.DataMemRTL import DataMemRTL -from ..mem.data.DataMemCL import DataMemCL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.AdderRTL import AdderRTL -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL - - -class CGRAKingMeshRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - FunctionUnit, FuList, preload_data = None, - preload_const = None ): - - s.num_mesh_ports = 8 - s.num_tiles = width * height - 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 ) ] - - # Components - if preload_const == None: - preload_const = [[DataType(0, 0)] for _ in range(width*height)] - s.tile = [ TileRTL( DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, - s.num_mesh_ports, FuList=FuList, const_list = preload_const[i] ) - for i in range( s.num_tiles ) ] - s.data_mem = DataMemRTL( DataType, data_mem_size, height, height, preload_data ) - - # Connections - 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 - - # rows > 0 - if i // width > 0: - s.tile[i].send_data[PORT_SOUTH] //= s.tile[i-width].recv_data[PORT_NORTH] - - # rows < height - 1 - if i // width < height - 1: - s.tile[i].send_data[PORT_NORTH] //= s.tile[i+width].recv_data[PORT_SOUTH] - - # cols > 0 - if i % width > 0: - s.tile[i].send_data[PORT_WEST] //= s.tile[i-1].recv_data[PORT_EAST] - - # cols < width - 1 - if i % width < width - 1: - s.tile[i].send_data[PORT_EAST] //= s.tile[i+1].recv_data[PORT_WEST] - - # cols > 0 and rows < height - 1 - if i % width > 0 and i // width < height - 1: - s.tile[i].send_data[PORT_NORTHWEST] //= s.tile[i+width-1].recv_data[PORT_SOUTHEAST] - s.tile[i+width-1].send_data[PORT_SOUTHEAST] //= s.tile[i].recv_data[PORT_NORTHWEST] - - # cols < width - 1 and rows < height - 1 - if i % width < width - 1 and i // width < height - 1: - s.tile[i].send_data[PORT_NORTHEAST] //= s.tile[i+width+1].recv_data[PORT_SOUTHWEST] - s.tile[i+width+1].send_data[PORT_SOUTHWEST] //= s.tile[i].recv_data[PORT_NORTHEAST] - - # rows == 0 - 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 ) - s.tile[i].send_data[PORT_SOUTHWEST].rdy //= 0 - s.tile[i].recv_data[PORT_SOUTHWEST].en //= 0 - s.tile[i].recv_data[PORT_SOUTHWEST].msg //= DataType( 0, 0 ) - s.tile[i].send_data[PORT_SOUTHEAST].rdy //= 0 - s.tile[i].recv_data[PORT_SOUTHEAST].en //= 0 - s.tile[i].recv_data[PORT_SOUTHEAST].msg //= DataType( 0, 0 ) - - # rows < height - 1 - 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 ) - s.tile[i].send_data[PORT_NORTHWEST].rdy //= 0 - s.tile[i].recv_data[PORT_NORTHWEST].en //= 0 - s.tile[i].recv_data[PORT_NORTHWEST].msg //= DataType( 0, 0 ) - s.tile[i].send_data[PORT_NORTHEAST].rdy //= 0 - s.tile[i].recv_data[PORT_NORTHEAST].en //= 0 - s.tile[i].recv_data[PORT_NORTHEAST].msg //= DataType( 0, 0 ) - - # cols == 0 and rows > 0 - if i % width == 0 and i // width > 0: - s.tile[i].send_data[PORT_SOUTHWEST].rdy //= 0 - s.tile[i].recv_data[PORT_SOUTHWEST].en //= 0 - s.tile[i].recv_data[PORT_SOUTHWEST].msg //= DataType( 0, 0 ) - - # cols == 0 and rows > 0 - if i % width == 0 and i // width < height - 1: - s.tile[i].send_data[PORT_NORTHWEST].rdy //= 0 - s.tile[i].recv_data[PORT_NORTHWEST].en //= 0 - s.tile[i].recv_data[PORT_NORTHWEST].msg //= DataType( 0, 0 ) - - # cols == width - 1 and rows > 0 - if i % width == width - 1 and i // width > 0: - s.tile[i].send_data[PORT_SOUTHEAST].rdy //= 0 - s.tile[i].recv_data[PORT_SOUTHEAST].en //= 0 - s.tile[i].recv_data[PORT_SOUTHEAST].msg //= DataType( 0, 0 ) - - # cols == width - 1 and rows > 0 - if i % width == width - 1 and i // width < height - 1: - s.tile[i].send_data[PORT_NORTHEAST].rdy //= 0 - s.tile[i].recv_data[PORT_NORTHEAST].en //= 0 - s.tile[i].recv_data[PORT_NORTHEAST].msg //= DataType( 0, 0 ) - - # cols == 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 ) - - # cols == width - 1 - 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 ) - - # cols == 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: # cols != 0 - 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 diff --git a/cgra/CGRARTL.py b/cgra/CGRARTL.py deleted file mode 100644 index a7a0ec2..0000000 --- a/cgra/CGRARTL.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -========================================================================= -CGRARTL.py -========================================================================= -Author : Cheng Tan - Date : Dec 15, 2019 -""" - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.AdderRTL import AdderRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..mem.data.DataMemRTL import DataMemRTL -from ..mem.data.DataMemCL import DataMemCL -from ..noc.ChannelRTL import ChannelRTL -from ..noc.CrossbarRTL import CrossbarRTL -from ..tile.TileRTL import TileRTL - - -class CGRARTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, 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 ) ] - - # Components - if preload_const == None: - preload_const = [[DataType(0, 0)] for _ in range(width*height)] - s.tile = [ TileRTL( DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, - s.num_mesh_ports, - Fu = FunctionUnit, - FuList = FuList, - const_list = preload_const[i] ) - for i in range( s.num_tiles ) ] - s.data_mem = DataMemRTL( DataType, data_mem_size, height, height, preload_data ) - - # Connections - 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 diff --git a/cgra/CGRATemplateRTL.py b/cgra/CGRATemplateRTL.py deleted file mode 100644 index 30a279b..0000000 --- a/cgra/CGRATemplateRTL.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -========================================================================= -CGRARTL.py -========================================================================= -Author : Cheng Tan - Date : Dec 15, 2019 -""" - - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.AdderRTL import AdderRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..mem.data.DataMemRTL import DataMemRTL -from ..mem.data.DataMemCL import DataMemCL -from ..noc.ChannelRTL import ChannelRTL -from ..noc.CrossbarRTL import CrossbarRTL -from ..tile.TileRTL import TileRTL - - -class CGRATemplateRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - FunctionUnit, FuList, TileList, LinkList, dataSPM, - preload_data = None, preload_const = None ): - - # s.num_tiles = width * height - s.num_tiles = len( TileList ) - s.num_mesh_ports = 8 - 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 ) ] - - # Components - if preload_const == None: - # preload_const = [[DataType(0, 0)] for _ in range(width*height)] - preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] - s.tile = [ TileRTL( DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, - s.num_mesh_ports, FuList = FuList, - const_list = preload_const[i] ) - for i in range( s.num_tiles ) ] - s.data_mem = DataMemRTL( DataType, data_mem_size, dataSPM.getNumOfValidReadPorts(), dataSPM.getNumOfValidWritePorts(), preload_data ) - - for link in LinkList: - if link.isFromMem(): - memPort = link.getMemReadPort() - dstTileIndex = link.dstTile.getIndex( TileList ) - s.data_mem.recv_raddr[memPort] //= s.tile[dstTileIndex].to_mem_raddr - s.data_mem.send_rdata[memPort] //= s.tile[dstTileIndex].from_mem_rdata - - elif link.isToMem(): - memPort = link.getMemWritePort() - srcTileIndex = link.srcTile.getIndex( TileList ) - s.tile[srcTileIndex].to_mem_waddr //= s.data_mem.recv_waddr[memPort] - s.tile[srcTileIndex].to_mem_wdata //= s.data_mem.recv_wdata[memPort] - - else: - srcTileIndex = link.srcTile.getIndex( TileList ) - dstTileIndex = link.dstTile.getIndex( TileList ) - s.tile[srcTileIndex].send_data[link.srcPort] //= s.tile[dstTileIndex].recv_data[link.dstPort] - - # Connections - 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 - - for invalidInPort in TileList[i].getInvalidInPorts(): - s.tile[i].recv_data[invalidInPort].en //= 0 - s.tile[i].recv_data[invalidInPort].msg //= DataType( 0, 0 ) - - for invalidOutPort in TileList[i].getInvalidOutPorts(): - s.tile[i].send_data[invalidOutPort].rdy //= 0 - - if not TileList[i].hasFromMem(): - 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) - - if not TileList[i].hasToMem(): - 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 diff --git a/cgra/CGRAFL.py b/cgra/CgraFL.py similarity index 97% rename from cgra/CGRAFL.py rename to cgra/CgraFL.py index e32ab0c..16d21d0 100644 --- a/cgra/CGRAFL.py +++ b/cgra/CgraFL.py @@ -1,8 +1,8 @@ """ ========================================================================= -CGRAFL.py +CgraFL.py ========================================================================= -CGRAFL -- running DFG nodes one by one. +CgraFL -- running DFG nodes one by one. Author : Cheng Tan Date : Feb 13, 2020 @@ -15,7 +15,7 @@ #------------------------------------------------------------------------ # Assuming that the elements in FuDFG are already ordered well. #------------------------------------------------------------------------ -def CGRAFL( FuDFG, DataType, CtrlType, src_const ):#, data_spm ): +def CgraFL( FuDFG, DataType, CtrlType, src_const ):#, data_spm ): live_out_val = DataType( 0, 0 ) live_out_ctrl = DataType( 0, 0 ) diff --git a/cgra/test/CGRACL_FIR_demo_test.py b/cgra/test/CGRACL_FIR_demo_test.py deleted file mode 100644 index b9566d8..0000000 --- a/cgra/test/CGRACL_FIR_demo_test.py +++ /dev/null @@ -1,194 +0,0 @@ -""" -========================================================================== -CGRACL_fir_demo_test.py -========================================================================== -Test cases for CGRAs with CL data/config memory. - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - - -from pymtl3 import * -from ..CGRACL import CGRACL -from ..CGRAFL import CGRAFL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...lib.util.ctrl_helper import * -from ...lib.util.dfg_helper import * -from ...lib.messages import * -from ...lib.opt_type import * -import copy -import os - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, preload_data, preload_const ): - - s.num_tiles = width * height - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - s.dut = DUT( FunctionUnit, FuList, DataType, PredicateType, CtrlType, - width, height, ctrl_mem_size, data_mem_size, - len( src_opt[0] ), 100, src_opt, preload_data, - preload_const ) - s.DataType = DataType - - def line_trace( s ): - return s.dut.line_trace() - - def output_target_value( s ): - res = s.DataType(0, 1) - res.payload = s.dut.tile[9].element.send_out[0].msg.payload - return copy.deepcopy(res.payload) - - -def run_sim( test_harness, max_cycles=17 ): - test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) - - # Run simulation - ncycles = 0 - print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) - while ncycles < max_cycles: - test_harness.sim_tick() - ncycles += 1 - print( "{}:{}".format( ncycles, test_harness.line_trace() )) - - target_value = test_harness.output_target_value() - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - - print( '=' * 70 ) - print( "----------------- CL test ------------------" ) - print("CGRA CL model final result:", target_value) - print("=================================================================") - print("···························· split ······························") - print("=================================================================") - return target_value - -def run_CGRAFL(): - target_json = "dfg_fir.json" - script_dir = os.path.dirname(__file__) - file_path = os.path.join( script_dir, target_json ) - DataType = mk_data( 16, 1 ) - CtrlType = mk_ctrl() - const_data = [ DataType( 0, 1 ), - DataType( 1, 1 ), - DataType( 2, 1 ), - DataType( 3, 1 ), - DataType( 4, 1 ), - DataType( 5, 1 ) ] - data_spm = [ 5 for _ in range(100) ] - fu_dfg = DFG( file_path, const_data, data_spm ) - - print( "----------------- FL test ------------------" ) - # FL golden reference - return CGRAFL( fu_dfg, DataType, CtrlType, const_data )#, data_spm ) - -def test_CGRA_4x4_fir(): - target_json = "config_fir.json" - script_dir = os.path.dirname(__file__) - file_path = os.path.join( script_dir, target_json ) - - II = 4 - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 8 - width = 4 - height = 4 - num_tiles = width * height - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - ctrl_mem_size = II - data_mem_size = 100 - num_fu_in = 4 - DUT = CGRACL - FunctionUnit = FlexibleFuRTL - FuList = [ AdderRTL, PhiRTL, MemUnitRTL, CompRTL, MulRTL, BranchRTL ] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( 0 ) for x in range( num_fu_in ) ] - - cgra_ctrl = CGRACtrl( file_path, CtrlType, RouteType, width, height, - num_fu_in, num_xbar_inports, num_xbar_outports, - II ) - src_opt = cgra_ctrl.get_ctrl() - - # print( src_opt ) - - preload_data = [ DataType( 5, 1 ) ] * data_mem_size - preload_const = [] - for _ in range( num_tiles ): - preload_const.append([]) - preload_const[0].append( DataType( 0, 1) ) - preload_const[1].append( DataType( 0, 1) ) - preload_const[2].append( DataType( 0, 1) ) - preload_const[3].append( DataType( 0, 1) ) - preload_const[4].append( DataType( 0, 1) ) - preload_const[5].append( DataType( 10, 1) ) - preload_const[6].append( DataType( 0, 1) ) - preload_const[6].append( DataType( 1, 1) ) - preload_const[7].append( DataType( 0, 1) ) - preload_const[8].append( DataType( 0, 1) ) - preload_const[9].append( DataType( 0, 1) ) - preload_const[10].append( DataType( 0, 1) ) - preload_const[10].append( DataType( 3, 1) ) - preload_const[11].append( DataType( 0, 1) ) - preload_const[12].append( DataType( 0, 1) ) - preload_const[13].append( DataType( 0, 1) ) - preload_const[14].append( DataType( 0, 1) ) - preload_const[15].append( DataType( 0, 1) ) -# print(preload_const) - - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, preload_data, preload_const ) - - target = run_sim( th ) - - reference = run_CGRAFL()[0] - - assert(target == reference) - -#def test_CGRA(): -# -# # Attribute of CGRA -# width = 4 -# height = 4 -# DUT = CGRA -# FuList = [ ALU ] -# DataType = mk_data( 16 ) -# CtrlType = mk_ctrl() -# cgra_ctrl = CGRACtrl( "control_signal.json", CtrlType ) -# -# # FL golden reference -# fu_dfg = DFG( "dfg.json" ) -# data_mem = acc_fl( fu_dfg, DataType, CtrlType ) -# -# th = TestHarness( DUT, FuList, cgra_ctrl, DataType, CtrlType, -# width, height, data_mem ) -# run_sim( th ) - diff --git a/cgra/test/CGRACL_test.py b/cgra/test/CGRACL_test.py deleted file mode 100644 index 2511f97..0000000 --- a/cgra/test/CGRACL_test.py +++ /dev/null @@ -1,189 +0,0 @@ -""" -========================================================================== -CGRACL_test.py -========================================================================== -Test cases for CGRAs with CL data/config memory. - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - - -from pymtl3 import * -from ..CGRACL import CGRACL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...lib.opt_type import * -from ...lib.messages import * -from ...lib.util.ctrl_helper import * -import os - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, preload_data, preload_const ): - - s.num_tiles = width * height - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - max_sim_steps = 100 - - s.dut = DUT( FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - len( src_opt[0] ), max_sim_steps, src_opt, preload_data, - preload_const ) - s.DataType = DataType - - def line_trace( s ): - return s.dut.line_trace() - - def output_target_value( s ): - res = s.DataType(0, 1) - res.payload = s.dut.tile[9].element.send_out[0].msg.payload - return res - -def run_sim( test_harness, max_cycles=18 ): - test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) - test_harness.sim_reset() - - # Run simulation - ncycles = 0 - print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) - while ncycles < max_cycles: - test_harness.sim_tick() - ncycles += 1 - print( "{}:{}".format( ncycles, test_harness.line_trace() )) - - # Check timeout -# assert ncycles < max_cycles - - target_value = test_harness.output_target_value() - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - - print( '=' * 70 ) - print("final result:", target_value) - -#def test_cgra_2x2_universal(): -# -# num_tile_inports = 4 -# num_tile_outports = 4 -# num_xbar_inports = 6 -# num_xbar_outports = 8 -# ctrl_mem_size = 8 -# width = 2 -# height = 2 -# RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) -# AddrType = mk_bits( clog2( ctrl_mem_size ) ) -# num_tiles = width * height -# ctrl_mem_size = 8 -# data_mem_size = 10 -# num_fu_in = 4 -# DUT = CGRACL -# FunctionUnit = FlexibleFuRTL -# FuList = [AdderRTL, MemUnitRTL] -# DataType = mk_data( 16, 1 ) -# CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) -# FuInType = mk_bits( clog2( num_fu_in + 1 ) ) -# pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] -# src_opt = [[CtrlType( OPT_ADD_CONST, b1( 0 ), pickRegister, [ -# RouteType(3), RouteType(2), RouteType(1), RouteType(0), -# RouteType(4), RouteType(4), RouteType(4), RouteType(4)], [b1(0)]*num_xbar_inports ), -# CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ -# RouteType(3),RouteType(2), RouteType(1), RouteType(0), -# RouteType(4), RouteType(4), RouteType(4), RouteType(4)], [b1(0)]*num_xbar_inports ), -# CtrlType( OPT_STR, b1( 0 ), pickRegister, [ -# RouteType(3),RouteType(2), RouteType(1), RouteType(0), -# RouteType(4), RouteType(4), RouteType(4), RouteType(4)], [b1(0)]*num_xbar_inports ), -# CtrlType( OPT_SUB, b1( 0 ), pickRegister, [ -# RouteType(3),RouteType(2), RouteType(1), RouteType(0), -# RouteType(4), RouteType(4), RouteType(4), RouteType(4)], [b1(0)]*num_xbar_inports ) ] -# for _ in range( num_tiles ) ] -# print("see: ", src_opt) -# preload_data = [DataType(7, 1), DataType(7, 1), DataType(7, 1), DataType(7, 1)] -# preload_const = [[DataType(2, 1)], [DataType(1, 1)], -# [DataType(4, 1)], [DataType(3, 1)]] -# th = TestHarness( DUT, FunctionUnit, FuList, DataType, CtrlType, -# width, height, ctrl_mem_size, data_mem_size, -# src_opt, preload_data, preload_const ) -# run_sim( th ) - -def test_cgra_4x4_universal_fir(): - target_json = "config_fir.json" - script_dir = os.path.dirname(__file__) - file_path = os.path.join( script_dir, target_json ) - - II = 4 - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 8 - width = 4 - height = 4 - num_tiles = width * height - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - ctrl_mem_size = II - data_mem_size = 100 - num_fu_in = 4 - DUT = CGRACL - FunctionUnit = FlexibleFuRTL - FuList = [ AdderRTL, PhiRTL, MemUnitRTL, CompRTL, MulRTL, BranchRTL ] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( 0 ) for x in range( num_fu_in ) ] - - cgra_ctrl = CGRACtrl( file_path, CtrlType, RouteType, width, height, - num_fu_in, num_xbar_inports, num_xbar_outports, - II ) - src_opt = cgra_ctrl.get_ctrl() - -# print(src_opt) - - preload_data = [ DataType( 5, 1 ) ] * data_mem_size - preload_const = [] - for _ in range( num_tiles ): - preload_const.append([]) - preload_const[0].append( DataType( 0, 1) ) - preload_const[1].append( DataType( 0, 1) ) - preload_const[2].append( DataType( 0, 1) ) - preload_const[3].append( DataType( 0, 1) ) - preload_const[4].append( DataType( 0, 1) ) - preload_const[5].append( DataType( 10, 1) ) - preload_const[6].append( DataType( 0, 1) ) - preload_const[6].append( DataType( 1, 1) ) - preload_const[7].append( DataType( 0, 1) ) - preload_const[8].append( DataType( 0, 1) ) - preload_const[9].append( DataType( 0, 1) ) - preload_const[10].append( DataType( 0, 1) ) - preload_const[10].append( DataType( 3, 1) ) - preload_const[11].append( DataType( 0, 1) ) - preload_const[12].append( DataType( 0, 1) ) - preload_const[13].append( DataType( 0, 1) ) - preload_const[14].append( DataType( 0, 1) ) - preload_const[15].append( DataType( 0, 1) ) -# print(preload_const) - - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, preload_data, preload_const ) - run_sim( th ) - diff --git a/cgra/test/CGRAKingMeshRTL_test.py b/cgra/test/CGRAKingMeshRTL_test.py deleted file mode 100644 index 7553b54..0000000 --- a/cgra/test/CGRAKingMeshRTL_test.py +++ /dev/null @@ -1,181 +0,0 @@ -""" -========================================================================== -CGRAKingMeshRTL_test.py -========================================================================== -Test cases for CGRAs with different configurations. - -Author : Cheng Tan - Date : Dec 15, 2019 -""" - - -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 ..CGRAKingMeshRTL import CGRAKingMeshRTL -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.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - - 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 = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, 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 ) - -def test_hetero_2x2( cmdline_opts ): - num_tile_inports = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr ) - th.set_param("top.dut.tile[1].construct", FuList=[ShifterRTL]) - th.elaborate() - th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - 'ALWCOMBORDER'] ) - #th.set_param("top.dut.tile[1].construct", FuList=[MemUnitRTL,ShifterRTL]) - th = config_model_with_cmdline_opts( th, cmdline_opts, duts=['dut'] ) - run_sim( th ) - diff --git a/cgra/test/CGRARTL_test.py b/cgra/test/CGRARTL_test.py deleted file mode 100644 index 5c34b4a..0000000 --- a/cgra/test/CGRARTL_test.py +++ /dev/null @@ -1,169 +0,0 @@ -""" -========================================================================== -CGRARTL_test.py -========================================================================== -Test cases for CGRAs with different configurations. - -Author : Cheng Tan - Date : Dec 15, 2019 -""" - - -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 ..CGRARTL import CGRARTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.ShifterRTL import ShifterRTL - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - - 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_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRARTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, 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 ) - -def test_hetero_2x2( cmdline_opts ): - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 6 - width = 2 - height = 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRARTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr ) - th.set_param("top.dut.tile[1].construct", FuList=[ShifterRTL]) - 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'] ) - #th.set_param("top.dut.tile[1].construct", FuList=[MemUnitRTL,ShifterRTL]) - run_sim( th ) - diff --git a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py b/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py index 4ea112e..4e6ae05 100644 --- a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py +++ b/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py @@ -37,6 +37,7 @@ #------------------------------------------------------------------------- class TestHarness(Component): + def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, ControllerIdType, controller_id, width, height, diff --git a/cgra/test/CGRAFL_test.py b/cgra/test/CgraFL_test.py similarity index 89% rename from cgra/test/CGRAFL_test.py rename to cgra/test/CgraFL_test.py index 44a25e6..4a209d1 100644 --- a/cgra/test/CGRAFL_test.py +++ b/cgra/test/CgraFL_test.py @@ -1,6 +1,6 @@ """ ========================================================================== -CGRAFL_test.py +CgraFL_test.py ========================================================================== Test cases for HLS in terms of accelerator design. @@ -9,14 +9,12 @@ """ - from pymtl3 import * from ...lib.messages import * -from ..CGRAFL import CGRAFL +from ..CgraFL import CgraFL from ...lib.util.dfg_helper import * import os - def test_fl(): target_json = "dfg_fir.json" script_dir = os.path.dirname(__file__) @@ -34,6 +32,6 @@ def test_fl(): print( "----------------- FL test ------------------" ) # FL golden reference - CGRAFL( fu_dfg, DataType, CtrlType, const_data )#, data_spm ) + CgraFL( fu_dfg, DataType, CtrlType, const_data )#, data_spm ) print() diff --git a/cgra/test/CGRARTL_FIR_demo_test.py b/cgra/test/CgraRTL_fir_demo_test.py.disabled similarity index 100% rename from cgra/test/CGRARTL_FIR_demo_test.py rename to cgra/test/CgraRTL_fir_demo_test.py.disabled diff --git a/cgra/translate/CGRARTL_hetero_test.py b/cgra/translate/CGRARTL_hetero_test.py deleted file mode 100644 index 59c5f96..0000000 --- a/cgra/translate/CGRARTL_hetero_test.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -========================================================================== -CGRARTL_hetero_test.py -========================================================================== -Test cases for heterogeneous CGRAs. - -Author : Cheng Tan, Yanghui Ou - Date : July 12, 2023 -""" - -from pymtl3 import * -from pymtl3.passes.backends.verilog import (VerilogTranslationPass, - VerilogVerilatorImportPass) -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) - -from ...lib.opt_type import * -from ...lib.messages import * -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ..CGRARTL import CGRARTL - -num_tile_inports = 4 -num_tile_outports = 4 -num_xbar_inports = 6 -num_xbar_outports = 8 -ctrl_mem_size = 6 -width = 2 -height = 2 -RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) -AddrType = mk_bits( clog2( ctrl_mem_size ) ) -num_tiles = width * height -data_mem_size = 8 -DUT = CGRARTL -num_fu_in = 4 -FunctionUnit = FlexibleFuRTL -FuList = [MemUnitRTL, AdderRTL] -DataType = mk_data( 16, 1 ) -PredicateType = mk_predicate( 1, 1 ) -CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) -FuInType = mk_bits( clog2( num_fu_in + 1 ) ) -pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] -src_opt = [ [ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - for _ in range( num_tiles ) ] - -def test_elaborate(): - dut = CGRARTL( DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - dut.apply( DefaultPassGroup(linetrace=True) ) - dut.sim_reset() - dut.sim_tick() - dut.sim_tick() - -# TODO: fix import by either suppressing warnings or address them -def test_translate( cmdline_opts ): - dut = CGRARTL( DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'CGRAHeteroRTL' ) - dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - 'ALWCOMBORDER'] ) - config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) - # test_harness.dut.config_verilog_import = VerilatorImportConfigs(vl_Wno_list = ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', 'ALWCOMBORDER']) - diff --git a/cgra/translate/CGRARTL_test.py b/cgra/translate/CGRARTL_test.py deleted file mode 100644 index 0723450..0000000 --- a/cgra/translate/CGRARTL_test.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -========================================================================== -CGRARTL_test.py -========================================================================== -Translation for CGRAs with different configurations. - -Author : Cheng Tan, Yanghui Ou - Date : July 12, 2023 -""" - -from pymtl3 import * -from pymtl3.passes.backends.verilog import VerilogTranslationPass -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) - -from ...lib.opt_type import * -from ...lib.messages import * -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ..CGRARTL import CGRARTL - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -num_tile_inports = 4 -num_tile_outports = 4 -num_xbar_inports = 6 -num_xbar_outports = 8 -ctrl_mem_size = 6 -width = 4 -height = 4 -RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) -AddrType = mk_bits( clog2( ctrl_mem_size ) ) -num_tiles = width * height -data_mem_size = 2 -num_fu_in = 4 -DUT = CGRARTL -FunctionUnit = FlexibleFuRTL -FuList = [ AdderRTL, MemUnitRTL ]# SeqMulAdderRTL, AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL ] -# Parameterizes channel bandwidth as around 2-byte per cycle. -payload_nbits = 16 # 32 -predicate_nbits = 1 -DataType = mk_data( payload_nbits, predicate_nbits ) -PredicateType = mk_predicate( 1, 1 ) -# FuList = [ SeqMulAdderRTL, AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL ] -# DataType = mk_data( 16, 1 ) -CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) -FuInType = mk_bits( clog2( num_fu_in + 1 ) ) -pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] -src_opt = [ [ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - for _ in range( num_tiles ) ] - -def test_elaborate(): - dut = CGRARTL( DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - dut.apply( DefaultPassGroup(linetrace=True) ) - dut.sim_reset() - dut.sim_tick() - dut.sim_tick() - -# TODO: fix import by either suppressing warnings or address them -def test_translate( cmdline_opts ): - dut = CGRARTL( DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList ) - dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'CGRARTL' ) - config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) - diff --git a/cgra/translate/CGRATemplateRTL_test.py b/cgra/translate/CGRATemplateRTL_test.py deleted file mode 100644 index be25346..0000000 --- a/cgra/translate/CGRATemplateRTL_test.py +++ /dev/null @@ -1,374 +0,0 @@ -""" -========================================================================== -CGRATemplateRTL_test.py -========================================================================== -Translation for parameterizable CGRA based on the template. - -Author : Cheng Tan - Date : Dec 23, 2022 - -""" - -from pymtl3 import * -from pymtl3.passes.backends.verilog import (VerilogTranslationPass, - VerilogVerilatorImportPass) -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..CGRATemplateRTL import CGRATemplateRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...lib.util.common import * -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.RetRTL import RetRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.single.ShifterRTL import ShifterRTL - - -fuType2RTL = {} -fuType2RTL["Phi" ] = PhiRTL -fuType2RTL["Add" ] = AdderRTL -fuType2RTL["Shift"] = ShifterRTL -fuType2RTL["Ld" ] = MemUnitRTL -fuType2RTL["St" ] = MemUnitRTL -fuType2RTL["Sel" ] = SelRTL -fuType2RTL["Cmp" ] = CompRTL -fuType2RTL["MAC" ] = SeqMulAdderRTL -fuType2RTL["Ret" ] = RetRTL -fuType2RTL["Mul" ] = MulRTL -fuType2RTL["Logic"] = LogicRTL -fuType2RTL["Br" ] = BranchRTL - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, tileList, linkList, dataSPM ): - - s.num_tiles = len(tileList) - 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, FuList, tileList, linkList, dataSPM ) - - 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() - -class Tile: - def __init__( s, dimX, dimY ): - s.disabled = False - s.dimX = dimX - s.dimY = dimY - s.toMem = False - s.fromMem = False - s.invalidOutPorts = set() - s.invalidInPorts = set() - for i in range( PORT_DIRECTION_COUNTS ): - s.invalidOutPorts.add(i) - s.invalidInPorts.add(i) - - def getInvalidInPorts(s): - return s.invalidInPorts - - def getInvalidOutPorts(s): - return s.invalidOutPorts - - def hasToMem(s): - return s.toMem - - def hasFromMem(s): - return s.fromMem - - def getIndex( s, tileList ): - if s.disabled: - return -1 - index = 0 - for tile in tileList: - if tile.dimY < s.dimY and not tile.disabled: - index += 1 - elif tile.dimY == s.dimY and tile.dimX < s.dimX and not tile.disabled: - index += 1 - return index - -class DataSPM: - def __init__( s, numOfReadPorts, numOfWritePorts ): - s.numOfReadPorts = numOfReadPorts - s.numOfWritePorts = numOfWritePorts - - def getNumOfValidReadPorts( s ): - return s.numOfReadPorts - - def getNumOfValidWritePorts( s ): - return s.numOfWritePorts - -class Link: - def __init__( s, srcTile, dstTile, srcPort, dstPort ): - s.srcTile = srcTile - s.dstTile = dstTile - s.srcPort = srcPort - s.dstPort = dstPort - s.disabled = False - s.toMem = False - s.fromMem = False - s.memPort = -1 - - def getMemReadPort(s): - return s.memPort - - def getMemWritePort(s): - return s.memPort - - def isToMem(s): - return s.toMem - - def isFromMem(s): - return s.fromMem - - def validatePorts( s ): - if not s.toMem and not s.fromMem: - s.srcTile.invalidOutPorts.remove(s.srcPort) - s.dstTile.invalidInPorts.remove(s.dstPort) - if s.toMem: - s.srcTile.toMem = True - if s.fromMem: - s.dstTile.fromMem = True - - -import platform -import pytest - -# @pytest.mark.skipif('Linux' not in platform.platform(), -# reason="requires linux (gcc)") -# def test_cgra_universal(t_width=2, t_height=2, t_ctrl_mem_size=8, t_data_mem_size=8): -def test_cgra_universal( cmdline_opts, paramCGRA = None): - num_tile_inports = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = paramCGRA.configMemSize if paramCGRA != None else 8 - width = paramCGRA.rows if paramCGRA != None else 2 - height = paramCGRA.columns if paramCGRA != None else 2 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - # data_mem_size = paramCGRA != None ? paramCGRA.dataMemSize : 8 - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRATemplateRTL - FunctionUnit = FlexibleFuRTL - # FuList = [ SeqMulAdderRTL, MemUnitRTL ]#AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL ] - FuList = [ PhiRTL, AdderRTL, ShifterRTL, MemUnitRTL, SelRTL, CompRTL, SeqMulAdderRTL, RetRTL, MulRTL, LogicRTL, BranchRTL ] - DataType = mk_data( 32, 1 ) - PredicateType = mk_predicate( 1, 1 ) -# DataType = mk_data( 16, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [ [ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - for _ in range( num_tiles ) ] - ctrl_waddr = [ [ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ), AddrType( 3 ), - AddrType( 4 ), AddrType( 5 ) ] for _ in range( num_tiles ) ] - - dataSPM = None - tiles = [] - links = None - if paramCGRA != None: - tiles = paramCGRA.getValidTiles() - links = paramCGRA.getValidLinks() - dataSPM = paramCGRA.dataSPM - else: - dataSPM = DataSPM(2, 2) - for r in range( 2 ): - tiles.append([]) - for c in range( 2 ): - tiles[r].append(Tile(c, r)) - - links = [ Link(None, None, 0, 0) for _ in range(16) ] - - links[0].srcTile = None - links[0].dstTile = tiles[0][0] - links[0].srcPort = 0 - links[0].dstPort = PORT_WEST - links[0].fromMem = True - links[0].memPort = 0 - links[0].validatePorts() - - links[1].srcTile = tiles[0][0] - links[1].dstTile = None - links[1].srcPort = PORT_WEST - links[1].dstPort = 0 - links[1].toMem = True - links[1].memPort = 0 - links[1].validatePorts() - - links[2].srcTile = None - links[2].dstTile = tiles[1][0] - links[2].srcPort = 1 - links[2].dstPort = PORT_WEST - links[2].fromMem = True - links[2].memPort = 1 - links[2].validatePorts() - - links[3].srcTile = tiles[1][0] - links[3].dstTile = None - links[3].srcPort = PORT_WEST - links[3].dstPort = 1 - links[3].toMem = True - links[3].memPort = 1 - links[3].validatePorts() - - links[4].srcTile = tiles[0][0] - links[4].dstTile = tiles[0][1] - links[4].srcPort = PORT_EAST - links[4].dstPort = PORT_WEST - links[4].validatePorts() - - links[5].srcTile = tiles[0][1] - links[5].dstTile = tiles[0][0] - links[5].srcPort = PORT_WEST - links[5].dstPort = PORT_EAST - links[5].validatePorts() - - links[6].srcTile = tiles[1][0] - links[6].dstTile = tiles[1][1] - links[6].srcPort = PORT_EAST - links[6].dstPort = PORT_WEST - links[6].validatePorts() - - links[7].srcTile = tiles[1][1] - links[7].dstTile = tiles[1][0] - links[7].srcPort = PORT_WEST - links[7].dstPort = PORT_EAST - links[7].validatePorts() - - links[8].srcTile = tiles[0][0] - links[8].dstTile = tiles[1][0] - links[8].srcPort = PORT_NORTH - links[8].dstPort = PORT_SOUTH - links[8].validatePorts() - - links[9].srcTile = tiles[1][0] - links[9].dstTile = tiles[0][0] - links[9].srcPort = PORT_SOUTH - links[9].dstPort = PORT_NORTH - links[9].validatePorts() - - links[10].srcTile = tiles[0][1] - links[10].dstTile = tiles[1][1] - links[10].srcPort = PORT_NORTH - links[10].dstPort = PORT_SOUTH - links[10].validatePorts() - - links[11].srcTile = tiles[1][1] - links[11].dstTile = tiles[0][1] - links[11].srcPort = PORT_SOUTH - links[11].dstPort = PORT_NORTH - links[11].validatePorts() - - links[12].srcTile = tiles[0][0] - links[12].dstTile = tiles[1][1] - links[12].srcPort = PORT_NORTHEAST - links[12].dstPort = PORT_SOUTHWEST - links[12].validatePorts() - - links[13].srcTile = tiles[1][1] - links[13].dstTile = tiles[0][0] - links[13].srcPort = PORT_SOUTHWEST - links[13].dstPort = PORT_NORTHEAST - links[13].validatePorts() - - links[14].srcTile = tiles[0][1] - links[14].dstTile = tiles[1][0] - links[14].srcPort = PORT_NORTHWEST - links[14].dstPort = PORT_SOUTHEAST - links[14].validatePorts() - - links[15].srcTile = tiles[1][0] - links[15].dstTile = tiles[0][1] - links[15].srcPort = PORT_SOUTHEAST - links[15].dstPort = PORT_NORTHWEST - links[15].validatePorts() - - def handleReshape( t_tiles ): - tiles = [] - for row in t_tiles: - for t in row: - tiles.append(t) - return tiles - - tiles = handleReshape(tiles) - - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, tiles, links, dataSPM ) - th.elaborate() - th.dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'CGRATemplateRTL' ) - th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - 'ALWCOMBORDER'] ) - th = config_model_with_cmdline_opts( th, cmdline_opts, duts=['dut'] ) - - if paramCGRA != None: - for tile in tiles: - if not tile.isDefaultFus(): - targetFuList = [] - for fuType in tile.getAllValidFuTypes(): - targetFuList.append(fuType2RTL[fuType]) - targetTile = "top.dut.tile[" + str(tile.getIndex(tiles)) + "].construct" - th.set_param(targetTile, FuList=targetFuList) - - run_sim( th ) diff --git a/cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py b/cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py deleted file mode 100644 index 9757073..0000000 --- a/cgra/translate/CgraCrossbarDataMemRingCtrlMemRTL_test.py +++ /dev/null @@ -1,219 +0,0 @@ -""" -========================================================================== -CgraCrossbarDataMemRingCtrlMemRTL_test.py -========================================================================== -Test cases for CGRA with crossbar-based data memory and ring-based control -memory of each tile. - -Author : Cheng Tan - Date : Dec 22, 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 ..CgraCrossbarDataMemRingCtrlMemRTL import CgraCrossbarDataMemRingCtrlMemRTL -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.cmd_type import * -from ...lib.opt_type import * -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness(Component): - def construct(s, DUT, FunctionUnit, FuList, DataType, - PredicateType, CtrlPktType, CtrlSignalType, NocPktType, - CmdType, ControllerIdType, controller_id, width, height, - ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, - src_ctrl_pkt, ctrl_steps, controller2addr_map): - - s.num_tiles = width * height - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - DataAddrType = mk_bits(clog2(data_mem_size_global)) - s.src_ctrl_pkt = ValRdyTestSrcRTL(CtrlPktType, src_ctrl_pkt) - s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, - NocPktType, CmdType, ControllerIdType, controller_id, - width, height, ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, - ctrl_steps, ctrl_steps, FunctionUnit, FuList, - controller2addr_map) - - # Connections - s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt - - s.dut.send_to_noc.rdy //= 0 - s.dut.recv_from_noc.val //= 0 - s.dut.recv_from_noc.msg //= NocPktType(0, 0, 0, 0, 0, 0) - - for tile_col in range(width): - s.dut.send_data_on_boundary_north[tile_col].rdy //= 0 - s.dut.recv_data_on_boundary_north[tile_col].en //= 0 - s.dut.recv_data_on_boundary_north[tile_col].msg //= DataType() - - s.dut.send_data_on_boundary_south[tile_col].rdy //= 0 - s.dut.recv_data_on_boundary_south[tile_col].en //= 0 - s.dut.recv_data_on_boundary_south[tile_col].msg //= DataType() - - for tile_row in range(height): - s.dut.send_data_on_boundary_west[tile_row].rdy //= 0 - s.dut.recv_data_on_boundary_west[tile_row].en //= 0 - s.dut.recv_data_on_boundary_west[tile_row].msg //= DataType() - - s.dut.send_data_on_boundary_east[tile_row].rdy //= 0 - s.dut.recv_data_on_boundary_east[tile_row].en //= 0 - s.dut.recv_data_on_boundary_east[tile_row].msg //= DataType() - - def done(s): - return s.src_ctrl_pkt.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_global = 512 - data_mem_size_per_bank = 32 - num_banks_per_cgra = 2 - width = 2 - height = 2 - num_terminals = 4 - num_ctrl_actions = 6 - num_ctrl_operations = 64 - TileInType = mk_bits(clog2(num_tile_inports + 1)) - FuInType = mk_bits(clog2(num_fu_inports + 1)) - FuOutType = mk_bits(clog2(num_fu_outports + 1)) - addr_nbits = clog2(data_mem_size_global) - AddrType = mk_bits(addr_nbits) - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - num_tiles = width * height - DUT = CgraCrossbarDataMemRingCtrlMemRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data(32, 1) - PredicateType = mk_predicate(1, 1) - - CmdType = mk_bits(4) - ControllerIdType = mk_bits(clog2(num_terminals)) - controller_id = 1 - controller2addr_map = { - 0: [0, 3], - 1: [4, 7], - 2: [8, 11], - 3: [12, 15], - } - - CtrlPktType = \ - mk_ring_across_tiles_pkt(width * height, - num_ctrl_actions, - ctrl_mem_size, - num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - - CtrlSignalType = \ - mk_separate_ctrl(num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - - NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, - addr_nbits = addr_nbits, - data_nbits = 32, - predicate_nbits = 1) - pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)] - src_opt_per_tile = [[ - # src dst vc_id opq cmd_type addr operation predicate - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, 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)]), - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 2, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 3, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 4, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 5, 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)]), - - # This last one is for launching kernel. - CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, 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 i in range(num_tiles)] - - src_ctrl_pkt = [] - for opt_per_tile in src_opt_per_tile: - src_ctrl_pkt.extend(opt_per_tile) - - th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlPktType, CtrlSignalType, NocPktType, CmdType, - ControllerIdType, controller_id, width, height, - ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, - src_ctrl_pkt, ctrl_mem_size, controller2addr_map) - 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) - diff --git a/cgra/translate/CgraTemplateRTL_test.py b/cgra/translate/CgraTemplateRTL_test.py deleted file mode 100644 index c18d3c7..0000000 --- a/cgra/translate/CgraTemplateRTL_test.py +++ /dev/null @@ -1,398 +0,0 @@ -""" -========================================================================== -CgraTemplateRTL_test.py -========================================================================== -Translation for parameterizable CGRA based on the template. - -Author : Cheng Tan - Date : Dec 23, 2022 - -""" - -from pymtl3 import * -from pymtl3.passes.backends.verilog import (VerilogTranslationPass, - VerilogVerilatorImportPass) -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..CgraTemplateRTL import CgraTemplateRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL -from ...lib.messages import * -from ...lib.cmd_type import * -from ...lib.opt_type import * -from ...lib.util.common import * -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.RetRTL import RetRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.single.ShifterRTL import ShifterRTL - -fuType2RTL = {} -fuType2RTL["Phi" ] = PhiRTL -fuType2RTL["Add" ] = AdderRTL -fuType2RTL["Shift"] = ShifterRTL -fuType2RTL["Ld" ] = MemUnitRTL -fuType2RTL["St" ] = MemUnitRTL -fuType2RTL["Sel" ] = SelRTL -fuType2RTL["Cmp" ] = CompRTL -fuType2RTL["MAC" ] = SeqMulAdderRTL -fuType2RTL["Ret" ] = RetRTL -fuType2RTL["Mul" ] = MulRTL -fuType2RTL["Logic"] = LogicRTL -fuType2RTL["Br" ] = BranchRTL - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness(Component): - - def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlPktType, CtrlSignalType, NocPktType, CmdType, - ControllerIdType, controller_id, ctrl_mem_size, - data_mem_size_global, data_mem_size_per_bank, - num_banks_per_cgra, src_ctrl_pkt, ctrl_steps, TileList, - LinkList, dataSPM, controller2addr_map): - - s.num_tiles = len(TileList) - s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) - - s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, - NocPktType, CmdType, ControllerIdType, controller_id, - ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, - ctrl_steps, ctrl_steps, FunctionUnit, FuList, - TileList, LinkList, dataSPM, controller2addr_map) - - # Connections - s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt - - s.dut.send_to_noc.rdy //= 0 - s.dut.recv_from_noc.val //= 0 - s.dut.recv_from_noc.msg //= NocPktType(0, 0, 0, 0, 0, 0) - - def done(s): - return s.src_ctrl_pkt.done() - - def line_trace(s): - return s.dut.line_trace() - -class Tile: - def __init__(s, dimX, dimY): - s.disabled = False - s.dimX = dimX - s.dimY = dimY - s.toMem = False - s.fromMem = False - s.invalidOutPorts = set() - s.invalidInPorts = set() - for i in range(PORT_DIRECTION_COUNTS): - s.invalidOutPorts.add(i) - s.invalidInPorts.add(i) - - def getInvalidInPorts(s): - return s.invalidInPorts - - def getInvalidOutPorts(s): - return s.invalidOutPorts - - def hasToMem(s): - return s.toMem - - def hasFromMem(s): - return s.fromMem - - def getIndex(s, TileList): - if s.disabled: - return -1 - index = 0 - for tile in TileList: - if tile.dimY < s.dimY and not tile.disabled: - index += 1 - elif tile.dimY == s.dimY and tile.dimX < s.dimX and not tile.disabled: - index += 1 - return index - -class DataSPM: - def __init__(s, numOfReadPorts, numOfWritePorts): - s.numOfReadPorts = numOfReadPorts - s.numOfWritePorts = numOfWritePorts - - def getNumOfValidReadPorts(s): - return s.numOfReadPorts - - def getNumOfValidWritePorts(s): - return s.numOfWritePorts - -class Link: - def __init__(s, srcTile, dstTile, srcPort, dstPort): - s.srcTile = srcTile - s.dstTile = dstTile - s.srcPort = srcPort - s.dstPort = dstPort - s.disabled = False - s.toMem = False - s.fromMem = False - s.memPort = -1 - - def getMemReadPort(s): - return s.memPort - - def getMemWritePort(s): - return s.memPort - - def isToMem(s): - return s.toMem - - def isFromMem(s): - return s.fromMem - - def validatePorts(s): - if not s.toMem and not s.fromMem: - s.srcTile.invalidOutPorts.remove(s.srcPort) - s.dstTile.invalidInPorts.remove(s.dstPort) - if s.toMem: - s.srcTile.toMem = True - if s.fromMem: - s.dstTile.fromMem = True - - -import platform -import pytest - -def test_cgra_universal(cmdline_opts, paramCGRA = None): - num_tile_inports = 8 - num_tile_outports = 8 - num_fu_inports = 4 - num_fu_outports = 2 - num_routing_outports = num_tile_outports + num_fu_inports - ctrl_mem_size = paramCGRA.configMemSize if paramCGRA != None else 6 - width = paramCGRA.rows if paramCGRA != None else 2 - height = paramCGRA.columns if paramCGRA != None else 2 - data_mem_size_global = 512 - data_mem_size_per_bank = 32 - num_banks_per_cgra = 2 - num_terminals = 4 - num_ctrl_actions = 6 - num_ctrl_operations = 64 - TileInType = mk_bits(clog2(num_tile_inports + 1)) - FuInType = mk_bits(clog2(num_fu_inports + 1)) - FuOutType = mk_bits(clog2(num_fu_outports + 1)) - addr_nbits = clog2(data_mem_size_global) - AddrType = mk_bits(addr_nbits) - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - num_tiles = width * height - DUT = CgraTemplateRTL - FunctionUnit = FlexibleFuRTL - # FuList = [MemUnitRTL, AdderRTL] - FuList = [PhiRTL, AdderRTL, ShifterRTL, MemUnitRTL, SelRTL, CompRTL, SeqMulAdderRTL, RetRTL, MulRTL, LogicRTL, BranchRTL] - DataType = mk_data(32, 1) - PredicateType = mk_predicate(1, 1) - - CmdType = mk_bits(4) - ControllerIdType = mk_bits(clog2(num_terminals)) - controller_id = 1 - controller2addr_map = { - 0: [0, 3], - 1: [4, 7], - 2: [8, 11], - 3: [12, 15], - } - - CtrlPktType = \ - mk_ring_across_tiles_pkt(width * height, - num_ctrl_actions, - ctrl_mem_size, - num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - CtrlSignalType = \ - mk_separate_ctrl(num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - - NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, - addr_nbits = addr_nbits, - data_nbits = 32, - predicate_nbits = 1) - pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] - tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] - fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] - src_opt_per_tile = [[ - # src dst vc_id opq cmd_type addr operation predicate - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, OPT_INC, b1(0), - pick_register, tile_in_code, fu_out_code), - # This last one is for launching kernel. - CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), - pick_register, tile_in_code, fu_out_code) - ] for i in range(num_tiles)] - - src_ctrl_pkt = [] - for opt_per_tile in src_opt_per_tile: - src_ctrl_pkt.extend(opt_per_tile) - - dataSPM = None - tiles = [] - links = None - if paramCGRA != None: - tiles = paramCGRA.getValidTiles() - links = paramCGRA.getValidLinks() - dataSPM = paramCGRA.dataSPM - else: - dataSPM = DataSPM(2, 2) - for r in range(2): - tiles.append([]) - for c in range(2): - tiles[r].append(Tile(c, r)) - - links = [Link(None, None, 0, 0) for _ in range(16)] - - links[0].srcTile = None - links[0].dstTile = tiles[0][0] - links[0].srcPort = 0 - links[0].dstPort = PORT_WEST - links[0].fromMem = True - links[0].memPort = 0 - links[0].validatePorts() - - links[1].srcTile = tiles[0][0] - links[1].dstTile = None - links[1].srcPort = PORT_WEST - links[1].dstPort = 0 - links[1].toMem = True - links[1].memPort = 0 - links[1].validatePorts() - - links[2].srcTile = None - links[2].dstTile = tiles[1][0] - links[2].srcPort = 1 - links[2].dstPort = PORT_WEST - links[2].fromMem = True - links[2].memPort = 1 - links[2].validatePorts() - - links[3].srcTile = tiles[1][0] - links[3].dstTile = None - links[3].srcPort = PORT_WEST - links[3].dstPort = 1 - links[3].toMem = True - links[3].memPort = 1 - links[3].validatePorts() - - links[4].srcTile = tiles[0][0] - links[4].dstTile = tiles[0][1] - links[4].srcPort = PORT_EAST - links[4].dstPort = PORT_WEST - links[4].validatePorts() - - links[5].srcTile = tiles[0][1] - links[5].dstTile = tiles[0][0] - links[5].srcPort = PORT_WEST - links[5].dstPort = PORT_EAST - links[5].validatePorts() - - links[6].srcTile = tiles[1][0] - links[6].dstTile = tiles[1][1] - links[6].srcPort = PORT_EAST - links[6].dstPort = PORT_WEST - links[6].validatePorts() - - links[7].srcTile = tiles[1][1] - links[7].dstTile = tiles[1][0] - links[7].srcPort = PORT_WEST - links[7].dstPort = PORT_EAST - links[7].validatePorts() - - links[8].srcTile = tiles[0][0] - links[8].dstTile = tiles[1][0] - links[8].srcPort = PORT_NORTH - links[8].dstPort = PORT_SOUTH - links[8].validatePorts() - - links[9].srcTile = tiles[1][0] - links[9].dstTile = tiles[0][0] - links[9].srcPort = PORT_SOUTH - links[9].dstPort = PORT_NORTH - links[9].validatePorts() - - links[10].srcTile = tiles[0][1] - links[10].dstTile = tiles[1][1] - links[10].srcPort = PORT_NORTH - links[10].dstPort = PORT_SOUTH - links[10].validatePorts() - - links[11].srcTile = tiles[1][1] - links[11].dstTile = tiles[0][1] - links[11].srcPort = PORT_SOUTH - links[11].dstPort = PORT_NORTH - links[11].validatePorts() - - links[12].srcTile = tiles[0][0] - links[12].dstTile = tiles[1][1] - links[12].srcPort = PORT_NORTHEAST - links[12].dstPort = PORT_SOUTHWEST - links[12].validatePorts() - - links[13].srcTile = tiles[1][1] - links[13].dstTile = tiles[0][0] - links[13].srcPort = PORT_SOUTHWEST - links[13].dstPort = PORT_NORTHEAST - links[13].validatePorts() - - links[14].srcTile = tiles[0][1] - links[14].dstTile = tiles[1][0] - links[14].srcPort = PORT_NORTHWEST - links[14].dstPort = PORT_SOUTHEAST - links[14].validatePorts() - - links[15].srcTile = tiles[1][0] - links[15].dstTile = tiles[0][1] - links[15].srcPort = PORT_SOUTHEAST - links[15].dstPort = PORT_NORTHWEST - links[15].validatePorts() - - def handleReshape( t_tiles ): - tiles = [] - for row in t_tiles: - for t in row: - tiles.append(t) - return tiles - - tiles = handleReshape(tiles) - - th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlPktType, CtrlSignalType, NocPktType, CmdType, - ControllerIdType, controller_id, - ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, - src_ctrl_pkt, ctrl_mem_size, tiles, links, dataSPM, - controller2addr_map) - - th.elaborate() - th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, - f'CgraTemplateRTL') - th.dut.set_metadata(VerilogVerilatorImportPass.vl_Wno_list, - ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - 'ALWCOMBORDER']) - th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut']) - - if paramCGRA != None: - for tile in tiles: - if not tile.isDefaultFus(): - targetFuList = [] - for fuType in tile.getAllValidFuTypes(): - targetFuList.append(fuType2RTL[fuType]) - targetTile = "top.dut.tile[" + str(tile.getIndex(tiles)) + "].construct" - th.set_param(targetTile, FuList=targetFuList) - - run_sim(th) diff --git a/cgra/translate/VectorCGRAKingMeshRTL_test.py b/cgra/translate/VectorCGRAKingMeshRTL_test.py deleted file mode 100644 index f6826de..0000000 --- a/cgra/translate/VectorCGRAKingMeshRTL_test.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -========================================================================== -VectorCGRAKingMeshRTL_test.py -========================================================================== -Test cases for CGRAs with different configurations. - -Author : Cheng Tan - Date : April 1, 2023 -""" - - -from pymtl3 import * -from pymtl3.passes.backends.verilog import (VerilogTranslationPass, - VerilogVerilatorImportPass) -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..CGRAKingMeshRTL import CGRAKingMeshRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.vector.VectorAdderComboRTL import VectorAdderComboRTL -from ...fu.vector.VectorMulComboRTL import VectorMulComboRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, fu_list, DataType, PredicateType, - CtrlType, 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, width, height, - ctrl_mem_size, data_mem_size, len( src_opt[0] ), - len( src_opt[0] ), FunctionUnit, fu_list ) - - 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_4x4( cmdline_opts ): - num_tile_inports = 8 - num_tile_outports = 8 - num_xbar_inports = 10 - num_xbar_outports = 12 - ctrl_mem_size = 6 - width = 4 - height = 4 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - data_mem_size = 8 - num_fu_in = 4 - DUT = CGRAKingMeshRTL - FunctionUnit = FlexibleFuRTL - # FuList = [MemUnitRTL, AdderRTL] - vector_list = [ AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL, SelRTL, VectorMulComboRTL, VectorAdderComboRTL ] - scalar_list = [ AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL, SelRTL ] - DataType = mk_data( 64, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - src_opt = [[ CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_INC, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_STR, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(4),RouteType(3), RouteType(2), RouteType(1), - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(5), RouteType(5), RouteType(5), RouteType(5)] ) ] - 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, vector_list, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr ) - for row in range( height ): - for col in range( width ): - idx = col + row * height - if row % 2 == 0 and col % 2 == 1 or row % 2 == 1 and col % 2 == 0: - print( f' - set tile[{idx}] to vector') - th.set_param( f'top.dut.tile[{idx}].construct', FuList=vector_list ) - else: - print( f' - set tile[{idx}] to scalar') - th.set_param( f'top.dut.tile[{idx}].construct', FuList=scalar_list ) - - th.elaborate() - th.dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'VectorCGRAKingMeshRTL_{width}x{height}' ) - # 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 ) - diff --git a/cgra/translate/__init__.py b/cgra/translate/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/controller/ControllerRTL.py b/controller/ControllerRTL.py index 08691b5..06607e5 100644 --- a/controller/ControllerRTL.py +++ b/controller/ControllerRTL.py @@ -232,6 +232,7 @@ def update_sending_to_noc_msg(): s.crossbar.send[0].msg.predicate) def line_trace(s): + send_to_ctrl_ring_ctrl_pkt_str = "send_to_ctrl_ring_ctrl_pkt: " + str(s.send_to_ctrl_ring_ctrl_pkt.msg) recv_from_master_load_request_pkt_str = "recv_from_master_load_request_pkt: " + str(s.recv_from_master_load_request_pkt.msg) recv_from_master_load_response_pkt_str = "recv_from_master_load_response_pkt: " + str(s.recv_from_master_load_response_pkt.msg) recv_from_master_store_request_pkt_str = "recv_from_master_store_request_pkt: " + str(s.recv_from_master_store_request_pkt.msg) @@ -241,5 +242,5 @@ def line_trace(s): send_to_master_store_request_data_str = "send_to_master_store_request_data: " + str(s.send_to_master_store_request_data.msg) recv_from_noc_str = "recv_from_noc_pkt: " + str(s.recv_from_noc.msg) send_to_noc_str = "send_to_noc_pkt: " + str(s.send_to_noc.msg) + "; rdy: " + str(s.send_to_noc.rdy) + "; val: " + str(s.send_to_noc.val) - return f'{recv_from_master_load_request_pkt_str} || {recv_from_master_load_response_pkt_str} || {recv_from_master_store_request_pkt_str} || {crossbar_str} || {send_to_master_load_request_addr_str} || {send_to_master_store_request_addr_str} || {send_to_master_store_request_data_str} || {recv_from_noc_str} || {send_to_noc_str}\n' + return f'{send_to_ctrl_ring_ctrl_pkt_str} || {recv_from_master_load_request_pkt_str} || {recv_from_master_load_response_pkt_str} || {recv_from_master_store_request_pkt_str} || {crossbar_str} || {send_to_master_load_request_addr_str} || {send_to_master_store_request_addr_str} || {send_to_master_store_request_data_str} || {recv_from_noc_str} || {send_to_noc_str}\n' diff --git a/fu/basic/ThreeCombo.py b/fu/basic/ThreeCombo.py index 7686986..46c0246 100644 --- a/fu/basic/ThreeCombo.py +++ b/fu/basic/ThreeCombo.py @@ -56,17 +56,11 @@ def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, Fu2, @update def update_signal(): - all_rdy = s.Fu0.recv_in[0].rdy & \ - s.Fu0.recv_in[1].rdy & \ - s.Fu1.recv_in[0].rdy & \ - s.Fu1.recv_in[1].rdy & \ - s.Fu2.recv_in[0].rdy & \ - s.Fu2.recv_in[1].rdy - - s.recv_in[0].rdy @= all_rdy - s.recv_in[1].rdy @= all_rdy - s.recv_in[2].rdy @= all_rdy - s.recv_in[3].rdy @= all_rdy + + s.recv_in[0].rdy @= s.Fu0.recv_in[0].rdy + s.recv_in[1].rdy @= s.Fu0.recv_in[1].rdy + s.recv_in[2].rdy @= s.Fu1.recv_in[0].rdy + s.recv_in[3].rdy @= s.Fu1.recv_in[1].rdy s.Fu0.recv_in[0].val @= s.recv_in[0].val s.Fu0.recv_in[1].val @= s.recv_in[1].val @@ -81,8 +75,7 @@ def update_signal(): s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & \ s.Fu1.recv_opt.rdy & \ - s.Fu2.recv_opt.rdy & \ - all_rdy + s.Fu2.recv_opt.rdy s.send_out[0].val @= s.Fu2.send_out[0].val @@ -98,8 +91,7 @@ def update_signal(): s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ s.Fu1.recv_predicate.rdy & \ - s.Fu2.recv_predicate.rdy & \ - all_rdy + s.Fu2.recv_predicate.rdy s.Fu0.recv_predicate.val @= s.recv_predicate.val s.Fu1.recv_predicate.val @= s.recv_predicate.val diff --git a/fu/basic/TwoPrlCombo.py b/fu/basic/TwoPrlCombo.py index dabfb48..9615082 100644 --- a/fu/basic/TwoPrlCombo.py +++ b/fu/basic/TwoPrlCombo.py @@ -50,15 +50,11 @@ def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, @update def update_signal(): - all_rdy = s.Fu0.recv_in[0].rdy & \ - s.Fu0.recv_in[1].rdy & \ - s.Fu1.recv_in[0].rdy & \ - s.Fu1.recv_in[1].rdy - s.recv_in[0].rdy @= all_rdy - s.recv_in[1].rdy @= all_rdy - s.recv_in[2].rdy @= all_rdy - s.recv_in[3].rdy @= all_rdy + s.recv_in[0].rdy @= s.Fu0.recv_in[0].rdy + s.recv_in[1].rdy @= s.Fu0.recv_in[1].rdy + s.recv_in[2].rdy @= s.Fu1.recv_in[0].rdy + s.recv_in[3].rdy @= s.Fu1.recv_in[1].rdy s.Fu0.recv_in[0].val @= s.recv_in[0].val s.Fu0.recv_in[1].val @= s.recv_in[1].val @@ -68,7 +64,7 @@ def update_signal(): s.Fu0.recv_opt.val @= s.recv_opt.val s.Fu1.recv_opt.val @= s.recv_opt.val - s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy & all_rdy + s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy s.send_out[0].val @= s.Fu0.send_out[0].val s.send_out[1].val @= s.Fu1.send_out[0].val @@ -82,8 +78,7 @@ def update_signal(): s.Fu1.recv_opt.msg.predicate @= s.recv_opt.msg.predicate s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ - s.Fu1.recv_predicate.rdy & \ - all_rdy + s.Fu1.recv_predicate.rdy s.Fu0.recv_predicate.val @= s.recv_predicate.val s.Fu1.recv_predicate.val @= s.recv_predicate.val diff --git a/fu/basic/TwoSeqCombo.py b/fu/basic/TwoSeqCombo.py index f195b7b..d23ff50 100644 --- a/fu/basic/TwoSeqCombo.py +++ b/fu/basic/TwoSeqCombo.py @@ -26,7 +26,6 @@ def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, # Interface s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] - s.recv_in_count = [InPort(CountType) for _ in range(num_inports)] s.recv_predicate = RecvIfcRTL(PredicateType) s.recv_const = RecvIfcRTL(DataType) s.recv_opt = RecvIfcRTL(CtrlType) @@ -54,14 +53,10 @@ def construct(s, DataType, PredicateType, CtrlType, Fu0, Fu1, @update def update_signal(): - all_rdy = s.Fu0.recv_in[0].rdy & \ - s.Fu0.recv_in[1].rdy & \ - s.Fu1.recv_in[0].rdy & \ - s.Fu1.recv_in[1].rdy - s.recv_in[0].rdy @= all_rdy - s.recv_in[1].rdy @= all_rdy - s.recv_in[2].rdy @= all_rdy + s.recv_in[0].rdy @= s.Fu0.recv_in[0].rdy + s.recv_in[1].rdy @= s.Fu0.recv_in[1].rdy + s.recv_in[2].rdy @= s.Fu1.recv_in[1].rdy s.Fu0.recv_in[0].val @= s.recv_in[0].val s.Fu0.recv_in[1].val @= s.recv_in[1].val @@ -71,7 +66,7 @@ def update_signal(): s.Fu0.recv_opt.val @= s.recv_opt.val s.Fu1.recv_opt.val @= s.recv_opt.val - s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy & all_rdy + s.recv_opt.rdy @= s.Fu0.recv_opt.rdy & s.Fu1.recv_opt.rdy s.send_out[0].val @= s.Fu1.send_out[0].val @@ -84,8 +79,7 @@ def update_signal(): s.Fu1.recv_opt.msg.predicate @= s.recv_opt.msg.predicate s.recv_predicate.rdy @= s.Fu0.recv_predicate.rdy & \ - s.Fu1.recv_predicate.rdy & \ - all_rdy + s.Fu1.recv_predicate.rdy s.Fu0.recv_predicate.val @= s.recv_predicate.val s.Fu1.recv_predicate.val @= s.recv_predicate.val diff --git a/fu/flexible/FlexibleFuRTL.py b/fu/flexible/FlexibleFuRTL.py index c5c1ad5..457a825 100644 --- a/fu/flexible/FlexibleFuRTL.py +++ b/fu/flexible/FlexibleFuRTL.py @@ -116,7 +116,7 @@ def line_trace(s): opt_str = " #" if s.recv_opt.val: opt_str = OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl] - out_str = ",".join([str(x.msg) for x in s.send_out]) - recv_str = ",".join([str(x.msg) for x in s.recv_in]) - return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}, val: {s.recv_const.val}) ] = [out: {out_str}] (recv_opt.rdy: {s.recv_opt.rdy}, recv_in[0].rdy: {s.recv_in[0].rdy}, recv_in[1].rdy: {s.recv_in[1].rdy}, recv_predicate.msg: {s.recv_predicate.msg}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' + out_str = " | ".join([(str(x.msg) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy)) for x in s.send_out]) + recv_str = " | ".join([str(x.msg) for x in s.recv_in]) + return f'[recv: {recv_str}] {opt_str}(P{s.recv_opt.msg.predicate}) (const: {s.recv_const.msg}, val: {s.recv_const.val}, rdy: {s.recv_const.rdy}) ] = [out: {out_str}] (recv_opt.rdy: {s.recv_opt.rdy}, recv_in[0].rdy: {s.recv_in[0].rdy}, recv_in[1].rdy: {s.recv_in[1].rdy}, recv_predicate.msg: {s.recv_predicate.msg}, {OPT_SYMBOL_DICT[s.recv_opt.msg.ctrl]}, recv_opt.val: {s.recv_opt.val}, send[0].val: {s.send_out[0].val}) ' diff --git a/fu/flexible/translate/FlexibleFuRTL_test.py b/fu/flexible/translate/FlexibleFuRTL_test.py index d5ba865..103223e 100644 --- a/fu/flexible/translate/FlexibleFuRTL_test.py +++ b/fu/flexible/translate/FlexibleFuRTL_test.py @@ -49,9 +49,6 @@ def construct( s, FunctionUnit, FuList, DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size, FuList ) - for i in range( num_inports ): - s.dut.recv_in_count[i] //= 1 - connect( s.src_const.send, s.dut.recv_const ) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) diff --git a/fu/float/FpAddRTL.py b/fu/float/FpAddRTL.py index 12964e5..0ca51c8 100644 --- a/fu/float/FpAddRTL.py +++ b/fu/float/FpAddRTL.py @@ -139,7 +139,7 @@ def comb_logic(): s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy else: for j in range( num_outports ): - s.send_out[j].en @= b1(0) + s.send_out[j].val @= b1(0) s.recv_opt.rdy @= 0 s.recv_in[s.in0_idx].rdy @= 0 s.recv_in[s.in1_idx].rdy @= 0 diff --git a/fu/float/FpMulRTL.py b/fu/float/FpMulRTL.py index 0d1f627..848e0f0 100644 --- a/fu/float/FpMulRTL.py +++ b/fu/float/FpMulRTL.py @@ -114,7 +114,7 @@ def comb_logic(): else: for j in range( num_outports ): - s.send_out[j].en @= b1( 0 ) + s.send_out[j].val @= b1( 0 ) s.recv_opt.rdy @= 0 s.recv_in[s.in0_idx].rdy @= 0 s.recv_in[s.in1_idx].rdy @= 0 diff --git a/fu/vector/VectorAllReduceRTL.py b/fu/vector/VectorAllReduceRTL.py index b3af1e0..957b545 100644 --- a/fu/vector/VectorAllReduceRTL.py +++ b/fu/vector/VectorAllReduceRTL.py @@ -32,7 +32,6 @@ def construct(s, DataType, PredicateType, CtrlType, # Interface s.recv_in = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.recv_in_count = [ InPort( CountType ) for _ in range( num_inports ) ] s.recv_const = RecvIfcRTL( DataType ) s.recv_predicate = RecvIfcRTL( PredicateType ) s.recv_opt = RecvIfcRTL( CtrlType ) diff --git a/fu/vector/VectorMulRTL.py b/fu/vector/VectorMulRTL.py index 9fdaaea..1a3df45 100644 --- a/fu/vector/VectorMulRTL.py +++ b/fu/vector/VectorMulRTL.py @@ -36,7 +36,6 @@ def construct(s, bw, CtrlType, num_inports, num_outports, # Interface s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] - s.recv_in_count = [InPort(CountType) for _ in range(num_inports)] s.recv_const = RecvIfcRTL(DataType) s.recv_opt = RecvIfcRTL(CtrlType) s.send_out = [SendIfcRTL(DataType) for _ in range(num_outports)] diff --git a/lib/messages.py b/lib/messages.py index 0b58aaf..6bcbe42 100644 --- a/lib/messages.py +++ b/lib/messages.py @@ -327,7 +327,6 @@ def mk_ring_across_tiles_pkt(nrouters = 4, f"{ctrl_mem_size}_{ctrl_operations}_{ctrl_fu_inports}_"\ f"{ctrl_fu_outports}_{ctrl_tile_inports}_{ctrl_tile_outports}" - def str_func(s): out_str = '(ctrl_operation)' + str(s.ctrl_operation) out_str += '|(ctrl_fu_in)' diff --git a/mem/ctrl/CtrlMemDynamicRTL.py b/mem/ctrl/CtrlMemDynamicRTL.py index 65dd59d..924798e 100644 --- a/mem/ctrl/CtrlMemDynamicRTL.py +++ b/mem/ctrl/CtrlMemDynamicRTL.py @@ -12,7 +12,8 @@ from pymtl3 import * from pymtl3.stdlib.primitive import RegisterFile from ...lib.basic.en_rdy.ifcs import SendIfcRTL -from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL, ValRdySendIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ...lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ...lib.basic.val_rdy.queues import NormalQueueRTL from ...lib.cmd_type import * from ...lib.opt_type import * @@ -37,12 +38,11 @@ def construct(s, CtrlPktType, CtrlSignalType, ctrl_mem_size, num_routing_outports = num_tile_outports + num_fu_inports # Interface - s.send_ctrl = ValRdySendIfcRTL(CtrlSignalType) - s.recv_pkt = ValRdyRecvIfcRTL(CtrlPktType) + s.send_ctrl = SendIfcRTL(CtrlSignalType) + s.recv_pkt = RecvIfcRTL(CtrlPktType) # Component s.reg_file = RegisterFile(CtrlSignalType, ctrl_mem_size, 1, 1) - # FIXME: valrdy normal queue RTL? s.recv_pkt_queue = NormalQueueRTL(CtrlPktType) s.times = Wire(TimeType) s.start_iterate_ctrl = Wire(b1) @@ -139,5 +139,5 @@ def update_raddr(): def line_trace(s): config_mem_str = "|".join([str(data) for data in s.reg_file.regs]) - return f'{s.recv_pkt.msg} || config_mem: [{config_mem_str}] || out: {s.send_ctrl.msg}' + return f'{s.recv_pkt.msg}.recv_rdy:{s.recv_pkt.rdy} || control signal content: [{config_mem_str}] || ctrl_out: {s.send_ctrl.msg}, send_ctrl.val: {s.send_ctrl.val}, send_ctrl.rdy: {s.send_ctrl.rdy}' diff --git a/mem/ctrl/RingMultiCtrlMemDynamicRTL.py b/mem/ctrl/RingMultiCtrlMemDynamicRTL.py index d82b576..3be5f32 100644 --- a/mem/ctrl/RingMultiCtrlMemDynamicRTL.py +++ b/mem/ctrl/RingMultiCtrlMemDynamicRTL.py @@ -24,8 +24,8 @@ def construct(s, CtrlPktType, CtrlSignalType, width, height, ctrl_count_per_iter = 4, total_ctrl_steps = 4): # Constant num_terminals = width * height - CtrlRingPos = mk_ring_pos(num_terminals) s.num_terminals = width * height + CtrlRingPos = mk_ring_pos(num_terminals) # Interface s.send_ctrl = [SendIfcRTL(CtrlSignalType) for _ in range(s.num_terminals)] diff --git a/mem/data/DataMemWithCrossbarRTL.py b/mem/data/DataMemWithCrossbarRTL.py index 88cd407..b32ed4d 100644 --- a/mem/data/DataMemWithCrossbarRTL.py +++ b/mem/data/DataMemWithCrossbarRTL.py @@ -333,7 +333,7 @@ def line_trace(s): recv_from_noc_rdata_str += str(s.recv_from_noc_rdata.msg) + ";" # send_to_noc_waddr_str += str(s.send_to_noc_waddr.msg) + ";" # send_to_noc_wdata_str += str(s.send_to_noc_wdata.msg) + ";" - send_to_noc_store_pkt_str += str(s.send_to_noc_store_pkt.msg) + ";" + send_to_noc_store_pkt_str += str(s.send_to_noc_store_pkt.msg) + ", val: " + str(s.send_to_noc_store_pkt.val) + ";" recv_raddr_str += "}" send_rdata_str += "}" diff --git a/noc/BlockChannelRTL.py b/noc/BlockChannelRTL.py deleted file mode 100644 index 63d5b8d..0000000 --- a/noc/BlockChannelRTL.py +++ /dev/null @@ -1,80 +0,0 @@ -#========================================================================= -# BlockChannelRTL.py -#========================================================================= -# RTL channel module for testing the delayed data receiving. Basically, it -# set the recv.rdy signal after a few cycles. -# -# Author : Cheng Tan -# Date : Aug 26, 2023 - -from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import BypassQueue, NormalQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - - -class BlockChannelRTL( Component ): - def construct(s, DataType, delay = 5 ): - - # Constant - s.num_entries = 2 - s.data = DataType(0, 0) - s.count = OutPort( mk_bits( clog2( s.num_entries+1 ) ) ) - - # Interface - s.recv = RecvIfcRTL( DataType ) - s.send = SendIfcRTL( DataType ) - - - # Component - s.queue = NormalQueue( DataType, s.num_entries ) - s.bypass_q = BypassQueue( DataType, num_entries=1 ) - - s.bypass_q.enq_en //= s.recv.en - s.bypass_q.enq_msg //= s.recv.msg - - s.count //= s.queue.count - - # Tracks the cycles spent in this channel.. - s.timing = Wire( mk_bits( clog2( delay + 1 ) ) ) - - @update - def process(): - s.recv.rdy @= s.bypass_q.enq_rdy & (s.timing >= delay) - - if ~s.bypass_q.deq_msg.bypass: - s.queue.enq_msg @= s.bypass_q.deq_msg - s.bypass_q.deq_en @= s.queue.enq_rdy & s.bypass_q.deq_rdy - s.queue.enq_en @= s.queue.enq_rdy & s.bypass_q.deq_rdy - - s.send.msg @= s.queue.deq_msg - s.send.msg.delay @= s.queue.deq_msg.delay | ~s.queue.deq_rdy - s.send.en @= s.send.rdy & s.queue.deq_rdy - s.queue.deq_en @= s.send.rdy & s.queue.deq_rdy - - else: - s.queue.enq_en @= 0 - s.queue.enq_msg @= DataType() - s.queue.deq_en @= 0 - - s.send.msg @= DataType() - s.send.msg.payload @= s.bypass_q.deq_msg.payload - s.send.msg.predicate @= s.bypass_q.deq_msg.predicate - s.send.msg.bypass @= 0 - s.send.msg.delay @= s.bypass_q.deq_msg.delay | ~s.bypass_q.deq_rdy - s.send.en @= s.send.rdy & s.bypass_q.deq_rdy - s.bypass_q.deq_en @= s.send.rdy & s.bypass_q.deq_rdy - - @update_ff - def update_timing(): - if s.timing == delay + 1: - s.timing <<= 0 - else: - s.timing <<= s.timing + 1 - - def line_trace( s ): - trace = '>' - trace += s.bypass_q.line_trace() + '>' - trace += s.queue.line_trace() + '>' - return trace # f'{s.bypass_q.line_trace()}' - return f"in:{s.recv.msg}({trace})out:{s.send.msg}.count:{s.count} ## " - diff --git a/noc/BypassChannelRTL.py b/noc/BypassChannelRTL.py deleted file mode 100644 index 9cf6aaa..0000000 --- a/noc/BypassChannelRTL.py +++ /dev/null @@ -1,44 +0,0 @@ -#========================================================================= -# BypassChannelRTL.py -#========================================================================= -# RTL channel module for connecting basic components to form accelerator. -# This simple channel has latency insensitive send/recv interfaces. -# -# Author : Cheng Tan -# Date : Feb 22, 2020 - -from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import BypassQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - - -class BypassChannelRTL( Component ): - def construct(s, DataType ): - - # Constant - s.data = DataType(0, 0) - - # Interface - s.recv = RecvIfcRTL( DataType ) - s.send = SendIfcRTL( DataType ) - - # Component - s.bypass_q = BypassQueue( DataType, num_entries=1 ) - s.bypass_q.enq_en //= s.recv.en - s.bypass_q.enq_msg //= s.recv.msg - s.bypass_q.enq_rdy //= s.recv.rdy - - @update - def process(): - s.send.msg @= DataType() - s.send.msg.payload @= s.bypass_q.deq_msg.payload - s.send.msg.predicate @= s.bypass_q.deq_msg.predicate - s.send.msg.bypass @= 0 - s.send.msg.valid @= s.bypass_q.deq_rdy - s.send.en @= s.send.rdy & s.bypass_q.deq_rdy - s.bypass_q.deq_en @= s.send.rdy & s.bypass_q.deq_rdy - - def line_trace( s ): - trace = '>' - return f'{s.bypass_q.line_trace()}' - diff --git a/noc/ChannelRTL.py b/noc/ChannelRTL.py deleted file mode 100644 index 18903d9..0000000 --- a/noc/ChannelRTL.py +++ /dev/null @@ -1,93 +0,0 @@ -#========================================================================= -# ChannelRTL.py -#========================================================================= -# RTL channel module for connecting basic components to form accelerator. -# This simple channel has latency insensitive send/recv interfaces. -# -# Author : Cheng Tan -# Date : Feb 22, 2020 - -from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import BypassQueue, NormalQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - - -class ChannelRTL( Component ): - def construct(s, DataType, latency = 1 ): - - # Constant - s.latency = latency - s.num_entries = 2 - s.data = DataType(0, 0) - s.count = OutPort( mk_bits( clog2( s.num_entries+1 ) ) ) - - # Interface - s.recv = RecvIfcRTL( DataType ) - s.send = SendIfcRTL( DataType ) - - - # Component - s.queues = [ NormalQueue( DataType, s.num_entries ) - for _ in range( s.latency ) ] - - s.bypass_q = BypassQueue( DataType, num_entries=1 ) - s.bypass_q.enq_en //= s.recv.en - s.bypass_q.enq_msg //= s.recv.msg - s.bypass_q.enq_rdy //= s.recv.rdy - - - s.count //= s.queues[s.latency - 1].count - - @update - def process(): - for i in range(s.latency - 1): - s.queues[i+1].enq_msg @= s.queues[i].deq_msg - s.queues[i+1].enq_en @= s.queues[i].deq_rdy & s.queues[i+1].enq_rdy - s.queues[i].deq_en @= s.queues[i+1].enq_en - - if ~s.bypass_q.deq_msg.bypass: - s.queues[0].enq_msg @= s.bypass_q.deq_msg - s.bypass_q.deq_en @= s.queues[0].enq_rdy & s.bypass_q.deq_rdy - s.queues[0].enq_en @= s.queues[0].enq_rdy & s.bypass_q.deq_rdy - - s.send.msg @= s.queues[s.latency-1].deq_msg - # s.send.msg.delay @= s.queues[s.latency-1].deq_rdy - # s.send.msg.delay @= s.queues[s.latency-1].deq_msg.delay - # Set the delay if FU not yet completes pipeline (the msg.delay is - # set by the FU) or the data has not yet arrived due to the delay - # propagation. - # s.send.msg.delay @= s.queues[s.latency-1].deq_msg.delay | \ - # ~s.queues[s.latency-1].deq_rdy - s.send.msg.delay @= s.queues[s.latency-1].deq_msg.delay - s.send.en @= s.send.rdy & s.queues[s.latency-1].deq_rdy - s.queues[s.latency-1].deq_en @= s.send.rdy & s.queues[s.latency-1].deq_rdy - # print("s.queues[0].deq_en: ", s.queues[0].deq_en) - # print("s.queues[0].enq_en: ", s.queues[0].enq_en) - # print("s.bypass_q.deq_rdy: ", s.bypass_q.deq_rdy) - - else: - s.queues[0].enq_en @= 0 - s.queues[0].enq_msg @= DataType() - s.queues[s.latency-1].deq_en @= 0 - - s.send.msg @= DataType() - s.send.msg.payload @= s.bypass_q.deq_msg.payload - s.send.msg.predicate @= s.bypass_q.deq_msg.predicate - s.send.msg.bypass @= 0 - # s.send.msg.delay @= s.bypass_q.deq_rdy - # Set the delay if FU not yet completes pipeline (the msg.delay is - # set by the FU) or the data has not yet arrived due to the delay - # propagation. - # s.send.msg.delay @= s.bypass_q.deq_msg.delay | ~s.bypass_q.deq_rdy - s.send.msg.delay @= s.bypass_q.deq_msg.delay - s.send.en @= s.send.rdy & s.bypass_q.deq_rdy - s.bypass_q.deq_en @= s.send.rdy & s.bypass_q.deq_rdy - - def line_trace( s ): - trace = '>' - trace += s.bypass_q.line_trace() + '>' - for i in range( s.latency ): - trace += s.queues[i].line_trace() + '>' - return trace # f'{s.bypass_q.line_trace()}' - return f"in:{s.recv.msg}({trace})out:{s.send.msg}.count:{s.count} ## " - diff --git a/noc/CrossbarRTL.py b/noc/CrossbarRTL.py deleted file mode 100644 index 654ebc6..0000000 --- a/noc/CrossbarRTL.py +++ /dev/null @@ -1,153 +0,0 @@ -""" -========================================================================= -Crossbar.py -========================================================================= -Data-driven crossbar. Valid data is sent out only when - -Author : Cheng Tan - Date : August 26, 2023 -""" - -from pymtl3 import * -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL -from ..lib.opt_type import * - -class CrossbarRTL(Component): - - def construct(s, DataType, PredicateType, CtrlType, - num_inports = 5, num_outports = 5, bypass_point = 4, - id = 0): - - InType = mk_bits(clog2(num_inports + 1)) - s.bypass_point = bypass_point - - # Interface - - s.recv_opt = RecvIfcRTL( CtrlType ) - s.recv_data = [ RecvIfcRTL( DataType ) for _ in range( num_inports ) ] - s.send_data = [ SendIfcRTL( DataType ) for _ in range( num_outports ) ] - s.send_predicate = SendIfcRTL( PredicateType ) - - # TODO: should include position information or not - # s.pos = InPort( PositionType ) - - s.in_dir = [ Wire( InType ) for _ in range( num_outports ) ] - s.in_dir_local = [ Wire( InType ) for _ in range( num_outports ) ] - s.out_rdy_vector = Wire( num_outports ) - s.recv_predicate_vector = Wire( num_inports ) - # Used to indicate whether the recv_data could be popped. - s.recv_blocked_vector = Wire( num_inports ) - # received or sent once but there are still some others pending. So the - # one already done should not proceed the next to avoid overwriting. - s.recv_but_block_by_others = [ Wire( b1 ) for _ in range( num_inports ) ] - s.send_but_block_by_others = [ Wire( b1 ) for _ in range( num_outports ) ] - - # Routing logic - @update - def update_signal(): - s.out_rdy_vector @= 0 - s.recv_predicate_vector @= 0 - s.send_predicate.val @= 0 - s.recv_blocked_vector @= 0 - s.send_predicate.msg @= PredicateType() - for i in range( num_inports ): - s.recv_data[i].rdy @= 0 - for i in range( num_outports ): - s.in_dir[i] @= 0 - s.in_dir_local[i] @= 0 - s.send_data[i].val @= 0 - s.send_data[i].msg @= DataType() - - # For predication register update. 'predicate' and 'predicate_in' no need - # to be active at the same time. Specifically, the 'predicate' is for - # the operation at the current cycle while the 'predicate_in' accumulates - # the predicate and pushes into the predicate register that will be used - # in the future. - if s.recv_opt.msg.predicate: - s.send_predicate.msg @= PredicateType( b1(0), b1(0) ) - - if s.recv_opt.msg.ctrl != OPT_START: - for i in range( num_inports ): - # Set predicate once the recv_data is stable (i.e., en == true). - if s.recv_opt.msg.predicate_in[i] & s.recv_data[i].val: - s.send_predicate.val @= b1( 1 ) - s.send_predicate.msg.payload @= b1( 1 ) - s.recv_predicate_vector[i] @= s.recv_data[i].msg.predicate - - for i in range( num_inports ): - s.recv_blocked_vector[i] @= (s.recv_data[i].msg.delay == 1) - - # The predicate_in might not be issued to other ports on the xbar, - # but it also needs to be drained from the recv_data, otherwise, - # it would block the recv_data channel/buffer. - if s.recv_opt.msg.predicate_in[i] & \ - ~s.recv_blocked_vector[i] & \ - ~s.recv_but_block_by_others[i]: - s.recv_data[i].rdy @= 1 - - for i in range( num_outports ): - s.out_rdy_vector[i] @= s.send_data[i].rdy - s.in_dir[i] @= s.recv_opt.msg.outport[i] - if s.in_dir[i] > 0: - s.send_data[i].msg.delay @= s.recv_data[s.in_dir_local[i]].msg.delay - else: - s.out_rdy_vector[i] @= 1 - - for i in range( num_outports ): - s.in_dir[i] @= s.recv_opt.msg.outport[i] - if (s.in_dir[i] > 0) & s.send_data[i].rdy: - s.in_dir_local[i] @= s.in_dir[i] - 1 - - s.recv_data[s.in_dir_local[i]].rdy @= \ - s.send_data[i].rdy & \ - ~s.recv_blocked_vector[s.in_dir_local[i]] & \ - ~s.recv_but_block_by_others[s.in_dir_local[i]] & \ - ~s.send_but_block_by_others[i] - - s.send_data[i].val @= s.recv_data[s.in_dir_local[i]].val - if s.send_data[i].val & s.recv_data[s.in_dir_local[i]].rdy: - s.send_data[i].msg.payload @= s.recv_data[s.in_dir_local[i]].msg.payload - s.send_data[i].msg.predicate @= s.recv_data[s.in_dir_local[i]].msg.predicate - s.send_data[i].msg.bypass @= s.recv_data[s.in_dir_local[i]].msg.bypass - s.send_data[i].msg.delay @= 0 - # The generate one can be send to other tile without buffering, - # but buffering is still needed when 'other tile' is yourself - # (i.e., generating output to self input). Here we avoid self - # connecting by checking whether the inport belongs to FU and - # outport be towards to remote tiles to eliminate combinational - # loop. - if (s.in_dir_local[i] >= s.bypass_point) & (i < s.bypass_point): - s.send_data[i].msg.bypass @= b1( 1 ) - else: - s.send_data[i].msg.bypass @= b1( 0 ) - else: - s.send_data[i].val @= b1( 0 ) - - else: - for i in range( num_outports ): - s.send_data[i].val @= b1( 0 ) - s.recv_opt.rdy @= reduce_and( s.out_rdy_vector ) & ~reduce_or( s.recv_blocked_vector ) - s.send_predicate.msg.predicate @= reduce_or( s.recv_predicate_vector ) - - @update_ff - def update_blocked_by_others(): - for i in range( num_inports ): - if reduce_or( s.recv_blocked_vector ) & ~s.recv_blocked_vector[i]: - s.recv_but_block_by_others[i] <<= 1 - elif ~reduce_or( s.recv_blocked_vector ): - s.recv_but_block_by_others[i] <<= 0 - - for i in range( num_outports ): - if ~reduce_and( s.out_rdy_vector ) & s.out_rdy_vector[i]: - s.send_but_block_by_others[i] <<= 1 - elif reduce_and( s.out_rdy_vector ): - s.send_but_block_by_others[i] <<= 0 - - # Line trace - def line_trace( s ): - recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) - out_str = "|".join([ str(x.msg) for x in s.send_data ]) - pred_str = str( s.send_predicate.msg ) - return f"{recv_str} [{s.recv_opt.msg}] {out_str}-xbar.pred:{pred_str}" - diff --git a/noc/CrossbarSeparateRTL.py b/noc/CrossbarSeparateRTL.py index f8a0f7f..99db90e 100644 --- a/noc/CrossbarSeparateRTL.py +++ b/noc/CrossbarSeparateRTL.py @@ -15,8 +15,9 @@ from ..lib.opt_type import * class CrossbarSeparateRTL(Component): + def construct(s, DataType, PredicateType, CtrlType, num_inports = 5, - num_outports = 5, bypass_point = 4, id = 0): + num_outports = 5, id = 0, crossbar_type = "None"): InType = mk_bits(clog2(num_inports + 1)) num_index = num_inports if num_inports != 1 else 2 @@ -76,15 +77,17 @@ def update_signal(): for i in range(num_outports): s.send_data[i].val @= reduce_and(s.recv_valid_vector) & \ - reduce_and(s.send_rdy_vector) & \ s.send_required_vector[i] + # FIXME: Valid shouldn't depend on rdy. + # reduce_and(s.send_rdy_vector) & \ if reduce_and(s.recv_valid_vector) & \ reduce_and(s.send_rdy_vector) & \ s.send_required_vector[i]: s.send_data[i].msg.payload @= s.recv_data[s.in_dir_local[i]].msg.payload s.send_data[i].msg.predicate @= s.recv_data[s.in_dir_local[i]].msg.predicate - s.recv_opt.rdy @= reduce_and(s.send_rdy_vector) & reduce_and(s.recv_valid_vector) - s.send_predicate.msg.predicate @= reduce_or(s.recv_predicate_vector) + + s.send_predicate.msg.predicate @= reduce_or(s.recv_predicate_vector) + s.recv_opt.rdy @= reduce_and(s.send_rdy_vector) & reduce_and(s.recv_valid_vector) @update def update_valid_rdy_vector(): diff --git a/noc/DelayChannelRTL.py b/noc/DelayChannelRTL.py deleted file mode 100644 index b6dc88f..0000000 --- a/noc/DelayChannelRTL.py +++ /dev/null @@ -1,80 +0,0 @@ -#========================================================================= -# DelayChannelRTL.py -#========================================================================= -# RTL channel module for testing the delayed data arrival. Basically, it -# set the send.msg.delay signal for a few cycles. The consumer shouldn't -# accept/consume the data (i.e., set the rdy) before the delay signal is -# clear. -# -# Author : Cheng Tan -# Date : Aug 26, 2023 - -from pymtl3 import * -from pymtl3.stdlib.dstruct.queues import BypassQueue, NormalQueue -from ..lib.basic.en_rdy.ifcs import RecvIfcRTL, SendIfcRTL - -class DelayChannelRTL( Component ): - def construct(s, DataType, delay = 5 ): - - # Constant - s.num_entries = 2 - s.data = DataType(0, 0) - s.count = OutPort( mk_bits( clog2( s.num_entries+1 ) ) ) - - # Interface - s.recv = RecvIfcRTL( DataType ) - s.send = SendIfcRTL( DataType ) - - - # Component - s.queue = NormalQueue( DataType, s.num_entries ) - s.bypass_q = BypassQueue( DataType, num_entries=1 ) - - s.bypass_q.enq_en //= s.recv.en - s.bypass_q.enq_msg //= s.recv.msg - s.bypass_q.enq_rdy //= s.recv.rdy - - s.count //= s.queue.count - - # Tracks the cycles spent in this channel.. - s.timing = Wire( mk_bits( clog2( delay + 1 ) ) ) - - @update - def process(): - if ~s.bypass_q.deq_msg.bypass: - s.queue.enq_msg @= s.bypass_q.deq_msg - s.bypass_q.deq_en @= s.queue.enq_rdy & s.bypass_q.deq_rdy - s.queue.enq_en @= s.queue.enq_rdy & s.bypass_q.deq_rdy - - s.send.msg @= s.queue.deq_msg - s.send.msg.delay @= (s.timing != delay) - s.send.en @= s.send.rdy & s.queue.deq_rdy - s.queue.deq_en @= s.send.rdy & s.queue.deq_rdy - - else: - s.queue.enq_en @= 0 - s.queue.enq_msg @= DataType() - s.queue.deq_en @= 0 - - s.send.msg @= DataType() - s.send.msg.payload @= s.bypass_q.deq_msg.payload - s.send.msg.predicate @= s.bypass_q.deq_msg.predicate - s.send.msg.bypass @= 0 - s.send.msg.delay @= (s.timing != delay) - s.send.en @= s.send.rdy & s.bypass_q.deq_rdy - s.bypass_q.deq_en @= s.send.rdy & s.bypass_q.deq_rdy - - @update_ff - def update_timing(): - if s.timing == delay + 1: - s.timing <<= 0 - else: - s.timing <<= s.timing + 1 - - def line_trace( s ): - trace = '>' - trace += s.bypass_q.line_trace() + '>' - trace += s.queue.line_trace() + '>' - return trace # f'{s.bypass_q.line_trace()}' - return f"in:{s.recv.msg}({trace})out:{s.send.msg}.count:{s.count} ## " - diff --git a/noc/LinkOrRTL.py b/noc/LinkOrRTL.py index 5f382a1..ed9fa33 100644 --- a/noc/LinkOrRTL.py +++ b/noc/LinkOrRTL.py @@ -44,7 +44,8 @@ def process(): # s.send.msg.bypass @= 0 # s.send.msg.delay @= s.recv_fu.msg.delay | s.recv_xbar.msg.delay - s.send.val @= s.send.rdy & (s.recv_fu.val | s.recv_xbar.val) + # s.send.val @= s.send.rdy & (s.recv_fu.val | s.recv_xbar.val) + s.send.val @= s.recv_fu.val | s.recv_xbar.val s.recv_fu.rdy @= s.send.rdy s.recv_xbar.rdy @= s.send.rdy diff --git a/noc/MulticasterRTL.py b/noc/MulticasterRTL.py deleted file mode 100644 index 4fb5c5a..0000000 --- a/noc/MulticasterRTL.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -========================================================================= -MulticasterRTL.py -========================================================================= - -Author : Cheng Tan - Date : Feb 16, 2019 -""" - -from pymtl3 import * - -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * - -class MulticasterRTL( Component ): - - def construct( s, DataType, num_outports = 2 ): - - # Constand - if num_outports == 0: - num_outports = 1 - - # Interface - - s.recv = RecvIfcRTL( DataType ) - s.send = [ SendIfcRTL( DataType ) for _ in range ( num_outports ) ] - - @update - def update_signal(): - s.recv.rdy @= s.send[0].rdy - for i in range( num_outports ): - s.recv.rdy @= s.recv.rdy & s.send[i].rdy - s.send[i].en @= s.recv.en - s.send[i].msg @= s.recv.msg - - # Line trace - def line_trace( s ): - recv_str = s.recv.msg - out_str = "|".join([ str(x.msg) for x in s.send ]) - return f"{recv_str} -> {out_str}({s.recv.rdy},{s.send[0].en})" - diff --git a/noc/test/BlockChannelRTL_test.py b/noc/test/BlockChannelRTL_test.py deleted file mode 100644 index fbdfaf3..0000000 --- a/noc/test/BlockChannelRTL_test.py +++ /dev/null @@ -1,83 +0,0 @@ -#========================================================================= -# BlockChannelRTL_test.py -#========================================================================= -# Test for BlockChannel -# -# Author : Cheng Tan -# Date : August 26, 2023 - -import pytest -from pymtl3 import * -from pymtl3.stdlib.test_utils import TestVectorSimulator - -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ..BlockChannelRTL import BlockChannelRTL - -#------------------------------------------------------------------------- -# TestHarness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, MsgType, src_msgs, sink_msgs, latency ): - - s.src = TestSrcRTL ( MsgType, src_msgs ) - s.sink = TestSinkRTL( MsgType, sink_msgs ) - s.dut = BlockChannelRTL( MsgType, latency ) - - # Connections - s.src.send //= s.dut.recv - s.dut.send //= s.sink.recv - # s.dut.send.rdy //= 0 - - def done( s ): - return s.src.done() and s.sink.done() - - def line_trace( s ): - # 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=100 ): - - # 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() )) - if ncycles >= 4: - test_harness.dut.send.rdy @= 1 - - # Check timeout - assert ncycles < max_cycles - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - -#------------------------------------------------------------------------- -# Test cases -#------------------------------------------------------------------------- - -DataType = mk_data( 16, 1 ) -test_msgs = [ DataType(7,1,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] -sink_msgs = [ DataType(7,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] - -def test_latency(): - latency = 5 - th = TestHarness( DataType, test_msgs, sink_msgs, latency) - run_sim( th ) diff --git a/noc/test/ChannelRTL_test.py b/noc/test/ChannelRTL_test.py deleted file mode 100644 index 6241d4e..0000000 --- a/noc/test/ChannelRTL_test.py +++ /dev/null @@ -1,88 +0,0 @@ -#========================================================================= -# ChannelRTL_test.py -#========================================================================= -# Simple test for Channel -# -# Author : Cheng Tan -# Date : Dec 11, 2019 - -import pytest -from pymtl3 import * -from pymtl3.stdlib.test_utils import TestVectorSimulator - -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ..ChannelRTL import ChannelRTL - -#------------------------------------------------------------------------- -# TestHarness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, MsgType, src_msgs, sink_msgs, latency ): - - s.src = TestSrcRTL ( MsgType, src_msgs ) - s.sink = TestSinkRTL( MsgType, sink_msgs ) - s.dut = ChannelRTL( MsgType, latency ) - - # Connections - s.src.send //= s.dut.recv - s.dut.send //= s.sink.recv - # s.dut.send.rdy //= 0 - - def done( s ): - return s.src.done() and s.sink.done() - - def line_trace( s ): - # 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=100 ): - - # 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() )) - if ncycles >= 4: - test_harness.dut.send.rdy @= 1 - - # Check timeout - assert ncycles < max_cycles - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - -#------------------------------------------------------------------------- -# Test cases -#------------------------------------------------------------------------- - -DataType = mk_data( 16, 1 ) -test_msgs = [ DataType(7,1,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] -sink_msgs = [ DataType(7,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] - -def test_simple(): - latency = 1 - th = TestHarness( DataType, test_msgs, sink_msgs, latency) - run_sim( th ) - -def test_latency(): - latency = 2 - th = TestHarness( DataType, test_msgs, sink_msgs, latency) - run_sim( th ) diff --git a/noc/test/CrossbarBlockRTL_test.py b/noc/test/CrossbarBlockRTL_test.py deleted file mode 100644 index 2ed94f7..0000000 --- a/noc/test/CrossbarBlockRTL_test.py +++ /dev/null @@ -1,117 +0,0 @@ -""" -========================================================================== -CrossbarBlockRTL_test.py -========================================================================== -Test cases for Crossbar. Output is blocked for a few cycles. - -Author : Cheng Tan - Date : August 26, 2023 - -""" - -from pymtl3 import * -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..CrossbarRTL import CrossbarRTL -from ..BlockChannelRTL import BlockChannelRTL -from ...lib.opt_type import * -from ...lib.messages import * - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, CrossbarUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, - src_data, src_routing, sink_out ): - - s.num_inports = num_inports - s.num_outports = num_outports - - s.src_opt = TestSrcRTL( CtrlType, src_routing ) - s.src_data = [ TestSrcRTL( DataType, src_data[i] ) - for i in range( num_inports ) ] - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( num_outports ) ] - - s.dut = CrossbarUnit( DataType, PredicateType, CtrlType, num_inports, - num_outports, num_inports ) - - # Delayed latency. - latency = 9 - s.channel = BlockChannelRTL( DataType, latency ) - - for i in range( num_inports ): - connect( s.src_data[i].send, s.dut.recv_data[i] ) - if i != 0: - s.dut.send_data[i] //= s.sink_out[i].recv - else: - s.dut.send_data[i] //= s.channel.recv - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.channel.send, s.sink_out[0].recv ) - - def done( s ): - done = True - for i in range( s.num_inports ): - if not s.src_data[i].done(): - done = False - break - for i in range( s.num_outports ): - if not s.sink_out[i].done(): - done = False - break - return done - - def line_trace( s ): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles=100 ): - 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() - -def test_multi(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), - RouteType(1), - RouteType(1)]), - CtrlType( OPT_SUB, b1(0), pickRegister, [RouteType(3), - RouteType(2), - RouteType(1)]) ] - src_data = [ [DataType(3, 1), DataType(4, 1)], [DataType(2, 1), DataType(7, 1)], [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1), DataType(9, 1)], - [DataType(3, 1), DataType(7, 1)], - [DataType(3, 1), DataType(4, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - diff --git a/noc/test/CrossbarDelayRTL_test.py b/noc/test/CrossbarDelayRTL_test.py deleted file mode 100644 index 9086614..0000000 --- a/noc/test/CrossbarDelayRTL_test.py +++ /dev/null @@ -1,186 +0,0 @@ -""" -========================================================================== -CrossbarDelayRTL_test.py -========================================================================== -Test cases for Crossbar. The input data is delayed for arrival. In -practice, the delay is caused by the functional units (e.g., a pipeline or -multi-stage FU, a LD/ST operation hitting bank conflict or cache miss). -In these cases, the FU would set the msg.delay before the real data is -sent out. The delay signal/msg should be propagated to the others. - -Author : Cheng Tan - Date : August 26, 2023 - -""" - -from pymtl3 import * -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL - -from ..CrossbarRTL import CrossbarRTL -from ..DelayChannelRTL import DelayChannelRTL -from ...lib.opt_type import * -from ...lib.messages import * - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, CrossbarUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, - src_data, src_routing, sink_out ): - - s.num_inports = num_inports - s.num_outports = num_outports - - s.src_opt = TestSrcRTL( CtrlType, src_routing ) - s.src_data = [ TestSrcRTL( DataType, src_data[i] ) - for i in range( num_inports ) ] - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( num_outports ) ] - - s.dut = CrossbarUnit( DataType, PredicateType, CtrlType, num_inports, - num_outports, num_inports - 1 ) - # Delayed latency. - latency = 5 - s.channel = DelayChannelRTL( DataType, latency ) - - assert( num_inports == 3 ) - connect( s.src_data[0].send, s.dut.recv_data[0] ) - connect( s.dut.send_data[0], s.sink_out[0].recv ) - - # The channel/fifo connecting with inport 1 has latency of 2. - connect( s.src_data[1].send, s.channel.recv ) - connect( s.channel.send, s.dut.recv_data[1] ) - connect( s.dut.send_data[1], s.sink_out[1].recv ) - - connect( s.src_data[2].send, s.dut.recv_data[2] ) - connect( s.dut.send_data[2], s.sink_out[2].recv ) - - connect( s.src_opt.send, s.dut.recv_opt ) - - def done( s ): - done = True - for i in range( s.num_inports ): - if not s.src_data[i].done(): - done = False - break - for i in range( s.num_outports ): - if not s.sink_out[i].done(): - done = False - break - return done - - def line_trace( s ): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles=30 ): - 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() - -def test_mul_with_long_latency_input(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, - [RouteType(2), RouteType(1), RouteType(1)]), - CtrlType( OPT_SUB, b1(0), pickRegister, - [RouteType(3), RouteType(2), RouteType(1)]) ] - src_data = [ [DataType(3, 1), DataType(4, 1)], [DataType(2, 1), DataType(7, 1)], [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1), DataType(9, 1, 1)], - [DataType(3, 1), DataType(7, 1)], - [DataType(3, 1), DataType(4, 1)] ] - - # src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(1)]) ] - # src_data = [ [DataType(3, 1), DataType(7, 1)], [DataType(2, 1, 1)], [DataType(9, 1)] ] - # sink_out = [ [DataType(2, 1)], [DataType(3, 1)], [DataType(3, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - -def test_latency_with_predicate(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, - [RouteType(2), RouteType(1), RouteType(1)], - [b1(1), b1(0), b1(0)] ), - CtrlType( OPT_SUB, b1(0), pickRegister, - [RouteType(3), RouteType(2), RouteType(0)], - [b1(1), b1(0), b1(0)] ), - CtrlType( OPT_ADD, b1(0), pickRegister, - [RouteType(0), RouteType(0), RouteType(2)], - [b1(1), b1(0), b1(0)] ), - CtrlType( OPT_SUB, b1(0), pickRegister, - [RouteType(0), RouteType(0), RouteType(1)], - [b1(0), b1(0), b1(0)] ) ] - - src_data = [ [DataType(3, 1), DataType(4, 1), DataType(5, 1), DataType(6, 1)], - [DataType(2, 1), DataType(7, 1), DataType(8, 1)], - [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1), DataType(9, 1, 1)], - [DataType(3, 1), DataType(7, 1)], - [DataType(3, 1), DataType(8, 1), DataType(6, 1)] ] - - # src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(1)]) ] - # src_data = [ [DataType(3, 1), DataType(7, 1)], [DataType(2, 1, 1)], [DataType(9, 1)] ] - # sink_out = [ [DataType(2, 1)], [DataType(3, 1)], [DataType(3, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - -# 141 def test_predicate(): -# 142 FU = CrossbarRTL -# 143 num_fu_in = 3 -# 144 num_inports = 3 -# 145 num_outports = 3 -# 146 DataType = mk_data( 16, 1 ) -# 147 PredicateType = mk_predicate( 1, 1 ) -# 148 CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) -# 149 FuInType = mk_bits( clog2( num_inports + 1 ) ) -# 150 pickRegister = [ FuInType( 0 ) for x in range( num_inports ) ] -# 151 RouteType = mk_bits( clog2( num_inports + 1 ) ) -# 152 src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(0)], [b1(0), b1(0), b1(1)]), -# 153 CtrlType( OPT_SUB, b1(0), pickRegister, [RouteType(0), RouteType(3), RouteType(2)], [b1(0), b1(0), b1(0)]), -# 154 CtrlType( OPT_ADD, b1(1), pickRegister, [RouteType(0), RouteType(0), RouteType(0)], [b1(1), b1(1), b1(0)]) ] -# 155 src_data = [ [DataType(1, 1), DataType(2, 1)], [DataType(3, 1), DataType(4, 1), DataType(5, 0)], [DataType(6, 1), DataType(7, 0)] ] -# 156 sink_out = [ [DataType(3, 1)], [DataType(1, 1), DataType(7, 0, 1)], [DataType(4, 1)] ] -# 157 th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, -# 158 src_data, src_opt, sink_out ) -# 159 run_sim( th ) diff --git a/noc/test/CrossbarRTL_test.py b/noc/test/CrossbarRTL_test.py index faa5f79..eb13461 100644 --- a/noc/test/CrossbarRTL_test.py +++ b/noc/test/CrossbarRTL_test.py @@ -10,7 +10,7 @@ """ from pymtl3 import * -from ..CrossbarRTL import CrossbarRTL +from ..CrossbarSeparateRTL import CrossbarSeparateRTL from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ...lib.opt_type import * @@ -20,140 +20,115 @@ # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, CrossbarUnit, DataType, PredicateType, CtrlType, - num_inports, num_outports, - src_data, src_routing, sink_out ): + def construct(s, CrossbarUnit, DataType, PredicateType, CtrlType, + num_inports, num_outports, src_data, src_routing, + sink_out): s.num_inports = num_inports s.num_outports = num_outports - s.src_opt = TestSrcRTL( CtrlType, src_routing ) - s.src_data = [ TestSrcRTL( DataType, src_data[i] ) - for i in range( num_inports ) ] - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( num_outports ) ] + s.src_opt = TestSrcRTL(CtrlType, src_routing) + s.src_data = [TestSrcRTL(DataType, src_data[i]) + for i in range(num_inports)] + s.sink_out = [TestSinkRTL(DataType, sink_out[i]) + for i in range(num_outports)] - s.dut = CrossbarUnit( DataType, PredicateType, CtrlType, num_inports, - num_outports, num_inports-1 ) + s.dut = CrossbarUnit(DataType, PredicateType, CtrlType, num_inports, + num_outports) - for i in range( num_inports ): - connect( s.src_data[i].send, s.dut.recv_data[i] ) - connect( s.dut.send_data[i], s.sink_out[i].recv ) - connect( s.src_opt.send, s.dut.recv_opt ) + for i in range(num_inports): + s.src_data[i].send //= s.dut.recv_data[i] + s.dut.send_data[i] //= s.sink_out[i].recv + s.src_opt.send //= s.dut.recv_opt - def done( s ): + for i in range(num_outports): + s.dut.crossbar_outport[i] //= s.src_opt.send.msg.routing_xbar_outport[i] + + def done(s): done = True - for i in range( s.num_inports ): + for i in range(s.num_inports): if not s.src_data[i].done(): done = False break - for i in range( s.num_outports ): + for i in range(s.num_outports): if not s.sink_out[i].done(): done = False break return done - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def run_sim( test_harness, max_cycles=100 ): +def run_sim(test_harness, max_cycles = 20): test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) + test_harness.apply(DefaultPassGroup()) test_harness.sim_reset() # Run simulation ncycles = 0 print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) + 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() )) + 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() +FU = CrossbarSeparateRTL +num_fu_inports = 2 +num_fu_outports = 2 +num_tile_inports = 3 +num_tile_outports = 1 +num_routing_outports = num_fu_inports + num_tile_outports +num_ctrl_operations = 64 +TileInType = mk_bits(clog2(num_tile_inports + 1)) +FuInType = mk_bits(clog2(num_fu_inports + 1)) +FuOutType = mk_bits(clog2(num_fu_outports + 1)) +DataType = mk_data(16, 1) +PredicateType = mk_predicate(1, 1) +CtrlType = \ + mk_separate_ctrl(num_ctrl_operations, num_fu_inports, + num_fu_outports, num_tile_inports, + num_tile_outports) +# CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) +pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)] +# RouteType = mk_bits( clog2( num_inports + 1 ) ) +# src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(3), RouteType(1)]) ] + def test_crossbar(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(3), RouteType(1)]) ] - src_data = [ [DataType(3, 1)], [DataType(2, 1)], [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1)], [DataType(9, 1, 1)], [DataType(3, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - -def test_multi(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(1)]) ] - src_data = [ [DataType(3, 1)], [DataType(2, 1)], [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1)], [DataType(3, 1)], [DataType(3, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - -def test_multi2(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( 0 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - # RouteType(0) indicates no data movement. Reg ID starts from 1, which will get "minus 1" - # the logic. - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(0)]), - CtrlType( OPT_SUB, b1(0), pickRegister, [RouteType(0), RouteType(3), RouteType(2)]) ] - src_data = [ [DataType(3, 1)], [DataType(2, 1), DataType(20, 1)], [DataType(9, 1)] ] - sink_out = [ [DataType(2, 1)], [DataType(3, 1), DataType(9, 1, 1)], [DataType(20, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) - -def test_predicate(): - FU = CrossbarRTL - num_fu_in = 3 - num_inports = 3 - num_outports = 3 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( 0 ) for x in range( num_inports ) ] - RouteType = mk_bits( clog2( num_inports + 1 ) ) - src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(1), RouteType(0)], [b1(0), b1(0), b1(1)]), - CtrlType( OPT_SUB, b1(0), pickRegister, [RouteType(0), RouteType(3), RouteType(2)], [b1(0), b1(0), b1(0)]), - CtrlType( OPT_ADD, b1(1), pickRegister, [RouteType(0), RouteType(0), RouteType(0)], [b1(1), b1(1), b1(0)]) ] - src_data = [ [DataType(1, 1), DataType(2, 1)], [DataType(3, 1), DataType(4, 1), DataType(5, 0)], [DataType(6, 1), DataType(7, 0)] ] - sink_out = [ [DataType(3, 1)], [DataType(1, 1), DataType(7, 0, 1)], [DataType(4, 1)] ] - th = TestHarness( FU, DataType, PredicateType, CtrlType, num_inports, num_outports, - src_data, src_opt, sink_out ) - run_sim( th ) + src_opt = [CtrlType(OPT_ADD, b1(0), pickRegister, + # routing_xbar_output + [TileInType(2), TileInType(3), TileInType(1)], + # fu_xbar_output + [FuOutType(0), FuOutType(0), FuOutType(0)])] + src_data = [[DataType(3, 1)], [DataType(2, 1)], [DataType(9, 1)]] + sink_out = [[DataType(2, 1)], [DataType(9, 1)], [DataType(3, 1)]] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_tile_inports, + num_routing_outports, src_data, src_opt, sink_out) + run_sim(th) + +def test_multi_cast(): + src_opt = [CtrlType(OPT_ADD, b1(0), pickRegister, + # routing_xbar_output + [TileInType(2), TileInType(1), TileInType(1)], + # fu_xbar_output + [FuOutType(0), FuOutType(0), FuOutType(0)]), + CtrlType(OPT_NAH, b1(0), pickRegister, + # routing_xbar_output + [TileInType(0), TileInType(0), TileInType(3)], + # fu_xbar_output + [FuOutType(0), FuOutType(0), FuOutType(0)])] + src_data = [[DataType(3, 1)], [DataType(2, 1)], [DataType(9, 1)]] + sink_out = [[DataType(2, 1)], [DataType(3, 1)], [DataType(3, 1), DataType(9, 1)]] + th = TestHarness(FU, DataType, PredicateType, CtrlType, num_tile_inports, + num_routing_outports, src_data, src_opt, sink_out) + run_sim(th) diff --git a/noc/test/Multicaster_test.py b/noc/test/Multicaster_test.py deleted file mode 100644 index 394dd09..0000000 --- a/noc/test/Multicaster_test.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -========================================================================== -MulticasterRTL_test.py -========================================================================== -Test cases for Multicaster. - -Author : Cheng Tan - Date : Feb 16, 2019 - -""" - -from pymtl3 import * -from ..MulticasterRTL import MulticasterRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.opt_type import * -from ...lib.messages import * - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, Unit, DataType, num_outports, src_data ): - - s.num_outports = num_outports - - s.src_data = TestSrcRTL( DataType, src_data ) - s.sink_out = [ TestSinkRTL( DataType, src_data ) - for _ in range( num_outports ) ] - - s.dut = Unit( DataType, num_outports ) - - connect( s.src_data.send, s.dut.recv ) - for i in range( num_outports ): - connect( s.dut.send[i], s.sink_out[i].recv ) - - def done( s ): - done = True - for i in range( s.num_outports ): - if not s.sink_out[i].done(): - done = False - break - return done - - def line_trace( s ): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles=100 ): - 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() - -def test_Multicaster(): - FU = MulticasterRTL - num_outports = 3 - DataType = mk_data( 16, 1 ) - src_data = [ DataType(3, 1), DataType(2, 1), DataType(9, 1) ] - th = TestHarness( FU, DataType, num_outports, src_data ) - run_sim( th ) - diff --git a/scale_out/translate/RingMultiCgraRingCtrlMemRTL_test.py b/scale_out/translate/RingMultiCgraRingCtrlMemRTL_test.py deleted file mode 100644 index ea2a223..0000000 --- a/scale_out/translate/RingMultiCgraRingCtrlMemRTL_test.py +++ /dev/null @@ -1,218 +0,0 @@ -""" -========================================================================== -RingMultiCgraRingCtrlMemRTL_test.py -========================================================================== -Test cases for CGRA with controller. - -Author : Cheng Tan - Date : Dec 23, 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 ..RingMultiCgraRingCtrlMemRTL import RingMultiCgraRingCtrlMemRTL -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.cmd_type import * -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness(Component): - def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlPktType, CtrlSignalType, NocPktType, CmdType, - cgra_rows, cgra_columns, width, height, ctrl_mem_size, - data_mem_size_global, data_mem_size_per_bank, - num_banks_per_cgra, src_ctrl_pkt, ctrl_steps, - controller2addr_map): - - s.num_terminals = cgra_rows * cgra_columns - s.num_tiles = width * height - # CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - - # s.src_opt = [[TestSrcRTL(CtrlType, src_opt[j]) - # for j in range(s.num_tiles)] - # for i in range(s.num_terminals)] - s.src_ctrl_pkt = ValRdyTestSrcRTL(CtrlPktType, src_ctrl_pkt) - # s.ctrl_waddr = [[TestSrcRTL(CtrlAddrType, ctrl_waddr[j]) - # for j in range(s.num_tiles)] - # for i in range(s.num_terminals)] - - s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, - NocPktType, CmdType, cgra_rows, cgra_columns, height, width, - ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, - num_banks_per_cgra, ctrl_steps, ctrl_steps, - FunctionUnit, FuList, controller2addr_map) - - # Connections - # s.dut.data_mem.recv_from_noc.rdy //= 0 - # s.dut.data_mem.send_to_noc.msg //= DataType(0, 0) - # s.dut.data_mem.send_to_noc.en //= 0 - # s.src_val_rdy.send //= s.dut.recv_from_other - # s.dut.send_to_other //= s.sink_val_rdy.recv - - # s.dut.recv_towards_controller.en //= 0 - # s.dut.recv_towards_controller.msg //= DataType(0, 0) - # s.dut.send_from_controller.rdy //= 0 - - # for i in range(num_terminals): - # for j in range(s.num_tiles): - # connect(s.src_opt[i][j].send, s.dut.recv_wopt[i][j]) - # connect(s.ctrl_waddr[i][j].send, s.dut.recv_waddr[i][j]) - s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt - - def done(s): - return s.src_ctrl_pkt.done() - # for i in range(s.num_terminals): - # for j in range(s.num_tiles): - # if not s.src_opt[i][j].done(): - # return False - # return True - - 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_global = 32 - data_mem_size_per_bank = 4 - num_banks_per_cgra = 2 - cgra_rows = 2 - cgra_columns = 2 - num_terminals = cgra_rows * cgra_columns - width = 2 - height = 2 - num_ctrl_actions = 6 - num_ctrl_operations = 64 - TileInType = mk_bits(clog2(num_tile_inports + 1)) - FuInType = mk_bits(clog2(num_fu_inports + 1)) - FuOutType = mk_bits(clog2(num_fu_outports + 1)) - ctrl_addr_nbits = clog2(ctrl_mem_size) - # CtrlAddrType = mk_bits(ctrl_addr_nbits) - data_addr_nbits = clog2(data_mem_size_global) - DataAddrType = mk_bits(clog2(data_mem_size_global)) - num_tiles = width * height - DUT = RingMultiCgraRingCtrlMemRTL - FunctionUnit = FlexibleFuRTL - FuList = [MemUnitRTL, AdderRTL] - DataType = mk_data(32, 1) - PredicateType = mk_predicate(1, 1) - CmdType = mk_bits(4) - controller2addr_map = { - 0: [0, 7], - 1: [8, 15], - 2: [16, 23], - 3: [24, 31], - } - CtrlPktType = \ - mk_ring_across_tiles_pkt(width * height, - num_ctrl_actions, - ctrl_mem_size, - num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - CtrlSignalType = \ - mk_separate_ctrl(num_ctrl_operations, - num_fu_inports, - num_fu_outports, - num_tile_inports, - num_tile_outports) - NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, - addr_nbits = data_addr_nbits, - data_nbits = 32, - predicate_nbits = 1) - pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)] - src_opt_per_tile = [[ - # src dst vc_id opq cmd_type addr operation predicate - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, 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)]), - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 2, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 3, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 4, 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)]), - - CtrlPktType(0, i, 0, 0, CMD_CONFIG, 5, 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)]), - - # This last one is for launching kernel. - CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, 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 i in range(num_tiles)] - - src_ctrl_pkt = [] - for opt_per_tile in src_opt_per_tile: - src_ctrl_pkt.extend(opt_per_tile) - - th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, CtrlPktType, - CtrlSignalType, NocPktType, CmdType, cgra_rows, cgra_columns, - width, height, ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, src_ctrl_pkt, - ctrl_mem_size, controller2addr_map) - 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) - diff --git a/scale_out/translate/__init__.py b/scale_out/translate/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/systolic/CgraMemBottomRTL.py b/systolic/CgraMemBottomRTL.py deleted file mode 100644 index 6b22c79..0000000 --- a/systolic/CgraMemBottomRTL.py +++ /dev/null @@ -1,115 +0,0 @@ -""" -========================================================================= -CgraMemBottomRTL.py -========================================================================= -The scrachpad memory is connected to the bottom (first row) tiles. - -Author : Cheng Tan - Date : Nov 18, 2024 -""" - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.AdderRTL import AdderRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..mem.data.DataMemRTL import DataMemRTL -from ..mem.data.DataMemCL import DataMemCL -from ..noc.ChannelRTL import ChannelRTL -from ..noc.CrossbarRTL import CrossbarRTL -from ..tile.TileRTL import TileRTL - -class CgraMemBottomRTL(Component): - def construct(s, DataType, PredicateType, CtrlType, 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)] - - # Components - if preload_const == None: - preload_const = [[DataType(0, 0)] for _ in range(width * height)] - s.tile = [TileRTL(DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, - s.num_mesh_ports, Fu = FunctionUnit, - FuList = FuList, const_list = preload_const[i]) - for i in range(s.num_tiles)] - s.data_mem = DataMemRTL(DataType, data_mem_size, height, height, - preload_data) - - s.send_data = [SendIfcRTL(DataType) for _ in range (height - 1)] - - # Connections - 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: - if i // width != 0: - # Connects the send ports to the right-most tiles (except the - # ones on the first row). - s.tile[i].send_data[PORT_EAST] //= s.send_data[i // width - 1] - s.tile[i].recv_data[PORT_EAST].en //= 0 - s.tile[i].recv_data[PORT_EAST].msg //= DataType(0, 0) - else: - 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 :: Mem [" + s.data_mem.line_trace() + "] \n" - return res diff --git a/systolic/CgraMemRightAndBottomRTL.py b/systolic/CgraMemRightAndBottomRTL.py index f96550f..8b6ac9a 100644 --- a/systolic/CgraMemRightAndBottomRTL.py +++ b/systolic/CgraMemRightAndBottomRTL.py @@ -20,33 +20,32 @@ from ..lib.util.common import * from ..mem.data.DataMemRTL import DataMemRTL from ..mem.data.DataMemCL import DataMemCL -from ..noc.ChannelRTL import ChannelRTL from ..noc.CrossbarRTL import CrossbarRTL -from ..tile.TileRTL import TileRTL +from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL class CgraMemRightAndBottomRTL(Component): - def construct(s, DataType, PredicateType, CtrlType, width, height, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - FunctionUnit, FuList, preload_data = None, + def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, + 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 + s.num_tiles = width * height 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_wopt = [RecvIfcRTL(CtrlSignalType) for _ in range(s.num_tiles)] # Components if preload_const == None: preload_const = [[DataType(0, 0)] for _ in range(width * height)] - s.tile = [TileRTL(DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, - s.num_mesh_ports, Fu = FunctionUnit, - FuList = FuList, const_list = preload_const[i]) - for i in range(s.num_tiles)] + s.tile = [TileSeparateCrossbarRTL( + DataType, PredicateType, CtrlPktType, CtrlPktType, + CtrlSignalType, ctrl_mem_size, data_mem_size, num_ctrl, + total_steps, 4, 2, s.num_mesh_ports, s.num_mesh_ports, + Fu = FunctionUnit, FuList = FuList, + const_list = preload_const[i]) for i in range(s.num_tiles)] s.data_mem_south = DataMemRTL(DataType, data_mem_size, rd_ports = width, wr_ports = width, diff --git a/systolic/CgraSystolicArrayRTL.py b/systolic/CgraSystolicArrayRTL.py new file mode 100644 index 0000000..5244ccb --- /dev/null +++ b/systolic/CgraSystolicArrayRTL.py @@ -0,0 +1,176 @@ +""" +========================================================================= +CgraSystolicArrayRTL.py +========================================================================= + +Author : Cheng Tan + Date : Dec 22, 2024 +""" + +from pymtl3 import * +from ..controller.ControllerRTL import ControllerRTL +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.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL +from ..lib.opt_type import * +from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL +from ..noc.ChannelNormalRTL import ChannelNormalRTL +from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL +from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos +from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL +from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL + +class CgraSystolicArrayRTL(Component): + + def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, + NocPktType, CmdType, ControllerIdType, controller_id, + width, height, ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, num_ctrl, + total_steps, FunctionUnit, FuList, controller2addr_map, + preload_data = None, preload_const = None): + + # Other topology can simply modify the tiles connections, or + # leverage the template for modeling. + s.num_mesh_ports = 4 + + assert(width == 3) + assert(height == 3) + assert(num_banks_per_cgra == 4) + s.num_tiles = width * height + CtrlRingPos = mk_ring_pos(s.num_tiles) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + DataAddrType = mk_bits(clog2(data_mem_size_global)) + assert(data_mem_size_per_bank * num_banks_per_cgra <= \ + data_mem_size_global) + + # Interfaces + s.recv_from_cpu_ctrl_pkt = RecvIfcRTL(CtrlPktType) + s.recv_from_noc = RecvIfcRTL(NocPktType) + s.send_to_noc = SendIfcRTL(NocPktType) + + # Interfaces on the boundary of the CGRA. + s.recv_data_on_boundary_south = [RecvIfcRTL(DataType) for _ in range(width )] + s.send_data_on_boundary_south = [SendIfcRTL(DataType) for _ in range(width )] + s.recv_data_on_boundary_north = [RecvIfcRTL(DataType) for _ in range(width )] + s.send_data_on_boundary_north = [SendIfcRTL(DataType) for _ in range(width )] + + s.recv_data_on_boundary_east = [RecvIfcRTL(DataType) for _ in range(height)] + s.send_data_on_boundary_east = [SendIfcRTL(DataType) for _ in range(height)] + s.recv_data_on_boundary_west = [RecvIfcRTL(DataType) for _ in range(height)] + s.send_data_on_boundary_west = [SendIfcRTL(DataType) for _ in range(height)] + + # Components + if preload_const == None: + preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] + s.tile = [TileSeparateCrossbarRTL( + DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, + data_mem_size_global, num_ctrl, total_steps, 4, 2, + s.num_mesh_ports, s.num_mesh_ports, FuList = FuList, + const_list = preload_const[i], id = i) for i in range(s.num_tiles)] + s.data_mem = DataMemWithCrossbarRTL(NocPktType, DataType, + data_mem_size_global, + data_mem_size_per_bank, + num_banks_per_cgra, + # 4 read/write from tiles and 1 read/write from NoC. + 4, 4, + preload_data) + s.controller = ControllerRTL(ControllerIdType, CmdType, CtrlPktType, + NocPktType, DataType, DataAddrType, + controller_id, controller2addr_map) + s.ctrl_ring = RingNetworkRTL(CtrlPktType, CtrlRingPos, s.num_tiles, 0) + + # Connections + # Connects data memory with controller. + s.data_mem.recv_raddr[4] //= s.controller.send_to_master_load_request_addr + s.data_mem.recv_waddr[4] //= s.controller.send_to_master_store_request_addr + s.data_mem.recv_wdata[4] //= s.controller.send_to_master_store_request_data + s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data + s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt + s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt + s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt + + s.recv_from_noc //= s.controller.recv_from_noc + s.send_to_noc //= s.controller.send_to_noc + + # Connects the ctrl interface between CPU and controller. + s.recv_from_cpu_ctrl_pkt //= s.controller.recv_from_cpu_ctrl_pkt + + # Connects ring with each control memory. + for i in range(s.num_tiles): + s.ctrl_ring.send[i] //= s.tile[i].recv_ctrl_pkt + + s.ctrl_ring.recv[0] //= s.controller.send_to_ctrl_ring_ctrl_pkt + for i in range(1, s.num_tiles): + s.ctrl_ring.recv[i].val //= 0 + s.ctrl_ring.recv[i].msg //= CtrlPktType() + + for i in range(s.num_tiles): + + 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] //= s.send_data_on_boundary_south[i % width] + s.tile[i].recv_data[PORT_SOUTH] //= s.recv_data_on_boundary_south[i % width] + + if i // width == height - 1: + s.tile[i].send_data[PORT_NORTH] //= s.send_data_on_boundary_north[i % width] + s.tile[i].recv_data[PORT_NORTH] //= s.recv_data_on_boundary_north[i % width] + + if i % width == 0: + s.tile[i].send_data[PORT_WEST] //= s.send_data_on_boundary_west[i // width] + s.tile[i].recv_data[PORT_WEST] //= s.recv_data_on_boundary_west[i // width] + + if i % width == width - 1: + s.tile[i].send_data[PORT_EAST] //= s.send_data_on_boundary_east[i // width] + s.tile[i].recv_data[PORT_EAST] //= s.recv_data_on_boundary_east[i // width] + + # Memory banks are connected at bottom and right of the CGRA/systolic array. + if i == 0: + s.tile[i].to_mem_raddr //= s.data_mem.recv_raddr[0] + s.tile[i].from_mem_rdata //= s.data_mem.send_rdata[0] + s.tile[i].to_mem_waddr //= s.data_mem.recv_waddr[0] + s.tile[i].to_mem_wdata //= s.data_mem.recv_wdata[0] + elif i == 1: + s.tile[i].to_mem_raddr //= s.data_mem.recv_raddr[1] + s.tile[i].from_mem_rdata //= s.data_mem.send_rdata[1] + s.tile[i].to_mem_waddr //= s.data_mem.recv_waddr[1] + s.tile[i].to_mem_wdata //= s.data_mem.recv_wdata[1] + elif i == 5: + s.tile[i].to_mem_raddr //= s.data_mem.recv_raddr[2] + s.tile[i].from_mem_rdata //= s.data_mem.send_rdata[2] + s.tile[i].to_mem_waddr //= s.data_mem.recv_waddr[2] + s.tile[i].to_mem_wdata //= s.data_mem.recv_wdata[2] + elif i == 8: + s.tile[i].to_mem_raddr //= s.data_mem.recv_raddr[3] + s.tile[i].from_mem_rdata //= s.data_mem.send_rdata[3] + s.tile[i].to_mem_waddr //= s.data_mem.recv_waddr[3] + s.tile[i].to_mem_wdata //= s.data_mem.recv_wdata[3] + else: + s.tile[i].to_mem_raddr.rdy //= 0 + s.tile[i].from_mem_rdata.val //= 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): + res = "Controller: " + s.controller.line_trace() + "\n" + res += "Ctrl Ring: " + s.ctrl_ring.line_trace() + "\n" + res += "||\n\n".join([(("[tile"+str(i)+"]: ") + x.line_trace()) + for (i,x) in enumerate(s.tile)]) + res += "\nData Memory: [" + s.data_mem.line_trace() + "] \n" + return res + diff --git a/systolic/SystolicCL.py b/systolic/SystolicCL.py deleted file mode 100644 index 4600171..0000000 --- a/systolic/SystolicCL.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -========================================================================= -SystolicCL.py -========================================================================= - -Author : Cheng Tan - Date : May 24, 2020 -""" - - -from pymtl3 import * -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..mem.data.DataMemCL import DataMemCL -from ..noc.CrossbarRTL import CrossbarRTL -from ..noc.ChannelRTL import ChannelRTL -from ..tile.TileCL import TileCL - - -class SystolicCL( Component ): - - def construct( s, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - num_ctrl, total_steps, preload_ctrl, preload_data, - preload_const ): - - # Constant - NORTH = 0 - SOUTH = 1 - WEST = 2 - EAST = 3 - s.num_tiles = width * height - s.num_mesh_ports = 4 - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - s.send_data = [ SendIfcRTL( DataType ) for _ in range ( height-1 ) ] - - # Components - s.tile = [ TileCL( FunctionUnit, FuList, DataType, PredicateType, - CtrlType, ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, preload_const[i], preload_ctrl[i] ) - for i in range( s.num_tiles ) ] - s.data_mem = DataMemCL( DataType, data_mem_size, height, height, - preload_data ) - - # Connections - - for i in range( s.num_tiles): - - if i // width > 0: - s.tile[i].send_data[SOUTH] //= s.tile[i-width].recv_data[NORTH] - - if i // width < height - 1: - s.tile[i].send_data[NORTH] //= s.tile[i+width].recv_data[SOUTH] - - if i % width > 0: - s.tile[i].send_data[WEST] //= s.tile[i-1].recv_data[EAST] - - if i % width < width - 1: - s.tile[i].send_data[EAST] //= s.tile[i+1].recv_data[WEST] - - if i // width == 0: - s.tile[i].send_data[SOUTH].rdy //= 0 - s.tile[i].recv_data[SOUTH].en //= 0 - s.tile[i].recv_data[SOUTH].msg //= DataType( 0, 0 ) - - if i // width == height - 1: - s.tile[i].send_data[NORTH].rdy //= 0 - s.tile[i].recv_data[NORTH].en //= 0 - s.tile[i].recv_data[NORTH].msg //= DataType( 0, 0 ) - - if i % width == 0: - s.tile[i].send_data[WEST].rdy //= 0 - s.tile[i].recv_data[WEST].en //= 0 - s.tile[i].recv_data[WEST].msg //= DataType( 0, 0 ) - - if i % width == width - 1: - if i // width != 0: - s.tile[i].send_data[EAST] //= s.send_data[i//width-1] - s.tile[i].recv_data[EAST].en //= 0 - s.tile[i].recv_data[EAST].msg //= DataType( 0, 0 ) - else: - s.tile[i].send_data[EAST].rdy //= 0 - s.tile[i].recv_data[EAST].en //= 0 - s.tile[i].recv_data[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 = "||\n".join([ (x.line_trace() + x.ctrl_mem.line_trace()) - for x in s.tile ]) - str += "\n[data] :: [" + s.data_mem.line_trace() + "]\n" - return str - diff --git a/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py new file mode 100644 index 0000000..86574b0 --- /dev/null +++ b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py @@ -0,0 +1,666 @@ +""" +========================================================================== +CgraRightAndBottomRTL_matmul_2x2_test.py +========================================================================== +Translation for 3x3 CGRA. The provided test is only used for a 2x2 matmul. + +Author : Cheng Tan + Date : Nov 19, 2024 +""" + +from pymtl3 import * +from pymtl3.passes.backends.verilog import VerilogTranslationPass +from pymtl3.stdlib.test_utils import (run_sim, + config_model_with_cmdline_opts) +from ..CgraSystolicArrayRTL import CgraSystolicArrayRTL +from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL +from ...fu.single.AdderRTL import AdderRTL +from ...fu.single.BranchRTL import BranchRTL +from ...fu.single.CompRTL import CompRTL +from ...fu.single.LogicRTL import LogicRTL +from ...fu.single.MemUnitRTL import MemUnitRTL +from ...fu.single.MulRTL import MulRTL +from ...fu.single.PhiRTL import PhiRTL +from ...fu.single.SelRTL import SelRTL +from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL +from ...fu.single.ShifterRTL import ShifterRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL +from ...lib.cmd_type import * +from ...lib.messages import * +from ...lib.opt_type import * + +#------------------------------------------------------------------------- +# Test harness +#------------------------------------------------------------------------- + +kMaxCycles = 100 + +class TestHarness(Component): + def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, width, height, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + src_ctrl_pkt, ctrl_steps, controller2addr_map, + preload_data, preload_const, expected_out): + + s.DataType = DataType + s.num_tiles = width * height + s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) + s.expected_out = expected_out + + s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, + NocPktType, CmdType, ControllerIdType, controller_id, + width, height, ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + # FIXME: num_ctrl should be just 1, or support + # prologue: https://github.com/tancheng/VectorCGRA/issues/55. + kMaxCycles, kMaxCycles, FunctionUnit, FuList, + controller2addr_map, preload_data, preload_const) + + # Connections. + s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt + + s.dut.send_to_noc.rdy //= 0 + s.dut.recv_from_noc.val //= 0 + s.dut.recv_from_noc.msg //= NocPktType(0, 0, 0, 0, 0, 0) + + for tile_col in range(width): + s.dut.send_data_on_boundary_north[tile_col].rdy //= 0 + s.dut.recv_data_on_boundary_north[tile_col].val //= 0 + s.dut.recv_data_on_boundary_north[tile_col].msg //= DataType() + + s.dut.send_data_on_boundary_south[tile_col].rdy //= 0 + s.dut.recv_data_on_boundary_south[tile_col].val //= 0 + s.dut.recv_data_on_boundary_south[tile_col].msg //= DataType() + + for tile_row in range(height): + s.dut.send_data_on_boundary_west[tile_row].rdy //= 0 + s.dut.recv_data_on_boundary_west[tile_row].val //= 0 + s.dut.recv_data_on_boundary_west[tile_row].msg //= DataType() + + s.dut.send_data_on_boundary_east[tile_row].rdy //= 0 + s.dut.recv_data_on_boundary_east[tile_row].val //= 0 + s.dut.recv_data_on_boundary_east[tile_row].msg //= DataType() + + # Checks the output parity. + def check_parity(s): + for i in range(len(s.expected_out)): + for j in range(len(s.expected_out[i])): + # Outputs are stored in bank 2 and bank 3. + if s.dut.data_mem.reg_file[2+i].regs[j] != s.expected_out[i][j]: + return False + return True + + def done(s): + return s.check_parity() + + def line_trace(s): + return s.dut.line_trace() + +def run_sim(test_harness, enable_verification_pymtl, + max_cycles = kMaxCycles): + # test_harness.elaborate() + test_harness.apply(DefaultPassGroup()) + # Reset is essential for most simulation, which would initialize + # many signals. For example, the credit-based virtual channel + # needs to be initialized with number of supported credits. + test_harness.sim_reset() + + # Run simulation + ncycles = 0 + print() + print("{}:{}".format( ncycles, test_harness.line_trace())) + if enable_verification_pymtl: + while not test_harness.done() and ncycles < kMaxCycles: + test_harness.sim_tick() + ncycles += 1 + print("----------------------------------------------------") + print("{}:{}".format( ncycles, test_harness.line_trace())) + + # Checks the output parity. + assert test_harness.check_parity() + + # Checks timeout. + assert ncycles < max_cycles + else: + while ncycles < max_cycles: + test_harness.sim_tick() + ncycles += 1 + print("----------------------------------------------------") + print("{}:{}".format( ncycles, test_harness.line_trace())) + + test_harness.sim_tick() + test_harness.sim_tick() + test_harness.sim_tick() + +def test_CGRA_systolic(cmdline_opts): + + tile_ports = 4 + num_tile_inports = tile_ports + num_tile_outports = tile_ports + num_fu_inports = 4 + num_fu_outports = 2 + num_routing_outports = num_tile_outports + num_fu_inports + # FIXME: Needs to be more than number of ctrl signals. + # Maybe simplied as max(all_ctrl_across_all_tiles). + ctrl_mem_size = 8 + data_mem_size_global = 32 + data_mem_size_per_bank = 4 + num_banks_per_cgra = 4 + width = 3 + height = 3 + num_terminals = 2 + num_ctrl_actions = 6 + num_ctrl_operations = 64 + TileInType = mk_bits(clog2(num_tile_inports + 1)) + FuInType = mk_bits(clog2(num_fu_inports + 1)) + FuOutType = mk_bits(clog2(num_fu_outports + 1)) + addr_nbits = clog2(data_mem_size_global) + AddrType = mk_bits(addr_nbits) + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + num_tiles = width * height + DUT = CgraSystolicArrayRTL + FunctionUnit = FlexibleFuRTL + DataType = mk_data(32, 1) + PredicateType = mk_predicate(1, 1) + FuList = [SeqMulAdderRTL, AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL] + + CmdType = mk_bits(4) + ControllerIdType = mk_bits(clog2(num_terminals)) + controller_id = 0 + # controller2addr_map = { + # 0: [0, 3 ], + # 1: [4, 7 ], + # 2: [8, 11], + # 3: [12, 15], + # } + + controller2addr_map = { + 0: [0, 15], + 1: [16, 31], + } + + CtrlPktType = \ + mk_ring_across_tiles_pkt(width * height, + num_ctrl_actions, + ctrl_mem_size, + num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + CtrlSignalType = \ + mk_separate_ctrl(num_ctrl_operations, + num_fu_inports, + num_fu_outports, + num_tile_inports, + num_tile_outports) + + NocPktType = mk_ring_multi_cgra_pkt(nrouters = num_terminals, + addr_nbits = addr_nbits, + data_nbits = 32, + predicate_nbits = 1) + pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] + # tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] + # fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] + + # src_opt_per_tile = [ + # # src dst vc_id opq cmd_type addr operation predicate + # [CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, OPT_INC, b1(0), + # pick_register, tile_in_code, fu_out_code), + # # [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)]), + # CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, OPT_INC, b1(0), + # pick_register, tile_in_code, fu_out_code), + # # pick_register, + # # [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)]), + + + + src_opt_per_tile = [ + # On tile 0 ([0, 0]). + # src dst vc_id opq cmd_type addr operation predicate + [ + CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 0, OPT_LD_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 1, OPT_LD_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 2, OPT_LD_CONST, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 3, OPT_LD_CONST, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 0, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 1 ([0, 1]). + # src dst vc_id opq cmd_type addr operation predicate + [ + # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 0, OPT_LD_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 1, OPT_LD_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 3, OPT_LD_CONST, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 4, OPT_LD_CONST, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 1, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 2 ([0, 2]). + [CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 2, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 2, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 3 ([1, 0]). + [CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 1, OPT_MUL_CONST, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 2, OPT_MUL_CONST, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 3, OPT_MUL_CONST, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + + # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 3, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 4 ([1, 1]). + [ + # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 1, OPT_MUL_CONST_ADD, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 2, OPT_MUL_CONST_ADD, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 4, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 5 ([1, 2]). + [ + # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(3), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 1, OPT_STR_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(3), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 2, OPT_STR_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 5, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 6 ([2, 0]). + [ + # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 1, OPT_MUL_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 2, OPT_MUL_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 6, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 7 ([2, 1]). + [ + # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, + # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 1, OPT_MUL_CONST_ADD, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(3), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 2, OPT_MUL_CONST_ADD, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 7, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])], + + # On tile 8 ([2, 2]). + [ + # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 2, OPT_NAH, b1(0), pick_register, + # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(3), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 1, OPT_STR_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(3), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 2, OPT_STR_CONST, b1(0), pick_register, + [TileInType(0), TileInType(0), TileInType(0), TileInType(0), + TileInType(0), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), + CtrlPktType(0, 8, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, + [TileInType(2), TileInType(0), TileInType(0), TileInType(0), + TileInType(2), TileInType(0), TileInType(0), TileInType(0)], + [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), + FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)])]] + + src_ctrl_pkt = [] + for opt_per_tile in src_opt_per_tile: + src_ctrl_pkt.extend(opt_per_tile) + + test_meta_data = [ + # addr: 0 1 2 3 + [0x1, 0x2, 0x0, 0x0], + # addr: 4 5 6 7 + [0x3, 0x4, 0x0, 0x0], + # addr: 8 9 10 11 + [0x0, 0x0, 0x0, 0x0], + # addr: 12 13 14 15 + [0x0, 0x0, 0x0, 0x0]] + + preload_data_per_bank = [[DataType(test_meta_data[j][i], 1) + for i in range(data_mem_size_per_bank)] + for j in range(num_banks_per_cgra)] + + preload_const = [ + # The offset address used for loading input activation. + # We use a shared data memory here, indicating global address + # space. Users can make each tile has its own address space. + + # The last one is not useful for the first colum, which is just + # to make the length aligned. + [DataType(0, 1), DataType(1, 1), DataType(0, 0)], + # The first one is not useful for the second colum, which is just + # to make the length aligned. + [DataType(0, 0), DataType(4, 1), DataType(5, 1)], + # The third column is not actually necessary to perform activation + # loading nor storing parameters. + [DataType(0, 0), DataType(0, 0), DataType(0, 0)], + + # Preloads weights. 3 items to align with the above const length. + # Duplication exists as the iter of the const queue automatically + # increment. + [DataType(2, 1), DataType(2, 1), DataType(2, 1)], + [DataType(4, 1), DataType(4, 1), DataType(4, 1)], + # The third column (except the bottom one) is used to store the + # accumulated results. + [DataType(8, 1), DataType(9, 1), DataType(0, 0)], + + [DataType(6, 1), DataType(6, 1), DataType(6, 1)], + [DataType(8, 1), DataType(8, 1), DataType(8, 1)], + # The third column (except the bottom one) is used to store the + # accumulated results. + [DataType(12, 1), DataType(13, 1), DataType(0, 0)]] + + """ + 1 3 2 6 14 20 + x = + 2 4 4 8 30 44 + """ + expected_out = [[DataType(14, 1), DataType(20, 1)], + [DataType(30, 1), DataType(44, 1)]] + + # When the max iterations are larger than the number of control signals, + # enough ctrl_waddr needs to be provided to make execution (i.e., ctrl + # read) continue. + # 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, + # CtrlPktType, width, height, ctrl_mem_size, data_mem_size, + # src_opt, ctrl_waddr, preload_mem, preload_const, + # expected_out) + + th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, + CtrlPktType, CtrlSignalType, NocPktType, CmdType, + ControllerIdType, controller_id, width, height, + ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + src_ctrl_pkt, ctrl_mem_size, + controller2addr_map, preload_data_per_bank, + preload_const, expected_out) + + th.elaborate() + th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, + f'CgraSystolicArrayRTL') + # th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, + # ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', + # 'ALWCOMBORDER'] ) + th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut']) + + enable_verification_pymtl = not (cmdline_opts['test_verilog'] or \ + cmdline_opts['dump_vcd'] or \ + cmdline_opts['dump_vtb']) + run_sim(th, enable_verification_pymtl) + diff --git a/systolic/test/SystolicCL_test.py b/systolic/test/SystolicCL_test.py deleted file mode 100644 index 36eecf3..0000000 --- a/systolic/test/SystolicCL_test.py +++ /dev/null @@ -1,216 +0,0 @@ -""" -========================================================================== -SystolicCL_test.py -========================================================================== -Test cases for Systolic Array with CL data/config memory. - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - - -from pymtl3 import * -from ..SystolicCL import SystolicCL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...lib.util.ctrl_helper import * -import os - - -kMaxCycles = 6 - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, preload_data, preload_const, sink_out ): - - s.num_tiles = width * height - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( height-1 ) ] - - s.dut = DUT( FunctionUnit, FuList, DataType, PredicateType, CtrlType, - width, height, ctrl_mem_size, data_mem_size, - len( src_opt[0] ), kMaxCycles, src_opt, - preload_data, preload_const ) - - for i in range( height-1 ): - connect( s.dut.send_data[i], s.sink_out[i].recv ) - - def line_trace( s ): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles = kMaxCycles ): - test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) - - # Run simulation - ncycles = 0 - print() - print( "{}:{}".format( ncycles, test_harness.line_trace() )) - while ncycles < max_cycles: - test_harness.sim_tick() - ncycles += 1 - print( "----------------------------------------------------" ) - 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() - -# ------------------------------------------------------------------ -# To emulate systolic array -# left bottom is 0, 0 -# right top is 1, 1 -# 1: North, 2: South, 3: West, 4: East -# 5 - 8: registers -# ------------------------------------------------------------------ -def test_systolic_2x2(): - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 8 - width = 2 - height = 3 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - num_tiles = width * height - ctrl_mem_size = 8 - data_mem_size = 2 - # number of inputs of FU is fixed inside the tile - num_fu_in = 4 - - DUT = SystolicCL - FunctionUnit = FlexibleFuRTL - FuList = [AdderRTL, MemUnitRTL, SeqMulAdderRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - - src_opt = [ - # Tile 0: - [CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - ], - # Tile 1: - [CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_LD_CONST, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ), - ], - # Tile 2: - [CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_MUL_CONST, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_MUL_CONST, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_MUL_CONST, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - ], - # Tile 3: - [CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_MUL_CONST_ADD, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_MUL_CONST_ADD, b1( 0 ), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - ], - # Tile 4: - [CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_MUL_CONST, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - CtrlType( OPT_MUL_CONST, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)] ), - ], - # Tile 5: - [CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_MUL_CONST_ADD, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - CtrlType( OPT_MUL_CONST_ADD, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)] ), - ] - ] - preload_mem = [DataType(1, 1), DataType(2, 1), DataType(3, 1), DataType(4, 1)] - preload_const = [[DataType(0, 1), DataType(1, 1)], - [DataType(0, 0), DataType(2, 1), DataType(3, 1)], # offset address used for loading - [DataType(2, 1)], [DataType(4, 1)], # preloaded data - [DataType(6, 1)], [DataType(8, 1)]] # preloaded data - """ - 1 3 2 6 14 20 - x = - 2 4 4 8 30 44 - """ - sink_out = [[DataType(14, 1), DataType(20, 1)], [DataType(30, 1), DataType(44, 1)]] - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, len(preload_mem), - src_opt, preload_mem, preload_const, sink_out ) - run_sim( th ) - - diff --git a/systolic/translate/CgraMemBottomRTL_matmul_2x2_test.py b/systolic/translate/CgraMemBottomRTL_matmul_2x2_test.py deleted file mode 100644 index 69ffc0f..0000000 --- a/systolic/translate/CgraMemBottomRTL_matmul_2x2_test.py +++ /dev/null @@ -1,307 +0,0 @@ -""" -========================================================================== -CgraMemBottomRTL_matmul_2x2_test.py -========================================================================== -Translation for 3x2 CGRA. The provided test is only used for a 2x2 matmul. - -Author : Cheng Tan - Date : Oct 14, 2024 -""" - - -from pymtl3 import * -from pymtl3.passes.backends.verilog import VerilogTranslationPass -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..CgraMemBottomRTL import CgraMemBottomRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.messages import * -from ...lib.opt_type import * - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -kMaxCycles = 20 - -class TestHarness(Component): - def construct(s, DUT, FunctionUnit, fu_list, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, preload_data, preload_const, - sink_out): - - s.height = height - 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, width, height, - ctrl_mem_size, data_mem_size, kMaxCycles, - kMaxCycles, FunctionUnit, fu_list, preload_data, - preload_const) - - s.sink_out = [TestSinkRTL(DataType, sink_out[i]) - for i in range(height - 1)] - - for i in range(height - 1): - connect(s.dut.send_data[i], s.sink_out[i].recv) - - 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): - for i in range(s.height - 1): - if not s.sink_out[i].done(): - return False - return True - - def line_trace(s): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles = kMaxCycles ): - # test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) - - # Run simulation - ncycles = 0 - print() - print("{}:{}".format( ncycles, test_harness.line_trace())) - while not test_harness.done(): - test_harness.sim_tick() - ncycles += 1 - print("----------------------------------------------------") - 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() - -def test_CGRA_systolic(cmdline_opts): - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 10 - width = 2 - height = 3 - RouteType = mk_bits(clog2(num_xbar_inports + 1)) - AddrType = mk_bits(clog2(ctrl_mem_size)) - num_tiles = width * height - num_fu_in = 4 - DUT = CgraMemBottomRTL - FunctionUnit = FlexibleFuRTL - FuList = [SeqMulAdderRTL, AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL] - DataType = mk_data(32, 1) - PredicateType = mk_predicate(1, 1) - CtrlType = mk_ctrl(num_fu_in, num_xbar_inports, num_xbar_outports) - FuInType = mk_bits(clog2( num_fu_in + 1)) - pickRegister = [FuInType(x + 1) for x in range(num_fu_in)] - - src_opt = [ - # On tile 0 ([0, 0]). - [CtrlType(OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - # On tile 1 ([0, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - # On tile 2 ([1, 0]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - # On tile 3 ([1, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - ], - # On tile 4 ([2, 0]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - ], - # On tile 5 ([2, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - ] - ] - - preload_mem = [DataType(1, 1), DataType(2, 1), DataType(3, 1), - DataType(4, 1)] - preload_const = [ - # The offset address used for loading input activation. - # We use a shared data memory here, indicating global address - # space. Users can make each tile has its own address space. - - # The last one is not useful for the first colum, which is just - # to make the length aligned. - [DataType(0, 1), DataType(1, 1), DataType(0, 0)], - # The first one is not useful for the second colum, which is just - # to make the length aligned. - [DataType(0, 0), DataType(2, 1), DataType(3, 1)], - - # Preloads weights. 3 items to align with the above const length. - # Duplication exists as the iter of the const queue automatically - # increment. - [DataType(2, 1), DataType(2, 1), DataType(2, 1)], - [DataType(4, 1), DataType(4, 1), DataType(4, 1)], - [DataType(6, 1), DataType(6, 1), DataType(6, 1)], - [DataType(8, 1), DataType(8, 1), DataType(8, 1)]] - - data_mem_size = len(preload_mem) - - """ - 1 3 2 6 14 20 - x = - 2 4 4 8 30 44 - """ - sink_out = [[DataType(14, 1), DataType(20, 1)], [DataType(30, 1), - DataType(44, 1)]] - - # When the max iterations are larger than the number of control signals, - # enough ctrl_waddr needs to be provided to make execution (i.e., ctrl - # read) continue. - 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, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, preload_mem, preload_const, - sink_out) - - th.elaborate() - th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, - f'CgraMemBottomRTL') - # 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) - diff --git a/systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py b/systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py deleted file mode 100644 index 02dfb58..0000000 --- a/systolic/translate/CgraMemRightAndBottomRTL_matmul_2x2_test.py +++ /dev/null @@ -1,406 +0,0 @@ -""" -========================================================================== -CgraRightAndBottomRTL_matmul_2x2_test.py -========================================================================== -Translation for 3x3 CGRA. The provided test is only used for a 2x2 matmul. - -Author : Cheng Tan - Date : Nov 19, 2024 -""" - - -from pymtl3 import * -from pymtl3.passes.backends.verilog import VerilogTranslationPass -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..CgraMemRightAndBottomRTL import CgraMemRightAndBottomRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.double.SeqMulAdderRTL import SeqMulAdderRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -kMaxCycles = 12 - -class TestHarness(Component): - def construct(s, DUT, FunctionUnit, fu_list, DataType, PredicateType, - CtrlType, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, preload_data, preload_const, - expected_out): - - s.DataType = DataType - s.expected_out = expected_out - 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, width, height, - ctrl_mem_size, data_mem_size, kMaxCycles, - kMaxCycles, FunctionUnit, fu_list, preload_data, - preload_const) - - 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]) - - # Simulation terminates if the output memory contains - # not less than the expected number of outputs. - def done(s): - num_valid_out = 0 - for data in s.dut.data_mem_east.reg_file.regs: - if data != s.DataType(0, 0): - num_valid_out += 1 - if num_valid_out >= len(s.expected_out): - return True - return False - - # Checks the output parity. - def check_parity(s): - for i in range(len(s.expected_out)): - if s.expected_out[i] != s.dut.data_mem_east.reg_file.regs[i]: - return False - return True - - def line_trace(s): - return s.dut.line_trace() - -def run_sim(test_harness, enable_verification_pymtl, - max_cycles = kMaxCycles): - # test_harness.elaborate() - test_harness.apply( DefaultPassGroup() ) - - # Run simulation - ncycles = 0 - print() - print("{}:{}".format( ncycles, test_harness.line_trace())) - if enable_verification_pymtl: - while not test_harness.done(): - test_harness.sim_tick() - ncycles += 1 - print("----------------------------------------------------") - print("{}:{}".format( ncycles, test_harness.line_trace())) - - # Checks the output parity. - assert test_harness.check_parity() - - # Checks timeout. - assert ncycles < max_cycles - else: - while ncycles < max_cycles: - test_harness.sim_tick() - ncycles += 1 - print("----------------------------------------------------") - print("{}:{}".format( ncycles, test_harness.line_trace())) - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - -def test_CGRA_systolic(cmdline_opts): - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 8 - width = 3 - height = 3 - RouteType = mk_bits(clog2(num_xbar_inports + 1)) - AddrType = mk_bits(clog2(ctrl_mem_size)) - num_tiles = width * height - num_fu_in = 4 - DUT = CgraMemRightAndBottomRTL - FunctionUnit = FlexibleFuRTL - FuList = [SeqMulAdderRTL, AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL] - DataType = mk_data(32, 1) - PredicateType = mk_predicate(1, 1) - CtrlType = mk_ctrl(num_fu_in, num_xbar_inports, num_xbar_outports) - FuInType = mk_bits(clog2( num_fu_in + 1)) - pickRegister = [FuInType(x + 1) for x in range(num_fu_in)] - - src_opt = [ - # On tile 0 ([0, 0]). - [CtrlType(OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - # On tile 1 ([0, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_LD_CONST, b1(0), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(0), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - - # On tile 2 ([0, 2]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - - # On tile 3 ([1, 0]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - # On tile 4 ([1, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - ], - - # On tile 5 ([1, 2]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(3), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_STR_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(3), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_STR_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - - # On tile 6 ([2, 0]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_MUL_CONST, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - - ], - - # On tile 7 ([2, 1]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - CtrlType( OPT_MUL_CONST_ADD, b1(0), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(2), RouteType(0), RouteType(3), RouteType(0)]), - - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - - # On tile 8 ([2, 2]). - [CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_NAH, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(3), RouteType(0), RouteType(0), RouteType(0)]), - - CtrlType( OPT_STR_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(3), RouteType(0), RouteType(0), RouteType(0)]), - CtrlType( OPT_STR_CONST, b1(0), pickRegister, [ - RouteType(2), RouteType(0), RouteType(0), RouteType(0), - RouteType(2), RouteType(0), RouteType(0), RouteType(0)]), - ], - ] - - preload_mem = [DataType(1, 1), DataType(2, 1), DataType(3, 1), - DataType(4, 1)] - preload_const = [ - # The offset address used for loading input activation. - # We use a shared data memory here, indicating global address - # space. Users can make each tile has its own address space. - - # The last one is not useful for the first colum, which is just - # to make the length aligned. - [DataType(0, 1), DataType(1, 1), DataType(0, 0)], - # The first one is not useful for the second colum, which is just - # to make the length aligned. - [DataType(0, 0), DataType(2, 1), DataType(3, 1)], - # The third column is not actually necessary to perform activation - # loading nor storing parameters. - [DataType(0, 0), DataType(0, 0), DataType(0, 0)], - - # Preloads weights. 3 items to align with the above const length. - # Duplication exists as the iter of the const queue automatically - # increment. - [DataType(2, 1), DataType(2, 1), DataType(2, 1)], - [DataType(4, 1), DataType(4, 1), DataType(4, 1)], - # The third column (except the bottom one) is used to store the - # accumulated results. - [DataType(0, 1), DataType(2, 1), DataType(0, 0)], - - [DataType(6, 1), DataType(6, 1), DataType(6, 1)], - [DataType(8, 1), DataType(8, 1), DataType(8, 1)], - # The third column (except the bottom one) is used to store the - # accumulated results. - [DataType(1, 1), DataType(3, 1), DataType(0, 0)]] - - data_mem_size = len(preload_mem) - - """ - 1 3 2 6 14 20 - x = - 2 4 4 8 30 44 - """ - expected_out = [DataType(14, 1), DataType(30, 1), DataType(20, 1), - DataType(44, 1)] - - # When the max iterations are larger than the number of control signals, - # enough ctrl_waddr needs to be provided to make execution (i.e., ctrl - # read) continue. - 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, width, height, ctrl_mem_size, data_mem_size, - src_opt, ctrl_waddr, preload_mem, preload_const, - expected_out) - - th.elaborate() - th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, - f'CgraMemRightAndBottomRTL') - # th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - # ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - # 'ALWCOMBORDER'] ) - th = config_model_with_cmdline_opts(th, cmdline_opts, duts=['dut']) - - enable_verification_pymtl = not (cmdline_opts['test_verilog'] or \ - cmdline_opts['dump_vcd'] or \ - cmdline_opts['dump_vtb']) - run_sim(th, enable_verification_pymtl) - diff --git a/systolic/translate/__init__.py b/systolic/translate/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tile/TileCL.py b/tile/TileCL.py deleted file mode 100644 index 310bb1e..0000000 --- a/tile/TileCL.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -========================================================================= -TileCL.py -========================================================================= - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL -from ..mem.ctrl.CtrlMemCL import CtrlMemCL -from ..mem.const.ConstQueueRTL import ConstQueueRTL -from ..noc.ChannelRTL import ChannelRTL -from ..noc.CrossbarRTL import CrossbarRTL -from ..rf.RegisterRTL import RegisterRTL - -class TileCL(Component): - - def construct(s, Fu, FuList, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - const_list, opt_list, id=0): - - # Constant - num_xbar_inports = 6 - num_xbar_outports = 8 - num_fu_inports = 4 - num_fu_outports = 2 - num_mesh_ports = 4 - bypass_point = 4 - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - DataAddrType = mk_bits(clog2(data_mem_size)) - - # Interfaces - s.recv_data = [RecvIfcRTL(DataType) for _ in range (num_mesh_ports)] - s.send_data = [SendIfcRTL(DataType) for _ in range (num_mesh_ports)] - - # Data - s.to_mem_raddr = SendIfcRTL(DataAddrType) - s.from_mem_rdata = RecvIfcRTL(DataType) - s.to_mem_waddr = SendIfcRTL(DataAddrType) - s.to_mem_wdata = SendIfcRTL(DataType) - - # Components - s.element = FlexibleFuRTL( DataType, PredicateType, CtrlType, num_fu_inports, - num_fu_outports, data_mem_size, FuList ) - s.const_queue = ConstQueueRTL( DataType, const_list ) - s.crossbar = CrossbarRTL( DataType, PredicateType, CtrlType, num_xbar_inports, - num_xbar_outports, bypass_point, id ) - s.ctrl_mem = CtrlMemCL( CtrlType, ctrl_mem_size, num_ctrl, total_steps, - opt_list, id ) - s.channel = [ ChannelRTL ( DataType ) for _ in range( num_xbar_outports ) ] - - # Additional one register for partial predication - s.reg_predicate = RegisterRTL( PredicateType ) - - # Connections - - # Data - s.element.recv_const //= s.const_queue.send_const - - for i in range( len( FuList ) ): - if FuList[i] == MemUnitRTL: - s.to_mem_raddr //= s.element.to_mem_raddr[i] - s.from_mem_rdata //= s.element.from_mem_rdata[i] - s.to_mem_waddr //= s.element.to_mem_waddr[i] - s.to_mem_wdata //= s.element.to_mem_wdata[i] - else: - s.element.to_mem_raddr[i].rdy //= 0 - s.element.from_mem_rdata[i].val //= 0 - s.element.from_mem_rdata[i].msg //= DataType( 0, 0 ) - s.element.to_mem_waddr[i].rdy //= 0 - s.element.to_mem_wdata[i].rdy //= 0 - - for i in range( num_mesh_ports ): - s.recv_data[i] //= s.crossbar.recv_data[i] - - for i in range( num_xbar_outports ): - s.crossbar.send_data[i] //= s.channel[i].recv - - # One partial predication register for flow control. - s.crossbar.send_predicate //= s.reg_predicate.recv - s.reg_predicate.send //= s.element.recv_predicate - - for i in range( num_mesh_ports ): - s.channel[i].send //= s.send_data[i] - - for i in range( num_fu_inports ): - s.channel[num_mesh_ports+i].send //= s.element.recv_in[i] - - for i in range( num_fu_outports ): - s.element.send_out[i] //= s.crossbar.recv_data[num_mesh_ports+i] - - @update - def update_opt(): - s.element.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val - s.crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val - s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy or s.crossbar.recv_opt.rdy - - # Line trace - def line_trace( s ): - recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) - channel_recv_str = "|".join([ str(x.recv.msg) for x in s.channel ]) - channel_send_str = "|".join([ str(x.send.msg) for x in s.channel ]) - channel_str = "|".join([ str(x.line_trace()) for x in s.channel ]) - out_str = "|".join([ "("+str(x.msg.payload)+","+str(x.msg.predicate)+")" for x in s.send_data ]) - return f"\n{recv_str} => [crossbar: {s.crossbar.line_trace()}] (element: {s.element.line_trace()}) => {channel_str} => {out_str} |||" - diff --git a/tile/TileSeparateCrossbarRTL.py b/tile/TileSeparateCrossbarRTL.py index daa70f3..73ce300 100644 --- a/tile/TileSeparateCrossbarRTL.py +++ b/tile/TileSeparateCrossbarRTL.py @@ -38,7 +38,7 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, num_fu_inports, num_fu_outports, num_tile_inports, num_tile_outports, Fu = FlexibleFuRTL, FuList = [PhiRTL, AdderRTL, CompRTL, MulRTL, BranchRTL, - MemUnitRTL], const_list = None): + MemUnitRTL], const_list = None, id = 0): # Constants. num_routing_xbar_inports = num_tile_inports @@ -78,7 +78,8 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.fu_crossbar = CrossbarSeparateRTL(DataType, PredicateType, CtrlSignalType, num_fu_xbar_inports, - num_fu_xbar_outports) + num_fu_xbar_outports, id, + "fu") s.ctrl_mem = CtrlMemDynamicRTL(CtrlPktType, CtrlSignalType, ctrl_mem_size, num_fu_inports, num_fu_outports, @@ -103,6 +104,11 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Additional one register for partial predication s.reg_predicate = RegisterRTL(PredicateType) + # Signals indicating whether certain modules already done their jobs. + s.element_done = Wire(1) + s.fu_crossbar_done = Wire(1) + s.routing_crossbar_done = Wire(1) + # Connections. # Ctrl. s.ctrl_mem.recv_pkt //= s.recv_ctrl_pkt @@ -180,22 +186,44 @@ def update_opt(): s.routing_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg s.fu_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val - s.routing_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val - s.fu_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val - - s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & \ - s.routing_crossbar.recv_opt.rdy & \ - s.fu_crossbar.recv_opt.rdy + s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.element_done + s.routing_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.routing_crossbar_done + s.fu_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.fu_crossbar_done + + # s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & \ + # s.routing_crossbar.recv_opt.rdy & \ + # s.fu_crossbar.recv_opt.rdy + + # FIXME: yo96, rename ctrl.rdy to ctrl.proceed or sth similar. + # Allows either the FU-related go out first or routing-xbar go out first. And only + # allows the ctrl signal proceed till all the sub-modules done their own job (once). + s.ctrl_mem.send_ctrl.rdy @= (s.element.recv_opt.rdy | s.element_done) & \ + (s.routing_crossbar.recv_opt.rdy | s.routing_crossbar_done) & \ + (s.fu_crossbar.recv_opt.rdy | s.fu_crossbar_done) + + # Updates the signals indicating whether certain modules already done their jobs. + @update_ff + def already_done(): + if s.reset | s.ctrl_mem.send_ctrl.rdy: + s.element_done <<= 0 + s.fu_crossbar_done <<= 0 + s.routing_crossbar_done <<= 0 + else: + if s.element.recv_opt.rdy: + s.element_done <<= 1 + elif s.fu_crossbar.recv_opt.rdy: + s.fu_crossbar_done <<= 1 + elif s.routing_crossbar.recv_opt.rdy: + s.routing_crossbar_done <<= 1 # Line trace - def line_trace( s ): - recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) + def line_trace(s): + recv_str = "|".join(["(" + str(x.msg) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.recv_data]) tile_out_channel_recv_str = "|".join([str(x.recv.msg) for x in s.tile_out_channel]) tile_out_channel_send_str = "|".join([str(x.send.msg) for x in s.tile_out_channel]) fu_in_channel_recv_str = "|".join([str(x.recv.msg) for x in s.fu_in_channel]) fu_in_channel_send_str = "|".join([str(x.send.msg) for x in s.fu_in_channel]) - out_str = "|".join([ "("+str(x.msg.payload)+","+str(x.msg.predicate)+",val:"+str(x.val)+",rdy:"+str(x.rdy)+")" for x in s.send_data ]) + out_str = "|".join(["(" + str(x.msg.payload) + ", predicate: " + str(x.msg.predicate) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.send_data]) ctrl_mem = s.ctrl_mem.line_trace() - return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} || ctrl_mem: {ctrl_mem} ## " + return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} || s.element_done: {s.element_done}, s.fu_crossbar_done: {s.fu_crossbar_done}, s.routing_crossbar_done: {s.routing_crossbar_done} || ctrl_mem: {ctrl_mem} ## " diff --git a/tile/test/TileCL_test.py b/tile/test/TileCL_test.py deleted file mode 100644 index 4538b98..0000000 --- a/tile/test/TileCL_test.py +++ /dev/null @@ -1,136 +0,0 @@ -""" -========================================================================== -TileCL_test.py -========================================================================== -Test cases for Tile. - -Author : Cheng Tan - Date : Dec 28, 2019 -""" - - -from pymtl3 import * -from ..TileCL import TileCL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...mem.ctrl.CtrlMemCL import CtrlMemCL - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, ctrl_mem_size, data_mem_size, - num_tile_inports, num_tile_outports, - src_data, src_opt, src_const, sink_out ): - - s.num_tile_inports = num_tile_inports - s.num_tile_outports = num_tile_outports - - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - s.src_data = [ TestSrcRTL( DataType, src_data[i] ) - for i in range( num_tile_inports ) ] - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( num_tile_outports ) ] - - s.dut = DUT( FunctionUnit, FuList, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, len(src_opt), len(src_opt), - src_const, src_opt ) - - for i in range( num_tile_inports ): - connect( s.src_data[i].send, s.dut.recv_data[i] ) - for i in range( num_tile_outports ): - connect( s.dut.send_data[i], s.sink_out[i].recv ) - - if MemUnitRTL in FuList: - s.dut.to_mem_raddr.rdy //= 0 - s.dut.from_mem_rdata.en //= 0 - s.dut.from_mem_rdata.msg //= DataType( 0, 0 ) - s.dut.to_mem_waddr.rdy //= 0 - s.dut.to_mem_wdata.rdy //= 0 - - def done( s ): - done = True - for i in range( s.num_tile_outports ): - if not s.sink_out[i].done():# and not s.src_data[i].done(): - done = False - break - return done - - def line_trace( s ): - return s.dut.line_trace() - -def run_sim( test_harness, max_cycles=100 ): - 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() - -def test_tile_alu(): - num_tile_inports = 4 - num_tile_outports = 4 - num_xbar_inports = 6 - num_xbar_outports = 8 - ctrl_mem_size = 8 - data_mem_size = 8 - num_fu_in = 4 # number of inputs of FU is fixed inside the tile - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] - DUT = TileCL - FunctionUnit = FlexibleFuRTL - FuList = [AdderRTL, MemUnitRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - src_opt = [ CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(4), RouteType(3), RouteType(0), RouteType(0)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(4), RouteType(1), RouteType(0), RouteType(0)] ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(5), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ) ] - src_data = [ [DataType(2, 1)],# DataType( 3, 1)], - [],#DataType(3, 1), DataType( 4, 1)], - [DataType(4, 1)],# DataType( 5, 1)], - [DataType(5, 1), DataType( 7, 1)] ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ [DataType(5, 1, 0)],# DataType( 4, 1)], - [], - [], - [DataType(9, 1, 0), DataType( 5, 1, 0)]]#, DataType(4, 1)] ] - th = TestHarness( DUT, FunctionUnit, FuList, DataType, - PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, - num_tile_inports, num_tile_outports, - src_data, src_opt, src_const, sink_out ) - run_sim( th ) - diff --git a/tile/test/TileRTL_test.py b/tile/test/TileRTL_test.py deleted file mode 100644 index f165bc6..0000000 --- a/tile/test/TileRTL_test.py +++ /dev/null @@ -1,156 +0,0 @@ -""" -========================================================================== -TileRTL_test.py -========================================================================== -Test cases for Tile. -Command: -pytest TileRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd - -Author : Cheng Tan - Date : Dec 11, 2019 -""" - - -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 ..TileRTL import TileRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...lib.basic.en_rdy.test_sinks import TestSinkRTL -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...mem.ctrl.CtrlMemRTL import CtrlMemRTL - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, ctrl_mem_size, data_mem_size, - num_fu_inports, num_fu_outports, - src_data, src_opt, opt_waddr, sink_out ): - - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - - # s.src_predicate = TestSrcRTL( b1, src_predicate ) - s.src_opt = TestSrcRTL( CtrlType, src_opt ) - s.opt_waddr = TestSrcRTL( AddrType, opt_waddr ) - s.src_data = [ TestSrcRTL( DataType, src_data[i] ) - for i in range( 4 ) ]#num_tile_inports ) ] - s.sink_out = [ TestSinkRTL( DataType, sink_out[i] ) - for i in range( 4 ) ]#num_tile_outports ) ] - - s.dut = DUT( DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, len(src_opt), - len(src_opt), num_fu_inports, num_fu_outports, - 4, 4, FunctionUnit, FuList ) - - # connect( s.src_predicate.send, s.dut.reg_predicate ) - connect( s.src_opt.send, s.dut.recv_wopt ) - connect( s.opt_waddr.send, s.dut.recv_waddr ) - - for i in range( 4 ):#num_tile_inports ): - connect( s.src_data[i].send, s.dut.recv_data[i] ) - for i in range( 4 ):#num_tile_outports ): - connect( s.dut.send_data[i], s.sink_out[i].recv ) - - if MemUnitRTL in FuList: - s.dut.to_mem_raddr.rdy //= 0 - s.dut.from_mem_rdata.en //= 0 - s.dut.from_mem_rdata.msg //= DataType( 0, 0 ) - s.dut.to_mem_waddr.rdy //= 0 - s.dut.to_mem_wdata.rdy //= 0 - - def done( s ): - done = True - for i in range( 4 ):#s.num_tile_outports ): - if not s.sink_out[i].done():# and not s.src_data[i].done(): - done = False - break - return done - - def line_trace( s ): - return s.dut.line_trace() - -def test_tile_alu( cmdline_opts ): - num_connect_inports = 4 - num_connect_outports = 4 - num_fu_inports = 2 - num_fu_outports = 1 - num_xbar_inports = num_fu_outports + num_connect_inports - num_xbar_outports = num_fu_inports + num_connect_outports - ctrl_mem_size = 3 - data_mem_size = 8 - # number of inputs of FU is fixed inside the tile - num_fu_in = 4 - RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) - AddrType = mk_bits( clog2( ctrl_mem_size ) ) - FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - pickRegister0 = [ FuInType( 0 ) for x in range( num_fu_in ) ] - pickRegister1 = [ FuInType( 1 ), FuInType( 2 ), FuInType( 0 ), FuInType( 0 ) ] - DUT = TileRTL - FunctionUnit = FlexibleFuRTL - FuList = [AdderRTL, MulRTL, MemUnitRTL] - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) - CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) - opt_waddr = [ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ) ] - src_opt = [ CtrlType( OPT_NAH, b1(0), pickRegister0, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(4), RouteType(3), RouteType(0), RouteType(0)] ), - CtrlType( OPT_ADD, b1(0), pickRegister1, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(4), RouteType(1), RouteType(0), RouteType(0)] ), - CtrlType( OPT_SUB, b1(0), pickRegister1, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(5), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ) ] - src_data = [ [DataType(2, 1)],# DataType( 3, 1)], - [],#DataType(3, 1), DataType( 4, 1)], - [DataType(4, 1)],# DataType( 5, 1)], - [DataType(5, 1), DataType( 7, 1)] ] - # src_predicate = [ b1( 0 ), b1( 0 ), b1( 0 ) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] - sink_out = [ [DataType(5, 1)],# DataType( 4, 1)], - [], - [], - [DataType(9, 1), DataType( 5, 1)]] - """ - src_opt = [ CtrlType( OPT_NAH, [ - RouteType(4), RouteType(3), RouteType(2), RouteType(1), - RouteType(4), RouteType(3), RouteType(2), RouteType(1)] ), - CtrlType( OPT_ADD, [ - RouteType(3), RouteType(3), RouteType(3), RouteType(5), - RouteType(4), RouteType(1), RouteType(1), RouteType(1)] ), - CtrlType( OPT_SUB, [ - RouteType(5), RouteType(5), RouteType(2), RouteType(2), - RouteType(1), RouteType(1), RouteType(1), RouteType(1)] ) ] - src_data = [ [DataType(2, 1), DataType( 3, 1)], - [DataType(3, 1), DataType( 4, 1)], - [DataType(4, 1), DataType( 5, 1)], - [DataType(5, 1), DataType( 6, 1)] ] - sink_out = [ [DataType(5, 1), DataType( 5, 1), DataType( 3, 1)], - [DataType(4, 1), DataType( 5, 1), DataType( 3, 1)], - [DataType(3, 1), DataType( 5, 1)], - [DataType(2, 1), DataType( 9, 1)] ] - """ - th = TestHarness( DUT, FunctionUnit, FuList, DataType, PredicateType, - CtrlType, ctrl_mem_size, data_mem_size, - num_fu_inports, num_fu_outports, - src_data, src_opt, opt_waddr, sink_out ) - 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 ) - diff --git a/tile/test/TileSeparateCrossbarRTL_test.py b/tile/test/TileSeparateCrossbarRTL_test.py index b263882..dfbc525 100644 --- a/tile/test/TileSeparateCrossbarRTL_test.py +++ b/tile/test/TileSeparateCrossbarRTL_test.py @@ -16,12 +16,26 @@ from pymtl3.passes.backends.verilog import (VerilogTranslationPass, VerilogVerilatorImportPass) from ..TileSeparateCrossbarRTL import TileSeparateCrossbarRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.NahRTL import NahRTL + +from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL +from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL +from ...fu.vector.VectorMulComboRTL import VectorMulComboRTL +from ...fu.vector.VectorAdderComboRTL import VectorAdderComboRTL +from ...fu.vector.VectorAllReduceRTL import VectorAllReduceRTL +from ...fu.single.AdderRTL import AdderRTL +from ...fu.single.MemUnitRTL import MemUnitRTL +from ...fu.single.MulRTL import MulRTL +from ...fu.single.SelRTL import SelRTL +from ...fu.single.ShifterRTL import ShifterRTL +from ...fu.single.LogicRTL import LogicRTL +from ...fu.single.PhiRTL import PhiRTL +from ...fu.single.CompRTL import CompRTL +from ...fu.single.BranchRTL import BranchRTL +from ...fu.single.NahRTL import NahRTL +from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL +from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL + from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL from ...lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ...lib.messages import * @@ -86,7 +100,7 @@ def test_tile_alu(cmdline_opts): num_tile_inports = 4 num_tile_outports = 4 num_fu_inports = 4 - num_fu_outports = 1 + num_fu_outports = 2 num_routing_outports = num_fu_inports + num_tile_outports ctrl_mem_size = 3 data_mem_size = 8 @@ -100,8 +114,21 @@ def test_tile_alu(cmdline_opts): pickRegister1 = [FuInType(1), FuInType(2), FuInType(0), FuInType(0)] DUT = TileSeparateCrossbarRTL FunctionUnit = FlexibleFuRTL - FuList = [AdderRTL, MulRTL, MemUnitRTL] - DataType = mk_data(16, 1) + # FuList = [AdderRTL, MulRTL, MemUnitRTL] + FuList = [AdderRTL, + MulRTL, + LogicRTL, + ShifterRTL, + PhiRTL, + CompRTL, + BranchRTL, + MemUnitRTL, + SelRTL, + ThreeMulAdderShifterRTL, + VectorMulComboRTL, + VectorAdderComboRTL] + # 64-bit to satisfy the default bitwidth of vector FUs. + DataType = mk_data(64, 1) PredicateType = mk_predicate(1, 1) CtrlPktType = \ mk_ring_across_tiles_pkt(num_terminals, diff --git a/tile/translate/TileRTL_test.py b/tile/translate/TileRTL_test.py deleted file mode 100644 index a89fc19..0000000 --- a/tile/translate/TileRTL_test.py +++ /dev/null @@ -1,78 +0,0 @@ -''' -========================================================================== -TileRTL_test.py -========================================================================== - -Author: Yanghui Ou - Date: July 11, 2023 -''' - - -from pymtl3 import * -from pymtl3.passes.backends.verilog import VerilogTranslationPass -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) -from ..TileRTL import TileRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.float.FpAddRTL import FpAddRTL -from ...fu.float.FpMulRTL import FpMulRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...lib.messages import * -from ...lib.opt_type import * -from ...mem.ctrl.CtrlMemRTL import CtrlMemRTL - - -num_connect_inports = 4 -num_connect_outports = 4 -num_fu_inports = 4 -num_fu_outports = 2 -num_xbar_inports = num_fu_outports + num_connect_inports -num_xbar_outports = num_fu_inports + num_connect_outports -ctrl_mem_size = 3 -data_mem_size = 8 -num_fu_in = 4 - -RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) -AddrType = mk_bits( clog2( ctrl_mem_size ) ) -DUT = TileRTL -FunctionUnit = FlexibleFuRTL -FuList = [ AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, - CompRTL, BranchRTL, MemUnitRTL, SelRTL, FpAddRTL, - FpMulRTL ] #, ThreeMulAdderShifterRTL ] -DataType = mk_data( 16, 1 ) -PredicateType = mk_predicate( 1, 1 ) -CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) -FuInType = mk_bits( clog2( num_fu_in + 1 ) ) - -pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] -opt_waddr = [ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ) ] -src_opt = [ CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(4), RouteType(3), RouteType(0), RouteType(0)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(4), RouteType(1), RouteType(0), RouteType(0)] ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(5), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ) ] - - -# TODO: fix import by either suppressing warnings or address them -def test_translate( cmdline_opts ): - dut = TileRTL( DataType, PredicateType, CtrlType, ctrl_mem_size, - data_mem_size, len( src_opt ), len( src_opt ), - num_fu_inports, num_fu_outports, 4, 4, - FunctionUnit, FuList ) - dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'TileRTL' ) - config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) - diff --git a/tile/translate/TileVectorRTL_test.py b/tile/translate/TileVectorRTL_test.py deleted file mode 100644 index 14576ef..0000000 --- a/tile/translate/TileVectorRTL_test.py +++ /dev/null @@ -1,88 +0,0 @@ -''' -========================================================================== -TileVectorRTL_test.py -========================================================================== - -Author: Yanghui Ou - Date: July 11, 2023 -''' -from pymtl3 import * -from pymtl3.passes.backends.verilog import VerilogTranslationPass -from pymtl3.stdlib.test_utils import (run_sim, - config_model_with_cmdline_opts) - -from ...lib.opt_type import * -from ...lib.messages import * -from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ...fu.vector.VectorMulComboRTL import VectorMulComboRTL -from ...fu.vector.VectorAdderComboRTL import VectorAdderComboRTL -from ...fu.vector.VectorAllReduceRTL import VectorAllReduceRTL -from ...fu.single.AdderRTL import AdderRTL -from ...fu.single.MemUnitRTL import MemUnitRTL -from ...fu.single.MulRTL import MulRTL -from ...fu.single.SelRTL import SelRTL -from ...fu.single.ShifterRTL import ShifterRTL -from ...fu.single.LogicRTL import LogicRTL -from ...fu.single.PhiRTL import PhiRTL -from ...fu.single.CompRTL import CompRTL -from ...fu.single.BranchRTL import BranchRTL -from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL -from ...mem.ctrl.CtrlMemRTL import CtrlMemRTL -from ..TileRTL import TileRTL - -num_connect_inports = 4 -num_connect_outports = 4 -num_fu_inports = 4 -num_fu_outports = 2 -num_xbar_inports = num_fu_outports + num_connect_inports -num_xbar_outports = num_fu_inports + num_connect_outports -ctrl_mem_size = 3 -data_mem_size = 8 -num_fu_in = 4 - -RouteType = mk_bits( clog2( num_xbar_inports + 1 ) ) -AddrType = mk_bits( clog2( ctrl_mem_size ) ) -DUT = TileRTL -FunctionUnit = FlexibleFuRTL -# FuList = [ AdderRTL, BranchRTL, MemUnitRTL, VectorMulComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL, VectorAdderComboRTL ] -FuList = [ AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL, SelRTL, VectorMulComboRTL, VectorAdderComboRTL ]#, VectorAllReduceRTL ] -# FuList = [AdderRTL] -# FuList = [ThreeMulAdderShifterRTL] -DataType = mk_data( 64, 1 ) -PredicateType = mk_predicate( 1, 1 ) -CtrlType = mk_ctrl( num_fu_in, num_xbar_inports, num_xbar_outports ) -FuInType = mk_bits( clog2( num_fu_in + 1 ) ) -pickRegister = [ FuInType( x+1 ) for x in range( num_fu_in ) ] -opt_waddr = [ AddrType( 0 ), AddrType( 1 ), AddrType( 2 ) ] - -src_opt = [ CtrlType( OPT_NAH, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(0), - RouteType(4), RouteType(3), RouteType(0), RouteType(0)] ), - CtrlType( OPT_ADD, b1( 0 ), pickRegister, [ - RouteType(0), RouteType(0), RouteType(0), RouteType(5), - RouteType(4), RouteType(1), RouteType(0), RouteType(0)] ), - CtrlType( OPT_SUB, b1( 0 ), pickRegister, [ - RouteType(5), RouteType(0), RouteType(0), RouteType(5), - RouteType(0), RouteType(0), RouteType(0), RouteType(0)] ) ] - -def test_elaborate(): - dut = TileRTL( DataType, PredicateType, CtrlType, ctrl_mem_size, - data_mem_size, len( src_opt ), len( src_opt ), - num_fu_inports, num_fu_outports, 4, 4, - FunctionUnit, FuList ) - dut.apply( DefaultPassGroup(linetrace=True) ) - dut.sim_reset() - dut.sim_tick() - dut.sim_tick() - -# TODO: fix import by either suppressing warnings or address them -def test_translate( cmdline_opts ): - dut = TileRTL( DataType, PredicateType, CtrlType, ctrl_mem_size, - data_mem_size, len(src_opt), len(src_opt), - num_fu_inports, num_fu_outports, 4, 4, - FunctionUnit, FuList ) - dut.set_metadata( VerilogTranslationPass.explicit_module_name, - f'TileVectorRTL' ) - config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) - From 49a4d9040a6a7ff25362077ffc46e60ca3f1f2bb Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 17:11:29 +0000 Subject: [PATCH 03/10] [test] Provide topology for ring-based CGRAs --- .github/workflows/python-package.yml | 15 ++++++++------- scale_out/RingMultiCgraRingCtrlMemRTL.py | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 7769ff4..156da32 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -59,19 +59,20 @@ jobs: mkdir -p build && cd build source ${HOME}/venv/bin/activate # Simulation across all tests. - pytest .. -v --tb=short + pytest .. -v # Tile translation. - pytest ../tile/test/TileSeparateCrossbarRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../tile/test/TileSeparateCrossbarRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd # CGRA template translation. - pytest ../cgra/test/CgraTemplateRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../cgra/test/CgraTemplateRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd + # TODO: Need to check vector/heterogneous modules exist in the generated Verilog. # CGRA simulation/translation (including heterogeneous, kingmesh, vector). - pytest ../cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd # 3x3 CGRA performs 2x2 matmul simulation/translation. - pytest ../systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd + pytest ../systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py -xvs --test-verilog --dump-vtb --dump-vcd # Ring network simulation. - pytest ../noc/PyOCN/pymtl3_net/ringnet/test/RingNetworkRTL_test.py --tb=short -sv + pytest ../noc/PyOCN/pymtl3_net/ringnet/test/RingNetworkRTL_test.py # CGRAs are interconnected with ring topology. The CGRA contains # separate crossbars (for tiles and FUs), crossbar-based data memory (for # multi-bank), and controller. - pytest --tb=short -sv ../scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py --test-verilog --dump-vtb --dump-vcd + pytest ../scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd diff --git a/scale_out/RingMultiCgraRingCtrlMemRTL.py b/scale_out/RingMultiCgraRingCtrlMemRTL.py index 9dc243c..9a16a20 100644 --- a/scale_out/RingMultiCgraRingCtrlMemRTL.py +++ b/scale_out/RingMultiCgraRingCtrlMemRTL.py @@ -44,7 +44,7 @@ def construct(s, CGRADataType, PredicateType, CtrlPktType, NocPktType, CmdType, ControllerIdType, terminal_id, tile_columns, tile_rows, ctrl_mem_size, data_mem_size_global, data_mem_size_per_bank, num_banks_per_cgra, num_ctrl, - total_steps, FunctionUnit, FuList, controller2addr_map, + total_steps, FunctionUnit, FuList, "Mesh", controller2addr_map, preload_data = None, preload_const = None) for terminal_id in range(s.num_terminals)] s.ring = RingNetworkRTL(NocPktType, RingPos, s.num_terminals, 0) @@ -71,13 +71,13 @@ def construct(s, CGRADataType, PredicateType, CtrlPktType, else: for tile_col in range(tile_columns): s.cgra[cgra_row * cgra_columns + cgra_col].send_data_on_boundary_south[tile_col].rdy //= 0 - s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_south[tile_col].en //= 0 + s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_south[tile_col].val //= 0 s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_south[tile_col].msg //= CGRADataType() if cgra_row == cgra_rows - 1: for tile_col in range(tile_columns): s.cgra[cgra_row * cgra_columns + cgra_col].send_data_on_boundary_north[tile_col].rdy //= 0 - s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_north[tile_col].en //= 0 + s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_north[tile_col].val //= 0 s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_north[tile_col].msg //= CGRADataType() if cgra_col != 0: @@ -89,13 +89,13 @@ def construct(s, CGRADataType, PredicateType, CtrlPktType, else: for tile_row in range(tile_rows): s.cgra[cgra_row * cgra_columns + cgra_col].send_data_on_boundary_west[tile_row].rdy //= 0 - s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_west[tile_row].en //= 0 + s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_west[tile_row].val //= 0 s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_west[tile_row].msg //= CGRADataType() if cgra_col == cgra_columns - 1: for tile_row in range(tile_rows): s.cgra[cgra_row * cgra_columns + cgra_col].send_data_on_boundary_east[tile_row].rdy //= 0 - s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_east[tile_row].en //= 0 + s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_east[tile_row].val //= 0 s.cgra[cgra_row * cgra_columns + cgra_col].recv_data_on_boundary_east[tile_row].msg //= CGRADataType() def line_trace(s): From 3ce0af4cfaf9597fcf626381a0db926bfd105eda Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 18:24:38 +0000 Subject: [PATCH 04/10] [test&cleanup] Refactor and Re-organize fused ALU --- .../AluGenMacRTL.py} | 21 ++--- .../AluGenMacWrapperRTL.py} | 4 +- fu/fused_alu_fixedp/README.md | 12 +++ .../__init__.py | 0 .../svsrc/ALUgenMAC.sv | 0 .../test/AluGenMacRTL_test.py} | 80 +++++++++---------- .../test/AluGenMacWrapperRTL_test.py} | 14 ++-- .../test/__init__.py | 0 fu/pymtl3_fusedALU_fixedp/__init__.py | 0 fu/pymtl3_fusedALU_fixedp/test/__init__.py | 0 10 files changed, 70 insertions(+), 61 deletions(-) rename fu/{ALUgen_fusedALU_fixedp/ALUgenMACFU.py => fused_alu_fixedp/AluGenMacRTL.py} (92%) rename fu/{pymtl3_fusedALU_fixedp/ALUgenMACRTL.py => fused_alu_fixedp/AluGenMacWrapperRTL.py} (95%) create mode 100644 fu/fused_alu_fixedp/README.md rename fu/{ALUgen_fusedALU_fixedp => fused_alu_fixedp}/__init__.py (100%) rename fu/{pymtl3_fusedALU_fixedp => fused_alu_fixedp}/svsrc/ALUgenMAC.sv (100%) rename fu/{ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py => fused_alu_fixedp/test/AluGenMacRTL_test.py} (55%) rename fu/{pymtl3_fusedALU_fixedp/test/ALUgenMACRTL_test.py => fused_alu_fixedp/test/AluGenMacWrapperRTL_test.py} (85%) rename fu/{ALUgen_fusedALU_fixedp => fused_alu_fixedp}/test/__init__.py (100%) delete mode 100644 fu/pymtl3_fusedALU_fixedp/__init__.py delete mode 100644 fu/pymtl3_fusedALU_fixedp/test/__init__.py diff --git a/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py b/fu/fused_alu_fixedp/AluGenMacRTL.py similarity index 92% rename from fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py rename to fu/fused_alu_fixedp/AluGenMacRTL.py index 8a6fb5b..d43316a 100644 --- a/fu/ALUgen_fusedALU_fixedp/ALUgenMACFU.py +++ b/fu/fused_alu_fixedp/AluGenMacRTL.py @@ -1,6 +1,6 @@ """ ========================================================================== -ALUgenMACFU.py +AluGenMacRTL.py ========================================================================== Floating point add unit. @@ -10,25 +10,27 @@ from pymtl3 import * from ..basic.Fu import Fu -from ..pymtl3_fusedALU_fixedp.ALUgenMACRTL import ALUgenMAC +from .AluGenMacWrapperRTL import AluGenMacWrapperRTL from ...lib.opt_type import * -class ALUgenMACFU(Fu): +class AluGenMacRTL(Fu): + def construct(s, DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size): - super(ALUgenMACFU, s).construct(DataType, PredicateType, CtrlType, - num_inports, num_outports, - data_mem_size) + + super(AluGenMacRTL, s).construct(DataType, PredicateType, CtrlType, + num_inports, num_outports, + data_mem_size) # Local parameters assert DataType.get_field_type('payload').nbits == 16 num_entries = 3 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - CountType = mk_bits( clog2( num_entries + 1 ) ) + FuInType = mk_bits(clog2(num_inports + 1)) + CountType = mk_bits(clog2(num_entries + 1)) # Components - s.fALU = ALUgenMAC() + s.fALU = AluGenMacWrapperRTL() s.fALU.rhs_2 //= lambda: 0 if s.recv_opt.msg.ctrl == OPT_ADD else \ ( 1 if s.recv_opt.msg.ctrl == OPT_SUB else \ ( 3 if s.recv_opt.msg.ctrl == OPT_LT else \ @@ -109,6 +111,7 @@ def comb_logic(): s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy s.recv_in[s.in2_idx].rdy @= s.recv_all_val & s.send_out[0].rdy s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy + # FIXME: @RJ, what is the following for? #elif s.recv_opt.msg.ctrl == OPT_FADD_CONST: # s.fadd.rhs_0 @= s.recv_in[s.in0_idx].msg.payload # s.fadd.rhs_1 @= s.recv_const.msg.payload diff --git a/fu/pymtl3_fusedALU_fixedp/ALUgenMACRTL.py b/fu/fused_alu_fixedp/AluGenMacWrapperRTL.py similarity index 95% rename from fu/pymtl3_fusedALU_fixedp/ALUgenMACRTL.py rename to fu/fused_alu_fixedp/AluGenMacWrapperRTL.py index 0107d7b..c8c55ae 100644 --- a/fu/pymtl3_fusedALU_fixedp/ALUgenMACRTL.py +++ b/fu/fused_alu_fixedp/AluGenMacWrapperRTL.py @@ -2,12 +2,10 @@ # Wrapper for HardFloat's addition and subtraction module #========================================================================= - from pymtl3 import * from pymtl3.passes.backends.verilog import * - -class ALUgenMAC( VerilogPlaceholder, Component ): +class AluGenMacWrapperRTL( VerilogPlaceholder, Component ): # Constructor diff --git a/fu/fused_alu_fixedp/README.md b/fu/fused_alu_fixedp/README.md new file mode 100644 index 0000000..2e1f318 --- /dev/null +++ b/fu/fused_alu_fixedp/README.md @@ -0,0 +1,12 @@ +Publication +-------------------------------------------------------- +``` +@inproceedings{jokai2024fused, + title={Fused Functional Units for Area-Efficient CGRAs}, + author={Jokai, Ron and Tan, Cheng and Zhang, Jeff Jun}, + booktitle={2024 25th International Symposium on Quality Electronic Design (ISQED)}, + pages={1--8}, + year={2024}, + organization={IEEE} +} +``` diff --git a/fu/ALUgen_fusedALU_fixedp/__init__.py b/fu/fused_alu_fixedp/__init__.py similarity index 100% rename from fu/ALUgen_fusedALU_fixedp/__init__.py rename to fu/fused_alu_fixedp/__init__.py diff --git a/fu/pymtl3_fusedALU_fixedp/svsrc/ALUgenMAC.sv b/fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv similarity index 100% rename from fu/pymtl3_fusedALU_fixedp/svsrc/ALUgenMAC.sv rename to fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv diff --git a/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py b/fu/fused_alu_fixedp/test/AluGenMacRTL_test.py similarity index 55% rename from fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py rename to fu/fused_alu_fixedp/test/AluGenMacRTL_test.py index 9656d18..3516606 100644 --- a/fu/ALUgen_fusedALU_fixedp/test/ALUgenMACFU_test.py +++ b/fu/fused_alu_fixedp/test/AluGenMacRTL_test.py @@ -1,45 +1,43 @@ """ ========================================================================== -ALUgenMACFU_test.py +AluGenMacFuRTL_test.py ========================================================================== Author : RJ Date : Jan 6, 2024 """ - from pymtl3 import * from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) -from ..ALUgenMACFU import ALUgenMACFU +from ..AluGenMacRTL import AluGenMacRTL from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL - def test_elaborate( cmdline_opts ): DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) + PredType = mk_predicate( 1, 1 ) ConfigType = mk_ctrl(3, 3, 1) data_mem_size = 8 num_inports = 3 num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_in2 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] + FuInType = mk_bits(clog2(num_inports + 1)) + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_in0 = [ DataType(1, 1), DataType(7, 1), DataType( 4, 1) ] + src_in1 = [ DataType(2, 1), DataType(3, 1), DataType( 1, 1) ] + src_in2 = [ DataType(2, 1), DataType(3, 1), DataType( 1, 1) ] + src_predicate = [ PredType(1, 0), PredType(1, 0), PredType( 1, 1) ] + src_const = [ DataType(5, 1), DataType(0, 0), DataType( 7, 1) ] sink_out = [ DataType(6, 0), DataType(4, 0), DataType(11, 1) ] - src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] - dut = ALUgenMACFU( DataType, PredicateType, ConfigType, num_inports, + src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pick_register ), + ConfigType( OPT_SUB, b1( 1 ), pick_register ), + ConfigType( OPT_ADD_CONST, b1( 1 ), pick_register ) ] + dut = AluGenMacRTL( DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size ) - dut = config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) + dut = config_model_with_cmdline_opts(dut, cmdline_opts, duts = []) #------------------------------------------------------------------------- # Test harness @@ -47,7 +45,7 @@ def test_elaborate( cmdline_opts ): class TestHarness( Component ): - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, + def construct( s, FunctionUnit, DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size, src0_msgs, src1_msgs, src2_msgs, src_predicate, src_const, ctrl_msgs, sink_msgs ): @@ -55,12 +53,12 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, s.src_in0 = TestSrcRTL( DataType, src0_msgs ) s.src_in1 = TestSrcRTL( DataType, src1_msgs ) s.src_in2 = TestSrcRTL( DataType, src2_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) + s.src_predicate = TestSrcRTL( PredType, src_predicate ) s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) s.sink_out = TestSinkRTL( DataType, sink_msgs ) s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, + s.dut = FunctionUnit( DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size ) connect( s.src_in0.send, s.dut.recv_in[0] ) @@ -71,42 +69,42 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out.recv ) - def done( s ): + def done(s): return s.src_in0.done() and s.src_in1.done() and \ s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() def test_add_basic(cmdline_opts): - FU = ALUgenMACFU + FU = AluGenMacRTL exp_nbits = 4 sig_nbits = 11 - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) + DataType = mk_data(16, 1) + PredType = mk_predicate(1, 1) ConfigType = mk_ctrl(3, 3, 1) data_mem_size = 8 num_inports = 3 num_outports = 1 FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1),DataType(3, 1),DataType(3, 1),DataType(3, 1), DataType(4, 1), DataType(3, 1) ] - src_in1 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1),DataType(3, 1),DataType(3, 1),DataType(3, 1), DataType(5, 1), DataType(3, 1) ] - src_in2 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1),DataType(3, 1),DataType(3, 1),DataType(3, 1), DataType(3, 1), DataType(3, 1) ] - src_predicate = [ PredicateType(1, 1), PredicateType(1, 1), PredicateType(1, 1) ] + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1), DataType(3, 1), DataType(3, 1),DataType(3, 1), DataType( 4, 1), DataType( 3, 1) ] + src_in1 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1), DataType(3, 1), DataType(3, 1),DataType(3, 1), DataType( 5, 1), DataType( 3, 1) ] + src_in2 = [ DataType(1, 1), DataType(2, 1), DataType(3, 1), DataType(3, 1), DataType(3, 1),DataType(3, 1), DataType( 3, 1), DataType( 3, 1) ] + src_predicate = [ PredType(1, 1), PredType(1, 1), PredType(1, 1) ] src_const = [ DataType(1, 1), DataType(2, 1), DataType(3, 1) ] - sink_out = [ DataType(2, 1), DataType(0, 1), DataType(0, 1),DataType(1, 1),DataType(0, 1),DataType(1, 1), DataType(20, 1), DataType(12, 1) ] - src_opt = [ ConfigType( OPT_ADD, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_LT, b1( 1 ), pickRegister ), - ConfigType( OPT_LTE, b1( 1 ), pickRegister ), - ConfigType( OPT_GT, b1( 1 ), pickRegister ), - ConfigType( OPT_GTE, b1( 1 ), pickRegister ), - ConfigType( OPT_MUL, b1( 1 ), pickRegister ), - ConfigType( OPT_MUL_ADD, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, + sink_out = [ DataType(2, 1), DataType(0, 1), DataType(0, 1), DataType(1, 1), DataType(0, 1),DataType(1, 1), DataType(20, 1), DataType(12, 1) ] + src_opt = [ ConfigType( OPT_ADD, b1( 1 ), pick_register ), + ConfigType( OPT_SUB, b1( 1 ), pick_register ), + ConfigType( OPT_LT, b1( 1 ), pick_register ), + ConfigType( OPT_LTE, b1( 0 ), pick_register ), + ConfigType( OPT_GT, b1( 0 ), pick_register ), + ConfigType( OPT_GTE, b1( 0 ), pick_register ), + ConfigType( OPT_MUL, b1( 0 ), pick_register ), + ConfigType( OPT_MUL_ADD, b1( 0 ), pick_register ) ] + th = TestHarness( FU, DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size, src_in0, src_in1, src_in2, src_predicate, src_const, src_opt, sink_out ) - run_sim( th ) + run_sim(th) diff --git a/fu/pymtl3_fusedALU_fixedp/test/ALUgenMACRTL_test.py b/fu/fused_alu_fixedp/test/AluGenMacWrapperRTL_test.py similarity index 85% rename from fu/pymtl3_fusedALU_fixedp/test/ALUgenMACRTL_test.py rename to fu/fused_alu_fixedp/test/AluGenMacWrapperRTL_test.py index 29f4736..63a6f05 100644 --- a/fu/pymtl3_fusedALU_fixedp/test/ALUgenMACRTL_test.py +++ b/fu/fused_alu_fixedp/test/AluGenMacWrapperRTL_test.py @@ -2,18 +2,16 @@ # Unit testing for AddFNRTL PyMTL wrapper module #========================================================================= - from pymtl3 import * from pymtl3.stdlib.test_utils import run_test_vector_sim, TestVectorSimulator from pymtl3.passes.backends.verilog import * from hypothesis import given from hypothesis import settings from hypothesis import strategies as st -from ..ALUgenMACRTL import ALUgenMAC +from ..AluGenMacWrapperRTL import AluGenMacWrapperRTL import hypothesis import random - # =========================== Helper functions =========================== def abs( x ): if(x < 0): @@ -77,7 +75,7 @@ def test_add_ones(cmdline_opts): c = 99 out = a + b - run_tv_test( ALUgenMAC(), [[a, b, c, 0, out]], tolerance) + run_tv_test( AluGenMacWrapperRTL(), [[a, b, c, 0, out]], tolerance) def test_sub(cmdline_opts): tolerance = 0.00 @@ -87,7 +85,7 @@ def test_sub(cmdline_opts): c = 99 out = a - b - run_tv_test( ALUgenMAC(), [[a, b, c, 1, out]], tolerance) + run_tv_test( AluGenMacWrapperRTL(), [[a, b, c, 1, out]], tolerance) def test_gte(cmdline_opts): tolerance = 0.00 @@ -97,7 +95,7 @@ def test_gte(cmdline_opts): c = 99 out = 1 - run_tv_test( ALUgenMAC(), [[a, b, c, 7, out]], tolerance) + run_tv_test( AluGenMacWrapperRTL(), [[a, b, c, 7, out]], tolerance) def test_mul(cmdline_opts): tolerance = 0.00 @@ -107,7 +105,7 @@ def test_mul(cmdline_opts): c = 99 out = a * b - run_tv_test( ALUgenMAC(), [[a, b, c, 16, out]], tolerance) + run_tv_test( AluGenMacWrapperRTL(), [[a, b, c, 16, out]], tolerance) def test_mac(cmdline_opts): tolerance = 0.00 @@ -117,5 +115,5 @@ def test_mac(cmdline_opts): c = 99 out = a * b + c - run_tv_test( ALUgenMAC(), [[a, b, c, 48, out]], tolerance) + run_tv_test( AluGenMacWrapperRTL(), [[a, b, c, 48, out]], tolerance) diff --git a/fu/ALUgen_fusedALU_fixedp/test/__init__.py b/fu/fused_alu_fixedp/test/__init__.py similarity index 100% rename from fu/ALUgen_fusedALU_fixedp/test/__init__.py rename to fu/fused_alu_fixedp/test/__init__.py diff --git a/fu/pymtl3_fusedALU_fixedp/__init__.py b/fu/pymtl3_fusedALU_fixedp/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/fu/pymtl3_fusedALU_fixedp/test/__init__.py b/fu/pymtl3_fusedALU_fixedp/test/__init__.py deleted file mode 100644 index e69de29..0000000 From 418e75319ebf436e5a0987a38fab571b317cf17d Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 21:45:21 +0000 Subject: [PATCH 05/10] [test] Fix FP units rdy signals --- fu/flexible/translate/FlexibleFuRTL_test.py | 132 -------------------- fu/flexible/translate/__init__.py | 0 fu/float/FpAddRTL.py | 14 ++- fu/float/FpMulRTL.py | 22 ++-- fu/float/test/FpAddRTL_test.py | 96 +++++++------- fu/float/test/FpMulRTL_test.py | 103 +++++++-------- 6 files changed, 117 insertions(+), 250 deletions(-) delete mode 100644 fu/flexible/translate/FlexibleFuRTL_test.py delete mode 100644 fu/flexible/translate/__init__.py diff --git a/fu/flexible/translate/FlexibleFuRTL_test.py b/fu/flexible/translate/FlexibleFuRTL_test.py deleted file mode 100644 index 103223e..0000000 --- a/fu/flexible/translate/FlexibleFuRTL_test.py +++ /dev/null @@ -1,132 +0,0 @@ -""" -========================================================================== -FlexibleFuRTL_test.py -========================================================================== -Test cases for flexible functional unit. - -Author : Cheng Tan - Date : Dec 14, 2019 -""" - - -from pymtl3 import * -from pymtl3.stdlib.test_utils import run_sim, config_model_with_cmdline_opts -from ..FlexibleFuRTL import FlexibleFuRTL -from ...single.AdderRTL import AdderRTL -from ...single.BranchRTL import BranchRTL -from ...single.CompRTL import CompRTL -from ...single.LogicRTL import LogicRTL -from ...single.MemUnitRTL import MemUnitRTL -from ...single.MulRTL import MulRTL -from ...single.PhiRTL import PhiRTL -from ...single.SelRTL import SelRTL -from ...single.ShifterRTL import ShifterRTL -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL -from ....lib.messages import * -from ....lib.opt_type import * - - -#------------------------------------------------------------------------- -# Test harness -#------------------------------------------------------------------------- - -class TestHarness( Component ): - - def construct( s, FunctionUnit, FuList, DataType, PredicateType, CtrlType, - data_mem_size, num_inports, num_outports, - src0_msgs, src1_msgs, src_predicate, ctrl_msgs, - sink0_msgs, sink1_msgs ): - - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_const = TestSrcRTL( DataType, src1_msgs ) - s.src_opt = TestSrcRTL( CtrlType, ctrl_msgs ) - s.sink_out0 = TestSinkRTL( DataType, sink0_msgs ) - - s.dut = FunctionUnit( DataType, PredicateType, CtrlType, - num_inports, num_outports, data_mem_size, - FuList ) - - connect( s.src_const.send, s.dut.recv_const ) - connect( s.src_in0.send, s.dut.recv_in[0] ) - connect( s.src_in1.send, s.dut.recv_in[1] ) - connect( s.src_predicate.send, s.dut.recv_predicate ) - connect( s.src_opt.send, s.dut.recv_opt ) - connect( s.dut.send_out[0], s.sink_out0.recv ) - - AddrType = mk_bits( clog2( data_mem_size ) ) - s.to_mem_raddr = [ TestSinkRTL( AddrType, [] ) for _ in FuList ] - s.from_mem_rdata = [ TestSrcRTL( DataType, [] ) for _ in FuList ] - s.to_mem_waddr = [ TestSinkRTL( AddrType, [] ) for _ in FuList ] - s.to_mem_wdata = [ TestSinkRTL( DataType, [] ) for _ in FuList ] - - for i in range( len( FuList ) ): - s.to_mem_raddr[i].recv //= s.dut.to_mem_raddr[i] - s.from_mem_rdata[i].send //= s.dut.from_mem_rdata[i] - s.to_mem_waddr[i].recv //= s.dut.to_mem_waddr[i] - s.to_mem_wdata[i].recv //= s.dut.to_mem_wdata[i] - - def done( s ): - return s.src_in0.done() and s.src_in1.done() and\ - s.src_opt.done() and s.sink_out0.done() - - def line_trace( s ): - return s.dut.line_trace() - -# def run_sim( test_harness, max_cycles=100 ): -# test_harness.elaborate() -# test_harness.dut.verilog_translate_import = True -# test_harness.dut.config_verilog_import = VerilatorImportConfigs(vl_Wno_list = ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', 'ALWCOMBORDER']) -# test_harness = TranslationImportPass()(test_harness) -# 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() - -import platform -import pytest - -# @pytest.mark.skipif('Linux' not in platform.platform(), -# reason="requires linux (gcc)") -def test_flexible_mul( cmdline_opts ): - FU = FlexibleFuRTL - FuList = [AdderRTL, MulRTL, LogicRTL, ShifterRTL, PhiRTL, CompRTL, BranchRTL, MemUnitRTL, SelRTL] - DataType = mk_data( 64, 1 ) - PredicateType = mk_predicate( 1, 1 ) - data_mem_size = 8 - num_inports = 4 - num_outports = 2 - CtrlType = mk_ctrl(num_inports) - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(2, 1), DataType(9, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(2, 1) ] - src_predicate = [ PredicateType(1, 1), PredicateType(1, 0), PredicateType(1, 1) ] - sink_out = [ DataType(2, 1), DataType(6, 1), DataType(18, 1) ] - src_opt = [ CtrlType( OPT_MUL, b1( 0 ), pickRegister ), - CtrlType( OPT_MUL, b1( 0 ), pickRegister ), - CtrlType( OPT_MUL, b1( 0 ), pickRegister ) ] - th = TestHarness( FU, FuList, DataType, PredicateType, CtrlType, - data_mem_size, num_inports, num_outports, - src_in0, src_in1, src_predicate, src_opt, - sink_out, sink_out ) - th = config_model_with_cmdline_opts( th, cmdline_opts, duts=['dut'] ) - th.apply( DefaultPassGroup(linetrace=True) ) - # run_sim( th ) - diff --git a/fu/flexible/translate/__init__.py b/fu/flexible/translate/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/fu/float/FpAddRTL.py b/fu/float/FpAddRTL.py index 0ca51c8..ac58222 100644 --- a/fu/float/FpAddRTL.py +++ b/fu/float/FpAddRTL.py @@ -26,6 +26,7 @@ class FpAddRTL(Fu): def construct(s, DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size, exp_nbits = 4, sig_nbits = 11): + super(FpAddRTL, s).construct(DataType, PredicateType, CtrlType, num_inports, num_outports, data_mem_size) @@ -36,6 +37,7 @@ def construct(s, DataType, PredicateType, CtrlType, num_entries = 2 FuInType = mk_bits(clog2(num_inports + 1)) CountType = mk_bits(clog2(num_entries + 1)) + # TODO: parameterize rounding mode s.rounding_mode = 0b000 s.FLOATING_ONE = concat( @@ -43,17 +45,17 @@ def construct(s, DataType, PredicateType, CtrlType, mk_bits(sig_nbits)() ) # Components - s.fadd = AddFN( exp_nbits+1, sig_nbits ) + s.fadd = AddFN(exp_nbits + 1, sig_nbits) s.fadd.roundingMode //= s.rounding_mode s.fadd.subOp //= lambda: s.recv_opt.msg.ctrl == OPT_FSUB # Wires - s.in0 = Wire( FuInType ) - s.in1 = Wire( FuInType ) + s.in0 = Wire(FuInType) + s.in1 = Wire(FuInType) - idx_nbits = clog2( num_inports ) - s.in0_idx = Wire( idx_nbits ) - s.in1_idx = Wire( idx_nbits ) + idx_nbits = clog2(num_inports) + s.in0_idx = Wire(idx_nbits) + s.in1_idx = Wire(idx_nbits) s.in0_idx //= s.in0[0:idx_nbits] s.in1_idx //= s.in1[0:idx_nbits] diff --git a/fu/float/FpMulRTL.py b/fu/float/FpMulRTL.py index 848e0f0..dd62a33 100644 --- a/fu/float/FpMulRTL.py +++ b/fu/float/FpMulRTL.py @@ -42,7 +42,7 @@ def construct(s, DataType, PredicateType, CtrlType, s.rounding_mode = 0b000 # Components - s.fmul = MulFN(exp_nbits+1, sig_nbits) + s.fmul = MulFN(exp_nbits + 1, sig_nbits) s.fmul.roundingMode //= s.rounding_mode # Wires @@ -61,29 +61,27 @@ def construct(s, DataType, PredicateType, CtrlType, @update def comb_logic(): + s.recv_all_val @= 0 # For pick input register s.in0 @= 0 s.in1 @= 0 - for i in range( num_inports ): + for i in range(num_inports): s.recv_in[i].rdy @= b1(0) - for i in range( num_outports ): - s.send_out[i].en @= s.recv_opt.en + for i in range(num_outports): + s.send_out[i].val @= 0 s.send_out[i].msg @= DataType() s.recv_const.rdy @= 0 s.recv_predicate.rdy @= b1(0) s.recv_opt.rdy @= 0 - if s.recv_opt.en: + if s.recv_opt.val & s.send_out[0].rdy: if s.recv_opt.msg.fu_in[0] != 0: s.in0 @= zext(s.recv_opt.msg.fu_in[0] - 1, FuInType) if s.recv_opt.msg.fu_in[1] != 0: s.in1 @= zext(s.recv_opt.msg.fu_in[1] - 1, FuInType) - s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ - s.recv_in[s.in1_idx].msg.predicate - if s.recv_opt.val: if s.recv_opt.msg.ctrl == OPT_FMUL: s.fmul.a @= s.recv_in[s.in0_idx].msg.payload @@ -105,16 +103,16 @@ def comb_logic(): s.send_out[0].msg.predicate @= s.recv_in[s.in0_idx].msg.predicate & \ (~s.recv_opt.msg.predicate | \ s.recv_predicate.msg.predicate) - s.recv_all_val @= s.recv_in[s.in0_idx].val & s.recv_in[s.in1_idx].val & \ + s.recv_all_val @= s.recv_in[s.in0_idx].val & \ ((s.recv_opt.msg.predicate == b1(0)) | s.recv_predicate.val) s.send_out[0].val @= s.recv_all_val s.recv_in[s.in0_idx].rdy @= s.recv_all_val & s.send_out[0].rdy - s.recv_in[s.in1_idx].rdy @= s.recv_all_val & s.send_out[0].rdy + s.recv_const.rdy @= s.recv_all_val & s.send_out[0].rdy s.recv_opt.rdy @= s.recv_all_val & s.send_out[0].rdy else: - for j in range( num_outports ): - s.send_out[j].val @= b1( 0 ) + for j in range(num_outports): + s.send_out[j].val @= b1(0) s.recv_opt.rdy @= 0 s.recv_in[s.in0_idx].rdy @= 0 s.recv_in[s.in1_idx].rdy @= 0 diff --git a/fu/float/test/FpAddRTL_test.py b/fu/float/test/FpAddRTL_test.py index 85b3a97..bc8f1ab 100644 --- a/fu/float/test/FpAddRTL_test.py +++ b/fu/float/test/FpAddRTL_test.py @@ -8,7 +8,6 @@ Date : Aug 8, 2023 """ - from pymtl3 import * from pymtl3.stdlib.test_utils import (run_sim, config_model_with_cmdline_opts) @@ -21,50 +20,49 @@ from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL - round_near_even = 0b000 -def test_elaborate( cmdline_opts ): - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) +def test_elaborate(cmdline_opts): + DataType = mk_data(16, 1) + PredType = mk_predicate(1, 1) ConfigType = mk_ctrl() data_mem_size = 8 num_inports = 2 num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(2, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] + FuInType = mk_bits(clog2(num_inports + 1)) + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_in0 = [ DataType(1, 1), DataType(7, 1), DataType(4, 1) ] + src_in1 = [ DataType(3, 1), ] + src_predicate = [ PredType(1, 0), PredType(1, 0), PredType(1, 1) ] + src_const = [ DataType(5, 1), DataType(7, 1) ] sink_out = [ DataType(6, 0), DataType(4, 0), DataType(11, 1) ] - src_opt = [ ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_SUB, b1( 1 ), pickRegister ), - ConfigType( OPT_ADD_CONST, b1( 1 ), pickRegister ) ] - dut = FpAddRTL( DataType, PredicateType, ConfigType, num_inports, - num_outports, data_mem_size, exp_nbits = 4, sig_nbits = 11 ) - dut = config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) + src_opt = [ ConfigType( OPT_ADD_CONST, b1(1), pick_register ), + ConfigType( OPT_SUB, b1(1), pick_register ), + ConfigType( OPT_ADD_CONST, b1(1), pick_register ) ] + dut = FpAddRTL(DataType, PredType, ConfigType, num_inports, + num_outports, data_mem_size, exp_nbits = 4, sig_nbits = 11) + dut = config_model_with_cmdline_opts(dut, cmdline_opts, duts = []) #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, + def construct(s, FunctionUnit, DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size, src0_msgs, src1_msgs, src_predicate, src_const, - ctrl_msgs, sink_msgs ): + ctrl_msgs, sink_msgs): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_predicate = TestSrcRTL ( PredType, src_predicate ) + s.src_opt = TestSrcRTL ( ConfigType, ctrl_msgs ) + s.sink_out = TestSinkRTL( DataType, sink_msgs ) - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredType, ConfigType, + num_inports, num_outports, data_mem_size) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) @@ -73,43 +71,43 @@ def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, connect( s.src_opt.send, s.dut.recv_opt ) connect( s.dut.send_out[0], s.sink_out.recv ) - def done( s ): + def done(s): return s.src_in0.done() and s.src_in1.done() and \ s.src_opt.done() and s.sink_out.done() - def line_trace( s ): + def line_trace(s): return s.dut.line_trace() -def mk_float_to_bits_fn( DataType, exp_nbits = 4, sig_nbits = 11 ): +def mk_float_to_bits_fn(DataType, exp_nbits = 4, sig_nbits = 11): return lambda f_value, predicate: ( - DataType( floatToFN( f_value, - precision = 1 + exp_nbits + sig_nbits ), - predicate ) ) + DataType(floatToFN(f_value, + precision = 1 + exp_nbits + sig_nbits), + predicate)) def test_add_basic(): FU = FpAddRTL exp_nbits = 4 sig_nbits = 11 - DataType = mk_data( 1 + exp_nbits + sig_nbits, 1 ) - f2b = mk_float_to_bits_fn( DataType, exp_nbits, sig_nbits ) - PredicateType = mk_predicate( 1, 1 ) + DataType = mk_data(1 + exp_nbits + sig_nbits, 1) + f2b = mk_float_to_bits_fn(DataType, exp_nbits, sig_nbits) + PredType = mk_predicate(1, 1) ConfigType = mk_ctrl() data_mem_size = 8 num_inports = 2 num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ f2b(1.1, 1), f2b(7.7, 1), f2b(4.4, 1) ] - src_in1 = [ f2b(2.2, 1), f2b(3.3, 1), f2b(1.1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ f2b(5.5, 1), f2b(0, 0), f2b(7.7, 1) ] - sink_out = [ f2b(6.602, 0), f2b(4.4, 0), f2b(12.1, 1) ] # 6.6 -> 6.602 - src_opt = [ ConfigType( OPT_FADD_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_FSUB, b1( 1 ), pickRegister ), - ConfigType( OPT_FADD_CONST, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, + FuInType = mk_bits(clog2(num_inports + 1)) + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_predicate = [ PredType(1, 0), PredType(1, 0), PredType(1, 1) ] + src_in0 = [ f2b(1.1, 1), f2b(7.7, 1), f2b(4.4, 1) ] + src_in1 = [ f2b(3.3, 1), ] + src_const = [ f2b(5.5, 1), f2b(7.7, 1) ] + sink_out = [ f2b(6.602, 0), f2b(4.4, 0), f2b(12.1, 1) ] # 6.6 -> 6.602 + src_opt = [ ConfigType( OPT_FADD_CONST, b1(1), pick_register ), + ConfigType( OPT_FSUB, b1(1), pick_register ), + ConfigType( OPT_FADD_CONST, b1(1), pick_register ) ] + th = TestHarness( FU, DataType, PredType, ConfigType, num_inports, num_outports, data_mem_size, src_in0, src_in1, src_predicate, src_const, src_opt, sink_out ) - run_sim( th ) + run_sim(th) diff --git a/fu/float/test/FpMulRTL_test.py b/fu/float/test/FpMulRTL_test.py index e4af298..095e2fe 100644 --- a/fu/float/test/FpMulRTL_test.py +++ b/fu/float/test/FpMulRTL_test.py @@ -14,55 +14,56 @@ from ..FpMulRTL import FpMulRTL from ...pymtl3_hardfloat.HardFloat.converter_funcs import (floatToFN, fNToFloat) -from ....lib.basic.en_rdy.test_sinks import TestSinkRTL -from ....lib.basic.en_rdy.test_srcs import TestSrcRTL +from ....lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL +from ....lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ....lib.messages import * from ....lib.opt_type import * from ....mem.const.ConstQueueRTL import ConstQueueRTL round_near_even = 0b000 -def test_elaborate( cmdline_opts ): - DataType = mk_data( 16, 1 ) - PredicateType = mk_predicate( 1, 1 ) +def test_elaborate(cmdline_opts): + DataType = mk_data(16, 1) + PredType = mk_predicate(1, 1) ConfigType = mk_ctrl() data_mem_size = 8 num_inports = 2 num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ DataType(2, 1), DataType(7, 1), DataType(4, 1) ] - src_in1 = [ DataType(1, 1), DataType(3, 1), DataType(1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ DataType(5, 1), DataType(0, 0), DataType(7, 1) ] + FuInType = mk_bits(clog2(num_inports + 1)) + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_in0 = [ DataType(2, 1), DataType(7, 1), DataType(4, 1) ] + src_in1 = [ DataType(3, 1) ] + src_predicate = [ PredType(1, 0), PredType(1, 0), PredType(1, 1) ] + src_const = [ DataType(5, 1), DataType(7, 1) ] sink_out = [ DataType(10, 0), DataType(21, 0), DataType(28, 1) ] - src_opt = [ ConfigType( OPT_MUL_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_MUL, b1( 1 ), pickRegister ), - ConfigType( OPT_MUL_CONST, b1( 1 ), pickRegister ) ] - dut = FpMulRTL( DataType, PredicateType, ConfigType, num_inports, - num_outports, data_mem_size, exp_nbits=4, sig_nbits=11 ) - dut = config_model_with_cmdline_opts( dut, cmdline_opts, duts=[] ) + src_opt = [ ConfigType( OPT_MUL_CONST, b1(1), pick_register ), + ConfigType( OPT_MUL, b1(1), pick_register ), + ConfigType( OPT_MUL_CONST, b1(1), pick_register ) ] + dut = FpMulRTL(DataType, PredType, ConfigType, num_inports, + num_outports, data_mem_size, exp_nbits = 4, + sig_nbits = 11) + dut = config_model_with_cmdline_opts(dut, cmdline_opts, duts = []) #------------------------------------------------------------------------- # Test harness #------------------------------------------------------------------------- -class TestHarness( Component ): +class TestHarness(Component): - def construct( s, FunctionUnit, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src0_msgs, src1_msgs, src_predicate, src_const, - ctrl_msgs, sink_msgs ): + def construct(s, FunctionUnit, DataType, PredType, ConfigType, + num_inports, num_outports, data_mem_size, + src0_msgs, src1_msgs, src_predicate, src_const, + ctrl_msgs, sink_msgs): - s.src_in0 = TestSrcRTL( DataType, src0_msgs ) - s.src_in1 = TestSrcRTL( DataType, src1_msgs ) - s.src_predicate = TestSrcRTL( PredicateType, src_predicate ) - s.src_opt = TestSrcRTL( ConfigType, ctrl_msgs ) - s.sink_out = TestSinkRTL( DataType, sink_msgs ) + s.src_in0 = TestSrcRTL ( DataType, src0_msgs ) + s.src_in1 = TestSrcRTL ( DataType, src1_msgs ) + s.src_predicate = TestSrcRTL ( PredType, src_predicate ) + s.src_opt = TestSrcRTL ( ConfigType, ctrl_msgs ) + s.sink_out = TestSinkRTL( DataType, sink_msgs ) - s.const_queue = ConstQueueRTL( DataType, src_const ) - s.dut = FunctionUnit( DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size ) + s.const_queue = ConstQueueRTL(DataType, src_const) + s.dut = FunctionUnit(DataType, PredType, ConfigType, + num_inports, num_outports, data_mem_size) connect( s.src_in0.send, s.dut.recv_in[0] ) connect( s.src_in1.send, s.dut.recv_in[1] ) @@ -78,36 +79,36 @@ def done(s): def line_trace(s): return s.dut.line_trace() -def mk_float_to_bits_fn( DataType, exp_nbits = 4, sig_nbits = 11 ): +def mk_float_to_bits_fn(DataType, exp_nbits = 4, sig_nbits = 11): return lambda f_value, predicate: ( - DataType( floatToFN( f_value, - precision = 1 + exp_nbits + sig_nbits ), - predicate ) ) + DataType(floatToFN(f_value, + precision = 1 + exp_nbits + sig_nbits), + predicate)) def test_mul(): FU = FpMulRTL exp_nbits = 4 sig_nbits = 11 - DataType = mk_data( 1 + exp_nbits + sig_nbits, 1 ) - f2b = mk_float_to_bits_fn( DataType, exp_nbits, sig_nbits ) - PredicateType = mk_predicate( 1, 1 ) + DataType = mk_data(1 + exp_nbits + sig_nbits, 1) + f2b = mk_float_to_bits_fn(DataType, exp_nbits, sig_nbits) + PredType = mk_predicate(1, 1) ConfigType = mk_ctrl() data_mem_size = 8 num_inports = 2 num_outports = 1 - FuInType = mk_bits( clog2( num_inports + 1 ) ) - pickRegister = [ FuInType( x+1 ) for x in range( num_inports ) ] - src_in0 = [ f2b(2.2, 1), f2b(7.7, 1), f2b(4.4, 1) ] - src_in1 = [ f2b(1.1, 1), f2b(3.3, 1), f2b(1.1, 1) ] - src_predicate = [ PredicateType(1, 0), PredicateType(1, 0), PredicateType(1, 1) ] - src_const = [ f2b(5.5, 1), f2b(0, 0), f2b(7.7, 1) ] + FuInType = mk_bits(clog2(num_inports + 1)) + pick_register = [ FuInType(x + 1) for x in range(num_inports) ] + src_predicate = [ PredType(1, 0), PredType(1, 0), PredType(1, 1) ] + src_in0 = [ f2b(2.2, 1), f2b(7.7, 1), f2b(4.4, 1) ] + src_in1 = [ f2b(3.3, 1) ] + src_const = [ f2b(5.5, 1), f2b(7.7, 1) ] sink_out = [ f2b(12.1, 0), f2b(25.4, 0), f2b(33.88, 1) ] # 25.41 -> 25.4 - src_opt = [ ConfigType( OPT_FMUL_CONST, b1( 1 ), pickRegister ), - ConfigType( OPT_FMUL, b1( 1 ), pickRegister ), - ConfigType( OPT_FMUL_CONST, b1( 1 ), pickRegister ) ] - th = TestHarness( FU, DataType, PredicateType, ConfigType, - num_inports, num_outports, data_mem_size, - src_in0, src_in1, src_predicate, src_const, src_opt, - sink_out ) - run_sim( th ) + src_opt = [ ConfigType( OPT_FMUL_CONST, b1(1), pick_register ), + ConfigType( OPT_FMUL, b1(1), pick_register ), + ConfigType( OPT_FMUL_CONST, b1(1), pick_register ) ] + th = TestHarness(FU, DataType, PredType, ConfigType, + num_inports, num_outports, data_mem_size, + src_in0, src_in1, src_predicate, src_const, src_opt, + sink_out) + run_sim(th) From 747560844b522875deb87cf4dad6ef359a450574 Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 22:50:22 +0000 Subject: [PATCH 06/10] [cleanup] Rename and remove files --- ...barDataMemRingCtrlMemRTL.py => CgraRTL.py} | 34 +-- cgra/CgraTemplateRTL.py | 30 +- ...RingCtrlMemRTL_test.py => CgraRTL_test.py} | 6 +- controller/ControllerRTL.py | 132 ++++---- controller/test/ControllerRTL_test.py | 92 +++--- noc/ChannelNormalRTL.py | 54 ---- ...{CrossbarSeparateRTL.py => CrossbarRTL.py} | 2 +- noc/test/ChannelNormalRTL_test.py | 89 ------ noc/test/CrossbarRTL_test.py | 7 +- systolic/CgraMemRightAndBottomRTL.py | 133 -------- systolic/CgraSystolicArrayRTL.py | 29 +- tile/TileRTL.py | 289 ++++++++++++------ tile/TileSeparateCrossbarRTL.py | 229 -------------- ...ateCrossbarRTL_test.py => TileRTL_test.py} | 24 +- 14 files changed, 368 insertions(+), 782 deletions(-) rename cgra/{CgraCrossbarDataMemRingCtrlMemRTL.py => CgraRTL.py} (87%) rename cgra/test/{CgraCrossbarDataMemRingCtrlMemRTL_test.py => CgraRTL_test.py} (98%) delete mode 100644 noc/ChannelNormalRTL.py rename noc/{CrossbarSeparateRTL.py => CrossbarRTL.py} (99%) delete mode 100644 noc/test/ChannelNormalRTL_test.py delete mode 100644 systolic/CgraMemRightAndBottomRTL.py delete mode 100644 tile/TileSeparateCrossbarRTL.py rename tile/test/{TileSeparateCrossbarRTL_test.py => TileRTL_test.py} (94%) diff --git a/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py b/cgra/CgraRTL.py similarity index 87% rename from cgra/CgraCrossbarDataMemRingCtrlMemRTL.py rename to cgra/CgraRTL.py index 7d390ba..8d8be27 100644 --- a/cgra/CgraCrossbarDataMemRingCtrlMemRTL.py +++ b/cgra/CgraRTL.py @@ -1,6 +1,6 @@ """ ========================================================================= -CgraCrossbarDataMemRingCtrlMemRTL.py +CgraRTL.py ========================================================================= Author : Cheng Tan @@ -17,13 +17,11 @@ from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL -from ..noc.ChannelNormalRTL import ChannelNormalRTL -from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL -from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL +from ..tile.TileRTL import TileRTL -class CgraCrossbarDataMemRingCtrlMemRTL(Component): +class CgraRTL(Component): def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, ControllerIdType, controller_id, @@ -68,11 +66,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Components if preload_const == None: preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] - s.tile = [TileSeparateCrossbarRTL( - DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, - data_mem_size_global, 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.tile = [TileRTL(DataType, PredicateType, CtrlPktType, + CtrlSignalType, ctrl_mem_size, + data_mem_size_global, 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 = DataMemWithCrossbarRTL(NocPktType, DataType, data_mem_size_global, data_mem_size_per_bank, @@ -86,13 +86,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Connections # Connects data memory with controller. - s.data_mem.recv_raddr[height] //= s.controller.send_to_master_load_request_addr - s.data_mem.recv_waddr[height] //= s.controller.send_to_master_store_request_addr - s.data_mem.recv_wdata[height] //= s.controller.send_to_master_store_request_data - s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data - s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt - s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt - s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt + s.data_mem.recv_raddr[height] //= s.controller.send_to_tile_load_request_addr + s.data_mem.recv_waddr[height] //= s.controller.send_to_tile_store_request_addr + s.data_mem.recv_wdata[height] //= s.controller.send_to_tile_store_request_data + s.data_mem.recv_from_noc_rdata //= s.controller.send_to_tile_load_response_data + s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_tile_load_request_pkt + s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_tile_load_response_pkt + s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_tile_store_request_pkt s.recv_from_noc //= s.controller.recv_from_noc s.send_to_noc //= s.controller.send_to_noc diff --git a/cgra/CgraTemplateRTL.py b/cgra/CgraTemplateRTL.py index cca1f94..c6a2d79 100644 --- a/cgra/CgraTemplateRTL.py +++ b/cgra/CgraTemplateRTL.py @@ -17,11 +17,9 @@ from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL -from ..noc.ChannelNormalRTL import ChannelNormalRTL -from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL -from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL +from ..tile.TileRTL import TileRTL class CgraTemplateRTL(Component): @@ -62,11 +60,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Components if preload_const == None: preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] - s.tile = [TileSeparateCrossbarRTL( - DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, - data_mem_size_global, 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.tile = [TileRTL(DataType, PredicateType, CtrlPktType, + CtrlSignalType, ctrl_mem_size, + data_mem_size_global, 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)] # FIXME: Need to enrish data-SPM-related user-controlled parameters, e.g., number of banks. s.data_mem = DataMemWithCrossbarRTL(NocPktType, DataType, data_mem_size_global, @@ -82,13 +82,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Connections # Connects data memory with controller. - s.data_mem.recv_raddr[dataSPM.getNumOfValidReadPorts()] //= s.controller.send_to_master_load_request_addr - s.data_mem.recv_waddr[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_master_store_request_addr - s.data_mem.recv_wdata[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_master_store_request_data - s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data - s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt - s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt - s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt + s.data_mem.recv_raddr[dataSPM.getNumOfValidReadPorts()] //= s.controller.send_to_tile_load_request_addr + s.data_mem.recv_waddr[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_tile_store_request_addr + s.data_mem.recv_wdata[dataSPM.getNumOfValidWritePorts()] //= s.controller.send_to_tile_store_request_data + s.data_mem.recv_from_noc_rdata //= s.controller.send_to_tile_load_response_data + s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_tile_load_request_pkt + s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_tile_load_response_pkt + s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_tile_store_request_pkt s.recv_from_noc //= s.controller.recv_from_noc s.send_to_noc //= s.controller.send_to_noc diff --git a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py b/cgra/test/CgraRTL_test.py similarity index 98% rename from cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py rename to cgra/test/CgraRTL_test.py index 4e6ae05..9763701 100644 --- a/cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py +++ b/cgra/test/CgraRTL_test.py @@ -1,6 +1,6 @@ """ ========================================================================== -CgraCrossbarDataMemRingCtrlMemRTL_test.py +CgraRTL_test.py ========================================================================== Test cases for CGRA with crossbar-based data memory and ring-based control memory of each tile. @@ -14,7 +14,7 @@ config_model_with_cmdline_opts) from pymtl3.passes.backends.verilog import (VerilogTranslationPass, VerilogVerilatorImportPass) -from ..CgraCrossbarDataMemRingCtrlMemRTL import CgraCrossbarDataMemRingCtrlMemRTL +from ..CgraRTL import CgraRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ...fu.single.AdderRTL import AdderRTL from ...fu.single.BranchRTL import BranchRTL @@ -113,7 +113,7 @@ def init_param(topology, FuList = [MemUnitRTL, AdderRTL]): AddrType = mk_bits(addr_nbits) CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) num_tiles = width * height - DUT = CgraCrossbarDataMemRingCtrlMemRTL + DUT = CgraRTL FunctionUnit = FlexibleFuRTL DataType = mk_data(32, 1) PredicateType = mk_predicate(1, 1) diff --git a/controller/ControllerRTL.py b/controller/ControllerRTL.py index 06607e5..153c47c 100644 --- a/controller/ControllerRTL.py +++ b/controller/ControllerRTL.py @@ -13,8 +13,8 @@ from ..lib.basic.val_rdy.ifcs import SendIfcRTL as SendIfcRTL from ..lib.basic.val_rdy.ifcs import RecvIfcRTL as RecvIfcRTL from ..lib.basic.val_rdy.queues import NormalQueueRTL -from ..noc.ChannelNormalRTL import ChannelNormalRTL from ..noc.PyOCN.pymtl3_net.xbar.XbarBypassQueueRTL import XbarBypassQueueRTL +from ..noc.PyOCN.pymtl3_net.channel.ChannelRTL import ChannelRTL from ..lib.cmd_type import * from ..lib.opt_type import * @@ -32,29 +32,29 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, s.recv_from_cpu_ctrl_pkt = RecvIfcRTL(CtrlPktType) s.send_to_ctrl_ring_ctrl_pkt = SendIfcRTL(CtrlPktType) - # Request from/to master. - s.recv_from_master_load_request_pkt = RecvIfcRTL(NocPktType) - s.recv_from_master_load_response_pkt = RecvIfcRTL(NocPktType) - s.recv_from_master_store_request_pkt = RecvIfcRTL(NocPktType) + # Request from/to tiles. + s.recv_from_tile_load_request_pkt = RecvIfcRTL(NocPktType) + s.recv_from_tile_load_response_pkt = RecvIfcRTL(NocPktType) + s.recv_from_tile_store_request_pkt = RecvIfcRTL(NocPktType) - s.send_to_master_load_request_addr = SendIfcRTL(CGRAAddrType) - s.send_to_master_load_response_data = SendIfcRTL(CGRADataType) - s.send_to_master_store_request_addr = SendIfcRTL(CGRAAddrType) - s.send_to_master_store_request_data = SendIfcRTL(CGRADataType) + s.send_to_tile_load_request_addr = SendIfcRTL(CGRAAddrType) + s.send_to_tile_load_response_data = SendIfcRTL(CGRADataType) + s.send_to_tile_store_request_addr = SendIfcRTL(CGRAAddrType) + s.send_to_tile_store_request_data = SendIfcRTL(CGRADataType) # Component - s.recv_from_master_load_request_pkt_queue = ChannelNormalRTL(NocPktType, latency = 1, num_entries = 2) - s.recv_from_master_load_response_pkt_queue = ChannelNormalRTL(NocPktType, latency = 1, num_entries = 2) - s.recv_from_master_store_request_pkt_queue = ChannelNormalRTL(NocPktType, latency = 1, num_entries = 2) + s.recv_from_tile_load_request_pkt_queue = ChannelRTL(NocPktType, latency = 1) + s.recv_from_tile_load_response_pkt_queue = ChannelRTL(NocPktType, latency = 1) + s.recv_from_tile_store_request_pkt_queue = ChannelRTL(NocPktType, latency = 1) - s.send_to_master_load_request_addr_queue = ChannelNormalRTL(CGRAAddrType, latency = 1, num_entries = 2) - s.send_to_master_load_response_data_queue = ChannelNormalRTL(CGRADataType, latency = 1, num_entries = 2) - s.send_to_master_store_request_addr_queue = ChannelNormalRTL(CGRAAddrType, latency = 1, num_entries = 2) - s.send_to_master_store_request_data_queue = ChannelNormalRTL(CGRADataType, latency = 1, num_entries = 2) + s.send_to_tile_load_request_addr_queue = ChannelRTL(CGRAAddrType, latency = 1) + s.send_to_tile_load_response_data_queue = ChannelRTL(CGRADataType, latency = 1) + s.send_to_tile_store_request_addr_queue = ChannelRTL(CGRAAddrType, latency = 1) + s.send_to_tile_store_request_data_queue = ChannelRTL(CGRADataType, latency = 1) - # s.recv_from_other_cmd_queue = ChannelNormalRTL(CmdType, latency = 1, num_entries = 2) - # s.send_to_master_cmd_queue = ChannelNormalRTL(CmdType, latency = 1, num_entries = 2) - # s.send_to_other_cmd_queue = ChannelNormalRTL(CmdType, latency = 1, num_entries = 2) + # s.recv_from_other_cmd_queue = ChannelRTL(CmdType, latency = 1, num_entries = 2) + # s.send_to_tile_cmd_queue = ChannelRTL(CmdType, latency = 1, num_entries = 2) + # s.send_to_other_cmd_queue = ChannelRTL(CmdType, latency = 1, num_entries = 2) # Crossbar with 3 inports (load and store requests towards remote # memory, and load response from master) and 1 outport (only @@ -99,15 +99,15 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, # Connections # Requests towards others, 1 cycle delay to improve timing. - s.recv_from_master_load_request_pkt_queue.recv //= s.recv_from_master_load_request_pkt - s.recv_from_master_load_response_pkt_queue.recv //= s.recv_from_master_load_response_pkt - s.recv_from_master_store_request_pkt_queue.recv //= s.recv_from_master_store_request_pkt + s.recv_from_tile_load_request_pkt_queue.recv //= s.recv_from_tile_load_request_pkt + s.recv_from_tile_load_response_pkt_queue.recv //= s.recv_from_tile_load_response_pkt + s.recv_from_tile_store_request_pkt_queue.recv //= s.recv_from_tile_store_request_pkt # Reqeusts towards local from others, 1 cycle delay to improve timing. - s.send_to_master_load_request_addr_queue.send //= s.send_to_master_load_request_addr - s.send_to_master_load_response_data_queue.send //= s.send_to_master_load_response_data - s.send_to_master_store_request_addr_queue.send //= s.send_to_master_store_request_addr - s.send_to_master_store_request_data_queue.send //= s.send_to_master_store_request_data + s.send_to_tile_load_request_addr_queue.send //= s.send_to_tile_load_request_addr + s.send_to_tile_load_response_data_queue.send //= s.send_to_tile_load_response_data + s.send_to_tile_store_request_addr_queue.send //= s.send_to_tile_store_request_addr + s.send_to_tile_store_request_data_queue.send //= s.send_to_tile_store_request_data # For control signals delivery from CPU to tiles. # TODO: https://github.com/tancheng/VectorCGRA/issues/11 -- The request needs @@ -126,35 +126,35 @@ def update_received_msg(): kStoreRequestInportIdx = 2 # For the load request from master. - s.crossbar.recv[kLoadRequestInportIdx].val @= s.recv_from_master_load_request_pkt_queue.send.val - s.recv_from_master_load_request_pkt_queue.send.rdy @= s.crossbar.recv[kLoadRequestInportIdx].rdy + s.crossbar.recv[kLoadRequestInportIdx].val @= s.recv_from_tile_load_request_pkt_queue.send.val + s.recv_from_tile_load_request_pkt_queue.send.rdy @= s.crossbar.recv[kLoadRequestInportIdx].rdy s.crossbar.recv[kLoadRequestInportIdx].msg @= \ NocPktType(controller_id, 0, 0, 0, CMD_LOAD_REQUEST, - s.recv_from_master_load_request_pkt_queue.send.msg.addr, + s.recv_from_tile_load_request_pkt_queue.send.msg.addr, 0, 1) # For the store request from master. - s.crossbar.recv[kStoreRequestInportIdx].val @= s.recv_from_master_store_request_pkt_queue.send.val - s.recv_from_master_store_request_pkt_queue.send.rdy @= s.crossbar.recv[kStoreRequestInportIdx].rdy + s.crossbar.recv[kStoreRequestInportIdx].val @= s.recv_from_tile_store_request_pkt_queue.send.val + s.recv_from_tile_store_request_pkt_queue.send.rdy @= s.crossbar.recv[kStoreRequestInportIdx].rdy s.crossbar.recv[kStoreRequestInportIdx].msg @= \ NocPktType(controller_id, 0, 0, 0, CMD_STORE_REQUEST, - s.recv_from_master_store_request_pkt_queue.send.msg.addr, - s.recv_from_master_store_request_pkt_queue.send.msg.data, - s.recv_from_master_store_request_pkt_queue.send.msg.predicate) + s.recv_from_tile_store_request_pkt_queue.send.msg.addr, + s.recv_from_tile_store_request_pkt_queue.send.msg.data, + s.recv_from_tile_store_request_pkt_queue.send.msg.predicate) # For the load response (i.e., the data towards other) from master. s.crossbar.recv[kLoadResponseInportIdx].val @= \ - s.recv_from_master_load_response_pkt_queue.send.val - s.recv_from_master_load_response_pkt_queue.send.rdy @= s.crossbar.recv[kLoadResponseInportIdx].rdy + s.recv_from_tile_load_response_pkt_queue.send.val + s.recv_from_tile_load_response_pkt_queue.send.rdy @= s.crossbar.recv[kLoadResponseInportIdx].rdy s.crossbar.recv[kLoadResponseInportIdx].msg @= \ NocPktType(controller_id, 0, @@ -163,9 +163,9 @@ def update_received_msg(): CMD_LOAD_RESPONSE, # Retrieves the load (from NoC) address from the message. # The addr information is embedded in the message. - s.recv_from_master_load_response_pkt_queue.send.msg.addr, - s.recv_from_master_load_response_pkt_queue.send.msg.data, - s.recv_from_master_load_response_pkt_queue.send.msg.predicate) + s.recv_from_tile_load_response_pkt_queue.send.msg.addr, + s.recv_from_tile_load_response_pkt_queue.send.msg.data, + s.recv_from_tile_load_response_pkt_queue.send.msg.predicate) # TODO: For the other cmd types. @@ -173,43 +173,43 @@ def update_received_msg(): # def update_received_msg_from_noc(): # Initiates the signals. - s.send_to_master_load_request_addr_queue.recv.val @= 0 - s.send_to_master_store_request_addr_queue.recv.val @= 0 - s.send_to_master_store_request_data_queue.recv.val @= 0 - s.send_to_master_load_response_data_queue.recv.val @= 0 - s.send_to_master_load_request_addr_queue.recv.msg @= CGRAAddrType() - s.send_to_master_store_request_addr_queue.recv.msg @= CGRAAddrType() - s.send_to_master_store_request_data_queue.recv.msg @= CGRADataType() - s.send_to_master_load_response_data_queue.recv.msg @= CGRADataType() + s.send_to_tile_load_request_addr_queue.recv.val @= 0 + s.send_to_tile_store_request_addr_queue.recv.val @= 0 + s.send_to_tile_store_request_data_queue.recv.val @= 0 + s.send_to_tile_load_response_data_queue.recv.val @= 0 + s.send_to_tile_load_request_addr_queue.recv.msg @= CGRAAddrType() + s.send_to_tile_store_request_addr_queue.recv.msg @= CGRAAddrType() + s.send_to_tile_store_request_data_queue.recv.msg @= CGRADataType() + s.send_to_tile_load_response_data_queue.recv.msg @= CGRADataType() s.recv_from_noc.rdy @= 0 # For the load request from NoC. received_pkt = s.recv_from_noc.msg if s.recv_from_noc.val: if s.recv_from_noc.msg.cmd == CMD_LOAD_REQUEST: - if s.send_to_master_load_request_addr_queue.recv.rdy: + if s.send_to_tile_load_request_addr_queue.recv.rdy: s.recv_from_noc.rdy @= 1 - s.send_to_master_load_request_addr_queue.recv.msg @= \ + s.send_to_tile_load_request_addr_queue.recv.msg @= \ CGRAAddrType(received_pkt.addr) - s.send_to_master_load_request_addr_queue.recv.val @= 1 + s.send_to_tile_load_request_addr_queue.recv.val @= 1 elif s.recv_from_noc.msg.cmd == CMD_STORE_REQUEST: - if s.send_to_master_store_request_addr_queue.recv.rdy & \ - s.send_to_master_store_request_data_queue.recv.rdy: + if s.send_to_tile_store_request_addr_queue.recv.rdy & \ + s.send_to_tile_store_request_data_queue.recv.rdy: s.recv_from_noc.rdy @= 1 - s.send_to_master_store_request_addr_queue.recv.msg @= \ + s.send_to_tile_store_request_addr_queue.recv.msg @= \ CGRAAddrType(received_pkt.addr) - s.send_to_master_store_request_data_queue.recv.msg @= \ + s.send_to_tile_store_request_data_queue.recv.msg @= \ CGRADataType(received_pkt.data, received_pkt.predicate, 0, 0) - s.send_to_master_store_request_addr_queue.recv.val @= 1 - s.send_to_master_store_request_data_queue.recv.val @= 1 + s.send_to_tile_store_request_addr_queue.recv.val @= 1 + s.send_to_tile_store_request_data_queue.recv.val @= 1 elif s.recv_from_noc.msg.cmd == CMD_LOAD_RESPONSE: - if s.send_to_master_load_response_data_queue.recv.rdy: + if s.send_to_tile_load_response_data_queue.recv.rdy: s.recv_from_noc.rdy @= 1 - s.send_to_master_load_response_data_queue.recv.msg @= \ + s.send_to_tile_load_response_data_queue.recv.msg @= \ CGRADataType(received_pkt.data, received_pkt.predicate, 0, 0) - s.send_to_master_load_response_data_queue.recv.val @= 1 + s.send_to_tile_load_response_data_queue.recv.val @= 1 # else: # # TODO: Handle other cmd types. @@ -233,14 +233,14 @@ def update_sending_to_noc_msg(): def line_trace(s): send_to_ctrl_ring_ctrl_pkt_str = "send_to_ctrl_ring_ctrl_pkt: " + str(s.send_to_ctrl_ring_ctrl_pkt.msg) - recv_from_master_load_request_pkt_str = "recv_from_master_load_request_pkt: " + str(s.recv_from_master_load_request_pkt.msg) - recv_from_master_load_response_pkt_str = "recv_from_master_load_response_pkt: " + str(s.recv_from_master_load_response_pkt.msg) - recv_from_master_store_request_pkt_str = "recv_from_master_store_request_pkt: " + str(s.recv_from_master_store_request_pkt.msg) + recv_from_tile_load_request_pkt_str = "recv_from_tile_load_request_pkt: " + str(s.recv_from_tile_load_request_pkt.msg) + recv_from_tile_load_response_pkt_str = "recv_from_tile_load_response_pkt: " + str(s.recv_from_tile_load_response_pkt.msg) + recv_from_tile_store_request_pkt_str = "recv_from_tile_store_request_pkt: " + str(s.recv_from_tile_store_request_pkt.msg) crossbar_str = "crossbar: {" + s.crossbar.line_trace() + "}" - send_to_master_load_request_addr_str = "send_to_master_load_request_addr: " + str(s.send_to_master_load_request_addr.msg) - send_to_master_store_request_addr_str = "send_to_master_store_request_addr: " + str(s.send_to_master_store_request_addr.msg) - send_to_master_store_request_data_str = "send_to_master_store_request_data: " + str(s.send_to_master_store_request_data.msg) + send_to_tile_load_request_addr_str = "send_to_tile_load_request_addr: " + str(s.send_to_tile_load_request_addr.msg) + send_to_tile_store_request_addr_str = "send_to_tile_store_request_addr: " + str(s.send_to_tile_store_request_addr.msg) + send_to_tile_store_request_data_str = "send_to_tile_store_request_data: " + str(s.send_to_tile_store_request_data.msg) recv_from_noc_str = "recv_from_noc_pkt: " + str(s.recv_from_noc.msg) send_to_noc_str = "send_to_noc_pkt: " + str(s.send_to_noc.msg) + "; rdy: " + str(s.send_to_noc.rdy) + "; val: " + str(s.send_to_noc.val) - return f'{send_to_ctrl_ring_ctrl_pkt_str} || {recv_from_master_load_request_pkt_str} || {recv_from_master_load_response_pkt_str} || {recv_from_master_store_request_pkt_str} || {crossbar_str} || {send_to_master_load_request_addr_str} || {send_to_master_store_request_addr_str} || {send_to_master_store_request_data_str} || {recv_from_noc_str} || {send_to_noc_str}\n' + return f'{send_to_ctrl_ring_ctrl_pkt_str} || {recv_from_tile_load_request_pkt_str} || {recv_from_tile_load_response_pkt_str} || {recv_from_tile_store_request_pkt_str} || {crossbar_str} || {send_to_tile_load_request_addr_str} || {send_to_tile_store_request_addr_str} || {send_to_tile_store_request_data_str} || {recv_from_noc_str} || {send_to_noc_str}\n' diff --git a/controller/test/ControllerRTL_test.py b/controller/test/ControllerRTL_test.py index a0e9173..a1a6783 100644 --- a/controller/test/ControllerRTL_test.py +++ b/controller/test/ControllerRTL_test.py @@ -29,27 +29,27 @@ class TestHarness(Component): def construct(s, ControllerIdType, CtrlPktType, CmdType, MsgType, AddrType, PktType, controller_id, - from_master_load_request_pkt_msgs, - from_master_load_response_pkt_msgs, - from_master_store_request_pkt_msgs, - expected_to_master_load_request_addr_msgs, - expected_to_master_load_response_data_msgs, - expected_to_master_store_request_addr_msgs, - expected_to_master_store_request_data_msgs, + from_tile_load_request_pkt_msgs, + from_tile_load_response_pkt_msgs, + from_tile_store_request_pkt_msgs, + expected_to_tile_load_request_addr_msgs, + expected_to_tile_load_response_data_msgs, + expected_to_tile_store_request_addr_msgs, + expected_to_tile_store_request_data_msgs, from_noc_pkts, expected_to_noc_pkts, controller2addr_map): cmp_func = lambda a, b : a == b # a.data == b.data - s.src_from_master_load_request_pkt_en_rdy = TestSrcRTL(PktType, from_master_load_request_pkt_msgs) - s.src_from_master_load_response_pkt_en_rdy = TestSrcRTL(PktType, from_master_load_response_pkt_msgs) - s.src_from_master_store_request_pkt_en_rdy = TestSrcRTL(PktType, from_master_store_request_pkt_msgs) + s.src_from_tile_load_request_pkt_en_rdy = TestSrcRTL(PktType, from_tile_load_request_pkt_msgs) + s.src_from_tile_load_response_pkt_en_rdy = TestSrcRTL(PktType, from_tile_load_response_pkt_msgs) + s.src_from_tile_store_request_pkt_en_rdy = TestSrcRTL(PktType, from_tile_store_request_pkt_msgs) - s.sink_to_master_load_request_addr_en_rdy = TestSinkRTL(AddrType, expected_to_master_load_request_addr_msgs) - s.sink_to_master_load_response_data_en_rdy = TestSinkRTL(MsgType, expected_to_master_load_response_data_msgs) - s.sink_to_master_store_request_addr_en_rdy = TestSinkRTL(AddrType, expected_to_master_store_request_addr_msgs) - s.sink_to_master_store_request_data_en_rdy = TestSinkRTL(MsgType, expected_to_master_store_request_data_msgs) + s.sink_to_tile_load_request_addr_en_rdy = TestSinkRTL(AddrType, expected_to_tile_load_request_addr_msgs) + s.sink_to_tile_load_response_data_en_rdy = TestSinkRTL(MsgType, expected_to_tile_load_response_data_msgs) + s.sink_to_tile_store_request_addr_en_rdy = TestSinkRTL(AddrType, expected_to_tile_store_request_addr_msgs) + s.sink_to_tile_store_request_data_en_rdy = TestSinkRTL(MsgType, expected_to_tile_store_request_data_msgs) s.src_from_noc_val_rdy = TestSrcRTL(PktType, from_noc_pkts) s.sink_to_noc_val_rdy = TestNetSinkRTL(PktType, expected_to_noc_pkts, cmp_fn = cmp_func) @@ -59,14 +59,14 @@ def construct(s, ControllerIdType, CtrlPktType, CmdType, MsgType, controller2addr_map) # Connections - s.src_from_master_load_request_pkt_en_rdy.send //= s.dut.recv_from_master_load_request_pkt - s.src_from_master_load_response_pkt_en_rdy.send //= s.dut.recv_from_master_load_response_pkt - s.src_from_master_store_request_pkt_en_rdy.send //= s.dut.recv_from_master_store_request_pkt + s.src_from_tile_load_request_pkt_en_rdy.send //= s.dut.recv_from_tile_load_request_pkt + s.src_from_tile_load_response_pkt_en_rdy.send //= s.dut.recv_from_tile_load_response_pkt + s.src_from_tile_store_request_pkt_en_rdy.send //= s.dut.recv_from_tile_store_request_pkt - s.dut.send_to_master_load_request_addr //= s.sink_to_master_load_request_addr_en_rdy.recv - s.dut.send_to_master_load_response_data //= s.sink_to_master_load_response_data_en_rdy.recv - s.dut.send_to_master_store_request_addr //= s.sink_to_master_store_request_addr_en_rdy.recv - s.dut.send_to_master_store_request_data //= s.sink_to_master_store_request_data_en_rdy.recv + s.dut.send_to_tile_load_request_addr //= s.sink_to_tile_load_request_addr_en_rdy.recv + s.dut.send_to_tile_load_response_data //= s.sink_to_tile_load_response_data_en_rdy.recv + s.dut.send_to_tile_store_request_addr //= s.sink_to_tile_store_request_addr_en_rdy.recv + s.dut.send_to_tile_store_request_data //= s.sink_to_tile_store_request_data_en_rdy.recv s.src_from_noc_val_rdy.send //= s.dut.recv_from_noc s.dut.send_to_noc //= s.sink_to_noc_val_rdy.recv @@ -76,13 +76,13 @@ def construct(s, ControllerIdType, CtrlPktType, CmdType, MsgType, s.dut.send_to_ctrl_ring_ctrl_pkt.rdy //= 0 def done(s): - return s.src_from_master_load_request_pkt_en_rdy.done() and \ - s.src_from_master_load_response_pkt_en_rdy.done() and \ - s.src_from_master_store_request_pkt_en_rdy.done() and \ - s.sink_to_master_load_request_addr_en_rdy.done() and \ - s.sink_to_master_load_response_data_en_rdy.done() and \ - s.sink_to_master_store_request_addr_en_rdy.done() and \ - s.sink_to_master_store_request_data_en_rdy.done() and \ + return s.src_from_tile_load_request_pkt_en_rdy.done() and \ + s.src_from_tile_load_response_pkt_en_rdy.done() and \ + s.src_from_tile_store_request_pkt_en_rdy.done() and \ + s.sink_to_tile_load_request_addr_en_rdy.done() and \ + s.sink_to_tile_load_response_data_en_rdy.done() and \ + s.sink_to_tile_store_request_addr_en_rdy.done() and \ + s.sink_to_tile_store_request_data_en_rdy.done() and \ s.src_from_noc_val_rdy.done() and \ s.sink_to_noc_val_rdy.done() @@ -173,32 +173,32 @@ def mk_src_pkts(nterminals, lst): data_nbits = data_nbits, predicate_nbits = predicate_nbits) -from_master_load_request_pkts = [ +from_tile_load_request_pkts = [ # src dst opq vc cmd addr data predicate Pkt(0, 0, 0, 0, CMD_LOAD_REQUEST, 1, 0, 1), Pkt(0, 0, 0, 0, CMD_LOAD_REQUEST, 8, 0, 1), Pkt(0, 0, 0, 0, CMD_LOAD_REQUEST, 13, 0, 1), ] -from_master_load_response_pkts = [ +from_tile_load_response_pkts = [ # src dst opq vc cmd addr data predicate Pkt(0, 0, 0, 0, CMD_LOAD_RESPONSE, 11, 11, 1), Pkt(0, 0, 0, 0, CMD_LOAD_RESPONSE, 14, 14, 1), Pkt(0, 0, 0, 0, CMD_LOAD_RESPONSE, 12, 12, 1), ] -from_master_store_request_pkts = [ +from_tile_store_request_pkts = [ # src dst opq vc cmd addr data predicate Pkt(0, 0, 0, 0, CMD_STORE_REQUEST, 11, 110, 1), Pkt(0, 0, 0, 0, CMD_STORE_REQUEST, 3, 300, 1), Pkt(0, 0, 0, 0, CMD_STORE_REQUEST, 15, 150, 1), ] -expected_to_master_load_request_addr_msgs = [AddrType(2)] -expected_to_master_load_response_addr_msgs = [AddrType(8), AddrType(9)] -expected_to_master_load_response_data_msgs = [DataType(80, 1), DataType(90, 1)] -expected_to_master_store_request_addr_msgs = [AddrType(5)] -expected_to_master_store_request_data_msgs = [DataType(50, 1)] +expected_to_tile_load_request_addr_msgs = [AddrType(2)] +expected_to_tile_load_response_addr_msgs = [AddrType(8), AddrType(9)] +expected_to_tile_load_response_data_msgs = [DataType(80, 1), DataType(90, 1)] +expected_to_tile_store_request_addr_msgs = [AddrType(5)] +expected_to_tile_store_request_data_msgs = [DataType(50, 1)] from_noc_pkts = [ # src dst opq vc cmd addr data predicate @@ -228,16 +228,16 @@ def test_simple(): th = TestHarness(ControllerIdType, CtrlPktType, CmdType, DataType, AddrType, Pkt, controller_id, - from_master_load_request_pkts, - from_master_load_response_pkts, - from_master_store_request_pkts, - # from_master_load_response_data_msgs, - # from_master_store_request_addr_msgs, - # from_master_store_request_data_msgs, - expected_to_master_load_request_addr_msgs, - expected_to_master_load_response_data_msgs, - expected_to_master_store_request_addr_msgs, - expected_to_master_store_request_data_msgs, + from_tile_load_request_pkts, + from_tile_load_response_pkts, + from_tile_store_request_pkts, + # from_tile_load_response_data_msgs, + # from_tile_store_request_addr_msgs, + # from_tile_store_request_data_msgs, + expected_to_tile_load_request_addr_msgs, + expected_to_tile_load_response_data_msgs, + expected_to_tile_store_request_addr_msgs, + expected_to_tile_store_request_data_msgs, from_noc_pkts, expected_to_noc_pkts, controller2addr_map) diff --git a/noc/ChannelNormalRTL.py b/noc/ChannelNormalRTL.py deleted file mode 100644 index ec210d7..0000000 --- a/noc/ChannelNormalRTL.py +++ /dev/null @@ -1,54 +0,0 @@ -''' -========================================================================= -ChannelNormalRTL.py -========================================================================= -RTL channel module for connecting basic components within a CGRA tile -and across tiles. A channel normally takes single cycle while it could -be parameterizable with a few cycles in case the NoC is a torus. - -This simple channel has latency insensitive send/recv interfaces. - -Author : Cheng Tan - Date : Nov 26, 2024 -''' - -from pymtl3 import * -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL -from ..lib.basic.val_rdy.queues import NormalQueueRTL - -class ChannelNormalRTL(Component): - - def construct(s, DataType, latency = 1, num_entries = 2): - # Constant - assert(latency > 0) - s.latency = latency - # num_entries indicates how many items could be temporarily - # stored within the channel when there is congestion. Note - # that this would contribute to the overall register file size - # and it has nothing to do with the latency. - s.num_entries = num_entries - s.data = DataType() - s.count = OutPort(mk_bits(clog2(s.num_entries + 1))) - - # Interface - s.recv = RecvIfcRTL(DataType) - s.send = SendIfcRTL(DataType) - - # Component - s.queues = [NormalQueueRTL(DataType, s.num_entries) - for _ in range(s.latency)] - - - # Connections - s.count //= s.queues[s.latency - 1].count - for i in range(s.latency - 1): - s.queues[i+1].recv //= s.queues[i].send - - s.queues[0].recv //= s.recv - s.queues[s.latency - 1].send //= s.send - - def line_trace( s ): - trace = " -> ".join("channel_stage_" + str(i) + ": " + s.queues[i].line_trace() for i in range(s.latency)) - return trace - diff --git a/noc/CrossbarSeparateRTL.py b/noc/CrossbarRTL.py similarity index 99% rename from noc/CrossbarSeparateRTL.py rename to noc/CrossbarRTL.py index 99db90e..d8cdd05 100644 --- a/noc/CrossbarSeparateRTL.py +++ b/noc/CrossbarRTL.py @@ -14,7 +14,7 @@ from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * -class CrossbarSeparateRTL(Component): +class CrossbarRTL(Component): def construct(s, DataType, PredicateType, CtrlType, num_inports = 5, num_outports = 5, id = 0, crossbar_type = "None"): diff --git a/noc/test/ChannelNormalRTL_test.py b/noc/test/ChannelNormalRTL_test.py deleted file mode 100644 index 8975ed6..0000000 --- a/noc/test/ChannelNormalRTL_test.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -========================================================================= -ChannelNormalRTL_test.py -========================================================================= -Simple test for ChannelNormalRTL. There is no bypass functionality in -the channel. - -Author : Cheng Tan - Date : Nov 26, 2024 -""" - -import pytest -from pymtl3 import * -from pymtl3.stdlib.test_utils import TestVectorSimulator -from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL -from ...lib.messages import * -from ..ChannelNormalRTL import ChannelNormalRTL - -#------------------------------------------------------------------------- -# TestHarness -#------------------------------------------------------------------------- - -class TestHarness(Component): - - def construct(s, MsgType, src_msgs, sink_msgs, latency): - - s.src = TestSrcRTL(MsgType, src_msgs) - s.sink = TestSinkRTL(MsgType, sink_msgs) - s.dut = ChannelNormalRTL(MsgType, latency) - - # Connections - s.src.send //= s.dut.recv - s.dut.send //= s.sink.recv - - def done(s): - return s.src.done() and s.sink.done() - - def line_trace(s): - # 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 = 100): - - # 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())) - # if ncycles >= 6: - # test_harness.dut.send.rdy @= 1 - - # Check timeout - assert ncycles < max_cycles - - test_harness.sim_tick() - test_harness.sim_tick() - test_harness.sim_tick() - -#------------------------------------------------------------------------- -# Test cases -#------------------------------------------------------------------------- - -DataType = mk_data( 16, 1 ) -test_msgs = [ DataType(7,1,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] -sink_msgs = [ DataType(7,1,1), DataType(4,1), DataType(1,1), DataType(2,1), DataType(3,1) ] - -def test_simple(): - latency = 1 - th = TestHarness(DataType, test_msgs, sink_msgs, latency) - run_sim(th) - -def test_latency(): - latency = 2 - th = TestHarness(DataType, test_msgs, sink_msgs, latency) - run_sim(th) diff --git a/noc/test/CrossbarRTL_test.py b/noc/test/CrossbarRTL_test.py index eb13461..e5ad684 100644 --- a/noc/test/CrossbarRTL_test.py +++ b/noc/test/CrossbarRTL_test.py @@ -10,7 +10,7 @@ """ from pymtl3 import * -from ..CrossbarSeparateRTL import CrossbarSeparateRTL +from ..CrossbarRTL import CrossbarRTL from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL from ...lib.basic.val_rdy.SinkRTL import SinkRTL as TestSinkRTL from ...lib.opt_type import * @@ -82,7 +82,7 @@ def run_sim(test_harness, max_cycles = 20): test_harness.sim_tick() test_harness.sim_tick() -FU = CrossbarSeparateRTL +FU = CrossbarRTL num_fu_inports = 2 num_fu_outports = 2 num_tile_inports = 3 @@ -98,10 +98,7 @@ def run_sim(test_harness, max_cycles = 20): mk_separate_ctrl(num_ctrl_operations, num_fu_inports, num_fu_outports, num_tile_inports, num_tile_outports) -# CtrlType = mk_ctrl( num_fu_in, num_inports, num_outports ) pickRegister = [FuInType(x + 1) for x in range(num_fu_inports)] -# RouteType = mk_bits( clog2( num_inports + 1 ) ) -# src_opt = [ CtrlType( OPT_ADD, b1(0), pickRegister, [RouteType(2), RouteType(3), RouteType(1)]) ] def test_crossbar(): src_opt = [CtrlType(OPT_ADD, b1(0), pickRegister, diff --git a/systolic/CgraMemRightAndBottomRTL.py b/systolic/CgraMemRightAndBottomRTL.py deleted file mode 100644 index 8b6ac9a..0000000 --- a/systolic/CgraMemRightAndBottomRTL.py +++ /dev/null @@ -1,133 +0,0 @@ -""" -========================================================================= -CgraMemRightAndBottomRTL.py -========================================================================= -Two scrachpad memories are connected to the bottom (first row) and the -last column (except the one on the first row) tiles. For example, in a -3x3 CGRA, the bottom 3 tiles are connected to the south SPM while right- -most 2 tlies (from top to bottom) are connected to the east SPM. - -Author : Cheng Tan - Date : Nov 19, 2024 -""" - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.AdderRTL import AdderRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL -from ..lib.opt_type import * -from ..lib.util.common import * -from ..mem.data.DataMemRTL import DataMemRTL -from ..mem.data.DataMemCL import DataMemCL -from ..noc.CrossbarRTL import CrossbarRTL -from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL - -class CgraMemRightAndBottomRTL(Component): - def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, - width, height, ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, FunctionUnit, FuList, preload_data = None, - preload_const = None): - - s.num_mesh_ports = 4 - s.num_tiles = width * height - AddrType = mk_bits(clog2(ctrl_mem_size)) - - # Interfaces - s.recv_waddr = [RecvIfcRTL(AddrType) for _ in range(s.num_tiles)] - s.recv_wopt = [RecvIfcRTL(CtrlSignalType) for _ in range(s.num_tiles)] - - # Components - if preload_const == None: - preload_const = [[DataType(0, 0)] for _ in range(width * height)] - s.tile = [TileSeparateCrossbarRTL( - DataType, PredicateType, CtrlPktType, CtrlPktType, - CtrlSignalType, ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, 4, 2, s.num_mesh_ports, s.num_mesh_ports, - Fu = FunctionUnit, FuList = FuList, - const_list = preload_const[i]) for i in range(s.num_tiles)] - - s.data_mem_south = DataMemRTL(DataType, data_mem_size, - rd_ports = width, wr_ports = width, - preload_data = preload_data) - - s.data_mem_east = DataMemRTL(DataType, data_mem_size, - rd_ports = height - 1, - wr_ports = height - 1, - preload_data = None) - - # s.send_data = [SendIfcRTL(DataType) for _ in range (height - 1)] - - # Connections - 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: - # if i // width != 0: - # # Connects the send ports to the right-most tiles (except the - # # ones on the first row). - # s.tile[i].send_data[PORT_EAST] //= s.send_data[i // width - 1] - # s.tile[i].recv_data[PORT_EAST].en //= 0 - # s.tile[i].recv_data[PORT_EAST].msg //= DataType(0, 0) - # else: - 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: - # Connects the bottom tiles to the south SPM. - s.tile[i].to_mem_raddr //= s.data_mem_south.recv_raddr[i % width] - s.tile[i].from_mem_rdata //= s.data_mem_south.send_rdata[i % width] - s.tile[i].to_mem_waddr //= s.data_mem_south.recv_waddr[i % width] - s.tile[i].to_mem_wdata //= s.data_mem_south.recv_wdata[i % width] - elif i // width != 0 and i % width == width - 1: - # Connects the right-most tiles (except the bottom ones) to the east - # SPM. - s.tile[i].to_mem_raddr //= s.data_mem_east.recv_raddr[i // width - 1] - s.tile[i].from_mem_rdata //= s.data_mem_east.send_rdata[i // width - 1] - s.tile[i].to_mem_waddr //= s.data_mem_east.recv_waddr[i // width - 1] - s.tile[i].to_mem_wdata //= s.data_mem_east.recv_wdata[i // width - 1] - 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 :: SouthMem [" + s.data_mem_south.line_trace() + "] \n" - res += "\n :: EastMem [" + s.data_mem_east.line_trace() + "] \n" - return res diff --git a/systolic/CgraSystolicArrayRTL.py b/systolic/CgraSystolicArrayRTL.py index 5244ccb..83da687 100644 --- a/systolic/CgraSystolicArrayRTL.py +++ b/systolic/CgraSystolicArrayRTL.py @@ -17,11 +17,10 @@ from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL -from ..noc.ChannelNormalRTL import ChannelNormalRTL from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL -from ..tile.TileSeparateCrossbarRTL import TileSeparateCrossbarRTL +from ..tile.TileRTL import TileRTL class CgraSystolicArrayRTL(Component): @@ -65,11 +64,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Components if preload_const == None: preload_const = [[DataType(0, 0)] for _ in range(s.num_tiles)] - s.tile = [TileSeparateCrossbarRTL( - DataType, PredicateType, CtrlPktType, CtrlSignalType, ctrl_mem_size, - data_mem_size_global, num_ctrl, total_steps, 4, 2, - s.num_mesh_ports, s.num_mesh_ports, FuList = FuList, - const_list = preload_const[i], id = i) for i in range(s.num_tiles)] + s.tile = [TileRTL(DataType, PredicateType, CtrlPktType, + CtrlSignalType, ctrl_mem_size, + data_mem_size_global, num_ctrl, + total_steps, 4, 2, s.num_mesh_ports, + s.num_mesh_ports, FuList = FuList, + const_list = preload_const[i], id = i) + for i in range(s.num_tiles)] s.data_mem = DataMemWithCrossbarRTL(NocPktType, DataType, data_mem_size_global, data_mem_size_per_bank, @@ -84,13 +85,13 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, # Connections # Connects data memory with controller. - s.data_mem.recv_raddr[4] //= s.controller.send_to_master_load_request_addr - s.data_mem.recv_waddr[4] //= s.controller.send_to_master_store_request_addr - s.data_mem.recv_wdata[4] //= s.controller.send_to_master_store_request_data - s.data_mem.recv_from_noc_rdata //= s.controller.send_to_master_load_response_data - s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_master_load_request_pkt - s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_master_load_response_pkt - s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_master_store_request_pkt + s.data_mem.recv_raddr[4] //= s.controller.send_to_tile_load_request_addr + s.data_mem.recv_waddr[4] //= s.controller.send_to_tile_store_request_addr + s.data_mem.recv_wdata[4] //= s.controller.send_to_tile_store_request_data + s.data_mem.recv_from_noc_rdata //= s.controller.send_to_tile_load_response_data + s.data_mem.send_to_noc_load_request_pkt //= s.controller.recv_from_tile_load_request_pkt + s.data_mem.send_to_noc_load_response_pkt //= s.controller.recv_from_tile_load_response_pkt + s.data_mem.send_to_noc_store_pkt //= s.controller.recv_from_tile_store_request_pkt s.recv_from_noc //= s.controller.recv_from_noc s.send_to_noc //= s.controller.send_to_noc diff --git a/tile/TileRTL.py b/tile/TileRTL.py index dd68900..57f018f 100644 --- a/tile/TileRTL.py +++ b/tile/TileRTL.py @@ -1,134 +1,229 @@ """ ========================================================================= -TileRTL.py +TileSeparateCrossbarRTL.py ========================================================================= +The tile contains a list of functional units, a configuration memory, a +set of registers (e.g., channels), and two crossbars. One crossbar is for +routing the data to registers (i.e., the channels before FU and the +channels after the crossbar), and the other one is for passing the to the +next crossbar. + +Detailed in: https://github.com/tancheng/VectorCGRA/issues/13 (Option 2). Author : Cheng Tan - Date : Dec 11, 2019 + Date : Nov 26, 2024 """ - from pymtl3 import * from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ..fu.single.AdderRTL import AdderRTL from ..fu.single.BranchRTL import BranchRTL +from ..fu.single.PhiRTL import PhiRTL from ..fu.single.CompRTL import CompRTL from ..fu.single.MemUnitRTL import MemUnitRTL from ..fu.single.MulRTL import MulRTL -from ..fu.single.PhiRTL import PhiRTL -from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL +from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..mem.const.ConstQueueRTL import ConstQueueRTL -from ..mem.ctrl.CtrlMemRTL import CtrlMemRTL +from ..mem.ctrl.CtrlMemDynamicRTL import CtrlMemDynamicRTL from ..noc.CrossbarRTL import CrossbarRTL -from ..noc.ChannelRTL import ChannelRTL +from ..noc.PyOCN.pymtl3_net.channel.ChannelRTL import ChannelRTL +from ..noc.LinkOrRTL import LinkOrRTL from ..rf.RegisterRTL import RegisterRTL -# from ..noc.BypassChannelRTL import BypassChannelRTL - - -class TileRTL( Component ): - - def construct( s, DataType, PredicateType, CtrlType, - ctrl_mem_size, data_mem_size, num_ctrl, - total_steps, num_fu_inports, num_fu_outports, - num_connect_inports, num_connect_outports, - Fu=FlexibleFuRTL, - FuList=[PhiRTL,AdderRTL,CompRTL,MulRTL,BranchRTL,MemUnitRTL], - const_list = None ): - - # Constant - num_xbar_inports = num_fu_outports + num_connect_inports - num_xbar_outports = num_fu_inports + num_connect_outports - - CtrlAddrType = mk_bits( clog2( ctrl_mem_size ) ) - DataAddrType = mk_bits( clog2( data_mem_size ) ) - - # Interfaces - s.recv_data = [ RecvIfcRTL( DataType ) for _ in range ( num_connect_inports ) ] - s.send_data = [ SendIfcRTL( DataType ) for _ in range ( num_connect_outports ) ] - - # Ctrl - s.recv_waddr = RecvIfcRTL( CtrlAddrType ) - s.recv_wopt = RecvIfcRTL( CtrlType ) - - # Data - s.to_mem_raddr = SendIfcRTL( DataAddrType ) - s.from_mem_rdata = RecvIfcRTL( DataType ) - s.to_mem_waddr = SendIfcRTL( DataAddrType ) - s.to_mem_wdata = SendIfcRTL( DataType ) - - # Components - s.element = FlexibleFuRTL( DataType, PredicateType, CtrlType, - num_fu_inports, num_fu_outports, - data_mem_size, FuList ) - s.const_queue = ConstQueueRTL( DataType, const_list if const_list != None else [DataType(0)]) - s.crossbar = CrossbarRTL( DataType, PredicateType, CtrlType, - num_xbar_inports, num_xbar_outports ) - s.ctrl_mem = CtrlMemRTL( CtrlType, ctrl_mem_size, num_ctrl, total_steps ) - s.channel = [ ChannelRTL( DataType ) for _ in range( num_xbar_outports ) ] - # # Added to break the combinational loops - # s.bypass_channel = [ BypassChannelRTL( DataType ) for _ in range( num_fu_outports ) ] + +class TileRTL(Component): + + def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, + ctrl_mem_size, data_mem_size, num_ctrl, total_steps, + num_fu_inports, num_fu_outports, num_tile_inports, + num_tile_outports, Fu = FlexibleFuRTL, + FuList = [PhiRTL, AdderRTL, CompRTL, MulRTL, BranchRTL, + MemUnitRTL], const_list = None, id = 0): + + # Constants. + num_routing_xbar_inports = num_tile_inports + num_routing_xbar_outports = num_fu_inports + num_tile_outports + + num_fu_xbar_inports = num_fu_outports + num_fu_xbar_outports = num_fu_inports + num_tile_outports + + CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) + DataAddrType = mk_bits(clog2(data_mem_size)) + + # Interfaces. + s.recv_data = [RecvIfcRTL(DataType) + for _ in range (num_tile_inports)] + s.send_data = [SendIfcRTL(DataType) + for _ in range (num_tile_outports)] + + # Ctrl. + s.recv_ctrl_pkt = RecvIfcRTL(CtrlPktType) + + # Data. + s.to_mem_raddr = SendIfcRTL(DataAddrType) + s.from_mem_rdata = RecvIfcRTL(DataType) + s.to_mem_waddr = SendIfcRTL(DataAddrType) + s.to_mem_wdata = SendIfcRTL(DataType) + + # Components. + s.element = FlexibleFuRTL(DataType, PredicateType, CtrlSignalType, + num_fu_inports, num_fu_outports, + data_mem_size, FuList) + s.const_queue = ConstQueueRTL(DataType, const_list \ + if const_list != None else [DataType(0)]) + s.routing_crossbar = CrossbarRTL(DataType, PredicateType, + CtrlSignalType, + num_routing_xbar_inports, + num_routing_xbar_outports) + s.fu_crossbar = CrossbarRTL(DataType, PredicateType, + CtrlSignalType, + num_fu_xbar_inports, + num_fu_xbar_outports, id, + "fu") + s.ctrl_mem = CtrlMemDynamicRTL(CtrlPktType, CtrlSignalType, + ctrl_mem_size, + num_fu_inports, num_fu_outports, + num_tile_inports, num_tile_outports, + num_ctrl, total_steps) + # The `tile_out_channel` indicates the outport channels that are + # connected to the next tiles. + s.tile_out_channel = [ChannelRTL(DataType, latency = 1) + for _ in range(num_tile_outports)] + # The `fu_in_channel` indicates the inport channels that are + # connected to the FUs. + s.fu_in_channel = [ChannelRTL(DataType, latency = 1) + for _ in range(num_fu_inports)] + # The `tile_out_or_link` would "or" the outports of the + # `tile_out_channel` and the FUs. + s.tile_out_or_link = [LinkOrRTL(DataType) + for _ in range(num_tile_outports)] + # The `fu_in_or_link` would "or" the inports of the `fu_in_channel' + # and the outports of the fu_crossbar. + s.fu_in_or_link = [LinkOrRTL(DataType) for _ in range(num_fu_inports)] # Additional one register for partial predication - s.reg_predicate = RegisterRTL( PredicateType ) + s.reg_predicate = RegisterRTL(PredicateType) - # Connections + # Signals indicating whether certain modules already done their jobs. + s.element_done = Wire(1) + s.fu_crossbar_done = Wire(1) + s.routing_crossbar_done = Wire(1) - # Ctrl - s.ctrl_mem.recv_waddr //= s.recv_waddr - s.ctrl_mem.recv_ctrl //= s.recv_wopt + # Connections. + # Ctrl. + s.ctrl_mem.recv_pkt //= s.recv_ctrl_pkt - # Data + # Constant queue. s.element.recv_const //= s.const_queue.send_const - for i in range( len( FuList ) ): + for i in range(len(FuList)): if FuList[i] == MemUnitRTL: - s.to_mem_raddr //= s.element.to_mem_raddr[i] + s.to_mem_raddr //= s.element.to_mem_raddr[i] s.from_mem_rdata //= s.element.from_mem_rdata[i] - s.to_mem_waddr //= s.element.to_mem_waddr[i] - s.to_mem_wdata //= s.element.to_mem_wdata[i] + s.to_mem_waddr //= s.element.to_mem_waddr[i] + s.to_mem_wdata //= s.element.to_mem_wdata[i] else: - s.element.to_mem_raddr[i].rdy //= 0 - s.element.from_mem_rdata[i].en //= 0 + s.element.to_mem_raddr[i].rdy //= 0 + s.element.from_mem_rdata[i].val //= 0 s.element.from_mem_rdata[i].msg //= DataType() - s.element.to_mem_waddr[i].rdy //= 0 - s.element.to_mem_wdata[i].rdy //= 0 - - for i in range( num_connect_inports ): - s.recv_data[i] //= s.crossbar.recv_data[i] - - for i in range( num_xbar_outports ): - s.crossbar.send_data[i] //= s.channel[i].recv + s.element.to_mem_waddr[i].rdy //= 0 + s.element.to_mem_wdata[i].rdy //= 0 + + # Connections on the `routing_crossbar`. + # The data from other tiles should be connected to the + # `routing_crossbar`. + for i in range(num_tile_inports): + s.recv_data[i] //= s.routing_crossbar.recv_data[i] + + # # Connects specific xbar control signals to the corresponding crossbar. + for i in range(num_routing_xbar_outports): + s.routing_crossbar.crossbar_outport[i] //= \ + s.ctrl_mem.send_ctrl.msg.routing_xbar_outport[i] + s.fu_crossbar.crossbar_outport[i] //= \ + s.ctrl_mem.send_ctrl.msg.fu_xbar_outport[i] + + # The data going out to the other tiles should be from + # the `routing_crossbar`. Note that there are also data + # being fed into the FUs via the `routing_crossbar`, which + # are filtered out by `num_tile_outports` below. + for i in range(num_tile_outports): + s.routing_crossbar.send_data[i] //= s.tile_out_channel[i].recv # One partial predication register for flow control. - s.crossbar.send_predicate //= s.reg_predicate.recv + s.routing_crossbar.send_predicate //= s.reg_predicate.recv s.reg_predicate.send //= s.element.recv_predicate - for i in range( num_connect_outports ): - s.channel[i].send //= s.send_data[i] - - for i in range( num_fu_inports ): - s.channel[num_connect_inports+i].send //= s.element.recv_in[i] - s.channel[num_connect_inports+i].count //= s.element.recv_in_count[i] - - for i in range( num_fu_outports ): - s.element.send_out[i] //= s.crossbar.recv_data[num_connect_outports+i] - # s.element.send_out[i] //= s.bypass_channel[i].recv - # s.bypass_channel[i].send //= s.crossbar.recv_data[num_connect_outports+i] - + # Connects the FU's inport channels with the corresponding FU. + # FIXME: change element to use val/rdy ifcs. + for i in range(num_fu_inports): + s.fu_in_channel[i].send //= s.element.recv_in[i] + # s.fu_in_channel[i].count //= s.element.recv_in_count[i] + + # Connections on the `fu_crossbar`. + # FIXME: change element to use val/rdy ifcs. + for i in range(num_fu_outports): + s.element.send_out[i] //= s.fu_crossbar.recv_data[i] + + # Links "or" the outports of the FUs (via `fu_crossbar`) with the + # outports of the `routing_crossbar` through the corresponding channels. + for i in range(num_tile_outports): + s.fu_crossbar.send_data[i] //= s.tile_out_or_link[i].recv_fu + s.tile_out_channel[i].send //= s.tile_out_or_link[i].recv_xbar + s.tile_out_or_link[i].send //= s.send_data[i] + + # Links "or" the inports of the FUs (from the `routing_crossbar`) + # with the outports of the FUs (via the `fu_crossbar`). + for i in range(num_fu_inports): + s.fu_crossbar.send_data[num_tile_outports + i] //= s.fu_in_or_link[i].recv_fu + s.routing_crossbar.send_data[num_tile_outports + i] //= s.fu_in_or_link[i].recv_xbar + s.fu_in_or_link[i].send //= s.fu_in_channel[i].recv + + # Updates the configuration memory related signals. @update def update_opt(): - s.element.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.element.recv_opt.en @= s.ctrl_mem.send_ctrl.en - s.crossbar.recv_opt.en @= s.ctrl_mem.send_ctrl.en - s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & s.crossbar.recv_opt.rdy - # Line trace - def line_trace( s ): + s.element.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg + s.routing_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg + s.fu_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg + + s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.element_done + s.routing_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.routing_crossbar_done + s.fu_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.fu_crossbar_done + + # s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & \ + # s.routing_crossbar.recv_opt.rdy & \ + # s.fu_crossbar.recv_opt.rdy + + # FIXME: yo96, rename ctrl.rdy to ctrl.proceed or sth similar. + # Allows either the FU-related go out first or routing-xbar go out first. And only + # allows the ctrl signal proceed till all the sub-modules done their own job (once). + s.ctrl_mem.send_ctrl.rdy @= (s.element.recv_opt.rdy | s.element_done) & \ + (s.routing_crossbar.recv_opt.rdy | s.routing_crossbar_done) & \ + (s.fu_crossbar.recv_opt.rdy | s.fu_crossbar_done) + + # Updates the signals indicating whether certain modules already done their jobs. + @update_ff + def already_done(): + if s.reset | s.ctrl_mem.send_ctrl.rdy: + s.element_done <<= 0 + s.fu_crossbar_done <<= 0 + s.routing_crossbar_done <<= 0 + else: + if s.element.recv_opt.rdy: + s.element_done <<= 1 + elif s.fu_crossbar.recv_opt.rdy: + s.fu_crossbar_done <<= 1 + elif s.routing_crossbar.recv_opt.rdy: + s.routing_crossbar_done <<= 1 - recv_str = "|".join([ str(x.msg) for x in s.recv_data ]) - channel_recv_str = "|".join([ str(x.recv.msg) for x in s.channel ]) - channel_send_str = "|".join([ str(x.send.msg) for x in s.channel ]) - out_str = "|".join([ "("+str(x.msg.payload)+","+str(x.msg.predicate)+")" for x in s.send_data ]) - return f"{recv_str} => [{s.crossbar.recv_opt.msg}] ({s.element.line_trace()}) => {channel_recv_str} => {channel_send_str} => {out_str}" + # Line trace + def line_trace(s): + recv_str = "|".join(["(" + str(x.msg) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.recv_data]) + tile_out_channel_recv_str = "|".join([str(x.recv.msg) for x in s.tile_out_channel]) + tile_out_channel_send_str = "|".join([str(x.send.msg) for x in s.tile_out_channel]) + fu_in_channel_recv_str = "|".join([str(x.recv.msg) for x in s.fu_in_channel]) + fu_in_channel_send_str = "|".join([str(x.send.msg) for x in s.fu_in_channel]) + out_str = "|".join(["(" + str(x.msg.payload) + ", predicate: " + str(x.msg.predicate) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.send_data]) + ctrl_mem = s.ctrl_mem.line_trace() + return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} || s.element_done: {s.element_done}, s.fu_crossbar_done: {s.fu_crossbar_done}, s.routing_crossbar_done: {s.routing_crossbar_done} || ctrl_mem: {ctrl_mem} ## " diff --git a/tile/TileSeparateCrossbarRTL.py b/tile/TileSeparateCrossbarRTL.py deleted file mode 100644 index 73ce300..0000000 --- a/tile/TileSeparateCrossbarRTL.py +++ /dev/null @@ -1,229 +0,0 @@ -""" -========================================================================= -TileSeparateCrossbarRTL.py -========================================================================= -The tile contains a list of functional units, a configuration memory, a -set of registers (e.g., channels), and two crossbars. One crossbar is for -routing the data to registers (i.e., the channels before FU and the -channels after the crossbar), and the other one is for passing the to the -next crossbar. - -Detailed in: https://github.com/tancheng/VectorCGRA/issues/13 (Option 2). - -Author : Cheng Tan - Date : Nov 26, 2024 -""" - -from pymtl3 import * -from ..fu.flexible.FlexibleFuRTL import FlexibleFuRTL -from ..fu.single.AdderRTL import AdderRTL -from ..fu.single.BranchRTL import BranchRTL -from ..fu.single.PhiRTL import PhiRTL -from ..fu.single.CompRTL import CompRTL -from ..fu.single.MemUnitRTL import MemUnitRTL -from ..fu.single.MulRTL import MulRTL -from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL as RecvIfcRTL -from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL -from ..mem.const.ConstQueueRTL import ConstQueueRTL -from ..mem.ctrl.CtrlMemDynamicRTL import CtrlMemDynamicRTL -from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL -from ..noc.ChannelNormalRTL import ChannelNormalRTL -from ..noc.LinkOrRTL import LinkOrRTL -from ..rf.RegisterRTL import RegisterRTL - -class TileSeparateCrossbarRTL(Component): - - def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, - ctrl_mem_size, data_mem_size, num_ctrl, total_steps, - num_fu_inports, num_fu_outports, num_tile_inports, - num_tile_outports, Fu = FlexibleFuRTL, - FuList = [PhiRTL, AdderRTL, CompRTL, MulRTL, BranchRTL, - MemUnitRTL], const_list = None, id = 0): - - # Constants. - num_routing_xbar_inports = num_tile_inports - num_routing_xbar_outports = num_fu_inports + num_tile_outports - - num_fu_xbar_inports = num_fu_outports - num_fu_xbar_outports = num_fu_inports + num_tile_outports - - CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - DataAddrType = mk_bits(clog2(data_mem_size)) - - # Interfaces. - s.recv_data = [RecvIfcRTL(DataType) - for _ in range (num_tile_inports)] - s.send_data = [SendIfcRTL(DataType) - for _ in range (num_tile_outports)] - - # Ctrl. - s.recv_ctrl_pkt = RecvIfcRTL(CtrlPktType) - - # Data. - s.to_mem_raddr = SendIfcRTL(DataAddrType) - s.from_mem_rdata = RecvIfcRTL(DataType) - s.to_mem_waddr = SendIfcRTL(DataAddrType) - s.to_mem_wdata = SendIfcRTL(DataType) - - # Components. - s.element = FlexibleFuRTL(DataType, PredicateType, CtrlSignalType, - num_fu_inports, num_fu_outports, - data_mem_size, FuList) - s.const_queue = ConstQueueRTL(DataType, const_list \ - if const_list != None else [DataType(0)]) - s.routing_crossbar = CrossbarSeparateRTL(DataType, PredicateType, - CtrlSignalType, - num_routing_xbar_inports, - num_routing_xbar_outports) - s.fu_crossbar = CrossbarSeparateRTL(DataType, PredicateType, - CtrlSignalType, - num_fu_xbar_inports, - num_fu_xbar_outports, id, - "fu") - s.ctrl_mem = CtrlMemDynamicRTL(CtrlPktType, CtrlSignalType, - ctrl_mem_size, - num_fu_inports, num_fu_outports, - num_tile_inports, num_tile_outports, - num_ctrl, total_steps) - # The `tile_out_channel` indicates the outport channels that are - # connected to the next tiles. - s.tile_out_channel = [ChannelNormalRTL(DataType) - for _ in range(num_tile_outports)] - # The `fu_in_channel` indicates the inport channels that are - # connected to the FUs. - s.fu_in_channel = [ChannelNormalRTL(DataType) - for _ in range(num_fu_inports)] - # The `tile_out_or_link` would "or" the outports of the - # `tile_out_channel` and the FUs. - s.tile_out_or_link = [LinkOrRTL(DataType) - for _ in range(num_tile_outports)] - # The `fu_in_or_link` would "or" the inports of the `fu_in_channel' - # and the outports of the fu_crossbar. - s.fu_in_or_link = [LinkOrRTL(DataType) for _ in range(num_fu_inports)] - - # Additional one register for partial predication - s.reg_predicate = RegisterRTL(PredicateType) - - # Signals indicating whether certain modules already done their jobs. - s.element_done = Wire(1) - s.fu_crossbar_done = Wire(1) - s.routing_crossbar_done = Wire(1) - - # Connections. - # Ctrl. - s.ctrl_mem.recv_pkt //= s.recv_ctrl_pkt - - # Constant queue. - s.element.recv_const //= s.const_queue.send_const - - for i in range(len(FuList)): - if FuList[i] == MemUnitRTL: - s.to_mem_raddr //= s.element.to_mem_raddr[i] - s.from_mem_rdata //= s.element.from_mem_rdata[i] - s.to_mem_waddr //= s.element.to_mem_waddr[i] - s.to_mem_wdata //= s.element.to_mem_wdata[i] - else: - s.element.to_mem_raddr[i].rdy //= 0 - s.element.from_mem_rdata[i].val //= 0 - s.element.from_mem_rdata[i].msg //= DataType() - s.element.to_mem_waddr[i].rdy //= 0 - s.element.to_mem_wdata[i].rdy //= 0 - - # Connections on the `routing_crossbar`. - # The data from other tiles should be connected to the - # `routing_crossbar`. - for i in range(num_tile_inports): - s.recv_data[i] //= s.routing_crossbar.recv_data[i] - - # # Connects specific xbar control signals to the corresponding crossbar. - for i in range(num_routing_xbar_outports): - s.routing_crossbar.crossbar_outport[i] //= \ - s.ctrl_mem.send_ctrl.msg.routing_xbar_outport[i] - s.fu_crossbar.crossbar_outport[i] //= \ - s.ctrl_mem.send_ctrl.msg.fu_xbar_outport[i] - - # The data going out to the other tiles should be from - # the `routing_crossbar`. Note that there are also data - # being fed into the FUs via the `routing_crossbar`, which - # are filtered out by `num_tile_outports` below. - for i in range(num_tile_outports): - s.routing_crossbar.send_data[i] //= s.tile_out_channel[i].recv - - # One partial predication register for flow control. - s.routing_crossbar.send_predicate //= s.reg_predicate.recv - s.reg_predicate.send //= s.element.recv_predicate - - # Connects the FU's inport channels with the corresponding FU. - # FIXME: change element to use val/rdy ifcs. - for i in range(num_fu_inports): - s.fu_in_channel[i].send //= s.element.recv_in[i] - # s.fu_in_channel[i].count //= s.element.recv_in_count[i] - - # Connections on the `fu_crossbar`. - # FIXME: change element to use val/rdy ifcs. - for i in range(num_fu_outports): - s.element.send_out[i] //= s.fu_crossbar.recv_data[i] - - # Links "or" the outports of the FUs (via `fu_crossbar`) with the - # outports of the `routing_crossbar` through the corresponding channels. - for i in range(num_tile_outports): - s.fu_crossbar.send_data[i] //= s.tile_out_or_link[i].recv_fu - s.tile_out_channel[i].send //= s.tile_out_or_link[i].recv_xbar - s.tile_out_or_link[i].send //= s.send_data[i] - - # Links "or" the inports of the FUs (from the `routing_crossbar`) - # with the outports of the FUs (via the `fu_crossbar`). - for i in range(num_fu_inports): - s.fu_crossbar.send_data[num_tile_outports + i] //= s.fu_in_or_link[i].recv_fu - s.routing_crossbar.send_data[num_tile_outports + i] //= s.fu_in_or_link[i].recv_xbar - s.fu_in_or_link[i].send //= s.fu_in_channel[i].recv - - # Updates the configuration memory related signals. - @update - def update_opt(): - - s.element.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.routing_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - s.fu_crossbar.recv_opt.msg @= s.ctrl_mem.send_ctrl.msg - - s.element.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.element_done - s.routing_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.routing_crossbar_done - s.fu_crossbar.recv_opt.val @= s.ctrl_mem.send_ctrl.val & ~s.fu_crossbar_done - - # s.ctrl_mem.send_ctrl.rdy @= s.element.recv_opt.rdy & \ - # s.routing_crossbar.recv_opt.rdy & \ - # s.fu_crossbar.recv_opt.rdy - - # FIXME: yo96, rename ctrl.rdy to ctrl.proceed or sth similar. - # Allows either the FU-related go out first or routing-xbar go out first. And only - # allows the ctrl signal proceed till all the sub-modules done their own job (once). - s.ctrl_mem.send_ctrl.rdy @= (s.element.recv_opt.rdy | s.element_done) & \ - (s.routing_crossbar.recv_opt.rdy | s.routing_crossbar_done) & \ - (s.fu_crossbar.recv_opt.rdy | s.fu_crossbar_done) - - # Updates the signals indicating whether certain modules already done their jobs. - @update_ff - def already_done(): - if s.reset | s.ctrl_mem.send_ctrl.rdy: - s.element_done <<= 0 - s.fu_crossbar_done <<= 0 - s.routing_crossbar_done <<= 0 - else: - if s.element.recv_opt.rdy: - s.element_done <<= 1 - elif s.fu_crossbar.recv_opt.rdy: - s.fu_crossbar_done <<= 1 - elif s.routing_crossbar.recv_opt.rdy: - s.routing_crossbar_done <<= 1 - - # Line trace - def line_trace(s): - recv_str = "|".join(["(" + str(x.msg) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.recv_data]) - tile_out_channel_recv_str = "|".join([str(x.recv.msg) for x in s.tile_out_channel]) - tile_out_channel_send_str = "|".join([str(x.send.msg) for x in s.tile_out_channel]) - fu_in_channel_recv_str = "|".join([str(x.recv.msg) for x in s.fu_in_channel]) - fu_in_channel_send_str = "|".join([str(x.send.msg) for x in s.fu_in_channel]) - out_str = "|".join(["(" + str(x.msg.payload) + ", predicate: " + str(x.msg.predicate) + ", val: " + str(x.val) + ", rdy: " + str(x.rdy) + ")" for x in s.send_data]) - ctrl_mem = s.ctrl_mem.line_trace() - return f"tile_inports: {recv_str} => [routing_crossbar: {s.routing_crossbar.recv_opt.msg} || fu_crossbar: {s.fu_crossbar.recv_opt.msg} || element: {s.element.line_trace()} || tile_out_channels: {tile_out_channel_recv_str} => {tile_out_channel_send_str} || fu_in_channels: {fu_in_channel_recv_str} => {fu_in_channel_send_str}] => tile_outports: {out_str} || s.element_done: {s.element_done}, s.fu_crossbar_done: {s.fu_crossbar_done}, s.routing_crossbar_done: {s.routing_crossbar_done} || ctrl_mem: {ctrl_mem} ## " - diff --git a/tile/test/TileSeparateCrossbarRTL_test.py b/tile/test/TileRTL_test.py similarity index 94% rename from tile/test/TileSeparateCrossbarRTL_test.py rename to tile/test/TileRTL_test.py index dfbc525..3da4bc0 100644 --- a/tile/test/TileSeparateCrossbarRTL_test.py +++ b/tile/test/TileRTL_test.py @@ -1,10 +1,10 @@ """ ========================================================================== -TileSeparateCrossbarRTL_test.py +TileRTL_test.py ========================================================================== -Test cases for TileSeparateCrossbarRTL. +Test cases for TileRTL. Command: -pytest TileSeparateCrossbarRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd +pytest TileRTL_test.py -xvs --tb=short --test-verilog --dump-vtb --dump-vcd Author : Cheng Tan Date : Nov 26, 2024 @@ -15,8 +15,7 @@ config_model_with_cmdline_opts) from pymtl3.passes.backends.verilog import (VerilogTranslationPass, VerilogVerilatorImportPass) -from ..TileSeparateCrossbarRTL import TileSeparateCrossbarRTL - +from ..TileRTL import TileRTL from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL @@ -35,7 +34,6 @@ from ...fu.single.NahRTL import NahRTL from ...fu.triple.ThreeMulAdderShifterRTL import ThreeMulAdderShifterRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL - from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL from ...lib.basic.val_rdy.SinkRTL import SinkRTL as ValRdyTestSinkRTL from ...lib.messages import * @@ -110,9 +108,9 @@ def test_tile_alu(cmdline_opts): TileInType = mk_bits(clog2(num_tile_inports + 1)) FuInType = mk_bits(clog2(num_fu_inports + 1)) FuOutType = mk_bits(clog2(num_fu_outports + 1)) - pickRegister0 = [FuInType(0) for x in range(num_fu_inports)] - pickRegister1 = [FuInType(1), FuInType(2), FuInType(0), FuInType(0)] - DUT = TileSeparateCrossbarRTL + pick_register0 = [FuInType(0) for x in range(num_fu_inports)] + pick_register1 = [FuInType(1), FuInType(2), FuInType(0), FuInType(0)] + DUT = TileRTL FunctionUnit = FlexibleFuRTL # FuList = [AdderRTL, MulRTL, MemUnitRTL] FuList = [AdderRTL, @@ -145,28 +143,28 @@ def test_tile_alu(cmdline_opts): num_tile_outports) src_ctrl_pkt = [ # src dst vc_id opq cmd_type addr operation predicate - CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pickRegister0, + CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register0, # routing_xbar_output [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(4), TileInType(3), TileInType(0), TileInType(0)], # fu_xbar_output [FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0)]), - CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 1, OPT_ADD, b1(0), pickRegister1, + CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 1, OPT_ADD, b1(0), pick_register1, # routing_xbar_output [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(4), TileInType(1), TileInType(0), TileInType(0)], # fu_xbar_output [FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(1), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0)]), - CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 2, OPT_SUB, b1(0), pickRegister1, + CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 2, OPT_SUB, b1(0), pick_register1, # routing_xbar_output [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0)], # fu_xbar_output [FuOutType(1), FuOutType(0), FuOutType(0), FuOutType(1), FuOutType(0), FuOutType(0), FuOutType(0), FuOutType(0)]), - CtrlPktType(0, 0, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), pickRegister1, + CtrlPktType(0, 0, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), pick_register1, # routing_xbar_output [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0)], From 9eb65fc713a1238d3f4aca558f63d34ad587179a Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 23:06:46 +0000 Subject: [PATCH 07/10] [cleanup] Rename files and cleanup includes --- .github/workflows/python-package.yml | 6 +-- ...aRingCtrlMemRTL.py => RingMultiCgraRTL.py} | 21 ++++++----- ...emRTL_test.py => RingMultiCgraRTL_test.py} | 37 +++---------------- systolic/CgraSystolicArrayRTL.py | 1 - ...3x3MemRightAndBottomRTL_matmul_2x2_test.py | 5 ++- 5 files changed, 22 insertions(+), 48 deletions(-) rename scale_out/{RingMultiCgraRingCtrlMemRTL.py => RingMultiCgraRTL.py} (86%) rename scale_out/test/{RingMultiCgraRingCtrlMemRTL_test.py => RingMultiCgraRTL_test.py} (84%) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 156da32..71e3046 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -61,12 +61,12 @@ jobs: # Simulation across all tests. pytest .. -v # Tile translation. - pytest ../tile/test/TileSeparateCrossbarRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd + pytest ../tile/test/TileRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd # CGRA template translation. pytest ../cgra/test/CgraTemplateRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd # TODO: Need to check vector/heterogneous modules exist in the generated Verilog. # CGRA simulation/translation (including heterogeneous, kingmesh, vector). - pytest ../cgra/test/CgraCrossbarDataMemRingCtrlMemRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd + pytest ../cgra/test/CgraRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd # 3x3 CGRA performs 2x2 matmul simulation/translation. pytest ../systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py -xvs --test-verilog --dump-vtb --dump-vcd # Ring network simulation. @@ -74,5 +74,5 @@ jobs: # CGRAs are interconnected with ring topology. The CGRA contains # separate crossbars (for tiles and FUs), crossbar-based data memory (for # multi-bank), and controller. - pytest ../scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd + pytest ../scale_out/test/RingMultiCgraRTL_test.py -xvs --test-verilog --dump-vtb --dump-vcd diff --git a/scale_out/RingMultiCgraRingCtrlMemRTL.py b/scale_out/RingMultiCgraRTL.py similarity index 86% rename from scale_out/RingMultiCgraRingCtrlMemRTL.py rename to scale_out/RingMultiCgraRTL.py index 9a16a20..c182768 100644 --- a/scale_out/RingMultiCgraRingCtrlMemRTL.py +++ b/scale_out/RingMultiCgraRTL.py @@ -10,7 +10,7 @@ from pymtl3 import * from pymtl3.stdlib.primitive import RegisterFile -from ..cgra.CgraCrossbarDataMemRingCtrlMemRTL import CgraCrossbarDataMemRingCtrlMemRTL +from ..cgra.CgraRTL import CgraRTL from ..lib.basic.en_rdy.ifcs import SendIfcRTL, RecvIfcRTL from ..lib.basic.val_rdy.ifcs import ValRdyRecvIfcRTL from ..lib.opt_type import * @@ -18,7 +18,7 @@ from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL -class RingMultiCgraRingCtrlMemRTL(Component): +class RingMultiCgraRTL(Component): def construct(s, CGRADataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, cgra_rows, cgra_columns, tile_rows, tile_columns, ctrl_mem_size, @@ -39,14 +39,15 @@ def construct(s, CGRADataType, PredicateType, CtrlPktType, s.recv_from_cpu_ctrl_pkt = ValRdyRecvIfcRTL(CtrlPktType) # Components - s.cgra = [CgraCrossbarDataMemRingCtrlMemRTL( - CGRADataType, PredicateType, CtrlPktType, CtrlSignalType, - NocPktType, CmdType, ControllerIdType, terminal_id, - tile_columns, tile_rows, ctrl_mem_size, data_mem_size_global, - data_mem_size_per_bank, num_banks_per_cgra, num_ctrl, - total_steps, FunctionUnit, FuList, "Mesh", controller2addr_map, - preload_data = None, preload_const = None) - for terminal_id in range(s.num_terminals)] + s.cgra = [CgraRTL(CGRADataType, PredicateType, CtrlPktType, + CtrlSignalType, NocPktType, CmdType, + ControllerIdType, terminal_id, tile_columns, + tile_rows, ctrl_mem_size, data_mem_size_global, + data_mem_size_per_bank, num_banks_per_cgra, + num_ctrl, total_steps, FunctionUnit, FuList, + "Mesh", controller2addr_map, preload_data = None, + preload_const = None) + for terminal_id in range(s.num_terminals)] s.ring = RingNetworkRTL(NocPktType, RingPos, s.num_terminals, 0) # Connections diff --git a/scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py b/scale_out/test/RingMultiCgraRTL_test.py similarity index 84% rename from scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py rename to scale_out/test/RingMultiCgraRTL_test.py index ea2a223..f879aa4 100644 --- a/scale_out/test/RingMultiCgraRingCtrlMemRTL_test.py +++ b/scale_out/test/RingMultiCgraRTL_test.py @@ -1,6 +1,6 @@ """ ========================================================================== -RingMultiCgraRingCtrlMemRTL_test.py +RingMultiCgraRTL_test.py ========================================================================== Test cases for CGRA with controller. @@ -14,7 +14,7 @@ config_model_with_cmdline_opts) from pymtl3.passes.backends.verilog import (VerilogTranslationPass, VerilogVerilatorImportPass) -from ..RingMultiCgraRingCtrlMemRTL import RingMultiCgraRingCtrlMemRTL +from ..RingMultiCgraRTL import RingMultiCgraRTL from ...fu.flexible.FlexibleFuRTL import FlexibleFuRTL from ...fu.single.AdderRTL import AdderRTL from ...fu.single.MemUnitRTL import MemUnitRTL @@ -22,8 +22,7 @@ from ...lib.messages import * from ...lib.opt_type import * from ...lib.cmd_type import * -from ...lib.basic.en_rdy.test_srcs import TestSrcRTL -from ...lib.basic.val_rdy.SourceRTL import SourceRTL as ValRdyTestSrcRTL +from ...lib.basic.val_rdy.SourceRTL import SourceRTL as TestSrcRTL #------------------------------------------------------------------------- # Test harness @@ -39,15 +38,8 @@ def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, s.num_terminals = cgra_rows * cgra_columns s.num_tiles = width * height - # CtrlAddrType = mk_bits(clog2(ctrl_mem_size)) - # s.src_opt = [[TestSrcRTL(CtrlType, src_opt[j]) - # for j in range(s.num_tiles)] - # for i in range(s.num_terminals)] - s.src_ctrl_pkt = ValRdyTestSrcRTL(CtrlPktType, src_ctrl_pkt) - # s.ctrl_waddr = [[TestSrcRTL(CtrlAddrType, ctrl_waddr[j]) - # for j in range(s.num_tiles)] - # for i in range(s.num_terminals)] + s.src_ctrl_pkt = TestSrcRTL(CtrlPktType, src_ctrl_pkt) s.dut = DUT(DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, cgra_rows, cgra_columns, height, width, @@ -56,29 +48,10 @@ def construct(s, DUT, FunctionUnit, FuList, DataType, PredicateType, FunctionUnit, FuList, controller2addr_map) # Connections - # s.dut.data_mem.recv_from_noc.rdy //= 0 - # s.dut.data_mem.send_to_noc.msg //= DataType(0, 0) - # s.dut.data_mem.send_to_noc.en //= 0 - # s.src_val_rdy.send //= s.dut.recv_from_other - # s.dut.send_to_other //= s.sink_val_rdy.recv - - # s.dut.recv_towards_controller.en //= 0 - # s.dut.recv_towards_controller.msg //= DataType(0, 0) - # s.dut.send_from_controller.rdy //= 0 - - # for i in range(num_terminals): - # for j in range(s.num_tiles): - # connect(s.src_opt[i][j].send, s.dut.recv_wopt[i][j]) - # connect(s.ctrl_waddr[i][j].send, s.dut.recv_waddr[i][j]) s.src_ctrl_pkt.send //= s.dut.recv_from_cpu_ctrl_pkt def done(s): return s.src_ctrl_pkt.done() - # for i in range(s.num_terminals): - # for j in range(s.num_tiles): - # if not s.src_opt[i][j].done(): - # return False - # return True def line_trace(s): return s.dut.line_trace() @@ -108,7 +81,7 @@ def test_homo_2x2(cmdline_opts): data_addr_nbits = clog2(data_mem_size_global) DataAddrType = mk_bits(clog2(data_mem_size_global)) num_tiles = width * height - DUT = RingMultiCgraRingCtrlMemRTL + DUT = RingMultiCgraRTL FunctionUnit = FlexibleFuRTL FuList = [MemUnitRTL, AdderRTL] DataType = mk_data(32, 1) diff --git a/systolic/CgraSystolicArrayRTL.py b/systolic/CgraSystolicArrayRTL.py index 83da687..639c35e 100644 --- a/systolic/CgraSystolicArrayRTL.py +++ b/systolic/CgraSystolicArrayRTL.py @@ -17,7 +17,6 @@ from ..lib.basic.val_rdy.ifcs import ValRdySendIfcRTL as SendIfcRTL from ..lib.opt_type import * from ..mem.data.DataMemWithCrossbarRTL import DataMemWithCrossbarRTL -from ..noc.CrossbarSeparateRTL import CrossbarSeparateRTL from ..noc.PyOCN.pymtl3_net.ocnlib.ifcs.positions import mk_ring_pos from ..noc.PyOCN.pymtl3_net.ringnet.RingNetworkRTL import RingNetworkRTL from ..tile.TileRTL import TileRTL diff --git a/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py index 86574b0..264bd9b 100644 --- a/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py +++ b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py @@ -1,8 +1,9 @@ """ ========================================================================== -CgraRightAndBottomRTL_matmul_2x2_test.py +Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py ========================================================================== -Translation for 3x3 CGRA. The provided test is only used for a 2x2 matmul. +Simulation/translation for 3x3 CGRA. The provided test is only used for a +2x2 matmul, but is extendable/scalable to larger test. Author : Cheng Tan Date : Nov 19, 2024 From 8824891fe95a602653defa6dcdc46735a7122220 Mon Sep 17 00:00:00 2001 From: tancheng Date: Fri, 3 Jan 2025 23:19:30 +0000 Subject: [PATCH 08/10] [cleanup] Cleanup comments --- cgra/test/CgraRTL_test.py | 46 +--- ...3x3MemRightAndBottomRTL_matmul_2x2_test.py | 202 ------------------ 2 files changed, 5 insertions(+), 243 deletions(-) diff --git a/cgra/test/CgraRTL_test.py b/cgra/test/CgraRTL_test.py index 9763701..20892c9 100644 --- a/cgra/test/CgraRTL_test.py +++ b/cgra/test/CgraRTL_test.py @@ -163,58 +163,22 @@ def init_param(topology, FuList = [MemUnitRTL, AdderRTL]): # FuOutType(1), FuOutType(1), FuOutType(1), FuOutType(1)]), CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, OPT_INC, b1(0), pick_register, tile_in_code, fu_out_code), - # 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)]), - + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 2, OPT_ADD, b1(0), pick_register, tile_in_code, fu_out_code), - # 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)]), - + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 3, OPT_STR, b1(0), pick_register, tile_in_code, fu_out_code), - # 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)]), - + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 4, OPT_ADD, b1(0), pick_register, tile_in_code, fu_out_code), - # 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)]), - + CtrlPktType(0, i, 0, 0, CMD_CONFIG, 5, OPT_ADD, b1(0), pick_register, tile_in_code, fu_out_code), - # 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)]), - + # This last one is for launching kernel. CtrlPktType(0, i, 0, 0, CMD_LAUNCH, 0, OPT_ADD, b1(0), pick_register, tile_in_code, fu_out_code) - # 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 i in range(num_tiles)] src_ctrl_pkt = [] diff --git a/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py index 264bd9b..6c9e1e3 100644 --- a/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py +++ b/systolic/test/Cgra3x3MemRightAndBottomRTL_matmul_2x2_test.py @@ -170,13 +170,6 @@ def test_CGRA_systolic(cmdline_opts): CmdType = mk_bits(4) ControllerIdType = mk_bits(clog2(num_terminals)) controller_id = 0 - # controller2addr_map = { - # 0: [0, 3 ], - # 1: [4, 7 ], - # 2: [8, 11], - # 3: [12, 15], - # } - controller2addr_map = { 0: [0, 15], 1: [16, 31], @@ -203,29 +196,6 @@ def test_CGRA_systolic(cmdline_opts): data_nbits = 32, predicate_nbits = 1) pick_register = [FuInType(x + 1) for x in range(num_fu_inports)] - # tile_in_code = [TileInType(max(4 - x, 0)) for x in range(num_routing_outports)] - # fu_out_code = [FuOutType(x % 2) for x in range(num_routing_outports)] - - # src_opt_per_tile = [ - # # src dst vc_id opq cmd_type addr operation predicate - # [CtrlPktType(0, i, 0, 0, CMD_CONFIG, 0, OPT_INC, b1(0), - # pick_register, tile_in_code, fu_out_code), - # # [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)]), - # CtrlPktType(0, i, 0, 0, CMD_CONFIG, 1, OPT_INC, b1(0), - # pick_register, tile_in_code, fu_out_code), - # # pick_register, - # # [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)]), - - src_opt_per_tile = [ # On tile 0 ([0, 0]). @@ -241,26 +211,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 2, OPT_LD_CONST, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 3, OPT_LD_CONST, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 0, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 0, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -270,11 +220,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 1 ([0, 1]). # src dst vc_id opq cmd_type addr operation predicate [ - # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 0, OPT_LD_CONST, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0)], @@ -285,21 +230,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 3, OPT_LD_CONST, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 4, OPT_LD_CONST, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(0), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 1, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 1, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -312,31 +242,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 2, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 2, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 2, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(0)], @@ -359,22 +264,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(2), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 3, OPT_MUL_CONST, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - - # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 3, 0, 0, CMD_CONFIG, 5, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 3, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -383,11 +272,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 4 ([1, 1]). [ - # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(3), TileInType(0)], @@ -403,16 +287,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 4, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 4, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -421,16 +295,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 5 ([1, 2]). [ - # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(3), TileInType(0), TileInType(0), TileInType(0)], @@ -446,11 +310,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 5, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 5, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -459,11 +318,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 6 ([2, 0]). [ - # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -479,16 +333,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 6, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 6, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -497,16 +341,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 7 ([2, 1]). [ - # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(3), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, - # [TileInType(0), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(3), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(3), TileInType(0)], @@ -522,16 +356,6 @@ def test_CGRA_systolic(cmdline_opts): TileInType(0), TileInType(0), TileInType(0), TileInType(0)], [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (1), FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 3, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 7, 0, 0, CMD_CONFIG, 4, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 7, 0, 0, CMD_LAUNCH, 0, OPT_NAH, b1(0), pick_register, [TileInType(2), TileInType(0), TileInType(0), TileInType(0), TileInType(2), TileInType(0), TileInType(0), TileInType(0)], @@ -540,21 +364,6 @@ def test_CGRA_systolic(cmdline_opts): # On tile 8 ([2, 2]). [ - # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 1, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), - # CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 2, OPT_NAH, b1(0), pick_register, - # [TileInType(2), TileInType(0), TileInType(0), TileInType(0), - # TileInType(2), TileInType(0), TileInType(0), TileInType(0)], - # [FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0), - # FuOutType (0), FuOutType (0), FuOutType (0), FuOutType (0)]), CtrlPktType(0, 8, 0, 0, CMD_CONFIG, 0, OPT_NAH, b1(0), pick_register, [TileInType(0), TileInType(0), TileInType(0), TileInType(0), TileInType(3), TileInType(0), TileInType(0), TileInType(0)], @@ -635,14 +444,6 @@ def test_CGRA_systolic(cmdline_opts): # When the max iterations are larger than the number of control signals, # enough ctrl_waddr needs to be provided to make execution (i.e., ctrl # read) continue. - # 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, - # CtrlPktType, width, height, ctrl_mem_size, data_mem_size, - # src_opt, ctrl_waddr, preload_mem, preload_const, - # expected_out) - th = TestHarness(DUT, FunctionUnit, FuList, DataType, PredicateType, CtrlPktType, CtrlSignalType, NocPktType, CmdType, ControllerIdType, controller_id, width, height, @@ -655,9 +456,6 @@ def test_CGRA_systolic(cmdline_opts): th.elaborate() th.dut.set_metadata(VerilogTranslationPass.explicit_module_name, f'CgraSystolicArrayRTL') - # th.dut.set_metadata( VerilogVerilatorImportPass.vl_Wno_list, - # ['UNSIGNED', 'UNOPTFLAT', 'WIDTH', 'WIDTHCONCAT', - # 'ALWCOMBORDER'] ) th = config_model_with_cmdline_opts(th, cmdline_opts, duts = ['dut']) enable_verification_pymtl = not (cmdline_opts['test_verilog'] or \ From 845e3c0e07902c286da3cb641c3ad1692027a779 Mon Sep 17 00:00:00 2001 From: tancheng Date: Sat, 4 Jan 2025 01:46:20 +0000 Subject: [PATCH 09/10] [refactor] Re-organize fp verilog folder --- .gitmodules | 2 +- fu/flexible/FlexibleFuRTL.py | 12 ++++++------ fu/{ => fused_alu_fixedp}/dp_fpfma | 0 fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv | 2 +- tile/TileRTL.py | 3 --- 5 files changed, 8 insertions(+), 11 deletions(-) rename fu/{ => fused_alu_fixedp}/dp_fpfma (100%) diff --git a/.gitmodules b/.gitmodules index f717bec..99c0f0f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,7 +2,7 @@ path = fu/pymtl3_hardfloat url = https://github.com/pymtl/pymtl3-hardfloat.git [submodule "fu/dp_fpfma"] - path = fu/dp_fpfma + path = fu/fused_alu_fixedp/dp_fpfma url = https://github.com/tancheng/dp_fpfma [submodule "noc/PyOCN"] path = noc/PyOCN diff --git a/fu/flexible/FlexibleFuRTL.py b/fu/flexible/FlexibleFuRTL.py index 457a825..4b5d49e 100644 --- a/fu/flexible/FlexibleFuRTL.py +++ b/fu/flexible/FlexibleFuRTL.py @@ -28,8 +28,8 @@ def construct(s, DataType, PredicateType, CtrlType, if NahRTL not in FuList: FuList.append(NahRTL) s.fu_list_size = len(FuList) - CountType = mk_bits(clog2( num_entries + 1)) - AddrType = mk_bits(clog2( data_mem_size)) + CountType = mk_bits(clog2(num_entries + 1)) + AddrType = mk_bits(clog2(data_mem_size)) # Interface s.recv_in = [RecvIfcRTL(DataType) for _ in range(num_inports)] @@ -87,7 +87,7 @@ def comb_logic(): # send_out connection for j in range(num_outports): - # FIXME: need reduce_or here: https://github.com/tancheng/VectorCGRA/issues/51 + # FIXME: need reduce_or here: https://github.com/tancheng/VectorCGRA/issues/51. if s.fu[i].send_out[j].val: s.send_out[j].msg @= s.fu[i].send_out[j].msg s.send_out[j].val @= s.fu[i].send_out[j].val @@ -95,9 +95,9 @@ def comb_logic(): s.recv_const.rdy @= reduce_or(s.fu_recv_const_rdy_vector) s.recv_predicate.rdy @= reduce_or(s.fu_recv_predicate_rdy_vector) - # FIXME: Operation might be performed more than once due to the set of - # recv_opt.rdy is done separately: https://github.com/tancheng/VectorCGRA/issues/10 & - # https://github.com/tancheng/VectorCGRA/issues/53. + # Operation (especially mem access) won't perform more than once, because once the + # operation is performance (i.e., the recv_opt.rdy would be set), the `element_done` + # register would be set and be respected. s.recv_opt.rdy @= reduce_or(s.fu_recv_opt_rdy_vector) for j in range(num_inports): diff --git a/fu/dp_fpfma b/fu/fused_alu_fixedp/dp_fpfma similarity index 100% rename from fu/dp_fpfma rename to fu/fused_alu_fixedp/dp_fpfma diff --git a/fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv b/fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv index 477b6ee..bc70f36 100644 --- a/fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv +++ b/fu/fused_alu_fixedp/svsrc/ALUgenMAC.sv @@ -51,7 +51,7 @@ //`ifdef VCS /* verilator lint_off COMBDLY */ -`include "../../dp_fpfma/DW02_multp.v" +`include "../dp_fpfma/DW02_multp.v" /* verilator lint_on COMBDLY */ //`endif diff --git a/tile/TileRTL.py b/tile/TileRTL.py index 57f018f..232e9cd 100644 --- a/tile/TileRTL.py +++ b/tile/TileRTL.py @@ -154,13 +154,10 @@ def construct(s, DataType, PredicateType, CtrlPktType, CtrlSignalType, s.reg_predicate.send //= s.element.recv_predicate # Connects the FU's inport channels with the corresponding FU. - # FIXME: change element to use val/rdy ifcs. for i in range(num_fu_inports): s.fu_in_channel[i].send //= s.element.recv_in[i] - # s.fu_in_channel[i].count //= s.element.recv_in_count[i] # Connections on the `fu_crossbar`. - # FIXME: change element to use val/rdy ifcs. for i in range(num_fu_outports): s.element.send_out[i] //= s.fu_crossbar.recv_data[i] From b92cbf3904aa95fa6527e320ef1e9dc49eb2a77b Mon Sep 17 00:00:00 2001 From: yuqisun Date: Sat, 4 Jan 2025 23:56:11 +0800 Subject: [PATCH 10/10] fix typos --- controller/ControllerRTL.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controller/ControllerRTL.py b/controller/ControllerRTL.py index 153c47c..11a07a3 100644 --- a/controller/ControllerRTL.py +++ b/controller/ControllerRTL.py @@ -89,7 +89,7 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, for src_controller_id, address_range in controller2addr_map.items(): begin_addr, end_addr = address_range[0], address_range[1] address_length = end_addr - begin_addr + 1 - assert (address_length & (address_length - 1)) == 0, f"{adderss_length} is not a power of 2." + assert (address_length & (address_length - 1)) == 0, f"{address_length} is not a power of 2." addr_offset_nbits = clog2(address_length) addr_base = begin_addr >> addr_offset_nbits assert addr2controller_vector[addr_base] == -1, f"address range [{begin_addr}, {end_addr}] overlaps with others." @@ -103,7 +103,7 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, s.recv_from_tile_load_response_pkt_queue.recv //= s.recv_from_tile_load_response_pkt s.recv_from_tile_store_request_pkt_queue.recv //= s.recv_from_tile_store_request_pkt - # Reqeusts towards local from others, 1 cycle delay to improve timing. + # Requests towards local from others, 1 cycle delay to improve timing. s.send_to_tile_load_request_addr_queue.send //= s.send_to_tile_load_request_addr s.send_to_tile_load_response_data_queue.send //= s.send_to_tile_load_response_data s.send_to_tile_store_request_addr_queue.send //= s.send_to_tile_store_request_addr @@ -112,7 +112,7 @@ def construct(s, ControllerIdType, CmdType, CtrlPktType, NocPktType, # For control signals delivery from CPU to tiles. # TODO: https://github.com/tancheng/VectorCGRA/issues/11 -- The request needs # to go through the crossbar for arbitration as well. The packet targeting local - # tiles can be delivered via thr ring within the CGRA; The packet targetting + # tiles can be delivered via the ring within the CGRA; The packet targeting # other CGRAs can be delivered via the NoC across CGRAs. Note that the packet # format can be in a universal fashion to support both data and config. Later # on, the format can be packet-based or flit-based.