FPGA や CPLD は用途や機能が決まっている ASSP とは異なり、自由に かつ必要な機能だけを盛り込めます。

真っ白なキャンバスに絵を描くように、空っぽな箱(実際は空っぽではありませんが)に設計者が論理回路を作りこんでいく(デザインする)イメージです。自由に設計できるだけに、RTL 設計者は FPGA や CPLD に対する正しい設計手法を整理・確立し、特性を理解していないと、「シミュレーションで動いたのに、実機で動かない」とか「デバイスを冷やしたら動いた」などと言う不安定は事態が起こり得ます。これらはほとんどの場合がタイミングの問題から来ています。つまり “信頼度の低い論理回路がインプリメントされている” ことに他なりません。

信頼性の高い論理回路を構築するには、FPGA や CPLD を RTL 設計していく上でポイントとなるデザイン・テクニックの基本を学ぶことが重要です。

今回は、その記述テクニックをご紹介する前に、デジタル論理回路設計における「同期設計と非同期設計の違い」について触れておきたいと思います。

はじめて FPGA / CPLD の RTL設計をするユーザー必見です。

FPGA/CPLD 設計は同期化設計に尽きる!

インテルの FPGA や CPLD に限ったことではなく、すべての FPGA / CPLD メーカーに共通して言えることです。

それを理解する上で まず、同期、非同期のメリットとデメリットを理解しましょう。

同期回路とは

『同一クロックの同一エッジに同期して動作する回路系』を言います。

従って、同一クロックであっても逆位相のエッジを使用する場合は、同一クロックと見なしません。

また、基本的には単一クロック同期が望ましいです。異なるクロック間での信号の授受は非同期回路となり、非同期入力に対する適切な処理が必要になります。

Article header library 119381 pic01  1
同期回路のメリット 同期回路のデメリット
  • タイミングが取りやすい
  • グリッチ・フリーのシステムが構成可能
  • 高速動作が可能
  • デバッグがしやすい
  • 消費電力が大きい
  • 回路規模が大きくなりやすい

 

同期設計のデザイン例を VHDL 記述、VerilogHDL 記述に示します。

VHDL VerilogHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity s_counter is
port (
 clk : in std_logic;
 enable : in std_logic;
 q : out std_logic
);
end s_counter;

architecture sync_pld of s_counter is
begin

process (clk)
 variable cnt : std_logic_vector(2 downto 0);
begin
 if enable = '0' then
  cnt := cnt;
 elsif (rising_edge(clk)) then
  cnt := cnt + 1;
 end if;
  q <= cnt(2);
end process;

end sync_pld;

module s_counter (clk, enable, q);
input clk, enable;
output q;

reg [2:0] cnt;

always @(posedge clk)
 if (enable)
  cnt = cnt+1;
 else
  cnt = cnt;


assign q = cnt[2];

endmodule

非同期回路とは

『同一クロックの同一エッジに同期して動作しない回路系』を言います。

従って、同一クロックであっても異なるクロック・エッジで動作する回路は非同期回路となります。

リップル・クロックは、その最たる例です。また、内部で分周した出力を再利用することも源振クロックに対し非同期クロックとなります。

Article header library 119381 pic02  2
非同期回路のメリット 非同期回路のデメリット
  • 回路規模が小さい
  • 消費電力が小さい
  • タイミングが取り難い
  • 動作周波数が低い
  • タイミング・シミュレーションが難しい

 

非同期設計のデザイン例を VHDL 記述、VerilogHDL 記述に示します。

VHDL VerilogHDL

library ieee;
use ieee.std_logic_1164.all;

entity a_counter is
port (
 clk : in std_logic;
 enable : in std_logic;
 q : out std_logic
 );
end a_counter;

architecture async_pld of a_counter is
 signal cnt2, cnt1, cnt0: std_logic:='0';
begin
q0:process (clk) begin
 if (enable='0') then
  cnt0 <= cnt0;
 elsif rising_edge (clk) then
   cnt0 <= not cnt0;
 end if;
end process q0;

q1:process (cnt0) begin
 if rising_edge (cnt0) then
  cnt1 <= not cnt1;
 else
    cnt1 <= cnt1;
 end if;
end process q1;

q2:process (cnt1) begin
 if rising_edge (cnt1) then
    cnt2 <= not cnt2;
 else
    cnt2 <= cnt2;
 end if;
end process q2;


 q <= cnt2;

end async_pld;

module a_counter (clk, enable, q);
 input clk, enable;
 output q;

 reg cnt0, cnt1, cnt2;

always @(posedge clk) begin
 if (enable)

     cnt0 = ~cnt0;
 else

     cnt0 = cnt0;
 end

always @(posedge cnt0)
 cnt1 = ~cnt1;

always @(posedge cnt1)
 cnt2 = ~cnt2;

assign q = cnt2;

endmodule

 

逆位相クロックを使用したデザイン例を VHDL 記述、VerilogHDL 記述に示します。

Article header library 119381 pic03  1
VHDL VerilogHDL
library ieee;
use ieee.std_logic_1164.all;

entity rev_clk is
port (
 clk : in std_logic;
 data : in std_logic;
 q : out std_logic
 );
end rev_clk;

architecture rev_clk_pld of rev_clk is
 signal int0, int1: std_logic;

begin
process (clk) begin
 if (rising_edge(clk)) then
  int0 <= data;
 else
  int0 <= int0;
 end if;
end process;

process (clk) begin
 if (falling_edge(clk)) then
  int1 <= int0;
 else
  int1 <= int1;
 end if;
end process;
 q <= int1;
end rev_clk_pld;
module rev_clk (clk, data, q);
 input clk, data;
 output q;

 reg int, q;

always @(posedge clk)
 int = data;

always @(negedge clk)
 q = int;

endmodule

以上をふまえて

FPGA や CPLD を使ったシステムの高いデザイン品質を確保するための基本的な考え方は、単一クロックによる同期設計です。

FPGA/CPLD が大規模になるにつれて、高速性を維持しながらも柔軟性を確保するために各デバイス・ベンダーから様々なインターコネクトの方式が提案されています。

しかしながら、一つのデバイス全体を通じてあらゆるデバイス内のディレイが均一になるように配置することは現実として不可能です。

さらに、これらのディレイは、電圧変動、周囲温度、ロットのバラツキなどの外部要因によって度々変動します。

このような条件の下で非同期設計を行うとクロック信号とデータ信号との間で競争が発生します。時には、データがクロックを追い越してしまう『すっぽ抜け』の状態が発生します。

このようなことを防ぐためには、インテルが推奨する最悪条件を維持しながら同期設計をおこなう必要があります。

同期設計を行う限り、デバイス内でクロック・スキューが最小になるように調整されていますので、『すっぽ抜け』を心配する必要はありません。

そのため唯一注意することは、外部からの入力信号のセットアップ・タイムとホールド・タイムを確保するだけになるのです。

これらの点を意識して、より信頼性の高いデジタル論理回路設計を構築して欲しいと思います。
今回は FPGA / CPLD 設計の基本となる同期回路と非同期回路について説明しました。


おすすめ記事/資料はこちら

FPGA って何者?
Beryll の FPGA でクロック同期によるLチカ![#1/3]
[RTL 設計ビギナー必見] 非同期信号を入力した際のシステムへ与える影響
FPGA/CPLD の動作特性について