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

Clash Manifests

Clash generates a clash-manifest.json in each HDL output directory. The extension parses this to:

  • Determine the top component name and ports
  • Discover dependencies between components
  • Extract clock domain information
  • Collect all Verilog files (including sub-modules)

Manifest Structure

{
  "components": ["top_entity"],
  "dependencies": { "transitive": ["Example.Project.accum"] },
  "domains": {
    "Dom50": {
      "active_edge": "Rising",
      "init_behavior": "Defined",
      "period": 20000,
      "reset_kind": "Asynchronous",
      "reset_polarity": "ActiveHigh"
    }
  },
  "files": [
    { "name": "top_entity.v", "sha256": "..." },
    { "name": "top_entity.sdc", "sha256": "..." }
  ],
  "top_component": {
    "name": "top_entity",
    "ports_flat": [
      { "direction": "in", "is_clock": true, "name": "CLK", "width": 1 },
      ...
    ]
  }
}

Dependency Graph

ClashManifestParser.buildDependencyGraph() recursively follows dependency manifests and returns components in post-order (leaves first, top last). Each component’s dependencies list is reduced to direct only — transitive deps are removed via removeTransitiveDeps to prevent Yosys “Re-definition of module” errors during OOC synthesis.

Domain Analysis

Clock domain periods in the manifest are in picoseconds. The parser converts to MHz: frequencyMHz = 1_000_000 / periodPs

For example, Dom50 with period: 20000 (20 ns) → 50 MHz. This is the value place & route is constrained against — see Timing Analysis.

Which domain counts. domains lists every domain the design mentions, so the parser never chooses one by name. parseManifest walks top_component.ports_flat, and for every is_clock port pairs it with the domain that port declares, producing topClocks: TopClock[] — port, domain, period, and frequency, all as stated. A port with no domain, a domain the manifest does not define, or a domain without a usable period throws: the manifest contradicts itself and no substitute would be honest.

pnrTargetClock(manifest) then answers the one question place & route asks — which single clock to constrain against. Empty topClocks means no target (a combinational design); several ports sharing one domain is one target; two or more domains throws, because nextpnr’s --freq applies to the whole design and cannot satisfy both.