FFのリセット

[] [] []


FFのリセットは負論理の非同期リセットを使うのが一般的だが、FPGAファミリやブロックによっては必ずしもそうなっていない。

FF

ブロックの図

Intel

Xilinx

Logicブロック

FF

(*1)

非同期リセット(*2)

/負論理

リセット値0/1

非同期/同期リセット

/負論理(*3)

リセット値0/1

IOブロック

FF

DSPブロック

FF

非同期リセット

/負論理

リセット値0

同期リセット

/負論理(*3)

リセット値0

RAMブロック

FF

(*1)LogicブロックのFFLAB,Slice単位でリセットラインを共有している

(*2)同期リセットはLUTを使ってD入力とANDをとる回路に合成される。

(*3)Spartan6,7seriesFFのリセット端子は正論理になっており、

  RTLを負論理で書くとLogicブロックのLUTでリセットを反転した回路に合成される。

そこで、どのFPGAファミリでも使えるRTL記述するには次のようにするとよい

(1) 原則、FFは正論理の非同期リセットにする

これはSpartan6,7seriesが正論理で、その他は正負どちらでもよいので、正論理の方に合わせておけばよいという意図である。もっとも既存のRTL記述を負論理から正論理に書きなおすのは大変なので、書きなおし量とのトレードオフになる。

// 正論理の非同期リセット

always @(posedge clk or posedge rst) begin

  if(rst)

      d_reg <= 8'd0;

  else

      ...

end

(2) ただし、DSPブロックのFFRAMブロックの出力FFにはリセットを付けない

これはIntelが非同期リセットでXilinxが同期リセットなので、どちらでも使えるようにするにはリセットなしにするしかないからである。

RAMの出力FFはリセット解除したらすぐRAMの出力値に変わってしまうので、リセットを付けても付けなくても大差ない。

DSPFFは前段のリセット値が伝搬するように、リセット期間を数クロック確保すれば問題ないが、シミュレーション上はFFの初期値が不定値xになるので、不定値のフィードバックループは作らないように注意した方がよい。

// 乗算器のFFにリセットは付けない

always @(posedge clk) begin

  a_reg <= ain;

  b_reg <= bin;

  p_reg <= a_reg * b_reg;

end

assign ain = p_reg + cin;

のような不定値のフィードバックループ

を作らないように注意

 

// RAMの出力FFにリセットは付けない

always @(posedge clk) begin

  if(we) ram[addr] <= din; // write port

  dout <= ram[addr]; // read port

  dout_reg <= dout;  // 出力FF

end


[] [] []