1
この装置は、設計した論理回路を自由に書き込むことができる
FPGA (Field Programmable Gate Array)と呼ばれるLSIの一種で、
Xilinx社のSpartan2 (XC2S100)というLSIが搭載されていて、
さらに入力、出力として使うスイッチやLEDなども搭載されています。
設計した論理回路の情報は、PCからUSBケーブル経由で書き込むことができます。
こんな感じの画面が出るはずです。
これから設計していく論理回路は、「プロジェクト」という単位で
扱います。
早速、新しいプロジェクトを作ってみましょう。
まずは手始めに、NOTゲート1個を、入力にスイッチA、
出力にLEDをつないでみることにします。
File→New Projectで、新しいプロジェクトの作成を開始します。
プロジェクトの名前やファイルを置くディレクトリ名などを
入力します。
この例では、プロジェクトの名前にnot_gateとしています。
ファイルを置くディレクトリは、みなさんはファイルサーバ上に
適当なフォルダ("VHDL"など)をつくり、その中に作っていってください。
続いて、今回使うEDX-001に載っている、設計した論理回路を
書き込むFPGAとしてSpartan2 (XC2S100)を選びます。
そのほかにも、このSpartan2のパッケージ、ピン数などの情報を
選ぶ必要がありますので、↑この図の通りに選んでおきます。
特に、Deviceのところで"XC2S100"を選んでいるか注意しましょう。
続いて、設計する回路を記述するVHDLファイルを作成します。
今回は、新しいファイルを作りますので、
ここで新しいファイルを作るために、
New Sourceボタン(赤丸内)を押します。
新しく作成するファイルの種類とファイル名を入力します。
今回は、VHDLで回路を設計しますのでVHDL Moduleを選び、
ファイル名は、not_gateとしておきます。
Next> ボタンで次へ。
続いて、この回路の入力・出力を定義します。
この例では、入力(in)としてPSW_Aという名前の端子と、
出力(out)としてLED_0という名前の端子を使うことを指定しています。
また、最初は、構造記述で回路を記述することにしますので、
Architecture Nameのところに、archと書いておきます。
ちなみに入力のPSWは、プッシュスイッチ、の意味で、
EDX-001に載っているプッシュスイッチAを入力信号として
使う、という意味です。
また出力のLED_0は、EDX-001のLED_0(実際には"7"の番号が
ついているLED)を出力信号として使う、という意味です。
これで、これから設計する回路のVHDLファイルの定義がすみましたので、
ここで確認し、Finishボタンを押します。
新しいディレクトリ(フォルダ)を作成するかを聞かれるので、Yes。
ファイルはこれだけなので、Next。
このほかに、すでにあるファイルを使うかどうかを聞かれますが、
今回はないので、そのままNext。
これで、いまから設計を始める回路のプロジェクトの定義が
すみましたので、確認して、Finish。
これで、新しく回路の設計をはじめる準備が整いました。
↑画面内のnot_gate.vhdタブ(赤丸内)を押してみると、
いまから設計する回路not_gateを記述するVHDLファイルで、
必要な箇所(おまじないや、entity宣言など)が
既に記入されていることがわかります。
これは、プロジェクトの作成時に、使う入出力の名前などを
指定していたので、それにあわせて、VHDLのお決まりの記述の部分を
雛形(テンプレート)として自動的に作成されたのでした。
便利ですね。
では、本題であるNOTゲートを、architecture内に
↑このように記入をしておきましょう。
テストベンチを記述するVHDLファイルを新規に作成するため、
左上の方の、書き込み対象FPGAであるxc2s100-5tq144(↑図の赤丸内)を
右クリックし、New Sourceを選びます。
作成するファイルとして、VHDL TestBench、ファイル名をtest_not_gateと
して、Next。

テストベンチのVHDLファイルを作成する準備が整ったので、
Finish。
シミュレーションを行うため、左上のSource for:のところ(↑図の
上の赤丸内)をBehavioral Simulation(動作シミュレーション)に設定し、
テストベンチファイルであるtest_not_gate.vhdを選んだ状態(↑図の
下の赤丸内)にしておきます。
このテストベンチ内で、回路not_gateが、uutというインスタンス名で
呼ばれていることがわかります。
(ちなみに、このnot_gateが、arch(構造記述)であることも確認できます)
テストベンチファイルtest_not_gate.vhdが開かれている状態に
なっているはずですが、さきほどの回路本体のVHDLファイルのときと
同様に、おまじないなどの必要箇所は、すでに記入された状態に
なっています。便利ですね。
NOTゲートのシミュレーションですから、最初に0、続いて1、を
与えるテストベンチを↑図のように記述してみます。
これでテストベンチの記述が終わりましたので、
Processes画面内のSimulate Behavioral Model(↑図の赤丸内)を
右クリックし、Runを選んでシミュレーションを開始します。
このとき、記述した回路、テストベンチ等に記述ミスがあると
エラーメッセージが表示されますので、
エラーメッセージを参照しながら修正します。
新しい画面が立ち上がり、シミュレーション結果が表示されます。
ただし、最初は終わった後あたりの時刻の波形が表示されていますので、
↑図内の(1)でシミュレーション修了時刻を200nsに変更した後、
(2)(シミュレーションをリセット)→(3)(指定時刻までシミュレーションを実行)の
順で、シミュレーションを実行すると、結果が表示されます。
確かに入力であるPSW_Aが、0〜100nsは'0'、100ns〜200nsは'1'が与えられ、
それに応じた正しい出力LED_0が得られていることが確認できます。
まず、論理合成するために、
左上のSources for: をSynthesis/Implementationに選んでおきます。
続いて、ピン接続の定義、を行います。
例えばEDX-001のスイッチA(PSW_A)は、実際にはFPGA(XC2S100)の
50番ピンに接続されています。
(箱の中に入っている回路図で確認してみましょう)
このように、「実際の回路」で、「どのピンにどの信号を
割り当てるか」は、実際の装置で決まっていますので、
それにあわせて論理合成(正しくは配置配線)を行う必要があります。
今回使う入出力は、PSW_Aが50番ピン、LED_0が57番ピンに
つながっています。
このような指定は、UCF (User Constrain File)と呼ばれるファイルに
記述をしておく必要があります。
そこで、左上のSources:画面内で、設計対象の回路を記述している
not_gate.vhdを選んだ状態で、
右クリック→Add New File、で新しいファイルの追加を選び、
続くファイルの種類を選ぶ画面では、"Implementation Constraint File"を
選び、ファイル名をnot_gate.ucfとします。

その後、そのファイルを開くと、中身の何もないテキストファイルが作成されるので、
↑図のように指定を記述します。
ここでは、例えばPSW_Aという信号(NET)の場所(LOC=Location)を
"P50"(50番ピン)、として指定しています。
これで指定がすみましたので、早速論理合成をかけてみます。
Processes画面内のGenerate ProgrammingFileを右クリックし、
Runを選んで、実行します。
これは、論理合成に続いて、FPGAに書き込む情報への変換も
自動的に行うように指定しています。
実行中は、このような水色の丸がクルクル回るので、
終わるまで待ちます。
(ちょっと時間がかかります)
緑色のチェックマークがついたら、無事完了です。
赤丸の×印になったら、どこかでエラーがあったので、
エラーメッセージを見ながら修正をします。
では早速、設計した回路をEDX-001に書き込んでみましょう。
EDX-001を、PCとUSBケーブルで接続し、
PC側でコマンドプロンプトを立ち上げ(スタート→アクセサリ内)を
立ち上げます。
EDX-001のリセットをするためにINITボタンを押した後、
コマンドプロンプトで↑図のように入力すると、
設計した回路が転送されます。
(not_gateの部分が、今回設計した回路のプロジェクト名)
※コマンドプロンプトを開いたら、まずプロジェクトのファイルを保存しているフォルダ(ディレクトリ)に移動します。例えばMaguro(N:)へのドライブの変更は、「N:」と入力し、そこから先のフォルダ(ディレクトリ)の移動は、例えば"VHDL"という名前のフォルダ(ディレクトリ)に移動するときには、cdコマンドを使って「cd VHDL」のように入力します。
※「COM3:」のところは、EDX-001をどのUSBポートに接続するかで
変わります。演習室のPCの場合、前面の左側のUSBポートの場合は「COM4:」、
前面の右側のUSBポートの場合は「COM5:」となるようです。
よくわからない場合は、デバイスマネージャを開き、
「ポート」のところで、HuMANDATA...という名称のポートがあるはずですので、
そこに書いてあるCOM?の?の部分の番号を使います。
転送が終わると、EDX-001のDONEランプが点灯しているはずです。 転送が終わると、すぐに回路は動作を開始していますので、 スイッチAを押してみましょう。
ちなみに、スイッチAは、「負論理」、すなわち、 押すと'0'、押していないと'1'、の値が与えられます。 またLED_0も「負論理」、すなわち、 回路の出力が'0'のときに点灯、'1'のときに消灯します。 設計した回路がNOTゲートとして動作しているこをと確認しておきましょう。
プロジェクト名をadder2としてみます。
入力としてPSWという名称で4本分(PSW(3)〜PSW(0))、
出力としてLEDという名称で3本分(LED(3)〜LED(0))を使うことにします。
ちなみに右の方が下の桁PSW(0)のほうが直感的に分かりやすいと思いますので、
PSW(0)〜PSW(3)が、それぞれEDX-001のスイッチD〜Aに対応する
ことにしておきましょう。
またLED(3)〜LED(0)は、そのままEDX-001上の3〜0の番号がついたLEDです。
(画面の図は7〜0ですが、3〜0として読み替えてください)
これらのピン配置を、UCFファイルに↑図のように記述しておきます。
このうち、LED<4>〜LED<7>は書かないでおいてください。
これらを使って2ビットの加算器をつくってみましょう。
入出力は、例えば次のように割り当てるとよいでしょう。
(桁上がり入力ci=0で固定して、入力として与えないことにしてみます)
entity adder2 is
port (
PSW: in std_logic_vector(3 downto 0);
LED: out std_logic_vector(7 downto 0)
);
end adder2;
architecture arch of adder2 is
signal a, b : std_logic_vector(1 downto 0);
begin
a <= not PSW(3 downto 2);
b <= not PSW(1 downto 0);
process (a, b)
variable tmp: std_logic_vector(2 downto 0);
begin
tmp := ("0" & a) + ("0" & b);
LED(2) <= not tmp(2);
LED(1 downto 0) <= not tmp(1 downto 0);
end process;
end arch;
※New Projectから作った場合は、入出力の設定をするとエンティティ記述の部分は自動で生成されるので、architecture記述の中身だけ書けばOK
同様に、入力は4個までのスイッチ、出力は8個までのLEDの回路をつくることができます。