Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Targets

Targets are the primary mechanism in Bender for managing project configurations. They allow you to conditionally include source files, include directories, and dependencies based on the current context (e.g., simulation vs. synthesis, or FPGA vs. ASIC) or the desired configuration (e.g., with/without cache).

Target Expressions

Bender uses a simple boolean expression language for targets:

  • *: Wildcard, matches all target sets.
  • name: Matches if the target name is active (case-insensitive).
  • all(T1, T2, ...): Matches if all arguments match (boolean AND).
  • any(T1, T2, ...): Matches if at least one argument matches (boolean OR).
  • not(T): Matches if T does not match (boolean NOT).
  • (T): Parentheses for grouping.

Syntax Rules

Target names can contain alphanumeric characters, dots (.), underscores (_), and hyphens (-).

Restrictions:

  • They cannot contain colons (:), as colons are used for package-specific targets in the CLI.
  • They cannot start with a hyphen (-), as leading hyphens are used to disable targets in the CLI.

Logical Examples

  • all(asic, synthesis): Matches when both ‘asic’ and ‘synthesis’ are set.
  • any(vsim, vcs, riviera): Matches if any of the listed simulation tools are active.
  • not(simulation): Matches only when ‘simulation’ is not set.
  • any(test, all(rtl, simulation)): Matches for testbenches, or for RTL code during simulation.

Usage in Bender.yml

Source Groups

You can wrap a group of files in a target specification. This allows you to manage different implementations or verification components within the same package.

Testbench Inclusion

Ensures that verification-only code is never included in the synthesis or production flow:

sources:
  # RTL sources
  - files:
      - src/core.sv
      - src/alu.sv

  # Testbench only
  - target: test
    files:
      - tb/driver.sv
      - tb/tb_top.sv

Simulation vs. Synthesis

Commonly used to swap between an actual hardware macro and a fast behavioral model for simulation:

sources:
  # Behavioral model for faster simulation
  - target: all(simulation, not(synthesis))
    files:
      - src/behavioral/ip_model.sv

Technology Selection

Useful when choosing between different physical implementations, such as ASIC standard cells versus FPGA primitives:

sources:
  - target: asic
    files:
      - target/asic/clock_gate.sv
  - target: fpga
    files:
      - target/fpga/clock_gate.sv

Core Configuration

Targets can be used to select between different hardware architectures or feature sets:

sources:
  # 32-bit architecture
  - target: rv32
    files:
      - src/core/alu_32.sv
      - src/core/regfile_32.sv
  # 64-bit architecture
  - target: rv64
    files:
      - src/core/alu_64.sv
      - src/core/regfile_64.sv

Dependencies

You can make a dependency conditional using target expressions. This is commonly used to include verification IP or platform-specific components only when needed:

dependencies:
  # Included only during simulation
  uvm: { version: "1.2.0", target: simulation }
  # Included for either test or simulation
  common_verification: { version: "0.2", target: any(test, simulation) }

Built-in Targets

Bender automatically activates certain targets based on the subcommand and output format. These “default targets” ensure that tool-specific workarounds or flow-specific files are included correctly. You can disable this behavior with the --no-default-target flag.

Script Format Targets

The bender script command activates the following targets based on the chosen format:

FormatDefault Targets
flist, flist-plusflist
vsimvsim, simulation
vcsvcs, simulation
verilatorverilator, synthesis
synopsyssynopsys, synthesis
formalitysynopsys, synthesis, formality
rivierariviera, simulation
genusgenus, synthesis
vivadovivado, fpga, xilinx, synthesis
vivadosimvivado, fpga, xilinx, simulation
precisionprecision, fpga, synthesis

Special Targets

  • RTL: If you use the --assume-rtl flag, Bender will automatically assign the rtl target to any source group that does not have an explicit target specification.
  • ASIC: While asic is a common convention, it is not set automatically by Bender. It should be manually activated via -t asic when needed.

Bender does not enforce these, but the following user-defined targets are widely used across PULP projects and are a good default for new packages:

  • test — testbench code and verification IP, kept out of synthesis flows.
  • rtl — synthesizable RTL code.
  • gate — gate-level netlists, used in post-synthesis simulation and timing flows.

Similarly, asic vs. fpga is the conventional way to swap between technology-specific implementations.

Activating Targets via CLI

Use the -t or --target flag with Bender commands:

# Enable the 'test' target
bender script vsim -t test

# Enable multiple targets
bender script vivado -t synthesis -t fpga

Advanced CLI Syntax

  • Package-specific: -t my_pkg:my_target activates my_target only for my_pkg.
  • Negative targets: -t -old_target explicitly disables old_target.

Passing Targets Hierarchically

Bender allows you to configure your dependencies by passing specific targets down to them using the pass_targets field. This lets you propagate global settings or select alternative implementations within sub-modules.

Simple Passing

You can pass a target name as a string, which will then always be active for that specific dependency:

dependencies:
  my_submodule:
    version: "1.0.0"
    pass_targets: ["enable_debug"] # 'enable_debug' is always active for my_submodule

Conditional Passing

You can also pass targets conditionally, based on the targets active in the parent package:

dependencies:
  ariane:
    version: 5.3.0
    pass_targets:
      - {target: rv64, pass: "cv64a6_imafdcv_sv39"}
      - {target: rv32, pass: "cv32a6_imac_sv32"}

In this example, if the rv64 target is active globally, Bender will ensure the cv64a6_imafdcv_sv39 target is active specifically for the ariane dependency.