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

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



[第51回]


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

前回からの続きです。

次はcntr3です。

--cntr3
process(hblnkwk)
begin
                if hblnkwk'event and hblnkwk = '1' then
                cntr3 <= cntr3 +"000000001";
      end if;           
                if cntr3="111000001" then 
                cntr3<="000000000";
                end if;
end process;
cntr3は垂直同期信号のための9ビットカウンタです。
74HCなどのカウンタは大抵は4ビットですがVHDLの場合には半端なビット数のカウンタでも自由に作ることができます。
cntr3はhblnkwk信号の立ち上がりでカウントアップします。
そして111000001(1C1H=449)のとき000000000になります。
VGAインターフェースの垂直1画面はブランキング期間を含めて水平LINE449本分の期間になるのでこの値にします。
VGA信号については「CRTインターフェースボードの製作」[第17回]を参照してください。

次は垂直ブランキング信号と垂直同期信号です。

-- vblnk,vsync
process(cntr3)
begin
--vblnkwk               
                if cntr3(8)='0' then 
                        vblnkwk<='1';
                elsif cntr3(8 downto 4)="11001" then
                        vblnkwk<='0';
                end if;
--vsyncwk               
                if cntr3="110011100" then
                        vsyncwk<='0';
                elsif cntr3="110011110" then
                        vsyncwk<='1';
                end if;
end process;
cntr3のビット3〜ビット1はキャラクタジェネレータROMのアドレス下位3ビットとして垂直方向の文字パターン出力に使われます。
VGAの表示期間は垂直400ラインなのですが、このVGAインターフェース回路では簡易信号として水平2ラインは同じ信号を出力しています。
つまり水平信号16本を使って垂直方向の文字パターン8本を出力しています。
そのためcntr3のビット0はカウントアップのためだけに使われています。
cntr3のビット3〜ビット0までが垂直方向の文字パターンの出力に使われるので、それより上位のカウンタで垂直方向の表示期間とブランキング期間を決めています。
vblnkwkがそのための信号で、1のときが表示期間で0のときがブランキング期間です。
表示期間はcntr3の上位5ビットが00000〜11000(00〜18H、0〜24つまり縦方向25行)です。
vsyncwkは垂直同期信号です。

次はRAMアクセスのためのアドレス変換を行なっているところです。

--ramadrs
process(cntr2,cntr3,vblnkwk)
begin
                if vblnkwk='0' then
                        ramadrswk<="0000000";   
                        ramadrswk0<="0000000";
                elsif cntr3(3 downto 0)="1111" and hblnkwk = '0' then
                ramadrswk0 <= ramadrswk;
                elsif cntr2="1010000" and cntr1(0)='1' then
                ramadrswk <= ramadrswk0;
                elsif cntr2(3)'event and cntr2(3)='0' and hblnkwk='1' then
                        ramadrswk<=ramadrswk+"0000001"; 
                end if;
end process;
この部分の回路は[第45回]で説明しました。
そこでの説明も分かりにくかったかも知れませんが、このプログラムもちょっと説明がしにくいです。
自分の頭ではわかっているのですが、なかなか言葉では説明しにくいものがあります。
[第45回]で説明しましたように、文字パターンの第1ラインに相当する水平ラインの先頭アドレスをramadrswk0にラッチしておいて、水平1ラインが終るたびにラッチしておいたアドレスをramadrswkカウンタに戻します。
ということを上のプログラムでやっています。
ramadrswkはVRAMをスキャンするアドレス信号の上位7ビット(A10〜A4)になります。
ちなみに下位4ビット(A3〜A0)は、CNTR2の下位4ビットです。

下はそのアドレス信号を外部端子に出力しているところです。

-- address select
-- vrams
process(MREQ,MWR)
begin
                if MREQ='0' and MWR='0' and A11_15="11111" and vrams2='0' then
                        VRAMS<='0';
                        AHout<=AHin;
                        ALout<=ALin;
                        VRAMWR<=MWR;                            
                else 
                        VRAMS<='1';
                        AHout<=ramadrswk;
                        ALout<=cntr2(3 downto 0);
                        VRAMWR<='1';
                end if;
end process;
プログラムも最後に近付きました。
下はCPUバス信号によってVRAMにアクセスしたり、垂直ブランキング期間を読み取ることができるようにするための記述です。

-- vblnk read
-- i/o active vrams vactive     
process(Resetin,AHin,ALin,IOWR)
begin
                if Resetin='0' then
                        vrams2<='1';
                        vactive<='1';
                elsif  AHin(3 downto 0)="1101" and ALin(3 downto 2)="00" and IOWR='0' then
                        vrams2<=not D0IN;
                        vactive<=not D1IN;
                end if;
end process;

--see note 5/6
process(AHin,ALin,IORD)
begin
                if AHin(3 downto 0)="1101" and ALin(3 downto 2)="00" and IORD='0' and vblnkwk='0' then
                        D7OUT<='0';
                else 
                        D7OUT<='Z';
                end if;
end process;                            
最後のところです。
映像信号を外部端子に出力しています。
また上で説明したcntr3のビット3〜ビット1をキャラジェネROMのアドレス下位3ビットに出力しています。

        rgbout<=sftrgstr(7) and hblnkwk2 and vblnkwk and vactive;
        RGB_ROUT<=rgbout;
        RGB_GOUT<=rgbout;
        RGB_BOUT<=rgbout;
        ROMadrs<=cntr3( 3 downto 1);
end rtl;

CPLD入門![第51回]
2019.5.21upload

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