def test_aoi_const_mux_wrapper(height, width): """ Test that the mux wrapper circuit works as expected. Specifically, we initialize a mux with random height and width, and check that the output is as expected for select in range [0, height). Note that we do not check the behavior with sel > height, because this is undefined behavior. """ mux = AOIMuxWrapper(height, width, AOIMuxType.Const) assert mux.width == width assert mux.name() == \ f"MuxWrapperAOI_{height}_{width}_{AOIMuxType.Const.name}" mux_circuit = mux.circuit() tester = fault.Tester(mux_circuit) inputs = [fault.random.random_bv(width) for _ in range(height + 1)] for i, input_ in enumerate(inputs[:height]): tester.poke(mux_circuit.I[i], input_) for i in range(height + 1): tester.poke(mux_circuit.S, BitVector[mux.sel_bits](i)) tester.eval() if i < height: tester.expect(mux_circuit.O, inputs[i]) else: tester.expect(mux_circuit.O, 0) with tempfile.TemporaryDirectory() as tempdir: for aoi_mux in glob.glob("tests/common/rtl/*.sv"): shutil.copy(aoi_mux, tempdir) tester.compile_and_run(directory=tempdir, magma_output="coreir-verilog", flags=["-Wno-fatal"])
def add_power_domain(interconnect: Interconnect): # add features first for (x, y) in interconnect.tile_circuits: tile = interconnect.tile_circuits[(x, y)] tile_core = tile.core if isinstance(tile_core, IOCore) or tile_core is None: continue # Add PS config register pd_feature = PowerDomainConfigReg(tile.config_addr_width, tile.config_data_width) tile.add_feature(pd_feature) # replace all the interconnect mux with aoi mux. cb mux to aoi const # mux # note that because we have an index to all mux created, it is fairly # straight-forward for (x, y) in interconnect.tile_circuits: tile = interconnect.tile_circuits[(x, y)] for bit_width, sb in tile.sbs.items(): sb_muxs = sb.sb_muxs for _, (node, old_mux) in sb_muxs.items(): assert node.width == bit_width new_mux = AOIMuxWrapper(old_mux.height, bit_width, AOIMuxType.Regular, old_mux.instance_name) # replace it! replace(sb, old_mux, new_mux) reg_mux = sb.reg_muxs for _, (node, old_mux) in reg_mux.items(): assert node.width == bit_width new_mux = AOIMuxWrapper(old_mux.height, bit_width, AOIMuxType.Regular, old_mux.instance_name) # replace it! replace(sb, old_mux, new_mux) # cb is const aoi for _, cb in tile.cbs.items(): old_mux = cb.mux new_mux = AOIMuxWrapper(old_mux.height, cb.node.width, AOIMuxType.Const, cb.instance_name) # replace it! replace(cb, old_mux, new_mux)
def add_power_domain(interconnect: Interconnect): # add features first for (x, y) in interconnect.tile_circuits: tile = interconnect.tile_circuits[(x, y)] tile_core = tile.core if isinstance(tile_core, IOCore) or tile_core is None: continue # Add PS config register pd_feature = PowerDomainConfigReg(tile.config_addr_width, tile.config_data_width) tile.add_feature(pd_feature) # replace all the interconnect mux with aoi mux. cb mux to aoi const # mux # note that because we have an index to all mux created, it is fairly # straight-forward for (x, y) in interconnect.tile_circuits: tile = interconnect.tile_circuits[(x, y)] for bit_width, sb in tile.sbs.items(): # we need more efficient implementation for a simple replacement # pass. in other words, instead of an O(n^2) implementation, we # hand-crafted an O(n) with smaller constants sb_muxs = sb.sb_muxs mux_table = {} for _, (node, old_mux) in sb_muxs.items(): assert node.width == bit_width new_mux = AOIMuxWrapper(old_mux.height, bit_width, AOIMuxType.Regular, old_mux.instance_name) mux_table[old_mux] = new_mux reg_mux = sb.reg_muxs for _, (node, old_mux) in reg_mux.items(): assert node.width == bit_width new_mux = AOIMuxWrapper(old_mux.height, bit_width, AOIMuxType.Regular, old_mux.instance_name) mux_table[old_mux] = new_mux assert len(mux_table) == len(sb_muxs) + len(reg_mux) wires = set() for conn1, conn2 in sb.wires: if conn1.owner() in mux_table or conn2.owner() in mux_table: wires.add((conn1, conn2)) for conn1, conn2 in wires: # avoid O(n) search to remove the wires. this is safe # since we directly load these connection in sorted order sb.wires.remove((conn1, conn2)) for conn1, conn2 in wires: conn1_owner = conn1.owner() conn2_owner = conn2.owner() if conn1_owner in mux_table: conn1 = conn1.get_port(mux_table[conn1_owner].ports) if conn2_owner in mux_table: conn2 = conn2.get_port(mux_table[conn2_owner].ports) sb.wire(conn1, conn2) # cb is const aoi for _, cb in tile.cbs.items(): old_mux = cb.mux new_mux = AOIMuxWrapper(old_mux.height, cb.node.width, AOIMuxType.Const, cb.instance_name) # replace it! replace(cb, old_mux, new_mux)