舞鶴技術研究会 情報システム分科会 技術懇談会

「PLD/FPGAの応用と設計」

舞鶴工業高等専門学校 電子制御工学科 町田秀和
http://sun1.maizuru-ct.ac.jp/control/machida , machida@maizuru-ct.ac.jp
1999年7月22日(水) 14:30〜京都ポリテクカレッジ、視聴覚教室

ロータリエンコーダ・カウンタを例題として

  1. PLD/FPGAとは何か?
  2. 同期回路設計の考え方
  3. ハードウェア記述言語(VHDL)によるパソコンでの開発
  4. PLD/FPGA評価ボードでの実験/検証
  5. まとめと今後の課題

同期式ロータリエンコーダ・カウンタの全VHDLリスト
はこのページ末尾の付録にあります。

同期式ロータリエンコーダ・カウンタのMAX+PLUS2ソースファイル
 三菱電機マイコン機器ソフトウェア社の評価ボードMU200-EA10(Etude)用に デバイス/ピン・アサインしてありますが、どのシステムにもフィッティング しなおせると思います。
 C:\MAX2WORK\RECNT のようなサブディレクトリを作成し、そこに展開してください。


(1) PLD/FPGAとは何か?   =プログラム可能なIC

← 上は Altera MAX7000
  (FPGAあるいは Complex PLDと呼ばれる)

 

← 下は Lattice GAL16V8(Simple PLDと呼ばれる)


Simple PLD
例 Lattice GAL16V8 @\200
2段論理 小規模、高速、安価

アドレスもデータもプログラム可能なROM と考えられる。

状態方程式 x[k+1]=Ax[k]+bu[k] そのものである。

FPGA(Complex PLD)
例 Altera FLEX,MAX
ゲートアレイ、大規模、複雑でもOK


PLD/FPGAのメリット


その他の選択肢との比較


Simple-PLD Lattice GAL16V8の活用例

 舞鶴高専、電子制御工学科  4学年工学実験の1テーマ  「ステッピングモータの駆動回路」  1,2,1-2相パターン発生。  学生はPCBパターン作成から、  GAL開発まで全てをこなす。


左:ナイトライダーシーケンサ LEDが左右に流れる。
右:サイコロカウンタ、6進2桁 のカウンタと、サイコロ表示


(2)同期回路設計の考え方


同期回路のプリミティブ

非同期回路の例
 リップルカウンタ


(3)パソコンでのFPGAの開発

ここで紹介するFPGAの開発手順は以下のとおりです。

  1. ESDA(電子システム設計自動化)ツール:例えば、Visual-HDL による、ブロック図、フローチャート、真理値表、ステート図、 VHDL直接、のグラフィカルな記述。
  2. ESDAツールによるコンパイルおよびシミュレーション
  3. ベンダ提供の統合開発環境(Altera MAX+PLUS2)による VHDLソースの読み込み、デバイス、ピン指定、フィッティング
  4. MAX+PLUS2によるタイミング解析、もし満足できないならば、 [3]以前に戻る。これをバックアノテーションという。
  5. MAX+PLUS2から、プリンタポート経由でバイトブラスタケーブル を用いて、FPGA評価ボードに書きこみ(ダウンロード)
  6. 実験および評価:最後はやはりオシロの使いこなしが重要。


Visual-HDL for VHDL (SII) のグラフィカル入力例

ブロック線図

フローチャート

ステート線図

真理値表

これらから、VHDL言語のソース ファイルを生成でき、
さらに、 グラフィカルなシミュレータによって デバックできる。


VHDLとは
 ハードウェア記述言語(Hardware Description Language)の一つ。
 その他、ABEL,Verilog-HDL等。
 米国防総省が1981年に提唱した VHS(Very Hige Speed)-IC HDLIEEEで標準化されている。
 Very Hard Dificult to Learn と言わ れているが、それは、回路生成が 不能なコードを書いてしまえるから で、回路生成が可能な部分だけ を勉強するなら、難しくはない。
1週間で速習も夢でない。



上の回路のVHDL記述は以下のとおり
Architecture RTL of dffe
signal q_in;
begin
  q <= q_in;
  process(ck,d,e,r) begin
    if(ck’event and ck=‘1’) then
      if(r=‘1’) then
        q_in <= ‘0’;
      elsif(e=‘1’) then
        if(d=‘1’) then
          q_in <= ‘1’;
        else
          q_in <=‘0’;
        end if;
     end if;
  end process;
end dffe; 


例題:ロータリエンコーダ・カウンタ


 ロータリエンコーダとは、光学式の回転角度センサである。
高精度でノイズに強いがカウント回路が必要。


 A相とB相の2つの出力は、互いに 90度 ずれているので、回転方向を弁別できる。 これにより、アップあるいはダウンカウント すればよい。


 また、パルスのカウント法は、右図のよう に1,2,4逓倍の数え方がある。ここでは、 A相の立ち上りだけの1逓倍でカウントする。




同期式ロータリエンコーダ・カウンタの全VHDLリスト
はこのページ末尾の付録にあります。


Visual HDL for VHDL でのシミュレーション波形


Altera MAX+PLUS2でのFPGA用回路図


同期式ロータリエンコーダ・カウンタのMAX+PLUS2ソースファイル
 三菱電機マイコン機器ソフトウェア社の評価ボードMU200-EA10(Etude)用に デバイス/ピン・アサインしてありますが、どのシステムにもフィッティング しなおせると思います。
 C:\MAX2WORK\RECNT のようなサブディレクトリを作成し、そこに展開してください。


(4)PLD/FPGA評価ボードでの実験/検証

 MAX+PLUS2により、上の回路図をコンパイル/フィッティングする。 大変高速(10秒程度)で、スムーズに作業が進む。

 パソコンプリンタポートから MAX+PLUS2のガードアダプタ を介して、バイトブラスタ・ケー ブルで、評価ボードに接続し、 ダウンロードする。
 何度でも書きかえられるので、 コストパフォーマンスは高い。

 7セグLEDによってカウント値 が、単独LEDによって回転方向 が正しく得られていることを確認。 オシロスコープで波形を確認。
 ハードウェア実現なので、超 高速カウントが可能。


(5)まとめと今後の課題

まとめ

今後の課題


付録 FPGAを使い始めるには
必要な開発装置


情報
・PLD/FPGAカンファレンス、毎年7月始めごろ東京で 行われる。かなり盛大。この業界の元気なことが良くわかる。

参考文献
Design Wave Magazine
隔月間
\1,990
小林、三上
ABELによるASICの設計技法
\3,873
小林
ASICのシステム設計
\2,500
長谷川
VHDLによるハードウェア設計入門
\2,345
J.Bhaske
VHDL言語入門
\3,262
奥川
LSIによる論理設計
\2,781
P.Naish,P.Bishop
Designing ASIC 同期設計の基本
TriEx
\3,800


謝辞
本研究の一部は、以下の補助を受けています。

資料(カタログ)等提供(順不同)

ほんとうに、どうもありがとうございました!!


ご意見ご感想はこちらまで!!


付録:ロータリエンコーダ全VHDLリスト

----------------------------------------------------
--      VHDL code generated by Visual HDL
--  Root of Design:
--  ---------------
--      Unit    Name :  recnt
--      Library Name :  updn4
----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  rotary
--  Unit    Type :  Text Unit
----------------------------------------------------
library ieee; use ieee.std_logic_1164.all;

entity  rotary  is
port (y,z,clk,A,B :  in std_logic ;
               ud : out std_logic );
end;

architecture rotary of rotary is
begin
  process (clk)
  begin
     if (clk'event and clk = '1') then
          if ((a = '0' and b = '1' and y = '0' and z = '0') or 
              (a = '1' and b = '1' and y = '0' and z = '1') or 
              (a = '1' and b = '0' and y = '1' and z = '1') or 
              (a = '0' and b = '0' and y = '1' and z = '0'))
          then
            ud <= '0';
          elsif ((a = '1' and b = '0' and y = '0' and z = '0') or 
                 (a = '1' and b = '1' and y = '1' and z = '0') or
                 (a = '0' and b = '1' and y = '1' and z = '1') or
                 (a = '0' and b = '0' and y = '0' and z = '1'))
          then
            ud <= '1';
          end if;
     end if;
  end process;
end rotary;
----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  mem
--  Unit    Type :  Text Unit
----------------------------------------------------
library ieee; use ieee.std_logic_1164.all;

entity  mem  is
port (y,z : out std_logic ;
      A,B,clk : in std_logic );
end;

architecture  RTL  of  mem  is
begin
   process (clk) begin
    if(clk'event and clk='1') then
      y<=A; z<=B;
    end if;
  end process;
end RTL;

---------------------------------------------------- 
--  Library Name :  updn4
--  Unit    Name :  rot
--  Unit    Type :  Block Diagram
----------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
entity rot is
  port (a,b,clk :  in std_logic;
             ud : out std_logic );
end rot;
 
architecture rot of rot is
  signal y,z : std_logic;
  component mem
      port (    y,z : out std_logic;
            a,b,clk :  in std_logic );
  end component;
  component rotary
      port (y,z,clk,a,b :  in std_logic;
                     ud : out std_logic );
  end component;
begin
  inst_mem: mem
    port map (y=>y,z=>z,b=>b,a=>a,clk=>clk);
  inst_rotary: rotary
    port map (y=>y,z=>z,clk=>clk,ud=>ud,a=>a,b=>b);
end rot;

----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  udcnt4
--  Unit    Type :  Text Unit
----------------------------------------------------
library ieee; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity  udcnt4  is
port (rst,ud,enb,clk :  in std_logic ;
               carry : out std_logic ;
                   q : out std_logic_vector (3 downto 0));
end;

architecture  RTL  of  udcnt4 is
signal cnt : std_logic_vector(3 downto 0);
begin
  q<=cnt;
  carry<=((not ud) and enb and (not cnt(0)) and (not cnt(1)) and (not cnt(2)) and (not cnt(3)))
      or (     ud  and enb and      cnt(0)  and      cnt(1)  and      cnt(2)  and      cnt(3) );
  process (clk) begin
    if(clk'event and clk='1') then
      if(rst='1') then
        cnt<="0000";
      elsif(enb='1') then
        if(ud='1') then
          cnt<=cnt+'1';  
        else
          cnt<=cnt-'1';
        end if;
      end if;
    end if;
  end process;
end RTL;

----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  DFFR
--  Unit    Type :  Text Unit
----------------------------------------------------
library ieee; use ieee.std_logic_1164.all;

entity  DFFR  is
	port(CLK,D : in std_logic;
              Q,QN :out std_logic);
end DFFR;

architecture  RTL  of  DFFR  is
signal Q_IN : std_logic;
begin
	Q<=Q_IN; QN<=not Q_IN;
	process(CLK) begin
		if(CLK'event and CLK='1') then
			Q_IN <= D;
		end if;
	end process;
end RTL;

----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  syncup
--  Unit    Type :  Text Unit
----------------------------------------------------
library ieee; use ieee.std_logic_1164.all;

entity  syncup  is
port (A,clk :  in std_logic ;
        enb : out std_logic );
end;

architecture  RTL  of  syncup is

component DFFR
	port(CLK,D :  in std_logic;
              Q,QN : out std_logic);
end component;

signal Q1,Q1N,Q2 :std_logic;

begin
	U0:DFFR port map(clk,A,Q1,Q1N);
	U1:DFFR port map(clk,Q1,Q2);
	enb <= Q1N nor Q2;  
end RTL;

----------------------------------------------------
--  Library Name :  updn4
--  Unit    Name :  recnt
--  Unit    Type :  Block Diagram
----------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity recnt is
  port (a,b,clk,rst :  in std_logic;
              carry : out std_logic;
                  q : out std_logic_vector(3 downto 0 ) );
end recnt;

architecture recnt of recnt is
  signal enb,ud : std_logic;
  signal ud : std_logic;
  component syncup
      port (a,clk :  in std_logic;
              enb : out std_logic );
  end component;
  component udcnt4
      port (rst,ud,enb,clk :  in std_logic;
                     carry : out std_logic;
                         q : out std_logic_vector(3 downto 0 ) );
  end component;
  component rot
      port (a,b,clk :  in std_logic;
                 ud : out std_logic );
  end component;
 
begin
  inst_syncup: syncup
    port map (a=>a,enb=>enb,clk=>clk);
  inst_udcnt4: udcnt4
    port map (rst=>rst,ud=>ud,enb=>enb,clk=>clk,carry=>carry,q=>q(3 downto 0));
  inst_rot: rot
    port map (a=>a,b=>b,clk=>clk,ud=>ud);
end recnt;
メインページに戻る