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

Vendorizing External Code

Bender’s vendor command allows you to manage external dependencies that aren’t natively packaged for Bender. It works by copying a subset of files from an upstream Git repository into a local directory within your project, allowing you to track changes and maintain local patches.

This flow is heavily inspired by the vendor.py script used in the OpenTitan project.

Configuration

Vendorized packages are defined in the vendor_package section of your Bender.yml:

vendor_package:
  - name: my_ip
    target_dir: "deps/my_ip"
    upstream: { git: "https://github.com/external/my_ip.git", rev: "abcd123" }
    include_from_upstream:
      - "src/*.sv"
      - "include/*.svh"
    exclude_from_upstream:
      - "src/deprecated/*"
    patch_dir: "deps/patches/my_ip"
    mapping:
      - {from: 'src/old_name.sv', to: 'src/new_name.sv' }

Key Fields

  • name: A unique identifier for the vendorized package.
  • target_dir: Where the files should be copied to in your repository.
  • upstream: The Git repository and specific revision (commit/tag/branch) to pull from.
  • include_from_upstream: (Optional) Glob patterns of files to copy.
  • exclude_from_upstream: (Optional) Glob patterns of files to ignore.
  • patch_dir: (Optional) A directory containing .patch files to apply after copying.
  • mapping: (Optional) A list of specific file renames or movements during the copy process.

The Vendor Workflow

Using the configuration above, here is how you manage a vendorized IP:

1. Initialize (init)

To download the upstream code and copy it into your target_dir:

bender vendor init

Bender clones the upstream repository, filters the files based on your rules, and copies them to your project. If a patch_dir is specified, any existing patches are applied automatically.

Important: Vendored files are not automatically picked up as compilation sources. After bender vendor init, you still need to list the relevant files (or globs matching them) in the sources section of your Bender.yml for them to participate in script generation and source collection.

2. Make Local Changes and Diff

Assume you need to fix a bug in deps/my_ip/src/top.sv. You edit the file directly in your workspace. You can see how your local code differs from the upstream source (plus existing patches) by running:

bender vendor diff

3. Create a Patch (patch)

To make your fix permanent and shareable, stage the change and generate a patch:

# Stage the change in your main repository
git add deps/my_ip/src/top.sv

# Generate the patch file
bender vendor patch

Bender will prompt for a commit message and create a numbered patch file in your patch_dir (e.g., 0001-fix-bug.patch).

4. Commit Everything

Now you can create an atomic commit in your repository that contains both the modified source and the new patch file:

git add deps/patches/my_ip/0001-fix-bug.patch
git commit -m "Update my_ip with local bugfix"

The next time you (or a teammate) run bender vendor init, Bender will pull the fresh upstream code and automatically apply your patch.

Upstreaming Patches

If you want to contribute your fix back to the upstream repository:

  1. Clone the upstream repository separately.
  2. Check out the same revision (abcd123).
  3. Apply your patch: git am /path/to/your_repo/deps/patches/my_ip/0001-fix-bug.patch.
  4. The fix is now a proper Git commit in the upstream repo, with all metadata (author, timestamp) preserved.

When to use Vendor?

Use the vendor flow when:

  • The external IP does not have its own Bender.yml.
  • You need to include only a small subset of a massive repository.
  • You must maintain local modifications (bug fixes or tool workarounds) that haven’t been merged upstream yet.