LUNAROPS · OPERATIONAL UPLINK 100% UPTIME 1,247d POSTS 893 JEFF.MOON@LUNAROPS.DEV UTC --:--:--

DesignSync for Git Users: A Complete Guide to EDA Version Control

edadesignsyncversion-controlic-designsiemensenoviasemiconductor
Contents

If you are joining a semiconductor or mixed-signal hardware team from a software background, one of the first surprises is version control. Instead of Git, you are likely staring at dssc, sync:// URLs, vaults, locked checkouts, and manifests. The concepts exist in Git too — they just go by different names and carry different assumptions.

This guide maps everything you know from Git onto DesignSync (ENOVIA Synchronicity DesignSync Data Manager, from Dassault Systèmes/Siemens EDA). It assumes you are already comfortable with Git and need to get productive in DesignSync without wading through a 400-page manual.


Why EDA Uses a Different Version Control Model

Before the mapping, it helps to understand why hardware teams use DesignSync instead of Git. The reasons are not backwards thinking — they reflect genuine requirements that Git does not handle well:

Binary files dominate. A GDS layout for a complex block might be 10 GB. A full-chip netlist is often multiple gigabytes. Git’s delta compression and object model are designed for text; it handles large binary files poorly. Git LFS helps but introduces its own operational complexity.

Files cannot be merged. A SPICE schematic, a Verilog layout, or a Liberty file cannot be auto-merged the way Python source code can. If two engineers modify the same cell simultaneously, the result is not a conflict to resolve — it is a corrupted database. Pessimistic locking (only one person edits at a time) is the correct model for EDA data.

The hierarchy is part of the design. A chip is organized as a tree of IP blocks, each of which is itself versioned. The top-level design references specific versions of its sub-blocks. This hierarchical referencing — “the top-level chip uses ALU version 2.3 and cache version 1.8” — is a first-class concept in DesignSync, not bolted on as a .gitmodules afterthought.

Terabytes, not megabytes. A serious tape-out involves terabytes of data across hundreds of engineers at multiple sites. DesignSync’s mirroring and caching architecture was built for this scale from the start.

With that context, the design choices in DesignSync make much more sense.


The Conceptual Map: Git → DesignSync

Git Concept DesignSync Concept Notes
Remote repository Vault Centralized; all writes go here
Local clone / .git/ Workspace (workarea) Your local copy
git fetch / git pull dssc pop (populate) Fetches files from vault
git add + git commit + git push dssc ci (check-in) One step; writes directly to vault
git checkout (file) dssc co (check-out) Locks the file; required before editing
git tag tag (selector/label) Symbolic name for a module version
git branch branch Similar; scoped to modules
Repository URL sync:// URL e.g., sync://server:2647/Modules/MyBlock
.gitignore AccessControl / vault config Managed server-side
git submodule module hierarchy (href) Built into the core model
git log dssc log / dssc ls -hist Per-file or per-module history
git diff dssc diff Compares workspace vs vault version
git status dssc showstatus Shows modified, locked, out-of-sync files
Mirror (GitHub mirror) mirror Server-side replica for distributed teams
Bare repository vault Server stores versions only
Working tree workspace Your actual files on disk

The most important mental shift: DesignSync is centralized, not distributed. There is one vault that is the source of truth. You do not push and pull between peers. You check out from the vault, edit, and check in to the vault. The vault is always authoritative.


The Client Tools

DesignSync provides several command-line interfaces. Use the concurrent versions — they communicate directly with SyncServer without serialization bottlenecks:

Tool Description Use?
dssc DesignSync Concurrent Shell ✅ Recommended
stclc Synchronicity Tcl Shell (Concurrent) ✅ For scripting
dss DesignSync Shell (non-concurrent) ⚠️ Slower, legacy
stcl Synchronicity Tcl Shell (non-concurrent) ⚠️ Slower, legacy
DesSync GUI client For occasional use

Almost everything in this guide uses dssc. Unless you are writing automation scripts that need Tcl’s data structures, dssc is your daily driver.


Vaults: The Server-Side Repository

What a Vault Is

A vault is DesignSync’s equivalent of a bare Git repository combined with the server process that serves it. It stores:

  • Every version of every file ever checked in
  • Module manifests (the bill of materials recording which file versions make up a module snapshot)
  • Branch and tag metadata
  • Access control rules

Vaults are managed by the SyncServer process. You never touch vault files directly — all access goes through dssc commands that communicate with SyncServer.

The sync:// URL

Every vault is addressed by a sync:// URL:

sync://server:port/path/to/vault

The default SyncServer port is 2647. If your site uses the default, you often see URLs without the port:

sync://syncserver.company.com/Modules/TopChip
sync://syncserver.company.com:2647/Modules/Blocks/ALU

This is analogous to a GitHub remote URL (git@github.com:org/repo.git), but instead of SSH, DesignSync uses its own protocol over port 2647.

Checking Your Environment

Your team’s sysadmin will have set environment variables pointing to your SyncServer. Check what is configured:

1
2
3
4
echo $SYNC_SITE_SERVER    # The default server hostname
echo $SYNC_PORT           # Usually 2647
dssc showvault            # Show the vault associated with the current workspace
dssc url                  # Show the sync:// URL for the current location

Creating a Vault (Admin Task)

Creating a vault is typically a sysadmin or lead engineer task, not something most users do daily. For completeness:

1
2
3
4
5
6
# Create a new module/vault at a path on the server
dssc mkmod sync://syncserver.company.com/Modules/NewBlock

# Create with an initial comment
dssc mkmod -comment "ALU block for XLP-12 project" \
    sync://syncserver.company.com/Modules/Blocks/ALU

This is analogous to git init --bare on a server, except DesignSync’s server process immediately makes it accessible without additional SSH/HTTP setup.

Vault Structure

Inside a vault, DesignSync organizes content into a hierarchy of modules. Each module is a versioned unit — think of it as one Git repository. Modules can contain sub-modules, creating the design hierarchy that mirrors your chip’s block structure:

sync://server/Projects/XLP-12/
├── TopChip/          # Top-level module
├── Blocks/
│   ├── ALU/          # Sub-module: arithmetic logic unit
│   ├── Cache/        # Sub-module: cache block
│   └── IOController/ # Sub-module: I/O controller
└── Verification/
    ├── Testbench/
    └── Coverage/

Each of these is an independent module with its own version history, but the TopChip module holds a manifest that records which version of ALU, Cache, and IOController it was tested and taped out with.


Workspaces: Your Local Copy

What a Workspace Is

A workspace (also called a workarea) is your local working directory, populated with files from a vault. It is analogous to a Git clone, but there is a key difference: a workspace is not a full copy of the vault’s history. It only contains the files at a specific version, not all past versions. History lives on the server.

Associating a Workspace with a Vault

Before you can do anything, your working directory needs to be associated with a vault. The setvault command does this:

1
2
3
mkdir ~/work/alu-block
cd ~/work/alu-block
dssc setvault sync://syncserver.company.com/Modules/Blocks/ALU

This is roughly equivalent to git remote add origin <url>. It tells DesignSync which vault this directory corresponds to.

Populating Your Workspace

Populate is the command that gets files from the vault into your workspace. It is the equivalent of git pull or git checkout for setting up a workspace:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Get the latest version of everything
dssc pop

# Get a specific tagged version (the most common case)
dssc pop -get TopChip@RELEASE_1_0

# Get a specific branch
dssc pop -get @feature/new-adder

# Populate recursively (including all sub-modules)
dssc pop -rec

When you dssc pop, DesignSync fetches the file versions recorded in the module manifest for that tag or branch and places them in your workspace. If a file has not changed since your last populate, it is not re-downloaded — DesignSync tracks what you already have.

Common pattern when starting on a new project:

1
2
3
mkdir ~/work/xlp12-top && cd ~/work/xlp12-top
dssc setvault sync://server/Projects/XLP-12/TopChip
dssc pop -get @TAPE_OUT_CANDIDATE_3 -rec

The -rec flag populates the top module and recursively descends into all referenced sub-modules. Without it, you get only the files directly in TopChip, not the ALU/Cache/IOController sub-modules.

Checking Workspace Status

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Show what is modified, locked, out-of-sync
dssc showstatus

# List files and their current version information
dssc ls

# List files with verbose version details
dssc ls -all

# Show the relationship between your workspace and the vault
dssc compare

dssc showstatus is your git status. It shows:

  • Files you have locked (checked out for editing)
  • Files that have been modified in your workspace
  • Files that are out of date (newer version in vault)
  • Unmanaged files (not under version control)

The Check-Out / Check-In Workflow

This is the core operational difference from Git and the most important thing to internalize.

Why Locking Exists

In Git, two people can edit the same file simultaneously. Git tries to merge the changes later; if it cannot, you get a conflict to resolve manually. For Python or YAML, this is fine. For a SPICE netlist or layout database, a merge is meaningless — the result would be a corrupted file.

DesignSync prevents this with exclusive locks: only one person can hold a write lock on a file at a time. When you lock a file, everyone else sees it as locked and cannot modify it. This is pessimistic concurrency — you prevent conflicts rather than detecting them after the fact.

Checking Out a File (Acquiring a Lock)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Locked checkout — you intend to modify this file
dssc co -lock alu_datapath.v

# Lock multiple files
dssc co -lock alu_datapath.v alu_control.v alu_top.v

# Lock all Verilog files in the current directory
dssc co -lock *.v

# Lock recursively — all files in the module
dssc co -lock -rec .

After a locked checkout:

  • The file is marked as locked under your username in the vault
  • Everyone else sees “locked by alice@workstation” if they try to lock it
  • You can edit the file normally with any tool
  • No one else can check in changes to this file until you release the lock

There is also an unlocked checkout, but it behaves differently and is used less frequently:

1
2
3
# Unlocked checkout — creates a local copy but no lock
# NOTE: You CANNOT check this back in — it is read-only from the vault's perspective
dssc co alu_datapath.v

Unlocked checkout is mainly useful for getting a writable local copy to experiment with, without intending to commit back. Think of it like cp rather than a true checkout.

Making Your Changes

Once you have a locked checkout, edit files normally with your EDA tools (vim, emacs, Virtuoso, Design Compiler, etc.). DesignSync does not care what editor you use — it manages versions, not editors.

1
2
3
4
5
# Edit the file however you like
vim alu_datapath.v

# Check that your changes look right
dssc diff alu_datapath.v

Checking In (Committing to the Vault)

When your changes are ready, check them in. This creates a new version in the vault and releases the lock:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Check in a single file with a comment
dssc ci -comment "Fix carry chain timing in 8-bit adder" alu_datapath.v

# Check in multiple files
dssc ci -comment "Complete adder redesign" alu_datapath.v alu_control.v

# Check in all locked files in the current directory
dssc ci -comment "ALU timing fixes" .

# Check in recursively (all locked files in module and sub-modules)
dssc ci -rec -comment "Signed off on adder block" .

# Add a new file (one that was never version-controlled before)
dssc ci -new -comment "New ALU testbench" alu_tb.v

This is the equivalent of git add + git commit + git push in one step. There is no staging area. When you check in, the new version goes directly to the vault.

Cancelling a Checkout (Discarding Changes)

If you checked out a file and want to abandon your changes:

1
2
3
4
5
6
7
8
# Discard changes and release the lock
dssc cancel alu_datapath.v

# Force cancel (even if you modified the file — your changes are lost)
dssc cancel -force alu_datapath.v

# Or explicitly unlock without reverting
dssc unlock alu_datapath.v

dssc cancel is analogous to git checkout -- file (discard unstaged changes) combined with releasing the lock. dssc unlock releases the lock but leaves your modified file on disk (you just cannot check it in anymore until you re-lock).

Seeing Who Holds a Lock

1
2
3
4
5
6
7
8
# List all locked files in the vault
dssc ls -locked

# See lock details for a specific file
dssc ls -all alu_datapath.v

# Show module-wide lock status
dssc showstatus -locked

Diffs and History

Comparing Your Changes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Diff your workspace version against the vault version (standard format)
dssc diff alu_datapath.v

# Unified diff (like git diff)
dssc diff -unified alu_datapath.v

# Side-by-side diff
dssc diff -syncdiff alu_datapath.v

# Annotated diff (shows version info inline)
dssc diff -annotate alu_datapath.v

# Diff between two specific versions
dssc diff -version 1.4 -version 1.7 alu_datapath.v

# Launch GUI diff tool
dssc diff -gui alu_datapath.v

Viewing File History

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Show version history of a file
dssc ls -hist alu_datapath.v

# Show history with comments
dssc ls -hist -verbose alu_datapath.v

# Show history for the entire module
dssc log .

# Show what changed between two tags
dssc compare -version @RELEASE_1_0 -version @RELEASE_1_1

Tags: Marking Important Versions

Tags in DesignSync are symbolic names (labels) attached to a specific version of a module or file. They are similar to Git annotated tags, but with an important constraint: a tag can only point to one version at a time. If you try to apply a tag that already exists, DesignSync will error unless you explicitly choose to move it.

Creating Tags

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Tag the current module at its latest version
dssc tag RELEASE_1_0

# Tag with a comment
dssc tag -comment "Passed timing signoff" TAPE_OUT_CANDIDATE_1

# Tag a specific version explicitly
dssc tag -version 1.23 STABLE_BUILD

# Tag recursively (top module and all sub-modules)
dssc tag -rec FULL_CHIP_FREEZE

Using Tags

Tags are referenced using the @ syntax:

1
2
3
4
5
6
7
8
# Populate to a tagged version
dssc pop -get @RELEASE_1_0

# Compare current workspace against a tagged version
dssc compare -version @RELEASE_1_0

# View history at a tag
dssc ls -hist -version @RELEASE_1_0 alu_datapath.v

Tag Best Practices

Use a consistent naming convention for your team. Common patterns:

MILESTONE_001           # Sequential milestones
SIGNOFF_TIMING_2026Q1   # Signoff events with date
TAPE_OUT_CANDIDATE_3    # Tape-out candidates
RELEASE_2_4_1           # Semantic versioning
FREEZE_BEFORE_ECO_007   # Engineering change order markers

Unlike Git tags, which are cheap and lightweight, DesignSync tags are typically used sparingly for significant checkpoints — tapeout candidates, signoff milestones, release versions. Daily work is done against branches, not tags.


The Selector Language in Depth

Almost every dssc command that reads from the vault accepts a selector — a short expression that says “which version do you mean?”. Selectors are to DesignSync what refspecs are to Git, and mastering them is the fastest way to become productive.

A selector is a string like Latest, @RELEASE_1_0, 1.14, Date:2026-03-01, or combinations joined with ;. They are passed as -selector <expr> on commands that support it and as @<tag> shorthand on populate/compare.

Selector Primitives

Selector Meaning
Latest Newest version on the main branch
@TAG_NAME The version a tag points to
1.14 An explicit version number
:Trunk Explicit “main/trunk” branch (same as Latest by default)
:<branch> The tip of a specific branch
Date:YYYY-MM-DDTHH:MM:SS The version that was current at that timestamp
Modifier:<username> The last version modified by a specific user
Category:<name> A named category (server-defined tag grouping)
Mine The version you most recently checked out or in
Locker:<user> Files currently locked by a user

Composite Selectors

Selectors chain with semicolons, read left to right with each subsequent term narrowing the previous:

1
2
3
4
5
6
7
8
# Latest version on the 'devel' branch, as of March 1st
dssc pop -selector ":devel;Date:2026-03-01"

# Latest version modified by jdoe
dssc ls -selector "Latest;Modifier:jdoe"

# Tip of eco-branch, but only if tagged TESTED
dssc pop -selector ":eco-branch;@TESTED"

Workflow-Oriented Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# "Give me the exact files that were current on tape-out day"
dssc pop -rec -get "Date:2026-02-15T17:00:00"

# "Roll back to whatever RELEASE_1_0 pointed to at the time"
dssc rollback -version "@RELEASE_1_0" alu_datapath.v

# "Which files have I edited recently on the main branch?"
dssc ls -recursive -selector "Latest;Modifier:$USER"

# "Show everything still locked by anyone"
dssc ls -rec -selector "Locker:*"

Persistent Selectors (Default Context)

Rather than typing the same selector on every command, associate one with your workspace so every subsequent command picks it up:

1
2
3
4
5
6
7
8
# All future dssc commands in this workspace use the devel branch by default
dssc setselector ":devel"

# View the current default
dssc showselector

# Clear it (back to Latest)
dssc setselector -clear

This is invaluable when you’re working on a long-running branch — you stop having to tack -selector :devel onto every dssc ls, dssc co, and dssc ci.


Branches: Parallel Development

Branch Basics

DesignSync branches work similarly to Git branches — they are diverging lines of development from a common ancestor. The main difference is that branching happens at the file level (through the locking mechanism) rather than as a repository-wide concept.

1
2
3
4
5
6
7
8
# Create a new branch
dssc mkbranch -comment "ECO for metal layer fix" eco-metal-fix

# List branches in the current module
dssc ls -branches

# Switch your workspace to a branch
dssc pop -get @eco-metal-fix

Working on a Branch

Once on a branch, your check-in/check-out workflow is identical:

1
2
3
4
# You are now on the eco-metal-fix branch
dssc co -lock metal_layer.v
# ... make changes ...
dssc ci -comment "Reroute M3 to fix DRC violation" metal_layer.v

Check-ins on this branch do not affect the main line until you explicitly merge.

Auto-Branching on Checkout

One of DesignSync’s more powerful features is auto-branching: when you lock a file on a branch, DesignSync can automatically create a branch-specific version chain. This is what makes it possible to have parallel development without explicit branch creation in some workflows:

1
2
# Locking with an explicit branch selector
dssc co -lock -selector @feature-branch alu_datapath.v

Merging Branches

Branch merging in DesignSync is more manual than git merge. You typically:

  1. Populate from both branches into separate workspaces
  2. Use dssc diff to see what changed on each branch
  3. Apply changes manually or with a merge tool
  4. Check the merged result into the target branch

For text-based files (Verilog, SPICE), standard diff/patch tools work. For binary EDA formats, your EDA tool’s own merge capabilities (if any) are needed.


Module Hierarchy: DesignSync’s Answer to Submodules

The Problem Hierarchy Solves

A chip design is inherently hierarchical. The top-level RTL instantiates an ALU block, which instantiates full-adder cells, which use standard cell primitives. Each level is developed and versioned independently by different teams. When you tape out the chip, you need to record exactly which version of each block was used — and reproduce that exact combination later for metal ECOs or respins.

Git handles this with submodules (awkward) or monorepos (doesn’t scale to terabyte datasets). DesignSync handles it natively through module references (hrefs) and manifests.

Manifests

A manifest is a bill of materials for a module snapshot. When you tag a module, DesignSync records a manifest: the exact file versions included, the exact sub-module versions referenced, and the directory structure. This manifest is what you get when you populate to a tag — not just the file contents, but the exact hierarchical snapshot.

Think of it as a lockfile (like package-lock.json or go.sum) that is automatically maintained by DesignSync for every tagged state.

Creating Module References (href)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Establish that TopChip contains ALU as a sub-module
dssc addhref \
    sync://server/Projects/XLP-12/Blocks/ALU \
    Blocks/ALU

# Add with a specific version pinned
dssc addhref \
    -selector @RELEASE_2_1 \
    sync://server/Projects/XLP-12/Blocks/ALU \
    Blocks/ALU

# Remove a sub-module reference
dssc rmhref Blocks/ALU

# List all sub-module references in the current module
dssc ls -hrefs

Populating the Full Hierarchy

With hrefs in place, a single recursive populate gets the entire design hierarchy at consistent versions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Get the full chip at TAPE_OUT_CANDIDATE_3, all sub-blocks included
cd ~/work/xlp12-full
dssc setvault sync://server/Projects/XLP-12/TopChip
dssc pop -get @TAPE_OUT_CANDIDATE_3 -rec

# Your workspace now has:
# ~/work/xlp12-full/                 (TopChip files)
# ~/work/xlp12-full/Blocks/ALU/     (ALU at whatever version TopChip@TAPE_OUT_CANDIDATE_3 references)
# ~/work/xlp12-full/Blocks/Cache/   (Cache at its referenced version)
# ~/work/xlp12-full/Verification/   (Testbench at its referenced version)

This is significantly more powerful than git submodule update --init --recursive because the version pinning is built into the manifest and happens automatically — you cannot accidentally populate with an inconsistent combination of block versions.


Mirrors: Distributed Access Without a Distributed Model

What a Mirror Is

A mirror is a server-side replica of a vault, held on a second SyncServer. Mirrors provide:

  • Geographic distribution: Put a mirror server physically close to each team (US, Europe, Asia). Engineers populate from the nearest mirror rather than crossing the WAN to a remote vault.
  • Load distribution: High-traffic read operations (populates) go to mirrors; only writes go to the primary vault.
  • Resilience: If the primary server is briefly unavailable, engineers can still read from mirrors.
  • Archival: Mirrors serve as secondary backups.

Critically: mirrors are read-only for engineers. All check-ins still go to the primary vault. Mirrors receive updates automatically from the primary.

Mirror vs Cache

DesignSync has two similar but distinct concepts:

Mirror Cache
Location Server-side (another SyncServer) Local workarea (your disk)
Sharing Shared by many users Personal to your workspace
Management Admin/engineering lead Automatic by DesignSync
Purpose Geographic distribution Reduce repeated downloads
Update Sync from primary vault Populated on demand

Caches are managed automatically — when you populate files, DesignSync keeps a local cache so repeat populates of the same version don’t re-download. Mirrors must be explicitly configured.

Associating a Mirror with Your Workspace

Your sysadmin configures mirrors on the server side. As a user, you tell your workspace which mirror to use:

1
2
3
4
5
6
7
8
# Associate your workspace with a local mirror server
dssc setmirror sync://local-mirror.company.com/Mirrors/Projects/XLP-12

# Check which mirrors are configured
dssc showmirror

# Remove mirror association
dssc setmirror -clear

After setting a mirror, your dssc pop commands automatically use the mirror for read operations, dramatically improving performance for teams on slow WAN links.

Creating and Syncing Mirrors (Admin)

Mirror creation and synchronization are administrative operations, but understanding them helps you debug performance issues:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Create a mirror of a vault on a secondary server (run on the mirror server)
dssc mkmirror \
    sync://primary-server/Projects/XLP-12/TopChip \
    sync://mirror-server/Mirrors/XLP-12/TopChip

# Synchronize a mirror with its primary (pull latest changes)
dssc syncmirror sync://primary-server/Projects/XLP-12/TopChip

# Populate from a mirror explicitly (override workspace mirror setting)
dssc pop -get @RELEASE_1_0 \
    -mirror sync://local-mirror.company.com/Mirrors/XLP-12/TopChip

Mirrors are typically kept in sync by a cron job on the mirror server, running dssc syncmirror every few minutes. From a user perspective, you should never see the difference between the primary vault and a mirror — the data is identical.


Adding and Removing Files

Adding New Files to Version Control

1
2
3
4
5
6
7
8
# Add a new file that has never been checked in before
dssc ci -new -comment "Initial version" new_cell.v

# Add multiple new files
dssc ci -new -comment "Add testbench infrastructure" tb_top.v tb_env.v tb_driver.v

# Add an entire new directory of files
dssc ci -new -rec -comment "New coverage infrastructure" coverage/

There is no git add stage. -new on dssc ci is the signal that these files do not yet exist in the vault.

Removing Files

1
2
3
4
5
# Remove a file from version control (marks it as deleted in the vault)
dssc remove obsolete_block.v

# Remove a directory recursively
dssc remove -rec old_blocks/

Removed files are not truly deleted from the vault — their history is preserved, and you can retrieve old versions. Removal just means the file is no longer part of the module’s current state.


Rolling Back

Reverting a File to a Previous Version

1
2
3
4
5
6
7
8
# Revert a file to the version before your last check-in
dssc rollback alu_datapath.v

# Revert to a specific version number
dssc rollback -version 1.15 alu_datapath.v

# Revert to a tagged version
dssc rollback -version @RELEASE_1_0 alu_datapath.v

Reverting a Module to a Previous State

1
2
3
4
5
# Roll back the entire module to a tagged state
dssc rollback -rec -version @TAPE_OUT_CANDIDATE_2 .

# This creates new versions of all files at their @TAPE_OUT_CANDIDATE_2 state,
# making that the new current version — not a destructive operation on history

Note that dssc rollback does not delete the intervening versions — it creates new versions that happen to have the same content as the old ones. History is always preserved.


Importing from Remote Vaults

Sometimes you need to bring files from another vault (a vendor’s IP vault, another team’s vault) into your workspace:

1
2
3
4
5
6
7
# Import files from a remote vault into local workspace
dssc import sync://vendor-server/IP/Blocks/DDR4PHY ./vendor/ddr4phy

# Import a specific version
dssc import -version @VENDOR_RELEASE_4_2 \
    sync://vendor-server/IP/Blocks/DDR4PHY \
    ./vendor/ddr4phy

For a permanent sub-module relationship (your design depends on this vendor IP), use dssc addhref instead. Use dssc import for one-time or manual imports.


Access Control and Permissions

DesignSync has its own permission system, independent of Unix file permissions, enforced by SyncServer at vault access time. If a user can read files in a workspace but cannot check them in, 90% of the time it’s an ACL issue — not a disk permissions issue.

The Permission Model

Every vault (and every path within it) has an AccessControl list of entries that grant or deny operations. Permissions are inherited down the hierarchy unless overridden.

Common permissions:

Permission Allows
READ populate, diff, view history
LOCK checkout with lock
MODIFY check-in new versions of existing files
CREATE add new files (dssc ci -new)
TAG apply or move tags
BRANCH create branches
ADMIN modify the ACL itself, force-unlock others’ files

Managing ACLs

Permissions are managed with stclc or through the admin GUI. A typical entry grants a Unix group the ability to read and lock in a specific module path:

1
2
3
4
5
6
7
# stclc script
AccessControl sync://server/Modules/Blocks/ALU add \
    -identity "Group:alu-team" \
    -permission "READ,LOCK,MODIFY,CREATE"

# View the current ACL for a path
AccessControl sync://server/Modules/Blocks/ALU list

Common Failure Modes

“You do not have permission to lock this file” — the user’s Unix group isn’t in the ACL, or a DENY entry shadows the grant. ACL evaluation is first-match, so a DENY Group:* at the top of the list overrides everything below it.

“Check-in denied: file is not locked” — permissions are fine, but the file was either never locked or the lock was released. Run dssc co -lock first.

“AdminLevel required” operations — certain actions (mkmirror, modifying global policies, force-unlocking another user’s lock) require admin rights; see your site admin.


Triggers and Hooks

DesignSync supports server-side triggers — Tcl scripts that fire before or after specific operations on a vault. This is how sites enforce policy: requiring a Jira ticket in every check-in comment, preventing check-ins during freeze periods, notifying Slack of tag creation, kicking off a CI run after every check-in on main.

Trigger Types

Trigger Fires
PreCI Before a check-in is accepted
PostCI After a successful check-in
PreCO Before a checkout/lock
PreTag / PostTag Around tag creation
PreBranch / PostBranch Around branch creation
PreDelete Before file removal

Example: Require a Ticket ID in Check-in Comments

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# /site/synchronicity/triggers/require_ticket.tcl
proc check_comment {args} {
    array set opts $args
    if {![regexp {JIRA-\d+} $opts(-comment)]} {
        return -code error "Check-in comments must reference a JIRA ticket (e.g., JIRA-1234)"
    }
    return 0
}

trigger register -vault sync://server/Modules/TopChip \
    -event PreCI -callback check_comment

After registering, any dssc ci without a matching pattern is rejected by the server, before the new version is stored. Because the policy lives server-side, you cannot bypass it by using a different client.

Example: Post-Tag Notification

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Notify a CI server when a release tag is applied
proc notify_ci {args} {
    array set opts $args
    if {[string match "RELEASE_*" $opts(-tag)]} {
        exec curl -s -X POST \
            -d "tag=$opts(-tag)&module=$opts(-module)" \
            http://ci.company.com/hooks/designsync-tag &
    }
}

trigger register -vault sync://server/Modules/TopChip \
    -event PostTag -callback notify_ci

Daily Workflow Reference

Here is the complete daily workflow, mapped to Git equivalents:

Starting Your Day

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Navigate to your workspace
cd ~/work/my-block

# Check for updates in the vault (are there new versions you don't have?)
dssc showstatus

# Pull down any new versions from the vault
dssc pop

# See what others have checked in recently
dssc log .

Git equivalent: git fetch && git status && git pull && git log

Making Changes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Lock the file you want to edit
dssc co -lock alu_datapath.v

# Make your changes
vim alu_datapath.v

# Review what you changed
dssc diff alu_datapath.v

# Check in the change
dssc ci -comment "Fix sign extension in 32-bit subtract" alu_datapath.v

Git equivalent: git add alu_datapath.v && git commit -m "..." && git push

Reviewing Others’ Work

1
2
3
4
5
6
7
8
# See what files are currently locked (who is editing what)
dssc ls -locked

# See the history of a specific file
dssc ls -hist alu_datapath.v

# Compare two versions
dssc diff -version 1.8 -version 1.10 alu_datapath.v

Git equivalent: git log --oneline, git diff HEAD~2 HEAD -- alu_datapath.v

Releasing a Milestone

1
2
3
4
5
6
7
8
# Make sure everything is checked in
dssc showstatus

# Tag the current state
dssc tag -rec -comment "Timing clean, power budget met" SIGNOFF_TIMING_Q1

# Verify the tag was applied
dssc ls -tags

Git equivalent: git tag -a SIGNOFF_TIMING_Q1 -m "..." && git push --tags

Starting a New Feature Branch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Create the branch
dssc mkbranch -comment "Metal layer ECO for DRC fix" eco-m3-drc-fix

# Populate the branch into a fresh workspace
mkdir ~/work/eco-m3 && cd ~/work/eco-m3
dssc setvault sync://server/Blocks/ALU
dssc pop -get @eco-m3-drc-fix

# Work normally on the branch
dssc co -lock metal_layer.v
# ... make changes ...
dssc ci -comment "Reroute M3 per DRC cleanup" metal_layer.v

Git equivalent: git checkout -b eco-m3-drc-fix && git push -u origin eco-m3-drc-fix


Common Mistakes for Git Users

Editing without locking. In Git, you edit files freely and commit later. In DesignSync, if you edit a file without a locked checkout, you cannot check it in. Always dssc co -lock before you modify a file you intend to commit.

Expecting pop to behave like pull. dssc pop fetches files from the vault but does not automatically merge changes into files you have locked. If someone checks in a new version of a file you have locked, you need to dssc diff manually and reconcile.

Forgetting to release locks. If you decide not to make changes after locking a file, run dssc cancel or dssc unlock. Leaving orphaned locks blocks your teammates.

Thinking workspace = repository. Your workspace does not contain history. If your disk dies, you lose your in-progress work (locked, uncommitted changes), but nothing that was checked in is at risk — it is all in the vault.

Trying to work offline. DesignSync requires a live connection to the SyncServer for almost all operations. There is no local commit that you push later. Plan around server availability.

Checking in without a comment. Unlike Git (where a commit message is technically optional), in DesignSync leaving a comment blank on a large team is considered bad practice. Your check-in comment is the primary audit trail.


Useful One-Liners

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# What do I have locked right now?
dssc ls -locked

# What version of this file am I working with?
dssc ls -all alu_datapath.v

# What changed in the vault since I last populated?
dssc showstatus -newer

# Who last touched this file and when?
dssc ls -hist -verbose -limit 5 alu_datapath.v

# Get the sync:// URL of my current workspace vault
dssc url

# List all tags on the current module
dssc ls -tags

# Compare my workspace to a specific release
dssc compare -version @RELEASE_1_0

# Check in everything I have locked in the entire hierarchy
dssc ci -rec -comment "WIP save before lunch" .

# See all branches in the current module
dssc ls -branches

# Force-cancel someone else's stale lock (admin only)
dssc cancel -force -user bob alu_datapath.v

Scripting with stclc and Tcl

When you need real automation — conditional logic, loops, structured output, server-side policy — stclc (Synchronicity Tcl Concurrent shell) is the tool. Every dssc command is also a Tcl proc inside stclc, so ports between the two are mechanical.

Running a Tcl Script

1
2
3
4
5
6
7
8
# Non-interactive: run a script and exit
stclc -batch myscript.tcl

# Interactive REPL
stclc

# Execute a one-liner
stclc -cmd 'puts [url]'

Useful Idioms

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Get the list of all locked files in the current module as a Tcl list
set locked [ls -locked -list]
foreach file $locked {
    puts "Locked: $file"
}

# Check in every modified file in a directory with a uniform comment
foreach f [ls -modified -list] {
    ci -comment "Nightly auto-commit for $::env(USER)" $f
}

# Walk the module hierarchy and report on each
proc walk_hierarchy {url} {
    puts "Module: $url"
    foreach href [ls -hrefs -url $url -list] {
        walk_hierarchy $href
    }
}
walk_hierarchy [url]

Snapshot-Creation Script

Create a tagged, consistent snapshot of a full chip hierarchy, with a check that no files are still locked:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# release.tcl — run from the TopChip workspace
set tag "RELEASE_[clock format [clock seconds] -format %Y%m%d_%H%M]"

# Refuse to tag if anything is locked anywhere in the hierarchy
set locked [ls -rec -locked -list]
if {[llength $locked] > 0} {
    puts stderr "ERROR: Cannot tag — the following files are still locked:"
    foreach f $locked { puts stderr "  $f" }
    exit 1
}

# Tag recursively
tag -rec -comment "Automated release $tag" $tag
puts "Created snapshot $tag"

CI/CD Integration

DesignSync plays well with Jenkins/GitLab CI when you treat the CI worker as any other client. Pattern:

  1. Jenkins agent runs on a machine with dssc installed and MUNGE-equivalent credentials configured.
  2. The pipeline calls stclc -batch build.tcl to populate the latest tag into a clean workspace, run synthesis/simulation, and publish results.
  3. A PostTag trigger on the vault notifies Jenkins when new candidates appear, triggering verification flows.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Jenkinsfile fragment
stage('Populate') {
    steps {
        sh '''
            rm -rf workspace && mkdir workspace && cd workspace
            dssc setvault sync://server/Projects/XLP-12/TopChip
            dssc pop -rec -get @TAPE_OUT_CANDIDATE_${BUILD_NUMBER}
        '''
    }
}
stage('Regress') {
    steps { sh 'cd workspace && make regress' }
}
stage('Tag') {
    steps {
        sh '''
            cd workspace
            dssc tag -rec -comment "Passed Jenkins #${BUILD_NUMBER}" \
                REGRESSION_PASSED_${BUILD_NUMBER}
        '''
    }
}

Administrative Operations

Most users never run these commands, but knowing they exist helps you understand what your admin does and diagnose problems that aren’t really yours to fix.

Health Checks

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Inspect server status
stclc -cmd 'server status'

# Integrity-check a vault (detects corrupt chunks, missing manifests)
dssc vaultcheck sync://server/Modules/TopChip

# List all vaults on a server
dssc ls -url sync://server/

# Audit: who accessed what, when
dssc audit -since "2026-03-01" -url sync://server/Modules/TopChip

Backups

DesignSync vaults are directory trees of chunk files plus a metadata database. A consistent backup requires either:

  • Quiesce-and-copy: stop SyncServer briefly, rsync the vault directory, restart. Simple but requires downtime.
  • Snapshot-based: take an LVM/ZFS/NetApp snapshot of the vault filesystem while SyncServer is running, then back up the snapshot. No downtime but requires snapshot-capable storage.
  • dssc dump: export a module’s full history to a portable file, useful for archiving or migration but not for fast restore of a live vault.

Test your restore. A backup that has never been verified isn’t a backup.

Moving Vaults

Vaults can be relocated (different path on the same server, or a different server) with dssc movevault. The sync:// URL changes, and every workspace pointing to the old location needs dssc setvault updated — plan communications accordingly.


Performance Tuning

Slow populates or check-ins are almost always explainable by one of these root causes:

1. Missing mirror near the client. WAN round-trips dominate DesignSync performance. If engineers in Bangalore populate from a vault in California, every metadata round-trip takes ~250ms. A local mirror brings this to single-digit milliseconds. Mirror ROI is higher than any other tuning knob.

2. Cold local cache. First populate after a clean checkout fetches everything; subsequent ones only fetch changes. Keep workspaces around instead of deleting and recreating.

3. Huge single files. A 10 GB GDS file will take as long to transfer over 1 Gbps (~90s) as the network allows — no amount of tuning fixes physics. Consider whether that file really needs to live in DesignSync or in a separate IP management system.

4. -rec populates that fetch too much. If a hierarchy contains legacy blocks you don’t need, use -exclude or a workspace-level .syncignore-style configuration to skip them.

5. SyncServer memory/disk saturation. Check the SyncServer process with top and df. Metadata operations become O(log N) on directory contents once the server has paged; if your vault has millions of files and SyncServer has 4 GB of RAM, upgrade.

Tuning Knobs

1
2
3
4
5
6
# Increase client-side parallelism for large populates (1 by default)
dssc pop -rec -parallel 8 -get @RELEASE_1_0

# Cache sizing — set via site configuration
# SYNC_CACHE_DIR controls where your local cache lives
# A fast local SSD for this directory produces dramatic speedups

For multi-site deployments, the dssc syncmirror cron frequency is the tuning decision that matters most: too infrequent and engineers read stale versions; too frequent and the WAN never recovers. Five minutes is a common sweet spot.


Troubleshooting Guide

“Can’t connect to server” / “Connection refused”

Check the SyncServer is running and port 2647 is reachable:

1
2
3
nc -zv syncserver.company.com 2647    # Should say "succeeded"
ping syncserver.company.com
echo $SYNC_SITE_SERVER                # Is this variable even set?

Firewall rules, a stopped SyncServer process, or VPN disconnection are the usual causes.

“File is not checked out” on dssc ci

You can only check in files that are currently locked by you. If the lock expired, was canceled, or was force-unlocked, re-lock and try again:

1
2
dssc co -lock alu_datapath.v
dssc ci -comment "..." alu_datapath.v

“Version mismatch — your workspace is out of date”

Someone checked in a newer version of a file you have locked. The vault refuses to accept your check-in until you’ve reconciled with the newer version:

1
2
3
dssc diff -version Latest alu_datapath.v
# Manually merge the newer vault version into your working copy
dssc ci -merge -comment "Merged with tip" alu_datapath.v

“Lock is held by user ‘bob’ — contact a site administrator”

Bob is on vacation. An admin can force-unlock:

1
dssc cancel -force -user bob alu_datapath.v

Without admin rights, you can’t — this is by design, to prevent people from yanking files out from under active edits.

dssc pop is extremely slow

  • Are you populating from the primary vault across a WAN? Set a local mirror with dssc setmirror.
  • Is the cache directory on a slow filesystem (e.g., NFS home dir with a low quota)? Point SYNC_CACHE_DIR at local SSD.
  • Are you populating a module with thousands of tiny files? Check dssc ls -rec -count; the metadata round-trip count is often the bottleneck, not bandwidth.

Workspace says “out of sync” but dssc pop doesn’t fix it

A file in your workspace was modified but never checked in. dssc showstatus reports this as modified-and-out-of-date. Either:

1
2
3
dssc cancel <file>          # Discard your local changes, take the vault version
# or
dssc co -lock <file>        # Lock and keep your changes (merging manually)

“Incorrect vault URL” errors after a server move

The server moved. Update your workspace:

1
2
dssc setvault sync://new-server/Modules/TopChip
dssc pop                    # Refresh with the new URL

Stale locks after a workstation crash

dssc cancel releases a lock from the same machine. If you locked from a workstation that crashed and can’t come back, contact an admin for a force-cancel on your behalf. Some sites automate this with a trigger that releases locks older than N days.

“Module is frozen” errors

The module administrator set the freeze flag (often during a tape-out window). All check-ins are rejected until the freeze is lifted. Nothing to do but wait or escalate — the freeze exists deliberately to prevent last-minute changes during a critical milestone.


Conclusion

DesignSync is not Git with a different syntax — it embodies a fundamentally different philosophy. Git trusts engineers to merge concurrent edits; DesignSync prevents concurrent edits entirely. Git is distributed; DesignSync is deliberately centralized. Git treats history as local until pushed; DesignSync writes to the vault on every check-in.

For hardware engineers, these are not limitations — they are features. A layout database that two people accidentally modified simultaneously is not a merge conflict to resolve; it is a corrupted file that might cost weeks to rebuild. Pessimistic locking, centralized vaults, and manifest-based hierarchical snapshots exist because the cost of getting it wrong in silicon is enormous.

The transition from Git to DesignSync is smoother once you stop fighting the model and understand why it is built the way it is. Lock before you edit, check in often with meaningful comments, use tags for every milestone, and let the mirror infrastructure handle geographic distribution. The tooling will stay out of your way.

When you want to… Use…
See what’s going on dssc showstatus
Get files from vault dssc pop
Edit a file dssc co -lock <file>
Save changes to vault dssc ci -comment "..." <file>
Discard changes dssc cancel <file>
See your changes dssc diff <file>
See file history dssc ls -hist <file>
Mark a milestone dssc tag -rec <TAGNAME>
Start parallel work dssc mkbranch <branchname>
Get specific version dssc pop -get @<TAG>
Add a new file dssc ci -new -comment "..." <file>
See who’s editing what dssc ls -locked

Comments