diff --git a/src/testcrush/grammars/transformers.py b/src/testcrush/grammars/transformers.py index 45c0c20..83f48dd 100755 --- a/src/testcrush/grammars/transformers.py +++ b/src/testcrush/grammars/transformers.py @@ -22,7 +22,11 @@ class FaultListTransformer(lark.Transformer): - Fault_Sites (list[str]): A list of fault sites represented as strings - Fault_Attributes (dict[str, str]): A dictionary with all fault attributes (if present) """ + _prev_fstatus: str = "" + _prev_prime: Fault = None + _is_prime: bool = False + @staticmethod def filter_out_discards(container: Iterable) -> filter: @@ -73,14 +77,30 @@ def fault(self, fault_parts: list[tuple[str, Any]]) -> Fault: Returns: Fault: A Fault object whose attributes are: - Fault_Status: str - - Fault Type: str - - Fault Sites: list[str] - - Fault Attributes: dict[str, str] + - Fault_Type: str + - Fault_Sites: list[str] + - Fault_Attributes: dict[str, str] """ fault_parts = list(self.filter_out_discards(fault_parts)) + # Resolve fault equivalences. + if not self._is_prime: + + self._prev_prime.equivalent_faults += 1 + fault = Fault(**dict(fault_parts)) + fault.set("equivalent_to", self._prev_prime) + + else: + + fault = Fault(**dict(fault_parts)) + + # Reset the flag + self._is_prime = False + # Update the previous prime pointer + self._prev_prime = fault + log.debug(repr(Fault(**dict(fault_parts)))) - return Fault(**dict(fault_parts)) + return fault def fault_info(self, args) -> lark.visitors._DiscardType: """ @@ -124,6 +144,7 @@ def fault_status(self, fault_status: str) -> tuple[Literal["Fault Status"], str] if fault_status == "--": fault_status = self._prev_fstatus else: + self._is_prime = True self._prev_fstatus = fault_status log.debug(f"Returning Fault Status: {fault_status}") @@ -292,3 +313,40 @@ def reg_and_mem(self, *reg_val_pairs: str) -> str: """ reg_and_mem = f"\"{', '.join([ str(pair).strip() for pair in reg_val_pairs])}\"" return reg_and_mem + +if __name__ == "__main__": + + # Get the original STL statistics + parser = lark.Lark(grammar=open("fault_list.lark").read(), + start="start", + parser="lalr", + transformer=FaultListTransformer()) + fault_list = parser.parse(open("../../../sandbox/logfiles/test_primes.rpt").read()) + for fault in fault_list: + print(repr(fault), f"{'prime' if fault.is_prime() else 'equivalent'}") + exit(0) + pc_vals = [] + time_stamps = [] + + for fault in fault_list: + + if hasattr(fault, "Fault_Attributes"): + + pc_vals.append(fault.Fault_Attributes["PC_ID"]) + time_stamps.append(fault.Fault_Attributes["sim_time"]) + + from collections import Counter + + ccs = Counter(pc_vals) + ccs_times = Counter(time_stamps) + + parser = lark.Lark(grammar=open("trace_cv32e40p.lark").read(), + start="start", + parser="lalr", + transformer=TraceTransformerCV32E40P()) + # trace_core_00000000.log + + tracetext = parser.parse(open("../../../sandbox/logfiles/trace_core_00000000.log").read()) + + print(ccs) + print(ccs_times) diff --git a/src/unit_tests/test_transformers.py b/src/unit_tests/test_transformers.py index 363aef5..61a281c 100644 --- a/src/unit_tests/test_transformers.py +++ b/src/unit_tests/test_transformers.py @@ -20,7 +20,7 @@ class FaultListTransformerTest(unittest.TestCase): grammar = open("../testcrush/grammars/fault_list.lark").read() - + maxDiff = None def get_parser(self): return lark.Lark(grammar=self.grammar, start="start", parser="lalr", transformer=transformers.FaultListTransformer()) @@ -29,6 +29,7 @@ def test_stuck_at_fault_list(self): parser = self.get_parser() + fault_list_sample = r""" FaultList SAF { < 1> ON 0 {PORT "tb.dut.subunit_a.subunit_b.cellA.ZN"}(* "test1"->PC=30551073; "test1"->time="45ns"; *) @@ -46,6 +47,12 @@ def test_stuck_at_fault_list(self): fault_list = parser.parse(fault_list_sample) + # Manually resolve the fault equivalences + expected_faults[0].equivalent_faults = 4 + expected_faults[1].equivalent_to = expected_faults[0] + expected_faults[2].equivalent_to = expected_faults[0] + expected_faults[3].equivalent_to = expected_faults[0] + self.assertEqual(fault_list, expected_faults) def test_transition_delay_fault_list(self): @@ -77,6 +84,16 @@ def test_transition_delay_fault_list(self): zoix.Fault(Fault_Status='ON', Fault_Type='F', Fault_Sites=['tb.dut.subunit_c.U27.A']) ] + # Manually resolve the fault equivalences + expected_faults[1].equivalent_faults = 2 + expected_faults[2].equivalent_to = expected_faults[1] + expected_faults[3].equivalent_faults = 2 + expected_faults[4].equivalent_to = expected_faults[3] + expected_faults[5].equivalent_faults = 2 + expected_faults[6].equivalent_to = expected_faults[5] + expected_faults[7].equivalent_faults = 2 + expected_faults[8].equivalent_to = expected_faults[7] + fault_list = parser.parse(fault_list_sample) self.assertEqual(fault_list, expected_faults) @@ -116,6 +133,17 @@ def test_small_delay_defects_fault_list(self): ] + # Manually resolve the fault equivalences + expected_faults[1].equivalent_faults = 2 + expected_faults[2].equivalent_to = expected_faults[1] + expected_faults[3].equivalent_faults = 2 + expected_faults[4].equivalent_to = expected_faults[3] + expected_faults[5].equivalent_faults = 2 + expected_faults[6].equivalent_to = expected_faults[5] + expected_faults[7].equivalent_faults = 3 + expected_faults[8].equivalent_to = expected_faults[7] + expected_faults[9].equivalent_to = expected_faults[7] + self.assertEqual(fault_list, expected_faults) class TraceTransformerCV32E40PTest(unittest.TestCase):