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

背景
大学で動作未確認品のXlinx SPARTAN-6 XC6SLX16を入手したので,動かそうと試みました.
!!注意!!
今回はボードについてたUSB経由で書き込みを行いました.
使用環境
- Windows 11 Education 23H2
- 11th Gen Intel(R) Core(TM) i9-11900K @ 3.50GHz 3.50 GHz
- XC6SLX16が載った特殊電子回路のSpartan-6 Evaluation Board
まずはどんなものか調べよう
まずは公式サイトから大まかな情報をゲットしました.そこから使うソフトウェアはISE Design Toolであるとわかりました.
公式サイト↓
ISE Design Toolインストール手順
今回使うFPGAのソフトウェアです.まずはインストール方法を説明します.
!!注意!!
このアプリはzipで15GBくらいの容量なので,ある程度空き容量が必要です.
公式サイトからVersion14.7 Windows10をダウンロードしました.
!!注意!!
仮想支援機能が必要なので,有効にしなければならないです.
ダウンロードしたzipを解凍し,xsetup.exeを管理者権限で開きます.
"Next"を押します.

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

"Next"を押します.

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

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

インストール完了!!

出会ったトラブル
intelの仮想化支援機能が有効になっているにも関わらず以下のようなエラーが発生しました.BIOSでも有効になっていましたし,タスクマネージャのパフォーマンス>CPU>仮想化:のところが有効になっていました.
調べてみると,同様の問題が発生している人が一定数いるらしいです.1に解決策がありました.

解決
インストールしたファイルの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"押します.

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

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

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

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

"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をクリックし,シミュレーション画面を起動する.

プログラムファイル生成
View:を"Implementation"にし,Processes:のUser Constraints>I/O Pin Planning(Planahead) - Pre-Synthesisを押と以下のような画面が出てくるので"Yes"を押す.

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

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


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

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

Processes:のImplement Designを押し,Generate Program Fileを押します.
USBでFPGAに書き込む(Spartan6 Evaluation Board使用の場合)
- VirtualBoxで,共有フォルダに.bitファイルを入れる.VirtualBoxの共有フォルダの環境設定はこちらを参考にしてください
- Windowsでs6a7jtagw version 2.30aをインストール,中にあるexeを開いてアプリを起動させます.
- "FileOpen>Open a new file"でVirtualBoxと共有しているフォルダの中にあるさっきの.bitファイルを選択する
- FPGAボードをUSBで接続する.(ドライバを入れてない方は"case1 ドライバがWindowsに入ってない"の章を参考にしてください)
- "Connect"を押す.以下のように認識すればOK
- "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) [2]スパルタンⅡ FPGAトレーナ EDX-001 ダウンロード手順 ISE Foundation の使い方(閲覧日2024/10/26) [3]通常モードの使用 特殊電子回路株式会社(閲覧日2024/11/01)
コード
論理合成のとこのコード
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