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 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"])
class _PeakWrapper(metaclass=_PeakWrapperMeta): def __init__(self, peak_generator): pe = peak_generator(PyFamily()) assert issubclass(pe, peak.Peak) self._model = pe() #Lassen's name for the ISA is 'inst', so this is hardcoded self.__instr_name = 'inst' self.__instr_type = strip_modifiers(pe.input_t.field_dict['inst']) self.__inputs = OrderedDict(pe.input_t.field_dict) del self.__inputs['inst'] self.__outputs = OrderedDict(pe.output_t.field_dict) circuit = peak_generator(MagmaFamily()) self.__asm = Assembler(self.__instr_type) instr_magma_type = type(circuit.interface.ports[self.__instr_name]) self.__circuit = peak.wrap_with_disassembler( circuit, self.__asm.disassemble, self.__asm.width, HashableDict(self.__asm.layout), instr_magma_type) data_gate(self.__circuit) @property def model(self): return self._model def rtl(self): return self.__circuit def inputs(self): return self.__inputs def outputs(self): return self.__outputs def instruction_name(self): return self.__instr_name def instruction_type(self): return self.__instr_type def instruction_width(self): return self.__asm.width def assemble(self, instr): return self.__asm.assemble(instr)