目的 接続 電流制限抵抗 LEDフラッシュ デバッグ方針 生き死に判定 パルスの引き伸ばし ステートマシン 戻る

NP1003使い方の手引き 1.LED

 NP1003のデバッグ用LEDを使う方法を説明します。

デバッグ用LEDの概要

デバッグ用LEDの目的

 NP1003には4つのデバッグ用LEDが付属しています。LEDを使うと、オシロスコープやロジックアナライザを使わなくても、手軽にFPGAの出力する端子の状態を監視できます。
 たとえば、以下のような目的に使用することを想定しています。

  • FPGAの動作確認
  • ステートマシンの状態確認
  • アドレスカウンタ等の状態確認
 ただし、回路の状態がものすごい速さで動作しているときには、LEDはの点滅は速すぎて目では確認できません。そんな状況でもLEDはいろんな回路の動作を教えてくれます。

LEDの接続

 このLEDの接続は下の図のようになっていて、そのままではFPGAのどこの端子とも接続されていません。


 FPGAの出力でLEDを光らせるためには、ユーザーが配線を行います。FPGAの出力でユーザーが自由に使用できるのは、USER0〜USER36の37個の端子なので、このうちの好きな4つをLEDに配線します。なお、FPGAの出力がHの時、LEDは光ります。


電流制限抵抗

 LEDには直列で150Ωの電流制限抵抗を入れておりますので、追加の抵抗は不要です。また、本LEDは低消費電流のため、FPGAのH時の出力電流で十分に光らせることができます。

サンプル回路

LEDフラッシュ

 まず最初にFPGA工作を始めたとき、電源が投入され、FPGAが確実に動き出したことを確認するため、LEDをピカピカと光らせると安心できるでしょう。
 ここでは、最初のアプリケーションとして、LEDフラッシュ回路の作り方を解説します。
 単純にLEDを点滅させるだけなら、LEDにシステムクロックを入れれば点滅しますが、目に見えない速さで点滅してしまいます。目で容易に確認するためならば、点滅の速度は5Hz程度がよいでしょう。システムクロックを50MHzとすると、点滅のために速度を1000万分の1に落とす必要があります。
 具体的な記述は次のようになります。

    USER : out std_logic_vector(31 downto 0)
  );
end main;
     ・
     ・
     ・

signal LED   : std_logic;
signal count : std_logic_vector(23 downto 0);
          ・
          ・
begin
USER(15) <= LED;

process (CLK) begin
  if(CLK'event and CLK='1') then
    if(count = 5000000) then
      count <= (others=>'0');
      LED   <= not LED;
    else
      count <= count + 1;
    end if;
  end if;
end process;

 この記述では、システムクロック500万回で信号LEDの状態を反転させていますので、LEDはシステムクロックの1000万分の1の周期の信号となります。よって、システムクロックが50MHzのとき、LEDは5Hzで点滅します。
 また、上の例では、USERという名前の出力信号を直接ON/OFFせずに、LEDという内部signalをON/OFFさせ、それをUSER信号に出力しています。
 なぜこのようなことをしたかというと、2つの理由があります。1つ目の理由は、VHDLでは出力ピンは回路の内部で参照できないということで、もうひとつの理由は、USER15以外の信号に出力するような変更を容易にするためです。
 次の例は、出力ピンのUSER(15)を内部で参照しようとしている間違った例で、論理合成できません。

    USER : out std_logic_vector(31 downto 0)
  );
end main;
     ・
     ・
     ・
process (CLK) begin
  if(CLK'event and CLK='1') then
    if(count = 5000000) then
      count  <= (others=>'0');
      USER(15) <= not USER(15); ・・・USER(15)は出力だから、内部で参照はできない
    else
      count <= count + 1;
    end if;
  end if;
end process;

 このような場合で、どうしても出力ピンを参照したいならば、次の例のように出力ピンのタイプをoutではなく、inoutで宣言します。

    USER : inout std_logic_vector(31 downto 0)
  );
end main;
     ・
     ・
     ・
process (CLK) begin
  if(CLK'event and CLK='1') then
    if(count = 5000000) then
      count  <= (others=>'0');
      USER15 <= not USER15; ・・・USER15は入出力だから、内部で参照できる
    else
      count <= count + 1;
    end if;
  end if;
end process;

 このようにできることはできるのですが、やはり内部信号を作り、FPGAの外への出力は、内部信号と出力信号のマッピングで行ったほうが楽だと思います。

ピンの割り当て

 作成した回路を、特定のピンに割り当てるためには、UCFファイルを使用します。UCFファイルの使い方は、前章のピン配置の固定をご覧ください。

LEDでデバッグするノウハウ

方針

 LEDでのデバッグはオシロスコープとちがって、波形を観察することや、測定することはできません。
 しかし、LEDの明るさの具合や点滅の速度は、回路に起きているいろいろなことを教えてくれます。また、LEDが光るためには、プローブを当てる必要もありません。プローブという手作業が不要であり、疲れた目に新鮮に訴えかけてくるため、回路が生きているか死んでいるかを判断するにはとても便利です。
 この節では、LEDを使ってデバッグを行うコツのようなものを紹介します。

生き死に判定

 もっとも簡単で有効な使い方は、回路の生き死に判定です。
 FPGAで回路を作成するとき、ちょっとした記述ミスで回路の一部分あるいは全体が動かなくなってしまうことがあります。そのような場合、本来なら入力やカウンタによって変化するはずの出力信号が、HやLに固定されてしまいます。

 例えば上の図で、回路1はRS232Cの受信回路で、回路2はASCIIコードで大文字を小文字に変換して出力する回路と仮定します。
 ところが、回路2のイネーブル信号が誤ってGNDに接続されているため、回路2は常に同じ値を出力しつづけ、正しく動作しません。

 そんなとき、回路2の出力をLEDに出力させ、いろいろな入力を与えてみても変化がなければ、回路2が動作していないことがわかります。
 次に、回路1の出力をLEDに出力させ、いろいろな入力を与えてみて変化があれば、回路2の動作が不良であることから、不具合の個所を特定できます。
 このようなデバッグにLEDはとても便利です。

process (CLK) begin
  if(CLK'event and CLK='1') then
    if(EN = '1') then
      if((INDATA >= x"61") or (INDATA <= x"7a")) then
        OUTDATA <= INDATA - x"20";
      else
        OUTDATA <= INDATA;
      end if;
    end if;
  end if;
end process;

 このようなことは、例えば、VHDL上でのネットの名前のつけ間違いなどによって容易に起こります。自分が正しいと思って設計した回路を疑うのはとても難しいことですから、このようなケースではデバッグに時間を要するかもしれません。

鋭いパルスの引き伸ばし

 もし、100MHzまで見えるオシロスコープをお持ちならば、100MHzのパルスも観察できるでしょう。しかし、20MHzまでしか見えないオシロスコープでは100MHzは見えません。
 パルスが来たことだけが知りたい場合。つまり、パルスの位置や時間幅は気にせずに、その存在だけが知りたい場合があります。
 たとえば、微分回路といって、入力信号のH→L、あるいはL→Hへの変化に反応する回路があります。この回路の出力は、1クロックの幅しかありません。

 そのようなとき、パルスの幅を十分に長く引き伸ばして、人間の目でも判断できるようにすれば、パルスの到来をLEDの光でわかるようになります。引き伸ばす時間は、ミリ秒のオーダーがあれば、人間の目にはわかるでしょう。

 このようなことを実現するためには、タイマーを使います。
 いま、回路が100MHzのクロックで動いているとします。このとき、幅の鋭い10nsのパルスがやってきたとします。これをLEDにつないでも、LEDは10ns間光を出しますが、早すぎて人間の目には見えません。
 これを人間の目に見えるようにするためには、パルスの幅を十分に長くしてやります。そのためには、この例では24ビットのカウンタを用意します。24ビットのカウンタを100MHzのクロックでフリーランさせた場合、16,777,216/100MHzですから、16ミリ秒でカウンタがオーバーフローします。カウンタが動作中はLEDが点灯しますので16ミリ秒の間、LEDが点灯します。これなら人間の目に見えます。

signal   COUNT     : std_logic_vector(23 downto 0);
constant COUNT_MAX : integer := 16777215;
  ・・・
process (CLK) begin
  if(CLK'event and CLK='1') then
    if(COUNT /= 0) then
        COUNT <= COUNT - 1;
    elsif(DIN = '1') then
        COUNT <= conv_std_logic_vector(COUNT_MAX,24); 
    end if;

    if(COUNT /= 0) then
        LED_O <= '1';
    else
        LED_O <= '0';
    end if;
  end if;
end process;

あまり動かないステートマシンのデバッグ

 ステートマシンには、SDRAMのRAS、CAS制御のように、非常に高速に動作するものもありますが、すべてのステートマシンがクロックの限界で動作しているわけではありません。システムの全体を統括して、動作モードを決めるようなステートマシンは、人間の追いつく速さで動作しているかもしれません。
 そのようなステートマシンの動作や遷移を観察するのにも、LEDは最適です。