マルチプレクサ(Multiplexer)で選択されたクロックに対し、SDCファイルでTiming制約を入出力信号にかけるときに悩んだのでメモしておく。文章だとわかりづらいと思うので図を描いた。例えば、以下のような状況。
間違った書き方
この場合、1つのデータバス出力信号 DATA_OUT に対して、2種類の異なる周波数のクロック CLOCK_A、CLOCK_Bに対応したタイミング制約をかける必要がある。例えば下記のように書いた場合、うまく制約がかからない。
create_clock -period 25.0 -name clock_a [get_ports CLOCK_A]
create_clock -period 30.0 -name clock_b [get_ports CLOCK_B]
set_output_delay -clock clock_a -max 5.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_a -min 1.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_b -max 4.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_b -min 0.5 [get_ports {DATA_OUT}]
この場合、DATA_OUTに対する制約が上書きされてしまう。
正しい書き方
1つのデータバスに2種類以上の制約をかけるには、下記のように-add_delay optionを追加して、制約が上書きされないようにする必要がある。
create_clock -period 25.0 -name clock_a [get_ports CLOCK_A]
create_clock -period 30.0 -name clock_b [get_ports CLOCK_B]
set_output_delay -clock clock_a -max 5.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_a -min 1.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_b -max 4.0 [get_ports {DATA_OUT}] -add_delay
set_output_delay -clock clock_b -min 0.5 [get_ports {DATA_OUT}] -add_delay
また、CLOCK_AとCLOCK_Bは Multiplexer で選択されるため、両方が同時に使用されることない。つまりCLOCK_AとCLOCK_Bは排他の関係にあるわけだが、これをちゃんと教えてやらないとTiming Analyzerが両方のCLKが動作する状況を想定して解析を行ってしまう。必要のない条件がある中で最適化したら、当然ながら解析結果が悪くなる可能性がある。そのため、以下の文を追加してCLK_AとCLK_Bが排他であることを教えてやる。
set_clock_groups -exclusive -group {CLOCK_A} -group {CLOCK_B}
まとめると、上の図で制約をかけるときは以下のようにしてやれば良いということになる。
create_clock -period 25.0 -name clock_a [get_ports CLOCK_A]
create_clock -period 30.0 -name clock_b [get_ports CLOCK_B]
set_output_delay -clock clock_a -max 5.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_a -min 1.0 [get_ports {DATA_OUT}]
set_output_delay -clock clock_b -max 4.0 [get_ports {DATA_OUT}] -add_delay
set_output_delay -clock clock_b -min 0.5 [get_ports {DATA_OUT}] -add_delay
set_clock_groups -exclusive -group {CLOCK_A} -group {CLOCK_B}
この例は出力信号だが、set_output_delayをset_input_delayに置き換えれば入力でも同じ……はず。記事を書くにあたって、AlteraのSDC記述例のページを参照しながら書いた。