📝

入手したSpartan6というFPGAを動かしてみた

に公開

背景

大学で動作未確認品のXlinx SPARTAN-6 XC6SLX16を入手したので,動かそうと試みました.

!!注意!!

今回はボードについてたUSB経由で書き込みを行いました.

使用環境

まずはどんなものか調べよう

まずは公式サイトから大まかな情報をゲットしました.そこから使うソフトウェアはISE Design Toolであるとわかりました.

公式サイト↓
https://www.amd.com/ja/products/adaptive-socs-and-fpgas/fpga/spartan-6.html

ISE Design Toolインストール手順

今回使うFPGAのソフトウェアです.まずはインストール方法を説明します.

!!注意!!
このアプリはzipで15GBくらいの容量なので,ある程度空き容量が必要です.

公式サイトからVersion14.7 Windows10をダウンロードしました.

!!注意!!
仮想支援機能が必要なので,有効にしなければならないです.

https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive-ise.html

ダウンロードしたzipを解凍し,xsetup.exeを管理者権限で開きます.

"Next"を押します.

welcome window

agreementにチェックし,"Next"を押します.
agreement

"Next"を押します.

インストールするディレクトリ等を設定し,"Next"を押します.(私はデフォルトのままにしました)
directory

設定等が正しいか確認したあと,"install"を押します.
check instalol info

インストール完了!!
install finish

出会ったトラブル

intelの仮想化支援機能が有効になっているにも関わらず以下のようなエラーが発生しました.BIOSでも有効になっていましたし,タスクマネージャのパフォーマンス>CPU>仮想化:のところが有効になっていました.

調べてみると,同様の問題が発生している人が一定数いるらしいです.1に解決策がありました.
error_msg

解決

インストールしたファイルのbinのvalidate_virtualization_enabled.batをメモ帳とかで開くと

@echo off
%SYSTEMROOT%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& '%~dnp0.ps1'"

とあると思います.これを以下のように"#"でコメントアウトします.

@echo off
#%SYSTEMROOT%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& '%~dnp0.ps1'"

するとさっきエラーでたメッセージはでず,以下のようなWarningがでます.これらを無視してContinue押すとインストールできるようになります.

プロジェクトの作成

iMPACTを開くと,Vertual boxが開かれます.そのなかでproject navigatorを開きます.

"New Project"を押し,プロジェクト名を決めます.(私は"blinktest1"としました.)

ボードの設定をします."Next"押します.
PJsetting_board

確認したら,"Finish"を押します.

このような画面になります.
start

論理合成

Project>New sourceを押し,"VHDL Module"を選択し,ファイル名を入れて"Next"を押す.

ポートに名前を付けます.付けたら"Next"を押す.
port name

"Finish"を押す.

するとこのようにVHDファイルが作成され,表示されます.

このVHDLファイルにコードを書いていきます.(サンプルのコードはこの記事の最後に載せときます)

コードを書き終えたら保存し,"Processes"の"Synthesize -XST"をクリックして論理合成します.Consoleに"Process "Synthesize - XST" completed successfully"と出ればOKです.
エラーを吐いていたら,エラーメッセージを読んだ上で適宜修正し,再び論理合成を試みてください.

"Implement Design"も同様にクリックします.

論理シミュレーション

論理シミュレーションをします.

Project>New Sourceから"VHDL Test Bench"を選択し,ファイル名を入れた後,"Next"を押す.そのあとも"Next", "Finish"を押す

するとテストベンチのファイルが作成されます.

コード書き終えたらView:をSimulationにした上で

Processes:のISin Simulater>Behavioral Check Syntaxを押す.完了したら,Simulate Behavioral Modelをクリックし,シミュレーション画面を起動する.

Sim window

プログラムファイル生成

View:を"Implementation"にし,Processes:のUser Constraints>I/O Pin Planning(Planahead) - Pre-Synthesisを押と以下のような画面が出てくるので"Yes"を押す.

するとFPGAのpinアサインとかをするためのウィンドウが出現します.

I/O portのところをのAll ports>Scalar portsの+を押すと,それぞれのpinが出現します.これをボードの回路図見ながら設定していきます.

https://www.tokudenkairo.co.jp/sp6/sp6brd_manual.pdf

ポートの割り振りが終わったらセーブし,このウィンドウを閉じる

ここまでの操作を終えるとHierarchyに.ucfファイルが作成される.

Processes:のImplement Designを押し,Generate Program Fileを押します.

USBでFPGAに書き込む(Spartan6 Evaluation Board使用の場合)

  1. VirtualBoxで,共有フォルダに.bitファイルを入れる.VirtualBoxの共有フォルダの環境設定はこちらを参考にしてください
  2. Windowsでs6a7jtagw version 2.30aをインストール,中にあるexeを開いてアプリを起動させます.
    書き込みアプリ
  3. "FileOpen>Open a new file"でVirtualBoxと共有しているフォルダの中にあるさっきの.bitファイルを選択する
  4. FPGAボードをUSBで接続する.(ドライバを入れてない方は"case1 ドライバがWindowsに入ってない"の章を参考にしてください)
  5. "Connect"を押す.以下のように認識すればOK
  6. "AUTO"を押すと書き込まれます.

こんな感じでLEDが点灯します.

JTAG接続でFPGAに書き込み

FPGAをPCを接続し,Processes:のConfigure Target Device>Manage Configuration Project(iMPACT)を押すと"ISE iMPACT"というウィンドウが立ち上がります.iMPACT FlowのBoundary Scanを押します.

出てきたウィンドウで今作った.batを選択する.

するとこのような画面になるので,右のチップの絵を押し,iMPACT Processes:のProgramを押すとFPGAに書き込めます.(尚,ここから先はにひは試していません)

USBが認識しない人向け

case1 ドライバがWindowsに入ってない

デバイスマネージャを開くとわかります.どれがFPGAかわからないときは一回抜き差しして増減する項目を見てみると良いと思います.

ドライバはここから入手できます.入手したファイルを7zipなどで解凍し,入れることができます,詳細の入れ方はほかのサイト等を参照してください.

case2 Virtual BoxにUSBアクセスを渡してない

Virtual Boxのデバイスから対象のUSBを選択します.

参考文献

[1]"ISE Windows 10 version does not install" AMD Adaptive SoC &FPGA Support(閲覧日2024/10/26)
https://adaptivesupport.amd.com/s/question/0D52E00006hpmSfSAI/ise-windows-10-version-does-not-install?language=ja
[2]スパルタンⅡ FPGAトレーナ EDX-001 ダウンロード手順  ISE Foundation の使い方(閲覧日2024/10/26)
https://www.hdl.co.jp/EDX/HowToDownLoad/ISE.html
[3]通常モードの使用 特殊電子回路株式会社(閲覧日2024/11/01)
https://www.tokudenkairo.co.jp/s6a7jtagw/normal.html

コード

論理合成のとこのコード

VHDLファイル

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:52:58 10/25/2024 
-- Design Name: 
-- Module Name:    blinktest1 - blink 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity blinktest1 is
    Port ( RST : in  STD_LOGIC;
           CLK : in  STD_LOGIC;
           LED1 : out  STD_LOGIC;
           LED2 : out  STD_LOGIC;
           LED3 : out  STD_LOGIC;
           LED4 : out  STD_LOGIC;
           LED5 : out  STD_LOGIC;
           LED6 : out  STD_LOGIC;
           LED7 : out  STD_LOGIC;
           LED8 : out  STD_LOGIC);
end 
blinktest1;architecture blink of blinktest1 is
    signal ledsig : STD_LOGIC_VECTOR(7 downto 0) := (others => '0');
    signal led_index : integer range 0 to 7 := 0;
    signal delay_counter : integer := 0;  
    constant delay_max : integer := 1000000; 
begin
    process(CLK, RST)
    begin
        if RST = '1' then  -- Active low reset
            ledsig <= (others => '0');
            led_index <= 0;
            delay_counter <= 0;  -- Reset delay counter
        elsif rising_edge(CLK) then
            if delay_counter < delay_max then
                delay_counter <= delay_counter + 1;  -- Increment delay counter
            else
                delay_counter <= 0;  -- Reset delay counter
                ledsig <= (others => '0');  -- Turn off all LEDs
                ledsig(led_index) <= '1';  -- Turn on the current LED
                if led_index = 7 then
                    led_index <= 0;  -- Reset index after LED8
                else
                    led_index <= led_index + 1;  -- Move to next LED
                end if;
            end if;
        end if;
    end process;
    -- Map internal signal to output pins
    LED1 <= ledsig(0);
    LED2 <= ledsig(1);
    LED3 <= ledsig(2);
    LED4 <= ledsig(3);
    LED5 <= ledsig(4);
    LED6 <= ledsig(5);
    LED7 <= ledsig(6);
    LED8 <= ledsig(7);
end blink;

論理シュミュレーションの時のコード(工事中)

CLK,RSTの設定とかがちょいおかしくて波形でないかも...気が向いたら直しときます...2024/11/01

...
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY test1 IS
END test1;
 
ARCHITECTURE behavior OF test1 IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT blinktest1
    PORT(
         RST : IN  std_logic;
         CLK : IN  std_logic;
         LED1 : OUT  std_logic;
         LED2 : OUT  std_logic;
         LED3 : OUT  std_logic;
         LED4 : OUT  std_logic;
         LED5 : OUT  std_logic;
         LED6 : OUT  std_logic;
         LED7 : OUT  std_logic;
         LED8 : OUT  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal RST : std_logic := '1';
   signal CLK : std_logic := '0';

 	--Outputs
   signal LED1 : std_logic;
   signal LED2 : std_logic;
   signal LED3 : std_logic;
   signal LED4 : std_logic;
   signal LED5 : std_logic;
   signal LED6 : std_logic;
   signal LED7 : std_logic;
   signal LED8 : std_logic;

   -- Clock period definitions
   constant CLK_period : time := 10 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: blinktest1 PORT MAP (
          RST => RST,
          CLK => CLK,
          LED1 => LED1,
          LED2 => LED2,
          LED3 => LED3,
          LED4 => LED4,
          LED5 => LED5,
          LED6 => LED6,
          LED7 => LED7,
          LED8 => LED8
        );

   -- Clock process definitions
   CLK_process :process
   begin
		CLK <= '0';
		wait for CLK_period/2;
		CLK <= '1';
		wait for CLK_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin		
      -- hold reset state for 100 ns.
      wait for 100 ns;	

      wait for CLK_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

Discussion