信号の保持
RTL記述に書いた信号(wire変数)は、論理合成したネットリスト中に対応する信号が存在するとはかぎらないが、特定の信号を保持したい場合は合成制約keepをwire変数に指定する。
制約 |
Quartus |
Vivado |
信号の保持 |
syn_keep=1 |
keep="true"は合成だけに効くが dont_touch="true"は配置配線まで有効 |
(例1) ディレイライン
FPGAの出力信号に遅延をつけたいときはインバータを何段も直列につなげばよいが、そのままでは冗長な回路として削除されてしまうので、次のように書けばよい。
// ディレイライン (* syn_keep=1 *) wire[10:0] d_dly; (* syn_keep=1 *) wire[10:0] d_inv; assign d_inv[9:0] = ~d_dly[9:0]; assign d_dly[10:0] = ~{d_inv[9:0],d_r}; |
(例2) 非同期バスのアドレスデコード
イネーブル=1の期間のみアドレスが有効というインターフェイス仕様のとき、次のように書くとイネーブル=0の期間でもアドレスが変化するタイミングでハザードが出る可能性がある。
always @(posedge clk or posedge rst) begin if(rst) hit_r <= 1'b0; else hit_r <= (enable & (address[23:16]==8'h15))? 1'b1:1'b0; end |
そこで確実にイネーブル信号でANDをとるには次のように書けばよい。
(* syn_keep=1 *) wire match; assign match = (address[23:16]==8'h15); always @(posedge clk or posedge rst) begin if(rst) hit_r <= 1'b0; else hit_r <= (enable & match)? 1'b1:1'b0; end |