def test_sram_basic(data_width, mem_depth, fetch_width): # Set up model... # sram_py = sram_stub(depth, data_width, width_mult, family.PyFamily()) # model_sram = sram_py(family=family.PyFamily())() sram_magma = sram_stub(mem_depth, data_width, fetch_width, family=family.MagmaFamily()) sram_magma_defn = sram_magma(family=family.MagmaFamily()) tester = fault.Tester(sram_magma_defn, sram_magma_defn.CLK) data = 0 for i in range(100): tester.circuit.wen = i % 2 tester.circuit.cen = 1 tester.circuit.data_in = data tester.circuit.addr = data data = data + 1 tester.eval() tester.step(2) with tempfile.TemporaryDirectory() as tempdir: tester.compile_and_run(target="verilator", directory=tempdir, flags=["-Wno-fatal"])
def test_assemble(): @family_closure def PE_fc(family): Bit = family.Bit @family.assemble(locals(), globals()) class PESimple(Peak, typecheck=True): def __call__(self, in0: Bit, in1: Bit) -> Bit: return in0 & in1 return PESimple #verify BV works PE_bv = PE_fc(family.PyFamily()) vals = [Bit(0), Bit(1)] for i0, i1 in itertools.product(vals, vals): assert PE_bv()(i0, i1) == i0 & i1 #verify SMT works PE_smt = PE_fc(family.SMTFamily()) vals = [SMTBit(0), SMTBit(1), SMTBit(), SMTBit()] for i0, i1 in itertools.product(vals, vals): assert PE_smt()(i0, i1) == i0 & i1 #verify magma works PE_magma = PE_fc(family.MagmaFamily()) tester = fault.Tester(PE_magma) vals = [0, 1] for i0, i1 in itertools.product(vals, vals): tester.circuit.in0 = i0 tester.circuit.in1 = i1 tester.eval() tester.circuit.O.expect(i0 & i1) tester.compile_and_run("verilator", flags=["-Wno-fatal"])
def test_composition(): PE_magma = PE_fc(family.MagmaFamily()) PE_py = PE_fc(family.PyFamily())() tester = fault.Tester(PE_magma) Op = Inst.op0 assert Op is Inst.op1 asm = Assembler(Inst) for op0, op1, choice, in0, in1 in itertools.product( Inst.op0.enumerate(), Inst.op1.enumerate(), (Bit(0), Bit(1)), range(4), range(4), ): in0 = BitVector[16](in0) in1 = BitVector[16](in1) inst = Inst(op0=op0, op1=op1, choice=choice) gold = PE_py(inst=inst, data0=in0, data1=in1) tester.circuit.inst = asm.assemble(inst) tester.circuit.data0 = in0 tester.circuit.data1 = in1 tester.eval() tester.circuit.O.expect(gold) tester.compile_and_run("verilator", flags=["-Wno-fatal"])
def gen_verilog(): arch = read_arch("outputs/PE.json") graph_arch(arch) PE_fc = pe_arch_closure(arch) PE = PE_fc(family.MagmaFamily()) if not os.path.exists('outputs/verilog'): os.makedirs('outputs/verilog') m.compile(f"outputs/verilog/PE", PE, output="coreir-verilog")
def test_enum(): class Op(Enum): And = 1 Or = 2 @family_closure def PE_fc(family): Bit = family.Bit @family.assemble(locals(), globals()) class PE_Enum(Peak): def __call__(self, op: Const(Op), in0: Bit, in1: Bit) -> Bit: if op == Op.And: return in0 & in1 else: #op == Op.Or return in0 | in1 return PE_Enum # verify BV works PE_bv = PE_fc(family.PyFamily()) vals = [Bit(0), Bit(1)] for op in Op.enumerate(): for i0, i1 in itertools.product(vals, vals): res = PE_bv()(op, i0, i1) gold = (i0 & i1) if (op is Op.And) else (i0 | i1) assert res == gold # verify BV works PE_smt = PE_fc(family.SMTFamily()) Op_aadt = AssembledADT[Op, Assembler, SMTBitVector] vals = [SMTBit(0), SMTBit(1), SMTBit(), SMTBit()] for op in Op.enumerate(): op = Op_aadt(op) for i0, i1 in itertools.product(vals, vals): res = PE_smt()(op, i0, i1) gold = (i0 & i1) if (op is Op.And) else (i0 | i1) assert res == gold # verify magma works asm = Assembler(Op) PE_magma = PE_fc(family.MagmaFamily()) tester = fault.Tester(PE_magma) vals = [0, 1] for op in (Op.And, Op.Or): for i0, i1 in itertools.product(vals, vals): gold = (i0 & i1) if (op is Op.And) else (i0 | i1) tester.circuit.op = int(asm.assemble(op)) tester.circuit.in0 = i0 tester.circuit.in1 = i1 tester.eval() tester.circuit.O.expect(gold) tester.compile_and_run("verilator", flags=["-Wno-fatal"])
def test_wrap_with_disassembler(): class HashableDict(dict): def __hash__(self): return hash(tuple(sorted(self.keys()))) PE_magma = PE_fc(family.MagmaFamily()) instr_type = PE_fc(family.PyFamily()).input_t.field_dict['inst'] asm = Assembler(instr_type) instr_magma_type = type(PE_magma.interface.ports['inst']) PE_wrapped = wrap_with_disassembler(PE_magma, asm.disassemble, asm.width, HashableDict(asm.layout), instr_magma_type)
return SRAMStub return modules_fc if __name__ == "__main__": mem_depth = 4 data_width = 16 fetch_width = 4 addr_width = int(log2(mem_depth)) py_fam = family.PyFamily() sram_py = sram_stub(mem_depth, data_width, fetch_width, py_fam) sram_py_inst = sram_py(family=py_fam)() sram_magma = sram_stub(mem_depth, data_width, fetch_width, family=family.MagmaFamily()) sram_magma_defn = sram_magma(family=family.MagmaFamily()) tester = fault.Tester(sram_magma_defn, sram_magma_defn.CLK) model_sram = SRAMModel(data_width, fetch_width, mem_depth, 1) rand.seed(0) x = 0 for i in range(16): wen = 1 - (i % 2) # rand.randint(0, 1) cen = 1 # rand.randint(0, 1) addr = x # rand.randint(0, mem_depth - 1) data = x + 1 # rand.randint(0, 2**(data_width * fetch_width) - 1) print(f'wen: {wen}, cen: {cen}, addr: {addr}, data: {data}')
def check_families(PE_fc): PE_bv = PE_fc(f.PyFamily()) PE_smt = PE_fc(f.SMTFamily()) PE_magma = PE_fc(f.MagmaFamily())