Signoff arguments go wrong when two engineers mean different things by "domain". Fix the definition once, and every later lesson can use it without hedging.
A crossing is a signal launched by a flop on one clock and captured by a flop on another clock. Only the two endpoint flops matter: the combinational logic between them, however deep, does not change the answer.
If both flops sit on the same clock net, the path is an ordinary synchronous path, however slow or fast the clock is. If the nets differ, it is a crossing, however close the frequencies are.
A clock domain is the set of sequential elements driven by one clock net, plus the combinational logic between them. The clock that drives the capturing flop decides which domain a path endpoint belongs to. There is one source of truth, and it is the clock net in the netlist, not the block diagram, not the frequency, and not the designer's intent.
Path | Crossing? |
|---|---|
Flop on clk_a to flop on clk_a | No: ordinary synchronous path |
Flop on clk_a to flop on clk_b (any frequencies) | Yes, even at identical frequencies |
Flop on a divided clock to a flop on its source clock | Yes: different nets |
Flop on a gated clock to a flop on the ungated source | Yes: different nets (see the generated clocks lesson) |
Combinational output of domain A into domain B logic (no flop yet) | The crossing is at the first flop that captures it; trace the path to that flop |
Two flops on the same net, different clock-tree branches | No: one net, one domain (skew is a timing matter, not a crossing) |
A structural analysis builds the same picture: for every flop, which clock net drives it, and for every flop-to-flop path, whether the launch and capture nets differ. That pair list is the crossing list, and everything downstream (classification, synchroniser checks, waivers) hangs off it. An incomplete clock list therefore means a silently incomplete crossing list.
Yes, unless the two pins are the same net. Two independent oscillators give unrelated clocks at the same nominal frequency, so every flop-to-flop path between the blocks is a crossing.
Three capture endpoints, hence three crossings to classify, all launched (combinationally) from A and captured on clk_b. The fix must cover every capture flop, not just one.