From c3fe68d73d0c99d3a6b88980054c9f075d5d625b Mon Sep 17 00:00:00 2001 From: Carlos Azevedo Date: Wed, 6 Nov 2024 03:01:48 +0000 Subject: [PATCH] Create trigger blocks only for defined triggers. Adds YAML option 'trigger_pruned' support for the logic analyser to prevent the creation of trigger blocks for probes not listed as triggers. This pruning allows much higher fmax for the designs. --- src/manta/logic_analyzer/__init__.py | 20 ++++++++++++++++---- src/manta/logic_analyzer/fsm.py | 7 ++++++- src/manta/logic_analyzer/trigger_block.py | 19 ++++++++++++++----- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/manta/logic_analyzer/__init__.py b/src/manta/logic_analyzer/__init__.py index c337583..9b39d9e 100644 --- a/src/manta/logic_analyzer/__init__.py +++ b/src/manta/logic_analyzer/__init__.py @@ -1,7 +1,7 @@ from amaranth import * from manta.logic_analyzer.capture import LogicAnalyzerCapture -from manta.logic_analyzer.fsm import LogicAnalyzerFSM, TriggerModes +from manta.logic_analyzer.fsm import LogicAnalyzerFSM, TriggerModes, TriggerPrune from manta.logic_analyzer.trigger_block import LogicAnalyzerTriggerBlock from manta.memory_core import MemoryCore from manta.utils import * @@ -39,6 +39,7 @@ class LogicAnalyzerCore(MantaCore): self._trigger_location = sample_depth // 2 self._trigger_mode = TriggerModes.IMMEDIATE self._triggers = [] + self._trigger_pruned = TriggerPrune.FALSE # Bus Input/Output self.bus_i = Signal(InternalBus()) @@ -58,6 +59,7 @@ class LogicAnalyzerCore(MantaCore): "type": "logic_analyzer", "sample_depth": self._sample_depth, "probes": {p.name: len(p) for p in self._probes}, + "trigger_pruned": self._trigger_pruned, } if self._trigger_mode == TriggerModes.INCREMENTAL: @@ -81,6 +83,7 @@ class LogicAnalyzerCore(MantaCore): "triggers", "trigger_location", "trigger_mode", + "trigger_pruned", ] for option in config: if option not in valid_options: @@ -116,12 +119,13 @@ class LogicAnalyzerCore(MantaCore): core = cls(sample_depth, probes) # If any trigger-related configuration was provided, set the triggers with it - keys = ["trigger_mode", "triggers", "trigger_location"] + keys = ["trigger_mode", "triggers", "trigger_location", "trigger_pruned"] if any([key in config for key in keys]): core.set_triggers( trigger_mode=config.get("trigger_mode"), triggers=triggers, trigger_location=config.get("trigger_location"), + trigger_pruned=config.get("trigger_pruned"), ) return core @@ -137,6 +141,7 @@ class LogicAnalyzerCore(MantaCore): probes=self._probes, base_addr=self._fsm.max_addr + 1, interface=self.interface, + trig_names=[n[0] for n in self._triggers] if self._trigger_pruned else None, ) self._sample_mem = MemoryCore( @@ -215,7 +220,7 @@ class LogicAnalyzerCore(MantaCore): else: raise ValueError(f"Unable to interpret trigger condition '{trigger}'.") - def set_triggers(self, trigger_mode=None, triggers=None, trigger_location=None): + def set_triggers(self, trigger_mode=None, triggers=None, trigger_location=None, trigger_pruned=None): """ Args: trigger_mode (TriggerMode | str): @@ -223,6 +228,8 @@ class LogicAnalyzerCore(MantaCore): triggers (Optional[Sequence[Sequence[str | int]]]): trigger_location (Optional[int]): + + trigger_pruned (Optional[TriggerPrune]): """ # Obtain trigger mode if isinstance(trigger_mode, TriggerModes): @@ -234,6 +241,11 @@ class LogicAnalyzerCore(MantaCore): else: raise ValueError(f"Unrecognized trigger mode {trigger_mode} provided.") + # Obtain trigger pruning + if not isinstance(trigger_pruned, bool) and (trigger_pruned != None): + raise ValueError(f"Unrecognized trigger pruning {trigger_pruned} provided.") + self._trigger_pruned = trigger_pruned or TriggerPrune.FALSE + # Peform checks based on trigger mode if mode == TriggerModes.IMMEDIATE: # Warn on triggers @@ -275,7 +287,7 @@ class LogicAnalyzerCore(MantaCore): # Validate triggers self._validate_triggers(triggers) - self.trigger_mode = mode + self._trigger_mode = mode self._triggers = triggers self._trigger_location = trigger_location or self._sample_depth // 2 diff --git a/src/manta/logic_analyzer/fsm.py b/src/manta/logic_analyzer/fsm.py index 9f1dcd7..cb9b68a 100644 --- a/src/manta/logic_analyzer/fsm.py +++ b/src/manta/logic_analyzer/fsm.py @@ -1,5 +1,5 @@ from amaranth import * -from amaranth.lib.enum import IntEnum +from amaranth.lib.enum import IntEnum, Flag from manta.io_core import IOCore @@ -18,6 +18,11 @@ class TriggerModes(IntEnum): IMMEDIATE = 2 +class TriggerPrune(Flag): + TRUE = True + FALSE = False + + class LogicAnalyzerFSM(Elaboratable): """ A module containing the state machine for a LogicAnalyzerCore. Primarily diff --git a/src/manta/logic_analyzer/trigger_block.py b/src/manta/logic_analyzer/trigger_block.py index 52c6287..9913be8 100644 --- a/src/manta/logic_analyzer/trigger_block.py +++ b/src/manta/logic_analyzer/trigger_block.py @@ -12,10 +12,14 @@ class LogicAnalyzerTriggerBlock(Elaboratable): the triggers to be reprogrammed without reflashing the FPGA. """ - def __init__(self, probes, base_addr, interface): + def __init__(self, probes, base_addr, interface, trig_names): # Instantiate a bunch of trigger blocks + self._trig_names = trig_names self._probes = probes - self._triggers = [LogicAnalyzerTrigger(p) for p in self._probes] + if trig_names is None: + self._triggers = [LogicAnalyzerTrigger(p) for p in self._probes] + else: + self._triggers = [LogicAnalyzerTrigger(p) for p in self._probes if p.name in trig_names] # Make IO core for everything ops = [t.op for t in self._triggers] @@ -37,9 +41,14 @@ class LogicAnalyzerTriggerBlock(Elaboratable): def set_triggers(self, triggers): # Reset all triggers to disabled with no argument - for p in self._probes: - self.registers.set_probe(p.name + "_op", Operations.DISABLE) - self.registers.set_probe(p.name + "_arg", 0) + if self._trig_names is None: + for p in self._probes: + self.registers.set_probe(p.name + "_op", Operations.DISABLE) + self.registers.set_probe(p.name + "_arg", 0) + else: + for n in self._trig_names: + self.registers.set_probe(n + "_op", Operations.DISABLE) + self.registers.set_probe(n + "_arg", 0) # Set triggers for trigger in triggers: