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"])
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)
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)
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)
def test_wrapped_PE(): class HashableDict(dict): def __hash__(self): return hash(tuple(sorted(self.keys()))) pe = PE_fc(PyFamily()) #Lassen's name for the ISA is 'inst', so this is hardcoded __instr_name = 'inst' __instr_type = pe.input_t.field_dict['inst'] __inputs = OrderedDict(pe.input_t.field_dict) __inputs['inst'] __outputs = OrderedDict(pe.output_t.field_dict) circuit = PE_fc(MagmaFamily()) __asm = Assembler(__instr_type) instr_magma_type = type(circuit.interface.ports[__instr_name]) __circuit = peak.wrap_with_disassembler(circuit, __asm.disassemble, __asm.width, HashableDict(__asm.layout), instr_magma_type) assert __circuit is not None
and_, nand, or_, nor, mul, shftr, shftl, ) Word, Bit, Inst, sim = gen_sim(SMTBitVector.get_family()) T = Tuple[Word, Bit] S = Sum[Word, T] SMTInst = AssembledADT[Inst, Assembler, SMTBitVector] assembler = Assembler(Inst) opcode_asm = assembler.sub.Opcode.asm operand_1_asm = assembler.sub.operand_1.asm opcode_bv = SMTBitVector[opcode_asm.width](name='opcode') tag_bv = SMTBitVector[operand_1_asm.tag_width](name='tag') #Should be determined automatically binding = SMTBitVector[4](name='binding') x = Word(name='x') y = Word(name='y') b = Bit(name='b') free_bit = Bit(name='free_bit')
def __hash__(self): return hash(tuple(sorted(self.keys()))) Inst = Inst_fc(PyFamily()) Mode_t = Inst.rega PE_bv = PE_fc(PyFamily()) BFloat16 = BFloat16_fc(PyFamily()) Data = BitVector[DATAWIDTH] # create these variables in global space so that we can reuse them easily inst_name = 'inst' inst_type = PE_bv.input_t.field_dict[inst_name] _assembler = Assembler(inst_type) assembler = _assembler.assemble disassembler = _assembler.disassemble width = _assembler.width layout = _assembler.layout #PE_magma = PE_fc(MagmaFamily(), use_assembler=True) PE_magma = PE_fc(MagmaFamily()) instr_magma_type = type(PE_magma.interface.ports[inst_name]) pe_circuit = wrap_with_disassembler(PE_magma, disassembler, width, HashableDict(layout), instr_magma_type) tester = fault.Tester(pe_circuit, clock=pe_circuit.CLK) test_dir = "tests/build" # Explicitly load `float_DW` lib so we get technology specific mapping with # special code for BFloat rounding, for more info: