Skip to content

Logic Analyzer Core

Overview

The Logic Analyzer core allows for debugging logic by capturing a set of digital signals to memory. This is done in response to a trigger condition, which starts a capture, which continues until the onboard memory is full. The resulting data is then read out to the host machine, and can be displayed as a waveform, exported as a CSV file, or turned into a synthesizable playback module.

This is very similar to the behavior of a benchtop logic analyzer, but Manta's Logic Analyzer Core includes some extra features you may find useful. Both the Use Cases page and the repository's examples folder contain examples of the Logic Analyzer Core for your reference.

Configuration

As explained in the getting started page, the Logic Analyzer Core must be configured and included in the FPGA design before it can be operated. Configuration is performed differently depending on if you're using a traditional Verilog-based workflow, or if you're building an Amaranth-native design.

Verilog-Based Workflows

The Logic Analyzer Core is used by adding an entry in a cores section of a configuration file. This is best shown by example:

---
cores:
  my_logic_analyzer:
    type: logic_analyzer
    sample_depth: 4096
    trigger_location: 1000

    probes:
      larry: 1
      curly: 3
      moe: 9

    triggers:
      - moe RISING
      - curly FALLING
Inside this configuration, the following parameters may be set:

  • name(required): The name of the Logic Analyzer core, which is used when working with the API.
  • type(required): This denotes that this is a Logic Analyzer core. All cores contain a type field, which must be set to logic_analyzer to be recognized as an Logic Analyzer core.
  • sample_depth(required): The number of samples saved in the capture. A larger sample depth will use more FPGA resources, but will show what the probes are doing over a longer time interval.
  • probes (required): The signals in your logic that the Logic Analyzer connects to. Each probe is specified with a name and a width.

Name things carefully!

The names of the core and its probes are referenced in the autogenerated Verilog. This means that while the names can be arbitrary, they must be unique within your project and not contain any characters that your synthesis engine won't appreciate.

Triggers

Triggers are the conditions that your logic must meet in order to start a capture, and they're specified under the triggers entry in the config file. Manta's triggers are reprogrammable, meaning you don't need to rebuild your source code to change the trigger condition - just updating the configuration file is enough. If multiple triggers are provided, any one trigger being met will trigger the entire core.

Each individual trigger is specified with the following structure:

[probe] [operation] [argument]

  • probe: The probe that the trigger applies to. Each probe only supports one trigger on it. For instance, in the example above we couldn't add a trigger for curly LEQ 4, since we've already assigned a trigger to curly.

  • operation: The logical operation to perform. Manta supports the following operations:

    • RISING, which checks if the probe has increased in value since the last clock cycle.
    • FALLING, which checks if the probe has decreased in value since the last clock cycle.
    • CHANGING, which checks if the probe is changed in value since the last clock cycle.

    These operations only compare a probe's value with itself, but sometimes it is useful to compare a probe's value to a constant. Manta provides a operations for doing such, including:

    • GT, for greater than.
    • LT, for less than.
    • GEQ, for greater than or equal to.
    • LEQ, for less than or equal to.
    • EQ, for equal to.
    • NEQ, for not equal to.

    These operations require a constant to compare against, referred to as an argument, which is described below:

  • argument: A constant to compare against, if the operation specified requires one. On the FPGA, the argument will have just as many bits as the probe width.

Trigger Location (optional)

Sometimes, you care more about what happens before a trigger is met than afterwards, or vice versa. To accommodate this, the logic analyzer has an optional Trigger Location parameter, which sets when probe data is captured relative to the trigger condition being met. This is specified with the trigger_position entry in the configuration file, which sets how many samples to save prior to the trigger condition occurring. This is similar to a "holdoff" option on a traditional oscilloscope or logic analyzer.

If trigger_position is not specified, Manta will default to centering the capture window around the trigger condition. This results in just as many samples before the trigger as after.

Trigger Modes (optional)

The logic analyzer has a few different ways of capturing data, which are represented by the trigger modes below:

  • Single-Shot: Once the trigger condition is met, record the value of the probes on every clock cycle in a continuous single shot.
  • Incremental: Record samples when the trigger condition is met, but don't record the samples when the trigger condition is not met. This is super useful for applications like audio processing or memory controllers, where there are many system clock cycles between signals of interest.
  • Immediate: Record the value of the probes on every clock cycle, beginning immediately, and regardless of if the trigger condition is met. This is useful for investigating cases where a trigger condition is never being met (such as latchup or deadlock conditions) or obtaining a random snapshot of the FPGA's state.

Manta will use an Immediate trigger mode if no trigger_mode is provided in the configuration file.

Usage

Capturing Data

Once you have your Logic Analyzer core on the FPGA, you can capture data with:

manta capture [config_file] [la_core_name] [output path] [[additional output paths]...]
The capture may be exported as either a VCD or CSV file. If manta.yaml contained the configuration at the top of this page, then the following would export a .vcd file containing the captured waveform:

manta capture manta.yaml my_logic_analyzer capture.vcd

This will reset your logic analyzer, configure it with the triggers specified in manta.yaml, perform a capture, and create the file. Additional output files may be passed as well - Manta will detect the file format based on the extension (.vcd, .csv). Verilog (.v) files are also supported, and will follow the playback mechanism described below.

Playback

Manta has the ability to generate a module that plays back a set of data captured from a Logic Analyzer core. This module has a set of outputs matching the inputs of the Logic Analyzer, which when enabled, will take the exact values captured by the logic analyzer. This module is synthesizable, and can either be used in simulation or included in the FPGA design.

If the file manta.yaml contained the configuration above, then running:

manta capture manta.yaml my_logic_analyzer capture.v

Generates a Verilog module at capture.v which can then be instantiated in the testbench or FPGA design in which it is needed.

This is useful for two situations in particular:

  • Input Verification. Designs will often work in simulation, but fail in hardware. In the absence of any build errors, this usually means that the inputs being applied to the logic in simulation don't accurately represent those being applied to the logic in the real world. Playing signals back in simulation allows for easy comparison between simulated and measured input, and provides a nice way to check that the logic downstream is behaves properly.

  • Sparse Sampling. Sometimes designs will have a small number of inputs, but a huge amount of internal state. In situations like these, it may be more efficient to sample the inputs and simulate the logic, instead of directly sampling the state. For instance, debugging a misbehaving branch predictor in a CPU can be done by recording activity on the address and data busses and playing them back in simulation - which would use less FPGA resources than sampling the entire pattern history table.

Python API Documentation

manta.LogicAnalyzerCore

LogicAnalyzerCore(sample_depth, probes)

A module for generating a logic analyzer on the FPGA, with configurable triggers, trigger position, and trigger modes.

Provides methods for generating synthesizable logic for the FPGA, as well as methods for reading and writing the value of a register.

Create a Logic Analyzer Core with the given probes and sample depth.

This function is the main mechanism for configuring a Logic Analyzer in an Amaranth-native design.

Parameters:

  • sample_depth (int) –

    The number of samples saved in the capture. A larger sample depth will use more FPGA resources, but will show what the probes are doing over a longer time interval.

  • probes (List[Signal]) –

    The signals in your logic that the Logic Analyzer connects to. Each probe is specified with a name and a width.

capture

capture()

Performs a capture, recording the state of all probes to memory.

Returns:

  • capture ( LogicAnalyzerCapture ) –

    A LogicAnalyzerCapture object containing the capture and its metadata.

set_triggers

set_triggers(trigger_mode=None, triggers=None, trigger_location=None)

Parameters:

  • trigger_mode (TriggerMode | str, default: None ) –
  • triggers (Optional[Sequence[Sequence[str | int]]], default: None ) –
  • trigger_location (Optional[int], default: None ) –

manta.LogicAnalyzerCapture

LogicAnalyzerCapture(probes, trigger_location, trigger_mode, data, interface)

A container class for the data collected by a LogicAnalyzerCore. Contains methods for exporting the data as a VCD waveform file, a Python list, a CSV file, or a Verilog module.

export_csv

export_csv(path)

Export the capture to a CSV file.

Parameters:

  • path (str) –

    Path to the destination file.

Returns:

  • None

export_playback_verilog

export_playback_verilog(path)

Exports a Verilog module that will playback the captured data. This module is synthesizable, so it may be used in either simulation or on the FPGA directly by including it your build process.

export_vcd

export_vcd(path)

Export the capture to a VCD file.

Parameters:

  • path (str) –

    Path to the destination file.

Returns:

  • None

get_playback_module

get_playback_module()

Returns an Amaranth module that will playback the captured data. This module is synthesizable, so it may be used in either simulation or on the FPGA directly by including it your build process.

get_trace

get_trace(name)

Gets the value of a single probe over the capture.

Parameters:

  • name (str) –

    The name of the probe.

Returns:

  • data ( List[int] ) –

    The value of the probe at every timestep, interpreted as an unsigned integer. Has length equal to the sample_depth of the core that produced the capture.

get_trigger_location

get_trigger_location()

Returns the location of the trigger in the capture. This will match the value of "trigger_location" provided in the configuration file at the time of capture.

manta.LogicAnalyzerPlayback

LogicAnalyzerPlayback(probes, data)

A synthesizable module that plays back data captured by a LogicAnalyzerCore. Takes a list of all the samples captured by a core, along with the config of the core used to take it.

get_top_level_ports

get_top_level_ports()

Returns the Amaranth signals that should be included as ports in the exported Verilog module.