FPGAでグラフィックス液晶モジュール用の信号を生成する(その1)

_DSC9180.JPG
今回は鈴商で販売されているグラフィック液晶(384x192ドット、モノクロ)を利用するための信号をFPGAで生成する。この液晶パネルは鈴商で1300円、対応する18ピンコネクターは5個で300円。液晶パネル3枚とコネクター5個で送料を含めてちょうど5000円だった。
この液晶パネルを利用するにあたって以下のホームページを参考にしました。これらがなければまず映像を出せることはなかった。どうもありがとうございます。
・「Graphic LCD Contoller」(液晶パネルの概要)
・「鈴商dotLCD ~中間まとめ前半」(回路図など)
・「鈴商dotLCD ~中間まとめ後半」(端子説明など)
・「鈴商液晶(4) タイミングチャート(仮) 」(信号線のタイミング表:間違えてるバージョン)
・「鈴商液晶(5) (真)タイミングチャート」(信号線のタイミング表:正しいというバージョン=しかし私はこのタイミング表では動かせなかった。なぜ?)

_DSC9181.JPG
この液晶パネルではコントローラーとして「M5299C」と「M5298」が使われている。これらのデータシートはGoogleで検索すればダウンロード可能だが...私には理解できなかった。これらのデータシートだけで動かせる人は本当にすごいと思う。
液晶パネルからはバックライト用の2本の端子(未使用でOK)と写真の18ピンフラットケーブルが出ている。フラットケーブルは左側から1~18ピンで、その内訳は以下のようになっている。
1:LOAD(CL1)
2:CP(CL2)
3:IO1(FRM)
4:DF(M)
5:D0
6:D1
7:D2
8:D3
9:DISP(Vccへ接続)
10:Vee1(Vccへ接続)
11:Vee2(Vccへ接続)
12:Vee3(Vccへ接続)
13:CTRL(GNDへ接続=Vccへ接続すると写りません!)
14:SHL(GNDへ接続)
15:GND
16:GND
17:Vcc
18:Vcc

fpga_glcd_01_02.gif
「Xilinx ISE WebPack」を起動したら、新しいプロジェクトを作るため「File」メニューの「New Project」を選択する。

fpga_glcd_01_01.gif
ウイザードが開いた。今回はプロジェクト名を「GLCD」とした。

fpga_glcd_01_03.gif
次の画面ではデバイスの設定をする。今回もFPGAとしてDesign Wave Magazine 2007年7月号に付属していたSpartan3Eを使うことにした。
「Family」を「Spartan3E」に、
「Device」を「XC3S250E」に、
「Package」を「VQ100」に、
「Speed」を「-4」にする。これで設定が終わりだ。あとはデフォルト設定のまま「Next」ボタンで進み、「Finish」ボタンでウイザードを閉じる。

fpga_glcd_01_04.gif
プロジェクトが作れたら次にソースコードを追加する。「Project」メニューの「New Source」を選択する。

fpga_glcd_01_05.gif
ソースコードの形式は「VHDL Module」、ファイル名は「GenerateCP」とした。このソースコードは液晶パネルのCP信号(液晶に供給するクロック信号)を生成するのに使う。

fpga_glcd_01_06.gif
FPGA内のクロック信号を使って、液晶用のCP信号を生成するので、ポート名は「CLK」と「CP」、「Direction」はそれぞれ「in」と「out」にする。

fpga_glcd_01_07.gif
ソースコードが生成したら、CP信号を生成するためのVHDLを記述する。今回利用するSpartan3Eには33MHzの水晶発振子を接続している。このままではクロックが速すぎるので、5ビットのカウンターで32分周することにした。これによりCP信号は33MHz÷32=1.031MHzのクロックになる。


----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:43:32 07/03/2007
-- Design Name:
-- Module Name: GenerateCP - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

entity GenerateCP is
Port ( CLK : in STD_LOGIC;
CP : out STD_LOGIC);
end GenerateCP;

architecture Behavioral of GenerateCP is

signal TMP : STD_LOGIC_VECTOR(4 downto 0) := "00000";
begin

process (CLK)
begin
if CLK'event and CLK='1' then
TMP <= TMP + "00001";

if TMP < "10000" then
CP <= '1';
else
CP <= '0';
end if;
end if;
end process;

end Behavioral;





fpga_glcd_01_08.gif
さらに信号を生成するためソースコードを追加する。「Project」メニューの「New Source」を選択する。

fpga_glcd_01_09.gif
先ほどと同じようにソースコードの形式を「VHDL Module」にする。ファイル名は「GenerateLOAD」とした。これは液晶パネル用のLOAD信号生成用に使う。

fpga_glcd_01_10.gif
LOAD信号はCP信号を元に生成するので、ポート名で「CP」と「LOAD」を入力し、それぞれ「in」と「out」にする。

fpga_glcd_01_11.gif
ソースコードが生成したら、LOAD信号を作るためのVHDLを記述する。
LOAD信号はCP信号が100クロックごとに1クロック出るパルスとなる。生成タイミングは1列目のデータを液晶パネルに送る直前になる。タイミングチャートではCPがLowのときのみHighになるパルスだが、うまく動かなかったので最後のCP信号がHigh-Low両方のときにHighになるようにした。


----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:44:20 07/03/2007
-- Design Name:
-- Module Name: GenerateLOAD - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

entity GenerateLOAD is
Port ( CP : in STD_LOGIC;
LOAD : out STD_LOGIC);
end GenerateLOAD;

architecture Behavioral of GenerateLOAD is

signal TMP : STD_LOGIC_VECTOR( 7 downto 0 ) := "00000000";
begin

process (CP)
begin
if CP'event and CP='1' then
TMP <= TMP + "00000001";

if TMP = "01100011" then --99
TMP <= "00000000";
LOAD <= '1';
else
LOAD <= '0';
end if;
end if;

end process;

end Behavioral;





fpga_glcd_01_12.gif
これでCPとLOAD信号を生成するためのVHDLソースができた。さらに処理をするためソースコードを追加する。
「Project」メニューの「New Source」を選択する。

fpga_glcd_01_13.gif
今回はとりあえず先に作ったCPとLOAD信号を生成するモジュール同士を関連付けるためのソースコードを作る。ソースコードの形式で「VHDL Module」を、ファイル名を「GenerateSignals」にした。

fpga_glcd_01_14.gif
まだCPとLOAD信号用のVHDLしか作っていないが、実際に液晶パネルに出力することを考えて、すべての信号を定義しておく。「CLOCK」、「LOAD」、「CP」、「D」、「IO1」、「DF」を追加して、「CLOCK」を「in」に、ほかを「out」に設定する。

fpga_glcd_01_15.gif
これでソースコードを修正する。ソースコード内でほかのソースコードで記述したルーチンを使うにはcomponent定義をすればいい。IO1やDFなどまだ生成用のVHDLを用意していない信号は適当な固定値を出力するようにした。


----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:28:17 07/03/2007
-- Design Name:
-- Module Name: GenerateSignals - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

entity GenerateSignals is
Port ( CLOCK : in STD_LOGIC;
LOAD : out STD_LOGIC;
CP : out STD_LOGIC;
D : out STD_LOGIC_VECTOR(3 downto 0);
IO1 : out STD_LOGIC;
DF : out STD_LOGIC);
end GenerateSignals;

architecture Behavioral of GenerateSignals is

signal CP_TMP : STD_LOGIC;
signal LOAD_TMP : STD_LOGIC;

component GenerateCP
Port ( CLK : in STD_LOGIC;
CP : out STD_LOGIC);
end component;

component GenerateLOAD
Port ( CP : in STD_LOGIC;
LOAD : out STD_LOGIC);
end component;

begin

LOAD <= LOAD_TMP;
CP <= CP_TMP;
D(0) <= '1';
D(1) <= '1';
D(2) <= '0';
D(3) <= '0';
IO1 <= '0';
DF <= '0';

u0: GenerateCP port map(
CLK => CLOCK,
CP => CP_TMP);

u1: GenerateLOAD port map(
CP => CP_TMP,
LOAD => LOAD_TMP);

end Behavioral;





fpga_glcd_01_16.gif
とりあえずここまでのソースコードの変更を保存しておく。「File」メニューの「Save All」を選択する。

fpga_glcd_01_17.gif
次にこれまでに作成したCP信号とLOAD信号の生成用VHDLがきちんと意図した通りに動くかどうかPC内でシュミレーションしてみる。
「ModelSim」というシュミレーターソフトを起動する。このソフトはXilinxから無料ダウンロードできる(ただし制限が多いらしい)。Xilinx ISE WebPackにもシュミレーション機能が備わっているようだが使い方がよく分からなかったため今回はModelSimを利用した。

fpga_glcd_01_18.gif
ModelSimが起動したら「Compile」メニューの「Compile」を選択する。

fpga_glcd_01_19.gif
するとファイル選択画面が開くので、ISE WebPackで作成したプロジェクトのフォルダ内にある「GenerateCP.vhd」、「GenerateLOAD.vhd」、「GenerateSignals.vhd」の3ファイルを選択して「Compile」ボタンを押す。

fpga_glcd_01_20.gif
「work」ライブラリーがないから作るかと問われたら「Yes」を選択する。

fpga_glcd_01_21.gif
これでコンパイルが終わった。「Done」ボタンを押してこの画面を閉じる。

fpga_glcd_01_22.gif
初めてModelSimを使うときはこのままでは「work」ライブラリーが"見えない"ので一度ModelSimを再起動する。「File」メニューの「Quit」を選択してModelSimを終了してもう一度起動する。

fpga_glcd_01_23.gif
すると左側のツリー内に「work」ライブラリーが見えるようになる。この中にある「GenerateSignals」を右クリックして現れたメニューから「Simulate」を選択する。

fpga_glcd_01_24.gif
するとシュミレーション画面に切り替わる。ここで「View」メニューの「Wave」を選択して波形表示ウインドウを開く。

fpga_glcd_01_25.gif
波形表示用ウインドウが開いたらシュミレーションしたい信号名を選択してドラッグ・アンド・ドロップする。今回はCPとLOADを見たいのでこれらをドラッグ・アンド・ドロップする。

fpga_glcd_01_26.gif
すると波形表示用ウインドウ内に信号が追加される。

fpga_glcd_01_27.gif
次にクロックの設定をする。「clock」を右クリックして現れたメニューから「Clock」を選択する。

fpga_glcd_01_28.gif
するとクロック設定画面が開く。ここで「Period」を「2」にする。これは1クロック2ピコ秒という意味になる。利用するFPGA基板には33MHzの水晶発振子を搭載している。そのため実際にはクロックは30ピコ秒だが、今回は単に信号の現れ方を見たいだけなので2ピコ秒とした。

fpga_glcd_01_29.gif
クロックの設定が終わったら画面下部の「Transcript」部に「run 10000」と入力して[Enter]キーを押す。

fpga_glcd_01_30.gif
すると10000ピコ秒だけシュミレーションが実行され、生成した信号が表示される。

fpga_glcd_01_31.gif
もう一度「run 10000」を実行すると合計で2万ピコ秒分のシュミレーションが行われた。さらにLOAD信号のパルスも見える。

fpga_glcd_01_32.gif
実際にCP信号の周波数を見てみる。カーソル(黄色い線)を合わせるとその時間が下部に表示される。シュミレーションの開始位置で調べてみると64ピコ秒になっている。
シュミレーション用のクロックが1クロック2ピコ秒、CP信号生成用のカウンターが5ビットで32分周なので、2ps×32=64psということで設定どおりになっている。

fpga_glcd_01_33.gif
次に初めてLOAD信号のパルスが出るタイミングを見てみる。6400ピコ秒の時点で現れていた。CP信号が1クロック64ピコ秒なのでCP信号100パルス経った位置でLOAD信号が生成している。これで意図した通りに動いていることが確かめられた。

fpga_glcd_01_34.gif
最後に「Simulate」メニューの「End Simulation」を選択してシュミレーションを終了する。



カテゴリー「電子工作」 のエントリー