目次

USB接続教育用基板

 OSとしてWindowsを採用したPersonal Computerの中では
 従来のパラレルポートを持たず、USBのみになっている
 ことが多くなっています。特にノートPCの場合、重量や
 厚みを考え、USBのみをインタフェースにすることが多く
 なりました。

 USB接続教育用基板を動作させるまでの評価を依頼
 されたので、備忘録として残します。

 利用したUSB接続教育用基板は、以下。



 扱いなれているXilinxのSpartan-3のANシリーズを
 メインチップとしています。

 開発環境や動作を評価するためには、最低限のHDL
 記述の回路情報が必要になるので、VHDLでシステム
 クロックを分周し、LEDを点滅する回路をダウン
 ロードしてみます。

 ブロック図で示すと、以下。



 システムクロック50MHzを分周し2Hzを生成します。
 2Hzをスルーと反転した2信号にした後、I/Oピン
 から出力します。

 VHDLコードは、次のように定義しました。

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

entity tstxc3an is
  port ( 
    -- input 
    CLOCK : in  std_logic ; -- 50MHz
    -- output
    XCLK  : out std_logic_vector(1 downto 0) -- ;
  ) ;
end tstxc3an;

architecture Behavioral of tstxc3an is
  --
  CONSTANT CNTMAX  : integer := 24_999_999 ;
  CONSTANT CNTHALF : integer := 12_500_000 ;
  --
  signal iCNT : integer range 0 to CNTMAX ;
  signal iCLK : std_logic ;

begin
  -- output
  XCLK <= iCLK & (not iCLK) ;

  -- divider (generate 2Hz clock)
  process (CLOCK)
  begin
    if rising_edge(CLOCK) then
      if ( iCNT = CNTMAX ) then
        iCNT <= 0 ;
      else
        iCNT <= iCNT + 1 ;
      end if ;
    end if ;
  end process ;
  iCLK <= '1' when ( iCNT < CNTHALF ) else '0' ;

end Behavioral ;

 VHDLコードは、チップ内部の回路を記述するだけ
 なので、ピンアサインはUCFファイルで指定。

# system
NET "CLOCK"  LOC = "C10" ;

# test monitor
NET "XCLK<0>" LOC = "H1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "XCLK<1>" LOC = "G2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

 LEDには単体の表示器を利用します。




回路情報ファイル生成

 仕様を定義したならISEWebPackを利用し、ダウン  ロードに必要なファイルを生成します。  フォルダには、「\FPGA\tstxc3an」を使うことに。  プロジェクト作成   「New Project」をクリックします。   プロジェクト名、フォルダを指定後、「Next」をクリック。   チップ情報を指定後、「Next」をクリック。   提示情報を確認後、「Finish」をクリック。   プロジェクトマネージャに戻るので   チップアイコンをクリックします。   メニューバーの「Project」をクリックし、サブメニューを出します。   フォルダに含まれているファイル名が表示   されるので、VHDL、UCFの2ファイルを選択   しておきます。   「開く」をクリックし、プロジェクトにファイルが   取り込まれたなら、「OK」をクリック。   論理合成するため、左側にあるProcessesのメニュー   アイコンを利用。   記述に間違いがないかをクリックし、チェック。   「Synthesize - XST」をクリックし、論理合成。   「Implement Design」をクリックし、配置配線。   古いLicenseの場合、Warningが出されることがあります。   「Generate Programming ...」をクリックし、回路情報に   必要なファイルを作成します。   FPGAにダウンロードするファイルは、出来ています。   教育用基板には、拡張子が「bit」であるファイルを   USBシリアルで、転送するアプリがCD-ROMに入れられ   ています。

ダウンロード環境構築

 回路情報ダウンロードには、USBインタフェースを利用します。  デバイスドライバは、基板と共に入手したCD-ROMの中に  含まれています。  CD-ROMをメディアドライブに入れます。。  基板とPCをUSBケーブルで接続。  デバイスドライバをインストールするための  ウィンドウが開くので、次のようにチェック  を入れ、「次へ」をクリック。  ドライバをCD-ROMの中からインストールするため  チェックを入れ、「次へ」をクリック。  検索フォルダを指定しておきます。  (例 d:\JP\EDX_007_CD_20130523\DeviceDriver)  必要なファイルをコピー。  途中セキュリティのための確認がでますが  「続行」で進めます。  コピーが終われば、次の画面になるので  「完了」をクリック。  デバイスドライバのインストールが終わると  ダウンロードに必要なアプリケーション関連  のドライバをインストールにいきます。  ファイルをCD-ROMの中からインストールするため  チェックを入れ、「次へ」をクリック。  必要なファイルをCD-ROMからディスクに  コピーしますが、検索フォルダを指定し  余計な操作がないようにします。  途中セキュリティのための確認がでますが  「続行」で進めます。  コピーが終われば、次の画面になるので  「完了」をクリック。  仮想COMポートのアクセスを可能にする  アプリケーション関連ドライバのインス  トールに移ります。  ファイルをCD-ROMの中からインストールするため  チェックを入れ、「次へ」をクリック。  検索フォルダを指定しておきます。  (例 d:\JP\EDX_007_CD_20130523\DeviceDriver)  必要なファイルをCD-ROMからディスクに  コピー中、セキュリティ確認が出るなら  「続行」をクリック。  コピーが終われば、次の画面になるので  「完了」をクリック。  以上で、回路情報をFPGAへダウンロードする  環境が整いました。

ダウンロード

 回路情報をSpartan-3ANにダウンロードするには  次の2通りの方法があります。 BitCfg32.exeを利用する ISEWebPackのiMPACTを利用する  どちらでも、回路情報をダウンロードできますが  iMPACTを使う場合、少しだけ手順が複雑になります。  BitCfg32によるダウンロード   ダウンロード用アプリケーションソフトをCD-ROMから   利用しているコンピュータのディスクに、フォルダを   そのままコピーします。   ハードディスクにフォルダごとコピーして起動すると   次のウィンドウが開きます。   拡張子が「bit」のファイルを指定するには、「File」を   クリックしてフォルダをたどっていきます。   拡張子が「bit」のファイルを選択後、「開く」をクリック。   ファイル名が表示されたなら、「Download」を   クリックして回路情報を転送します。   ファイル転送の進行状況は、バー表示されます。   ファイルが転送され、書込みが成功するとStatusが   「Success」になります。

テスト回路の動作確認

 テスト用回路は、2HzクロックをCNAの7、8ピンに  出力してきます。  アナログマルチメータを、電圧レンジ(電圧は10Vまで測定  出来る位置にあわせる)にして、針が動くことを確認します。  マルチメータの針が動くことを確認後  LEDを接続します。

BBC BASIC10 Configuration

 最近のFPGAには、様々なコンフィグレーションが  できるようにインタフェースが工夫されています。  FTDI社のUSBチップには、BitBangモードと呼ばれる  シリアル通信のインタフェース信号を、別形式の  シリアル信号に変換して外部回路を操作することが  できます。  今回使用のFPGA基板は、Master Serialに設定すると  シリアルインタフェースでコンフィグレーション  できるようになります。  CD-ROMから「BBC BASIC10」のディレクトリを、そのまま  開発用コンピュータにコピーして利用します。  ディレクトリ(フォルダ)の内容は、以下となっています。  起動は、「BBC BASIC.exe」をダブルクリックするだけ。  Bitストリームファイルを転送するには、FPGAをMaster Serial  にしておかなければいけません。  電源をオフにしておき、S1の組み合わせを以下とします。  スイッチの設定を確認後、USBケーブルを接続し、「BBC BASIC10」を起動します。  「Device」の右にある▽で「EDX-005」を指定します。  「File Open」をクリックし、対象となるBitファイルを選択します。  「Download」をクリックし、FPGAに回路情報を転送します。  「Status」で「Success」が出ると、回路情報転送は成功です。

Generate PROM file and Download

 Spartan3ANには、チップ内部にEEPROMが含まれています。  bitファイルは、電源を落とすと揮発しますが、EEPROMに  書き込まれた情報は、揮発しません。  EEPROM用ファイルは、iMPACTを利用して生成します。  iMPACTを起動。  「iMPACT flows」を表示。  「Create PROM file」をクリック。  「PROM File Formatter」を表示。  「Spartan3AN」を選択し、「→」をクリック。  「Spartan3AN (bits)」の▽をクリック。  「xc3s200an」の選択し、「Add Storage Device」をクリック。  下のエリアに「xc3s200an」が表示されたなら、「→」をクリック。  Step 3がアクティブになったことを確認。  「Output File」のNameとLocationを指定。  Locationを変更したいときは、フォルダのアイコンを  クリックして変更します。  確定したなら、「OK」をクリックします。  bitファイル、mcsファイルを生成する画面が表示されます。  メッセージボックスの「OK」のクリック。  bitファイルを指定するため、ファイル選択の  画面が表示されます。  目的のbitファイルがあるディレクトリまで移動。  目的のbitファイルをマウスで選択し、「開く」をクリック。  バックグラウンドのMemory Mapの中に  目的のbitファイル名があることを確認。  メッセージボックスの「OK」をクリック。  「iMPACT Processes」の中に「Generate File ..」  があることを確認。  「Generate File ..」をクリック。  右のチップアイコンの下に「Generate Succeeded」と表示  されたことを確認。(何か問題があると、この表示では  ないので、戻って問題を修正します。)  「Generate Succeeded」が表示されると、bitファイルを  入れたディレクトリに、拡張子が「.mcs」であるファイル  ができています。  JTAG利用の回路情報転送には、電源とケーブルが必要ですが  ジャンパースイッチを次のように設定します。  USB接続のダウンローダは、「Cable USB II」を使います。  電源には5Vを利用しますが、安定した定電圧電源を用意します。  ダウンローダとFPGA基板は、ワイヤーに巻かれたバンドの  信号線を確認しながら、次のように接続します。  ジャンパーピン、ダウンロードケーブルが指定の状態で  あることを確認後、電源を接続し、iMPACTを起動します。  「Manage Configuration Project...」をクリックすると  次の画面になるので、「iMPACT Flows」までスクロール。  「Boundary Scan」をクリック。  画面の指示に従い、右クリック。  右クリックし、「Initialize Chain」を選択しクリック。  Spartan3ANを認識したことを確認します。  「Message Box」の問いに「Yes」をクリック。  デフォルトでアクセスできるディレクトリの内容が表示されます。  ターゲットのディレクトリに移動します。  bitファイルを選択し、「Open」をクリック。  「Identify Succeeded」が表示されます。  サブ画面で、内容を確認。  「OK」をクリック。  「OK」のクリックで、「Identify Succeeded」の画面に戻ります。  左の「Program Flash and FPGA」のダブルクリック。  回路情報のダウンロードが始まり、サブ画面で進行状況が出ます。  ダウンロードが完了で、「Program Succeeded」が表示されます。  bitファイルとmcsファイルの情報をダウンロードするので  2分近くの時間がかかります。開発マシンの状況にもよる  ので、ひとつの例と考えてください。  これでEEPROMの中に回路情報が書き込まれたので  電源をオフし、再度オンにして回路が動くように  なります。

テスト基板

 FPGA基板だけでは、何もできないので、テスト基板を作成しました。  基板の左側にコネクタを半田付けしてあります。  30ピンコネクタを4個利用し、利用したピンは以下です。  (31〜34、65、66は、使っていません。)  80ピンコネクタを秋月電子で入手すれば、CNA、CNBともに  全ピンをカバーできますが、手持ちがなかったので、次の  ように、隙が開いています。  2ピンのジャンパーピンを2組用意し、次の信号ピンを  LEDとスイッチに接続しました。また、シリアル通信用の  Rx、TxDを接続しました。 CNA(63) M15(IOA46) LED CNA(64) M16(IOA47) LED CNB(63) F16(IOA46) switch CNB(64) G16(IOA47) switch CNB(61) H13(IOA44) RxD CNB(62) G14(IOA45) TxD  USBのコネクタを上にすると、下の方に  I/Oをまとめると次のようになります。  回路図は、以下。  バスインタフェースは、10ピンコネクタを使い  2ポート半田付けしてあります。 Vcc(+5V) IOA7 K3 IOA6 K1 IOA5 J2 IOA4 J1 IOA3 J3 IOA2 H3 IOA1 H1 IOA0 G2 GND(0V) Vcc(+5V) IOA15 L2 IOA14 L1 IOA13 N1 IOA12 M1 IOA11 R1 IOA10 P2 IOA9 P1 IOA8 N2 GND(0V)  シリアル通信用のICを使わずに、論理反転とレベル変換  しています。トランジスタと抵抗だけを使います。  Personal Computer のシリアルケーブルは、次のように配線。  3線式として利用します。  Dsub9ピンは、デスクトップのPCで用意されていますが  USB/シリアルアダプタを使うと問題なく利用できます。  この基板の動作テストのために、VHDLコードを作成しました。  入力論理値で、LEDの点灯消灯を制御します。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity tstxc0 is port ( -- input CLOCK : in std_logic ; -- 50MHz -- clock monitor XCLK : out std_logic_vector(1 downto 0) ; -- input Din : in std_logic_vector(1 downto 0) ; -- output Dout : out std_logic_vector(1 downto 0) -- ; ) ; end tstxc0; architecture Behavioral of tstxc0 is -- CONSTANT CNTMAX : integer := 49_999 ; CONSTANT CNTHALF : integer := 25_000 ; CONSTANT SCNTMAX : integer := 999 ; CONSTANT SCNTHALF : integer := 500 ; -- clock monitor signal iCNT : integer range 0 to CNTMAX ; signal iCLK : std_logic ; signal iSCNT : integer range 0 to SCNTMAX ; signal iSCLK : std_logic ; -- input signal iDin : std_logic_vector(1 downto 0) ; -- internal register signal iREG : std_logic_vector(1 downto 0) ; -- output signal iDout : std_logic_vector(1 downto 0) ; begin -- output Dout <= iDout ; -- input iDin <= Din ; -- clock monitor XCLK <= iCLK & iSCLK ; -- clock divider (generate 1MHz clock) process (CLOCK) begin if rising_edge(CLOCK) then if ( iCNT = CNTMAX ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iCNT < CNTHALF ) else '0' ; -- second clock divider process (CLOCK) begin if rising_edge(CLOCK) then if ( iCNT = CNTMAX ) then iSCNT <= 0 ; else iSCNT <= iSCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iSCNT < SCNTHALF ) else '0' ; -- internal register process (iCLK) begin if rising_edge(iCLK) then iREG <= iDin ; end if ; end process ; iDout <= iREG ; end Behavioral ;  ピンアサインは、次のようにしました。 # system NET "CLOCK" LOC = "C10" ; # clock monitor NET "XCLK<0>" LOC = "H1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "XCLK<1>" LOC = "G2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; # input NET "Din<0>" LOC = "F16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; NET "Din<1>" LOC = "G16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; # output NET "Dout<0>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Dout<1>" LOC = "M16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;  入力は、駆動能力を指定しないで対応します。  2ポート分のバスの動作チェックもしたいので  上のVHDLコードに、カウンタを入れて外部基板  の8LEDを点滅する回路を入れました。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity tstxc0 is port ( -- input CLOCK : in std_logic ; -- 50MHz -- clock monitor XCLK : out std_logic_vector(1 downto 0) ; -- input Din : in std_logic_vector(1 downto 0) ; -- output Dout : out std_logic_vector(1 downto 0) ; -- counter output Lout : out std_logic_vector(7 downto 0) ; LoutX : out std_logic_vector(7 downto 0) ; ) ; end tstxc0; architecture Behavioral of tstxc0 is -- CONSTANT CNTMAX : integer := 49_999 ; CONSTANT CNTHALF : integer := 25_000 ; CONSTANT SCNTMAX : integer := 999 ; CONSTANT SCNTHALF : integer := 500 ; -- clock monitor signal iCNT : integer range 0 to CNTMAX ; signal iCLK : std_logic ; signal iSCNT : integer range 0 to SCNTMAX ; signal iSCLK : std_logic ; -- input signal iDin : std_logic_vector(1 downto 0) ; -- internal register signal iREG : std_logic_vector(1 downto 0) ; -- output signal iDout : std_logic_vector(1 downto 0) ; -- internal counter signal iXCNT : std_logic_vector(7 downto 0) ; begin -- output Dout <= iDout ; Lout <= iXCNT ; LoutX <= not iXCNT ; -- input iDin <= Din ; -- clock monitor XCLK <= iCLK & iSCLK ; -- clock divider (generate 1MHz clock) process (CLOCK) begin if rising_edge(CLOCK) then if ( iCNT = CNTMAX ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iCNT < CNTHALF ) else '0' ; -- second clock divider process (CLOCK) begin if rising_edge(CLOCK) then if ( iCNT = CNTMAX ) then iSCNT <= 0 ; else iSCNT <= iSCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iSCNT < SCNTHALF ) else '0' ; -- internal register process (iCLK) begin if rising_edge(iCLK) then iREG <= iDin ; end if ; end process ; iDout <= iREG ; -- internal counter process (iSCLK) begin if rising_edge(iSCLK) then iXCNT <= iXCNT + '1' ; end if ; end process ; end Behavioral ;  ピンアサインは、次のようにしました。 # system NET "CLOCK" LOC = "C10" ; # clock monitor NET "XCLK<0>" LOC = "H1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "XCLK<1>" LOC = "G2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; # input NET "Din<0>" LOC = "F16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; NET "Din<1>" LOC = "G16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; # output NET "Dout<0>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Dout<1>" LOC = "M16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; # counter output NET "Lout<0>" LOC = "G2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<1>" LOC = "H1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<2>" LOC = "H3" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<3>" LOC = "J3" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<4>" LOC = "J1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<5>" LOC = "J2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<6>" LOC = "K1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "Lout<7>" LOC = "K3" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<0>" LOC = "N2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<1>" LOC = "P1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<2>" LOC = "P2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<3>" LOC = "R1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<4>" LOC = "M1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<5>" LOC = "N1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<6>" LOC = "L1" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "LoutX<7>" LOC = "L2" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;  正論理、負論理で8本のLEDを点滅させられます。  単純なカウンタ値出力でも、ワイヤーの接続ミスや  半田不良などを見つけることができます。
目次

inserted by FC2 system