def test_sim(self, prog, cpu, util_tbl): """Test executing a program. `self` is this test case. `prog` is the program to run. `cpu` is the processor to run the program on. `util_tbl` is the expected utilization table. """ assert simulate([HwInstruction(*regs, ICaseString(categ)) for *regs, categ in prog], HwSpec(cpu)) == [ BagValDict(inst_util) for inst_util in util_tbl]
def test_processor(self, prog_file, proc_file, util_info): """Test simulating a program on the given processor. `self` is this test case. `prog_file` is the program file. `proc_file` is the processor description file. `util_info` is the expected utilization information. """ cpu = read_proc_file("processors", proc_file) capabilities = processor_utils.get_abilities(cpu) assert simulate(test_utils.compile_prog( prog_file, test_utils.read_isa_file( "singleInstructionISA.yaml", capabilities)), HwSpec(cpu)) == [ BagValDict(inst_util) for inst_util in util_info]
def test_mem_util_in_earlier_inputs_affects_later_ones(self): """Test propagation of memory utilization among inputs. `self` is this test case. """ full_sys_unit = UnitModel(ICaseString("full system"), 2, ["ALU"], LockInfo(True, True), ["ALU"]) res_util = (BagValDict( {ICaseString("full system"): [InstrState(instr)]}) for instr in [0, 1]) assert simulate( [HwInstruction([], out_reg, "ALU") for out_reg in ["R1", "R2"]], HwSpec(ProcessorDesc([], [], [full_sys_unit], []))) == list(res_util)
def test_hazard(self): """Test detecting RAR hazards. `self` is this test case. """ proc_desc = ProcessorDesc([], [], [ UnitModel(ICaseString(TEST_DIR), 2, ["ALU"], LockInfo(True, True), []) ], []) self.assertEqual( simulate([ HwInstruction(["R1"], out_reg, "ALU") for out_reg in ["R2", "R3"] ], HwSpec(proc_desc)), [BagValDict({ICaseString(TEST_DIR): map(InstrState, [0, 1])})])
def test_instructions_are_loaded_to_lexicographically_inputs_first(self): """Test instructions are fed into sorted input units. `self` is this test case. """ in_unit, out_unit = (UnitModel(ICaseString(name), 1, ["ALU"], LockInfo( rd_lock, wr_lock), mem_acl) for name, rd_lock, wr_lock, mem_acl in [("input 1", True, False, []), ("output 1", False, True, ["ALU"])]) proc_desc = ProcessorDesc( [in_unit], [FuncUnit(out_unit, [in_unit])], [UnitModel(ICaseString( "input 2"), 1, ["ALU"], LockInfo(True, False), [])], []) self.assertEqual(simulate( [HwInstruction([], "R1", "ALU")], HwSpec(proc_desc)), [BagValDict( cp_util) for cp_util in [{ICaseString("input 1"): [InstrState( 0)]}, {ICaseString("output 1"): [InstrState(0)]}]])
def test_unsupported_instruction_stalls_pipeline( self, valid_prog, util_tbl): """Test executing an invalid instruction after a valid program. `self` is this test case. `valid_prog` is a sequence of valid instructions. `util_tbl` is the utilization table. """ prog = starmap(lambda in_regs, out_reg, categ: HwInstruction(in_regs, out_reg, ICaseString(categ)), chain(valid_prog, [([], "R14", "MEM")])) ex_chk = raises(StallError, simulate, tuple(prog), HwSpec( read_proc_file("processors", "singleALUProcessor.yaml"))) test_utils.chk_error( [test_utils.ValInStrCheck(ex_chk.value.processor_state, [ BagValDict(cp_util) for cp_util in util_tbl])], ex_chk.value)
def test_hazard(self, instr_regs): """Test detecting data hazards. `self` is this test case. `instr_regs` are the registers accessed by each instruction. """ full_sys_unit = UnitModel(ICaseString(TEST_DIR), 2, ["ALU"], LockInfo(True, True), []) assert simulate( [HwInstruction(*regs, "ALU") for regs in instr_regs], HwSpec(ProcessorDesc([], [], [full_sys_unit], []))) == [ BagValDict(cp_util) for cp_util in [{ ICaseString(TEST_DIR): itertools.starmap(InstrState, [[0], [1, StallState.DATA]]) }, { ICaseString(TEST_DIR): [InstrState(1)] }] ]
def test_internal_stall_is_detected(self): """Test detecting stalls in internal units. `self` is this test case. """ in_unit, mid, out_unit = ( UnitModel(ICaseString(name), width, ["ALU"], LockInfo(rd_lock, wr_lock), []) for name, width, rd_lock, wr_lock in [("input", 2, True, False), ( "middle", 2, False, False), ("output", 1, False, True)]) proc_desc = ProcessorDesc([in_unit], [FuncUnit(out_unit, [mid])], [], [FuncUnit(mid, [in_unit])]) self.assertEqual(simulate( [HwInstruction([], out_reg, "ALU") for out_reg in ["R1", "R2"]], HwSpec(proc_desc)), [BagValDict(cp_util) for cp_util in [ {ICaseString("input"): map(InstrState, [0, 1])}, {ICaseString("middle"): map(InstrState, [0, 1])}, {ICaseString("middle"): [InstrState(1, StallState.STRUCTURAL)], ICaseString("output"): [InstrState(0)]}, {ICaseString("output"): [InstrState(1)]}]])
def test_only_mem_access_instructions_are_checked(self): """Test always allowing instructions without memory access. `self` is this test case. """ in_unit, out_unit = (UnitModel(ICaseString(name), 2, ["ALU", "MEM"], LockInfo(rd_lock, wr_lock), mem_acl) for name, rd_lock, wr_lock, mem_acl in [( "input", True, False, []), ("output", False, True, ["MEM"])]) proc_desc = ProcessorDesc([in_unit], [FuncUnit(out_unit, [in_unit])], [], []) self.assertEqual( simulate([ HwInstruction([], *instr_params) for instr_params in [["R1", "MEM"], ["R2", "ALU"]] ], HwSpec(proc_desc)), [ BagValDict({ICaseString(unit): map(InstrState, [0, 1])}) for unit in ["input", "output"] ])
def test_earlier_instructions_are_propagated_first(self): """Test earlier instructions are selected first. `self` is this test case. """ in_units = [UnitModel( ICaseString(name), 1, [categ], LockInfo(True, False), []) for name, categ in [("ALU input", "ALU"), ("MEM input", "MEM")]] out_unit = UnitModel(ICaseString("output"), 1, ["ALU", "MEM"], LockInfo(False, True), []) proc_desc = ProcessorDesc( in_units, [FuncUnit(out_unit, in_units)], [], []) self.assertEqual(simulate([HwInstruction( *instr_params) for instr_params in [[[], "R12", "MEM"], [ ["R11", "R15"], "R14", "ALU"]]], HwSpec(proc_desc)), [ BagValDict(inst_util) for inst_util in [{ICaseString("MEM input"): [InstrState(0)], ICaseString("ALU input"): [InstrState(1)]}, {ICaseString("output"): [InstrState(0)], ICaseString( "ALU input"): [InstrState(1, StallState.STRUCTURAL)]}, {ICaseString("output"): [InstrState(1)]}]])
def _run_cycle(program: Sequence[HwInstruction], acc_queues: Mapping[object, RegAccessQueue], hw_info: HwSpec, util_tbl: MutableSequence[BagValDict[ICaseString, InstrState]], issue_rec: _IssueInfo) -> None: """Run a single clock cycle. `program` is the program to run whose instructions. `acc_queues` are the planned access queues for registers. `hw_info` is the processor information. `util_tbl` is the utilization table. `issue_rec` is the issue record. """ old_util = util_tbl[-1] if util_tbl else BagValDict() cp_util = copy.deepcopy(old_util) _fill_cp_util(hw_info.processor_desc, program, cp_util, issue_rec) _chk_hazards(old_util, cp_util.items(), hw_info.name_unit_map, program, acc_queues) _chk_full_stall(old_util, cp_util, util_tbl) issue_rec.pump_outputs( _count_outputs(_get_out_ports(hw_info.processor_desc), cp_util)) util_tbl.append(cp_util)
def test_stalled_outputs_are_not_flushed(self, extra_instr_lst): """Test data hazards at output ports. `self` is this test case. `extra_instr_lst` is the extra instructions to execute after the ones causing the hazard. """ program = starmap(HwInstruction, chain( [[[], "R1", "ALU"], [["R1"], "R2", "ALU"]], extra_instr_lst)) extra_instr_len = len(extra_instr_lst) cores = starmap(lambda name, width: UnitModel( ICaseString(name), width, ["ALU"], LockInfo(True, True), []), [("core 1", 1), ("core 2", 1 + extra_instr_len)]) extra_instr_seq = range(2, 2 + extra_instr_len) assert simulate( tuple(program), HwSpec(ProcessorDesc([], [], cores, []))) == [ BagValDict(cp_util) for cp_util in [{ICaseString("core 1"): [InstrState(0)], ICaseString( "core 2"): starmap(InstrState, more_itertools.prepend( [1, StallState.DATA], ([instr] for instr in extra_instr_seq)))}, {ICaseString("core 2"): [InstrState(1)]}]]
def test_util_tbl_exists_in_StallError(self): """Test dumping the utilizaiton table in stall errors. `self` is this test case. """ long_input, mid, short_input, out_unit = ( UnitModel(ICaseString(name), 1, ["ALU"], LockInfo(rd_lock, wr_lock), []) for name, rd_lock, wr_lock in [("long input", False, False), ("middle", False, False), ("short input", False, False), ("output", True, True)]) proc_desc = ProcessorDesc([long_input, short_input], [FuncUnit( out_unit, [mid, short_input])], [], [FuncUnit(mid, [long_input])]) with self.assertRaises(StallError) as ex_chk: simulate([HwInstruction(*instr_regs, "ALU") for instr_regs in [[[], "R1"], [["R1"], "R2"]]], HwSpec(proc_desc)) self.assertEqual(ex_chk.exception.processor_state, [ BagValDict(cp_util) for cp_util in [{ICaseString("long input"): [InstrState(0)], ICaseString( "short input"): [InstrState(1)]}, {ICaseString("middle"): [InstrState(0)], ICaseString("output"): [InstrState(1, StallState.DATA)]}, {ICaseString("middle"): [InstrState(0, StallState.STRUCTURAL)], ICaseString("output"): [InstrState(1, StallState.DATA)]}]])