目次

Lattice CPLD (FPGA)

 秋月電子で販売されているLatticeSemiconductorのCPLD
 基板を入手しました。CPLDとうたってありますが、内部
 は、FPGAでした。



 開発環境はDiamondになっています。



 開発環境Diamondは、LatticeSemiconductorのWebサイト
 からダウンロードしましたが、1.3GバイトほどありUSA
 が真夜中の時間帯を利用しました。



 目的のファイルをダウンロードするには、LatticeSemiconductor
 サイトへの登録が必要です。登録料、年会費等は不要ですが。

 開発環境Diamondをインストールしてから、基板にUSBケーブルを
 接続すると、次のようにLEDが点滅しました。



 このDemoを実現するVHDLコードは、多分
  次のようになっているはず。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tcpld is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- output
    LOUT   : out std_logic_vector(7 downto 0) -- ;
  );
end tcpld ;

architecture Behavioral of tcpld is
  -- clock generator
  signal iCNT  : std_logic_vector(18 downto 0) ;
  -- decoder
  signal iLCNT : std_logic_vector(7 downto 0);
begin
  -- output
  LOUT <= not iLCNT ;

  -- decoder
  iLCNT <= X"55" when ( iCNT(18) = '1' ) else
           X"aa" ;

  -- clock generator
  process (nRESET,CLOCK)
  begin
    if ( nRESET = '0' ) then
      iCNT <= (others => '0') ;
    elsif rising_edge(CLOCK) then
      iCNT <= iCNT + '1' ;
    end if ;
  end process ;

end Behavioral;

 Lattice Semiconductorのサイトから、デモ用Zipファイル
 をダウンロードし、内容を確認すると、次のVerilogHDLの
 コードを見つけました。

module Default_w_standby_top (stdby_in,stdby1,osc_clk,led0,led1,led2,led3,led4,led5,led6,led7);
  input	 stdby_in ;
  output stdby1, osc_clk ;
  output led0,led1,led2,led3,led4,led5,led6,led7 ;

  wire  stby_flag ;
  reg   [21:0] cnt ;

  //assign clkout = clki ;
  //assign rstout = rstn ;

  // Internal Oscillator
  defparam OSCH_inst.NOM_FREQ = "2.08";	//  This is the default frequency

  OSCH OSCH_inst( .STDBY(stdby1 ), 	// 0=Enabled, 1=Disabled also Disabled with Bandgap=OFF
                 .OSC(osc_clk),
                 .SEDSTDBY());		//  this signal is not required if not using SED - see TN1199 for more details.

  pwr_cntrllr pcm1(.USERSTDBY(stdby_in ),.CLRFLAG(stby_flag ),.CFGSTDBY(1'b0 ),.STDBY(stdby1 ),.SFLAG(stby_flag));

  //  LED BLinking test FPGA for LATTICE X02-1200
  //  Turn on every other LED @ 1/2 second

  always @(posedge osc_clk or posedge stdby_in)
    if (stdby_in)
      cnt <= 0;
    else
      cnt <= cnt + 1;

  assign led0 = stdby_in ? 1'b1 : cnt[20];
  assign led1 = stdby_in ? 1'b1 : ~cnt[20];
  assign led2 = stdby_in ? 1'b1 : cnt[20];
  assign led3 = stdby_in ? 1'b1 : ~cnt[20];
  assign led4 = stdby_in ? 1'b1 : cnt[20];
  assign led5 = stdby_in ? 1'b1 : ~cnt[20];
  assign led6 = stdby_in ? 1'b1 : cnt[20];
  assign led7 = stdby_in ? 1'b1 : ~cnt[20];

endmodule

 デモに関連したVerilogHDLを見る限り、こちらで
 考えているVHDLコードと、ほぼ同じことをやって
 います。

 VerilogHDLコードの中に、利用クロックを2.08MHzと
 宣言しています。従って、21分周すると約2Hzでの
 LEDをブリンクする処理とわかります。

 CPLD/FPGAを動かす場合、最終ピン割当てが必要です。
 Diamondを利用するために、その定義がどこにあるのかを
 調べると、LPFという拡張子のconstraint fileに記述が
 ありました。

BLOCK RESETPATHS ;
BLOCK ASYNCPATHS ;
FREQUENCY NET "osc_clk_inferred_clock" 2.080000 MHz ;
BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;
IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;
LOCATE COMP "stdby_in" SITE "69" ;
LOCATE COMP "stdby1" SITE "38" ;
LOCATE COMP "osc_clk" SITE "40" ;
#
LOCATE COMP "led0" SITE "97" ;
LOCATE COMP "led1" SITE "98" ;
LOCATE COMP "led2" SITE "99" ;
LOCATE COMP "led3" SITE "100" ;
LOCATE COMP "led4" SITE "104" ;
LOCATE COMP "led5" SITE "105" ;
LOCATE COMP "led6" SITE "106" ;
LOCATE COMP "led7" SITE "107" ;

 ピンアサインは、「LOCATE COMP "led0" SITE "97" ;」で
 指定するとわかります。

 クロックは、LPFファイル中で指定できるようです。

 FREQUENCY NET "osc_clk_inferred_clock" 2.080000 MHz ;

 CPLD/FPGAには、内部ブロックとピンを接続する
 バンクが存在するので、利用電圧とI/Oタイプを
 指定しています。

BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;
IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;

 コメントは、#を利用するようです。

 ダウンロードしたマニュアルには、1200ZEと7000HEの
 ピン対応表があります。ピン番号は、端子互換になる
 ようになっています。

 基板上のLEDとスイッチだけでは、やりたいことが
 できないので、左右に翼のように基板をつけます。



 基板上に3端子レギュレータがあるので、+5Vを
 接続できるようにしました。+5Vは、USBから供給
 するのが、最も楽なのでアダプタを利用しました。



 Diamondの使い方をマスターするために、次のような
 動作をするVHDLコードを作成して、ダウンロードして
 みます。



 出力パターンを変えるだけなので、カウント値により
 上位4ビットが点灯、消灯になるようにします。

 内蔵オシレータが利用できるようですが
 外部に5MHzと10MHzの発振器を接続して
 動かしてみます。

 VHDLソースコードは、以下です。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lctst is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- monitor
    SEDC   : out std_logic ;
    -- output
    LOUT   : out std_logic_vector(7 downto 0) -- ;
  );
end lctst ;

architecture Behavioral of lctst is
  -- clock generator
  signal iCNT  : std_logic_vector(22 downto 0) ;
  -- decoder
  signal iLCNT : std_logic_vector(7 downto 0);
begin
  -- output
  LOUT <= not iLCNT ;
  SEDC <= iCNT(22) ;

  -- decoder
  iLCNT <= X"F0" when ( iCNT(22) = '1' ) else
           X"0F" ;

  -- clock generator
  process (nRESET,CLOCK)
  begin
    if ( nRESET = '0' ) then
      iCNT <= (others => '0') ;
    elsif rising_edge(CLOCK) then
      iCNT <= iCNT + '1' ;
    end if ;
  end process ;

end Behavioral;

 ソースコードができれば、ピンアサインを考えることに。
 ピンアサインをDiamondでどう設定するのかをマニュアル
 で理解します。

 評価基板のマニュアルで、LEDとの接続ピンを確認します。



 デバイスには、MachXO2_7000HE-4TG144Cが使われています。
 8つのLEDがあり、ピンアサインは以下です。
   PR2A  107  LED7(LED Array)
   PR2B  106  LED6(LED Array)
   PR3A  105  LED5(LED Array)
   PR3B  104  LED4(LED Array)
   PR5A  100  LED3(LED Array)
   PR5B  99   LED2(LED Array)
   PR7A  98   LED1(LED Array)
   PR7B  97   LED0(LED Array)

 他のピンは、どういう接続になっているかを
 抜き出してみると、次のように。
J2

 1 NC                   2 VCCIO0
 3 PT36D/DONE(109)      4 PT36C/INITn(110)
 5 PT36B(111)           6 PT36A(112)
 7 GND                  8 GND
 9 PT33B(113)          10 PT33A(114)
11 PT28B(115)          12 PT28A(117)
13 PT27D/PROGn(119)    14 PT27C/JTAGen(120)
15 GND                 16 GND
17 PT25B(121)          18 PT25A(122)
19 PT22D/SDA(125)      20 PT22C/SDL(126)
21 PT18B/PCLKC0_1(127) 22 PT18A(128)
23 GND                 24 GND
25 PT17D/TDM(130)      26 PT17C/TCK(131)
27 PT15B(132)          28 PT15A(133)
29 PT14D/TDI(136)      30 PT14C/TDO(137)
31 GND                 32 GND
33 PT11B(138)          34 PT11A(139)
35 PT10B(140)          36 PT10A(141)
37 PT9B (142)          38 PT9A (143)
39 GND                 40 GND

J3

 1 VCC_1.2V            2 VCCIO1
 3 VCC_1.2V            4 NC
 5 PR24A(74)           6 PR24B(73)
 7 PR23A(76)           8 PR23B(75)
 9 GND                10 GND
11 PR21A(78)          12 PR21B(77)
13 PR18A(82)          14 PR18B(81)
15 GND                16 GND
17 PR17A(84)          18 PR17B(83)
19 PR16A(86)          20 PR16B(85)
21 GND                22 GND
23 PR11A/PCLKT1_0(92) 24 PR12B(93)/PCLKC1_0
25 PR11A(94)          26 PR11B(93)
27 GND                28 GND
29 PR9A(96)           30 PR9B(95)
31 PR7A(98)           32 PR7B(97)
33 GND                34 GND
35 PR5A(100)          36 PR5B(99)
37 PR3A(105)          38 PR3B(104)
39 PR2A(107)          40 PR2B(106)

J4

 1 VCC_3.3V            2 VCCIO3/4/5
 3 VCC_3.3V            4 NC
 5 PL3A ( 1)           6 PL3B ( 2)
 7 PL4A ( 3)           8 PL4B ( 4)
 9 PL6A/PCLKT5_0( 5)  10 PL6B/PCLKC5_0( 6)
11 PL8A ( 9)          12 PL8B (10)
13 GND                14 GND
15 PL9A (11)          16 PL9B (12)
17 PL10A(13)          18 PL10B(14)
19 GND                20 GND
21 PL12A/PCLKT4_0(19) 22 PL12B/PCLKC4_0(20)
23 PL15A(21)          24 PL15B(22)
25 GND                26 GND
27 PL17A(23)          28 PL17B(24)
29 PL19A(25)          30 PL19B(26)
31 GND                32 GND
33 PL22A/PCLKT3_0(27) 34 PL22B/PCLKC3_0(28)
35 GND                36 GND
37 PL24A(32)          38 PL24B(33)
39 PL25A(34)          40 PL25B(35)

J5

 1 NC                   2 VCCIO2
 3 PB38B/SI/SISPI(71)   4 PB37B(69)
 5 PB38A/SN(70)         6 PB37A(68)
 7 PB35B(67)            8 PB31B(62)
 9 PB35A(65)           10 PB31A(61)
11 GND                 12 GND
13 PB29B(60)           14 PB26B(58)
15 PB29A(59)           16 PB26A(57)
17 GND                 18 GND
19 PB23B/PCLKT2_1(56)  20 PB18B(54)
21 PB23A/PCLKT2_0(55)  22 PB18A(52)
23 GND                 24 GND
25 PB16B/PCLKC2_0(50)  26 PB13B(48)
27 PB16A/PCLKT2_0(49)  28 PB13A(47)
29 GND                 30 GND
31 PB12B/S0/SPISO (45) 32 PB9B(43)
33 PB12A/MCLK/CCLK(44) 34 PB9A(42)
35 GND                 36 GND
37 PB6B(41)            38 PB4B(39)
39 PB6A/CSSPIN(40)     40 PB4A(38)

 外部接続で利用できるピンを見ると
 クロック入力できるところが、複数
 あります。

 CPLD内部に発振器とPLLがあるので
 外部クロックと同期して利用する
 場合に使うことを狙っているのかも
 知れません。

 PLLは、基本周波数frと出力周波数をfoutと
 すると、次の式で記述できます。

 fout = M x fr = (m/n)xfr

 Mは、基本周波数の何倍になるのかを表し
 これが(m/n)という有理数になると考えて
 処理します。

 入手した評価基板上のCPLDは、内蔵クロックジェネレータで
 2.08MHzを出力しています。デモ用回路では、クロックを分周
 約2Hzにして利用しています。

 20ビットカウンタで分周し、約2Hzとしていますが
 2のべき乗で計算すると、最大(1024x1024-1)カウント。
 2.08x1000x1000Hz/(1024x1024)となり、1024を1000とし
 2.08x1000x1000Hz/(1000x1000)=2.08Hz。近似しないと
 約2Hzになります。

 m = 1 , n = 1024 x 1024とすると
 fout = (m/n) x fr = (1/(1024x1024)) x 2.08MHz
  これでfoutは約2Hzとなります。

 ここまで準備ができたので、最初のプロジェクトを
 作ってみます。順を追って、操作していきます。

 下準備
  新しいディレクトリを作成し、その中にVHDLファイル
  を入れておきます。



 開発環境を起動
  デスクトップ上にある、次のアイコンをダブル
  クリックして、開発環境を起動します。



  Navigation GUIが表示されることを確認します。



  新しいプロジェクトを作成するので、StartPageタブの
  中にある、Projectの中のNewをクリックします。



  プロジェクト新規作成の開始ページが現れるので
  下の方にある、「Next」をクリックします。

  プロジェクト名、ディレクトリ情報を入力する
  ページが現れます。



  「Browse」を操作し、サブディレクトリを指定します。



  プロジェクト名を入力します。



  下の方にある、「Next」をクリックすると、付加する
  ファイルを指定するページが現れます。



  今回は、ディレクトリ、VHDLコードは作成済みなので
  「Add Source」をクリックします。



  ディレクトリに格納されているVHDLファイルが見えます。



  利用するファイルをすべて選択します。



  「開く」のクリックで、次のページ表示になります。



  下の方にある、「Next」をクリックします。
  Device Selectページに遷移します。



  評価基板上のチップにあうパラメータを設定します。



  パラメータを確認したなら、「Next」をクリックします。
  論理合成に使うツールの確認が出ます。



  種々の情報が表示されるので、確認したなら
  「Finish」をクリックします。



  Reportsタブが表示され、プロジェクト関連
  情報が表示されます。



  VHDLソースコードにエラーがある場合、下にある
  ステータスエリアに、赤でファイル名と行が表示
  されます。

 クロックソース指定
  クロックソースは、LPCファイルで指定可能なので
  あえて指定は不要です。ただし、LPCファイルの中で
  指定は必要です。

  外付けのデフォルトの5MHzを利用するとして、次のように
  LPCファイルの内容を記述します。

BLOCK RESETPATHS;
BLOCK ASYNCPATHS;
LOCATE COMP "CLOCK"  SITE "56" ; # 5MHz

 I/Oバンク処理
  CPLD/FPGAのチップは、正方形になっており、この
  4辺からピンが出ています。

  4辺それぞれにバンクの割当てがあるので
  電源電圧とI/Oタイプを指定します。

  ハードウエアで、バンクごとの電圧はすべて3.3V固定
  なので、LPCファイルにそれらを指定します。

BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;

  各ピンの出力は差分でなければ、次のインタフェースの
  いずれかを利用できます。

  デモ用のLPCファイルでは、3.3VのCMOSタイプを指定して
  LEDのブリンクをやっていたので、それに合わせます。

IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;

  ここまでの情報で指定できる、LPCファイルの内容を
  書き出しておきます。

BLOCK RESETPATHS;
BLOCK ASYNCPATHS;

BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;
IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;
LOCATE COMP "nRESET" SITE "109" ;
LOCATE COMP "CLOCK"  SITE "56" ; # 5MHz
#
LOCATE COMP "LOUT[0]" SITE "97"  ;
LOCATE COMP "LOUT[1]" SITE "98"  ;
LOCATE COMP "LOUT[2]" SITE "99"  ;
LOCATE COMP "LOUT[3]" SITE "100" ;
LOCATE COMP "LOUT[4]" SITE "104" ;
LOCATE COMP "LOUT[5]" SITE "105" ;
LOCATE COMP "LOUT[6]" SITE "106" ;
LOCATE COMP "LOUT[7]" SITE "107" ;

  リセットは外付けハードウエアに入れて
  あるので、負論理で利用しました。
  拡張基板を接続して、次のようにしました。



  J2、J5を利用して外部コネクタで拡張基板に
  接続しました。

J2

 1 NC
 2 VCCIO0             extened board Vcc
 3 PT36D/DONE(109)    push switch
 4 PT36C/INITn(110)   CONNECTOR_1 0
 5 PT36B(111)         CONNECTOR_1 1
 6 PT36A(112)         CONNECTOR_1 2
 7 GND
 8 GND
 9 PT33B(113)         CONNECTOR_1 3
10 PT33A(114)         CONNECTOR_1 4
11 PT28B(115)         CONNECTOR_1 5
12 PT28A(117)         CONNECTOR_1 6
13 PT27D/PROGn(119)   CONNECTOR_1 7
14 PT27C/JTAGen(120)  CONNECTOR_2 0
15 GND
16 GND
17 PT25B(121)         CONNECTOR_2 1
18 PT25A(122)         CONNECTOR_2 2
19 PT22D/SDA(125)     CONNECTOR_2 3
20 PT22C/SDL(126)     CONNECTOR_2 4
21 PT18B/PCLKC0_1(127)CONNECTOR_2 5
22 PT18A(128)
23 GND
24 GND
25 PT17D/TDM(130)
26 PT17C/TCK(131)
27 PT15B(132)         CONNECTOR_2 6
28 PT15A(133)         CONNECTOR_2 7
29 PT14D/TDI(136)
30 PT14C/TDO(137)
31 GND
32 GND
33 PT11B(138)         CONNECTOR_3 0
34 PT11A(139)         CONNECTOR_3 1
35 PT10B(140)         CONNECTOR_3 2
36 PT10A(141)         CONNECTOR_3 3
37 PT9B (142)         yellow LED
38 PT9A (143)         push switch
39 GND
40 GND


J5

 1 NC
 2 VCCIO2             extened board Vcc
 3 PB38B/SI/SISPI(71) CONNECTOR_4 0
 4 PB37B(69)
 5 PB38A/SN(70)       CONNECTOR_4 1
 6 PB37A(68)          CONNECTOR_4 2
 7 PB35B(67)          CONNECTOR_4 3
 8 PB31B(62)          CONNECTOR_4 4
 9 PB35A(65)          CONNECTOR_4 5
10 PB31A(61)          CONNECTOR_4 6
11 GND
12 GND
13 PB29B(60)          CONNECTOR_4 7
14 PB26B(58)          CONNECTOR_5 0
15 PB29A(59)          CONNECTOR_5 1
16 PB26A(57)          CONNECTOR_5 2
17 GND
18 GND
19 PB23B/PCLKT2_1(56) external clock 5MHz
20 PB18B(54)          CONNECTOR_5 3
21 PB23A/PCLKT2_0(55) CONNECTOR_5 4
22 PB18A(52)
23 GND
24 GND
25 PB16B/PCLKC2_0(50) external clock 10MHz
26 PB13B(48)          CONNECTOR_5 5
27 PB16A/PCLKT2_0(49) CONNECTOR_5 6
28 PB13A(47)          CONNECTOR_5 7
29 GND
30 GND
31 PB12B/S0/SPISO (45) CONNECTOR_6 0
32 PB9B(43)            CONNECTOR_6 1
33 PB12A/MCLK/CCLK(44) CONNECTOR_6 2
34 PB9A(42)            CONNECTOR_6 3
35 GND
36 GND
37 PB6B(41)            CONNECTOR_6 4
38 PB4B(39)            CONNECTOR_6 5
39 PB6A/CSSPIN(40)
40 PB4A(38)            CONNECTOR_6 6

  外部クロック生成回路は、以下。



 論理合成、配置配線
  論理合成、配置配線は、メニューバーの中にある
  次のアイコンをクリックします。



  処理がどこまで進んでいるのかは、左側に表示
  されている、Processを見るとわかります。
  Processが隠れているときは、下にあるタブを
  クリックすると、出てきます。



  WarningやErrorがあると、次のようなアイコンが
  Processの中に表示されます。



  何事もなければ、Signal All Greenで、次のアイコンが
  表示されます。



 JEDECファイル生成
  CPLDというカテゴリーにチップが含まれるので
  回路情報は、JEDECファイルとして生成します。

  JEDECファイルの生成は、Processにあるチェックボックスに
  チェックを入れたのち、JEDEC Fileをダブルクリックします。




 ダウンロード
  JEDECファイルに含まれている回路情報を、CPLD/FPGAに
  ダウンロードするには、メニューバーの次のアイコンを
  クリックします。



  GUIが出てきます。



  USBケーブルを認識させるために、「Detect Cable」を
  クリックします。すでに認識されていれば、この操作は
  不要です。



  転送するJEDECファイルを指定する前に「MachXO2」を
  クリックします。



  「MachXO2」が使えるようになると、表示が変わります。



  JEDECファイルを、File Managerで操作できるか
  どうかは、アイコンのグレイ表示で判断します。



  File Managerが使える状態で、次のアイコンを
  クリックします。



  Device PropertiesのGUI上で、3情報を指定します。



  ファイルは、右側にあるアイコンをクリックして
  ブラウザを動かすと簡単に指定できます。



  3情報を指定してから、OKをクリックした後
  ケーブル接続を確認したなら、次のアイコン
  をクリックすると、JEDECファイルの内容を
  FlashROMに転送します。



  ダウンロード状況は、ステータスバーの表示
  状況で確認できます。



 終了
  すべての操作が終わったなら、プロジェクトを
  保存し、Diamondを終了します。

  プロジェクトを閉じるには、メニューバーから
  File→Close Projectとクリックしていきます。



  プロジェクト情報の保存を聞かれるので
  OKかCancelのどちらかをクリックします。



  Diamondを終了するために、メニューバーから
  File→Exitとクリックしていきます。




Knight Rider

 複数のLEDを利用したC言語の"Hello , World !"に  相当するマイコンやCPLD/FPGAの定番テスト処理と  言えば、Knight Riderでしょう。  Michel Knightの愛車であるKnight 2000の  フロントグリルに着いたランプ処理を模倣  する処理を作成してテストします。  テスト基板には、スイッチをつけてあります。  このスイッチを利用し、Knight Riderの処理とします。  仕様は、以下。  CPLD/FPGA基板上にLEDがあるので、スイッチと  クロックをどこに接続するのかを決め、LPFの  内容を指定します。 BLOCK RESETPATHS; BLOCK ASYNCPATHS; # BANK 0 VCCIO 3.3 V; BANK 1 VCCIO 3.3 V; BANK 2 VCCIO 3.3 V; BANK 3 VCCIO 3.3 V; IOBUF ALLPORTS IO_TYPE=LVCMOS33 ; # LOCATE COMP "nRESET" SITE "109" ; LOCATE COMP "CLOCK" SITE "50" ; # 10MHz LOCATE COMP "ENA" SITE "143" ; # LOCATE COMP "LOUT[0]" SITE "97" ; LOCATE COMP "LOUT[1]" SITE "98" ; LOCATE COMP "LOUT[2]" SITE "99" ; LOCATE COMP "LOUT[3]" SITE "100" ; LOCATE COMP "LOUT[4]" SITE "104" ; LOCATE COMP "LOUT[5]" SITE "105" ; LOCATE COMP "LOUT[6]" SITE "106" ; LOCATE COMP "LOUT[7]" SITE "107" ;  クロックを10MHzにしたので、分周して  ステートマシンでジョンソンカウンタを  構成します。  VHDLコードは以下。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity knight is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- 10MHz -- direction ENA : in std_logic ; -- output LOUT : out std_logic_vector(7 downto 0) --; ); end knight; architecture behavioral of knight is -- clock divider signal iMCNT : std_logic_vector(19 downto 0) ; signal iMCLK : std_logic ; -- input signal iENA : std_logic ; -- output signal iLOUT : std_logic_vector(7 downto 0) ; -- decoder signal iLOUTX : std_logic_vector(7 downto 0) ; -- counter signal iSTATE : std_logic_vector(3 downto 0) ; begin -- input iENA <= not ENA ; -- output LOUT <= not iLOUT ; -- iLOUT <= iLOUTX when ( iENA = '1' ) else X"00" ; -- decoder iLOUTX <= X"81" when ( iSTATE = "0001" ) else X"42" when ( iSTATE = "0011" ) else X"24" when ( iSTATE = "0111" ) else X"18" when ( iSTATE = "1111" ) else X"24" when ( iSTATE = "1110" ) else X"42" when ( iSTATE = "1100" ) else X"81" when ( iSTATE = "1000" ) else X"00" ; -- clock divider process( nRESET , CLOCK ) begin if ( nRESET = '0' ) then iMCNT <= (others => '0') ; elsif rising_edge( CLOCK ) then iMCNT <= iMCNT + '1' ; end if; end process; iMCLK <= iMCNT(19) ; -- Global State machine process( nRESET , iMCLK ) begin if ( nRESET = '0' ) then iSTATE <= "0000" ; elsif rising_edge( iMCLK ) then case conv_integer(iSTATE) is when 0 => iSTATE <= "0001" ; when 1 => iSTATE <= "0011" ; when 3 => iSTATE <= "0111" ; when 7 => iSTATE <= "1111" ; when 15 => iSTATE <= "1110" ; when 14 => iSTATE <= "1100" ; when 12 => iSTATE <= "1000" ; when 8 => iSTATE <= "0000" ; when others => iSTATE <= "0000" ; end case ; end if; end process; end behavioral;  ステートマシンは、iSTATEの値を次のように  変化させていきます。
  1. 0000
  2. 0001
  3. 0011
  4. 0111
  5. 1111
  6. 1110
  7. 1100
  8. 1000
 8状態を順番にデコーダに出力していきます。  デコーダは、入力値に対応したビットパターン  を出力していきます。
  1. 00000000
  2. 10000001
  3. 01000010
  4. 00100100
  5. 00011000
  6. 00100100
  7. 01000010
  8. 10000001

シーケンサ処理

 拡張基板には、1個のLEDを実装したので  このLEDをプッシュスイッチを押すごとに  点滅と消灯を切り替えてみます。  点滅と消灯という2つの状態を持つので  シーケンサ(ステートマシン)の利用で  機械的に処理します。  点滅と消灯は、セレクタでLEDにクロックを  出力するか否かで実現します。  プッシュスイッチを押すたび、ENABLEを  1か0にするには、シーケンサを以下の  ように記述します。 process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iSTATE <= "00" ; elsif rising_edge(iMCLK) then case conv_integer(iSTATE) is -- wait trigger when 0 => if ( iTRG = '1' ) then iSTATE <= "01" ; else iSTATE <= "00" ; end if ; -- dummy skip when 1 => iSTATE <= "11" ; -- wait trigger when 3 => if ( iTRG = '1' ) then iSTATE <= "10" ; else iSTATE <= "11" ; end if ; -- return first state when 2 => iSTATE <= "00" ; -- default when others => iSTATE <= "00" ; end case ; end if ; end process ; iENABLE <= iSTATE(0) ;  ジョンソンカウンタを使い、シーケンサが  00→01→11→10のように状態遷移するよう  工夫します。  隣会うビットは、必ず1ビットしか変化しない  ように状態を定義していくと、LSBをそのまま  ENABLE信号で利用できます。  プッシュスイッチは、チャタリング除去のため  シフトレジスタを利用して、L→HかH→Lの変化  を捉えてトリガーとします。 process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge(iMCLK) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;  トリガーを利用して、シーケンサは  次の状態遷移をします。  状態を4つ持ちますが、半分をLEDの点滅、もう  半分をLEDの消灯で利用できます。  シーケンサは、チャタリング除去で利用した  クロック周波数と同じにしておきます。  内部でシーケンサが動いていることをモニタする  ために、CPLD/FPGA基板上の8個のLEDを点滅して  おきます。  人間の目でLEDの点滅がわかるように  しておかないと意味がなくなるので  LEDの点滅は2Hz程度にしておきます。  これらのことを踏まえ、VHDLコードを定義します。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity lcledt is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger TRG : in std_logic ; -- output LOUT : out std_logic_vector(7 downto 0); LOUTX : out std_logic -- ; ); end lcledt ; architecture Behavioral of lcledt is -- clock generator signal iCNT : std_logic_vector(27 downto 0) ; signal iMCLK : std_logic ; -- trigger handling signal iTRG_SFT : std_logic_vector(2 downto 0) ; signal iTRG : std_logic ; -- decoder signal iLOUTX : std_logic ; signal iLOUT : std_logic_vector(7 downto 0); -- sequencer signal iSTATE : std_logic_vector(1 downto 0) ; signal iENABLE : std_logic ; begin -- output LOUTX <= not iLOUTX ; LOUT <= not iLOUT ; -- clock generator process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iCNT <= (others => '0') ; elsif rising_edge(CLOCK) then iCNT <= iCNT + '1' ; end if ; end process ; iMCLK <= iCNT(18) ; -- trigger process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge(iMCLK) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ; -- sequencer process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iSTATE <= "00" ; elsif rising_edge(iMCLK) then case conv_integer(iSTATE) is -- wait trigger when 0 => if ( iTRG = '1' ) then iSTATE <= "01" ; else iSTATE <= "00" ; end if ; -- dummy skip when 1 => iSTATE <= "11" ; -- wait trigger when 3 => if ( iTRG = '1' ) then iSTATE <= "10" ; else iSTATE <= "11" ; end if ; -- return first state when 2 => iSTATE <= "00" ; -- default when others => iSTATE <= "00" ; end case ; end if ; end process ; iENABLE <= iSTATE(0) ; -- decoder iLOUTX <= iCNT(20) when ( iENABLE = '1' ) else '0' ; iLOUT <= iCNT(27 downto 20) ; end Behavioral;  ピンアサインは、次のようにします。 BLOCK RESETPATHS; BLOCK ASYNCPATHS; # BANK 0 VCCIO 3.3 V; BANK 1 VCCIO 3.3 V; BANK 2 VCCIO 3.3 V; BANK 3 VCCIO 3.3 V; IOBUF ALLPORTS IO_TYPE=LVCMOS33 ; # system LOCATE COMP "nRESET" SITE "109" ; LOCATE COMP "CLOCK" SITE "50" ; # 10MHz # trigger input LOCATE COMP "TRG" SITE "143" ; # LED output LOCATE COMP "LOUTX" SITE "142" ; # monitor LOCATE COMP "LOUT[0]" SITE "97" ; LOCATE COMP "LOUT[1]" SITE "98" ; LOCATE COMP "LOUT[2]" SITE "99" ; LOCATE COMP "LOUT[3]" SITE "100" ; LOCATE COMP "LOUT[4]" SITE "104" ; LOCATE COMP "LOUT[5]" SITE "105" ; LOCATE COMP "LOUT[6]" SITE "106" ; LOCATE COMP "LOUT[7]" SITE "107" ;
目次

inserted by FC2 system