特定の送受FFペアの間の論理回路の遅延時間が若干過大である場合に、送端のFFのクロックを早めたり、受端のFFのクロックを遅めたりしてサイクルタイムより長い遅延を許容するというケースがあるが、このようにクロックをずらすとどのようなことが起こるかについては図2.4を見て欲しい。FF2からFF-Bへのパスは多数段のNANDゲートを通過し、遅延時間がサイクルタイムをオーバするので、FF-BのクロックにDelay(遅延)を入れてクロックタイミングを遅らせて、若干遅れて到着する信号を受け取れるようにしている。

しかし、各FFは送端だけ、あるいは受端だけと役割が決まっているわけではなく、どのFFにも入力と出力がある。図2.4に示すように、FF-Bには、クロックが遅延されていない他のFF(この図ではFF-A)の出力からの信号が論理ゲート1段程度という短い遅延で到着するという状況は、普通に存在する。

図2.4 クロックタイミングをずらすとレーシングの危険がある

この時のクロックと信号のタイミングを書くと図2.5のようになる。FF-BのクロックがDelay分だけ遅らされているので、FF-Bから次のFFまでに使える時間は、青線のように1サイクルより短くなるが、これは前の段の論理回路に時間を分け与えてしまったので、やむを得ない。

図2.5 図2.4の回路でのクロックと信号のタイミング

しかし、問題はこれだけではなく、FF-Bの入力については注意が必要である。本来、FF-AからFF-Bへの信号は、遅延されたFF-Bのクロックの次のエッジで受け取るべきであるが、赤色で示したFF-AからFF-Bへのパスの遅延時間がDelay分より短いと、1サイクル早く信号を受け取ってしまう。このように、意図したサイクルより前のサイクルに信号を受け取ってしまい論理回路の動作がおかしくなってしまう現象をレーシング(Racing)と呼ぶ。

このように、クロックエッジのタイミングを変えるとレーシングが発生しやすくなり、設計が面倒になる。このため、1つのプロセサコアなどの緊密に連携して動くユニットの中の全部のFFのクロックのタイミングは原則として揃えるという設計が一般的である。

また、このようなレーシングは図2.4のように意図的にクロックに遅延を入れた場合だけでなく、クロック分配系のSkewが大きい場合にも発生する。このため、 FF間のパスの最小遅延時間を規定し、それに満たないパスには、図2.6に示すように、バッファなどのゲートを追加して遅延時間を増やすという設計を行うのが一般的である。この最小遅延時間値は、クロック分配系のSkewが大きければより大きい遅延時間にする必要があり、遅延時間を増やすために挿入するゲート数も多くなってしまう。この、遅延時間を増やすためのゲートは、ムダに面積を使い、消費電力も増やしてしまうのでクロックSkewは小さい方がよい。

図2.6 レーシング防止のためにインバータ2個を追加

なお、安全サイドの設計で、サイクルタイムを決める最大遅延時間を計算する場合は各論理ゲートの遅延時間はバラつきの範囲の最大値、レーシングを防ぐ最小遅延時間を計算する場合は各論理ゲートのバラつきの範囲の最小値を用いて計算するので、両方を同時に満足する解が無いというケースも起こり得る。このような場合には論理回路の組み方を変えたり、FF同士の位置を近づけてクロックSkewを減らしたりするなどの対策が取られる。

実際のプロセサの設計では、各ゲートの遅延時間はLogical Effortのところで述べた簡単な式よりも精度の高い式が提示される。この式に基づいて一定のサイクルタイムを達成でき、かつ、レーシングを起こさないように最小遅延時間を満足する論理回路を設計するのは論理設計者の仕事である。

機械部品でも製造バラつきは存在するが、VLSIの場合は、トランジスタや配線といった部品が非常に小さいので製造バラつきが大きい。このため、トランジスタのドレイン電流や配線の線幅などは、中心値に対してプラスマイナス20%とか30%とかのバラつきを許容する設計が要求される。トランジスタのドレイン電流が変われば、スイッチ速度が変わる。また、配線が太くなれば、配線抵抗は小さくなるが容量が増える。というように、これらのパラメタの変化は遅延時間に影響する。このため、設計的には同一のタイミングでクロックが分配されるようになっていても、実際に製造されたVLSIではある程度のバラつきが生じる。このような製造バラつきを考慮して、クロックSkewが一定の範囲に収まるようにクロック分配系を設計するのは黒魔術師の仕事である。