2019.5.20
前へ
次へ
ホームページトップへ戻る

[新連載]CPLD入門!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使うことになるだろうと思ってはいたのですが。
何を今頃になって、というようなものですが。
ようやく本気で、CPLDと四つに取り組みます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜



[第50回]


●VHDLプログラムリスト(ざっと説明)

また何日か間が空いてしまいました。
この数日間はどうしても手がけたい新しいことに首をつっこんで、悩んでおりました。
本日になって、やっとまあまあというところまでクリアできました。
そのことについても近いうちにホームページにて説明できると思います。
それで。
とりあえず本日のところは、前回お見せしたCPLD版VGAIFのVHDLプログラムについて、ざっと簡単に説明します。

先頭の部分は定型的なおまじないのようなものです。

--vga controller 18/12/22 12/23 12/24 12/25 12/26 12/27
--19/1/12 1/13 1/29 3/24 3/25 3/26 3/27
--5/4 5/5 5/6

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library ARITHMETIC;
use ARITHMETIC.std_logic_arith.all;

entity vgac2j is
        PORT (
                        AHout:out std_logic_vector(6 downto 0);
                        ALout:out std_logic_vector(3 downto 0);
                        AHin:in std_logic_vector(6 downto 0);
                        ALin:in std_logic_vector(3 downto 0);
                        ROMadrs:out std_logic_vector(2 downto 0);
                        ROMDATA:in std_logic_vector(7 downto 0);
                        A11_15:in std_logic_vector(4 downto 0);
                        IOWR:in std_logic;
                        IORD:in std_logic;
                        MREQ:in std_logic;
                        MWR:in std_logic;
                        VRAMWR:out std_logic;
                        VRAMS:out std_logic;
                        D0IN:in std_logic;
                        D1IN:in std_logic;
                        D7OUT:out std_logic;
                        RGB_ROUT:out std_logic;
                        RGB_GOUT:out std_logic;
                        RGB_BOUT:out std_logic;
                        HSYNC :out std_logic;
                        VSYNC :out std_logic;
                        Notused58:in std_logic;
                        Notused73:in std_logic;
                        Notused74:in std_logic;
                        T57:out std_logic;--vblnkwk
                        T67:out std_logic;--vactive
                        T68:out std_logic;--hblnkwk
                        T69:out std_logic;--hblnkwk2
                        Resetin:in std_logic;
                        CKIN :in std_logic);

end vgac2j;

外部入出力端子を定義しています。
その次のところでは内部で使う信号について定義しています。

architecture rtl of vgac2j is

        signal cntr1:std_logic_vector(2 downto 0);
        signal cntr2:std_logic_vector(6 downto 0);
        signal cntr3:std_logic_vector(8 downto 0);
        signal ramadrswk:std_logic_vector(6 downto 0);
        signal ramadrswk0:std_logic_vector(6 downto 0);
        signal sftrgstr:std_logic_vector(7 downto 0);
        signal hblnkwk:std_logic;
        signal hblnkwk2:std_logic;
        signal cntr3wk:std_logic;
        signal vblnkwk:std_logic;
        signal vrams2:std_logic;
        signal vactive:std_logic;
        signal rgbout:std_logic;
        signal hsyncwk:std_logic;
        signal vsyncwk:std_logic;

その次からが具体的な信号処理のプログラムになります。
最初の部分では外部端子に出力するため内部信号をつないでいます。

  begin
        T57<=vblnkwk;
        T67<=vactive;
        T68<=hblnkwk;
        T69<=hblnkwk2;
        Hsync<=hsyncwk;
        Vsync<=vsyncwk;
T57〜T69はテストのために一時的に使っています。

下はCNTR1とSFTRGSTRの記述です。

--cntr1 & sftrgstr
process(CKIN)
begin
                if CKIN'event and CKIN = '1' then
                        cntr1<=cntr1+"001";
                        sftrgstr<=sftrgstr(6 downto 0) & '0';
                end if;         
                if CKIN='1' and cntr1="111" then
                        sftrgstr<=ROMDATA;
                end if;
end process;
CNTR1はキャラクタジェレータROMからシフトレジスタ(SFTRGSTR)にLOADした8ビットの表示データをシフトするためのクロックを作り出している3ビットのカウンタです。
CKINには25.175MHzが入力されています。
CNTR1がカウントアップするごとにSFTRGSTRが左シフトします。
CKIN=1でかつCNTR1=111のとき、SFTRGSTRにキャラジェネROMからのデータがLOADされます。

次はCNTR2です。

--cntr2
process(cntr1)  
begin                   
                if cntr1(2)'event and cntr1(2) = '0' then
                cntr2 <= cntr2 +"0000001";
                end if;         
                if cntr2="1100100" then 
                cntr2<="0000000";
                end if;
end process;
CNTR2は水平同期信号と、VRAMをスキャンするためのアドレスを出力するための7ビットのカウンタです。
CNTR2はCNTR1が111から000になるタイミングでカウントアップします。
CNTR2は1100100(64H)のときに0000000になります。
これによってブランキング期間と表示期間を合わせた水平1ラインの期間(100文字=64H)を作り出しています。

次は水平ブランキング期間と水平同期信号です。

--hblnk,hsync
process(cntr2)
begin
--hblnkwk               
                if cntr2="0000000" then
                        hblnkwk<='1';
                --elsif cntr2="0000001" then see note 5/6
                        hblnkwk2<='1';
                elsif cntr2="1010000" then
                        hblnkwk<='0';
                elsif cntr2="1010001" then
                        hblnkwk2<='0';
--hsynkwk               
      elsif cntr2="1010011" then
                        hsyncwk<='0';
                elsif cntr2="1011111" then
                        hsyncwk<='1';
                end if;
end process;
hblnkwk、hblnkwk2は水平表示期間と水平ブランキング期間を決定する信号です。
1の期間は表示期間です。
0の期間はブランキング期間です。
ここでは[第48回]で書きました1文字のズレを調整するための信号を作っています。
hblnkwkはこのあとの垂直同期信号を作成するための「ズレのない」信号です。
hblnkwk2は1文字遅延させた信号です。
elsifがコメント行になっています。
本当はこの行も必要なのですが、この時点ではこの行を生かすと誤動作が発生するためこのようにしました。
後になって記述に問題があるらしいことがわかって、ここは最終的にはプログラムを訂正しました。
hsynkwkは水平同期信号です。

説明の途中ですが、本日は時間がなくなってしまいました。
この続きは次回にいたします。

CPLD入門![第50回]
2019.5.20upload

前へ
次へ
ホームページトップへ戻る