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

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



[第56回]


●垂直同期信号

垂直同期信号もVGAIFとCRTIFとでは規格が異なっています。
まずはVGAIF用のVHDLプログラムです。
cntr3は垂直ブランキング信号と垂直同期信号を生成するための9ビットのカウンタです。

--cntr3
process(hblnkwk)
begin
                if hblnkwk'event and hblnkwk = '1' then
                cntr3 <= cntr3 +"000000001";
      end if;           
                if cntr3="111000001" then --(1)
                cntr3<="000000000";
                end if;
end process;
cntr3はhblnkwkが’0’から’1’になるタイミングでカウントアップします。
そしてcntr3は111000001(1C1H)のときに000000000になります。
これによってブランキング期間と表示期間を合わせた垂直449ラインの期間(449=1C1H)を作り出しています。

この部分をCRTIF用に変更します。
ここも変更するのは(1)の行のみです。

--cntr3
process(hblnkwk)
begin
                if hblnkwk'event and hblnkwk = '1' then
                cntr3 <= cntr3 +"000000001";
      end if;           
                if cntr3(8)='1' then --(1)
                cntr3<="000000000";
                end if;
end process;
CRTIFの場合には、cntr3はビット8が’1’(つまり100000000)のときに000000000になります。
これによってブランキング期間と表示期間を合わせた垂直256ラインの期間(256=100H)を作り出しています。

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

-- 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;
vblnkwkは垂直表示期間と垂直ブランキング期間を決定する信号です。
’1’の期間は表示期間です。
’0’の期間はブランキング期間です。
表示期間は400ライン(190H)ですからその期間を’1’にします。

vsynkwkは垂直同期信号です。
cntr3が190Hでブランキング期間になったあと、垂直同期パルスまでがフロントポーチ(12ライン)で、そのあとが垂直同期パルス(2ライン)で残りがバックポーチ(35ライン)です。
vsynkwkはcntr3が19CHのときに’0’になります。
そして19EHのときに’1’になります。

ところでここではvblnkwkとvsyncwkを1つのPROCESS文のなかで記述していますが、特に問題は発生していません。
ま、しかし、hblnkwk2のようなことを経験した以上、ここも別々に記述するようにしたほうが安全かもしれません。
とりあえずはしばらくこのままで様子を見ることにします。

さて。
それで、この部分をCRTIF用に変更します。

-- vblnk,vsync
process(cntr3)
begin
--vblnkwk               
                if cntr3(7)='0' then 
                        vblnkwk<='1';
                elsif cntr3(7 downto 3)="11001" then
                        vblnkwk<='0';
                end if;
--vsyncwk               
                if cntr3(7 downto 3)="11011" then
                        vsyncwk<='0';
                elsif cntr3(7 downto 4)="1110" then
                        vsyncwk<='1';
                end if;
end process;
vblnkwkは垂直表示期間と垂直ブランキング期間を決定する信号です。
CRTIFの場合、表示期間は200ライン(C8H)ですからその期間を’1’にします。

vsynkwkは垂直同期信号です。
cntr3がC8Hでブランキング期間になったあと、垂直同期パルスまでがフロントポーチ(16ライン)で、そのあとが垂直同期パルス(8ライン)で残りがバックポーチ(32ライン)です。
vsynkwkはcntr3がD8Hのときに’0’になります。
そしてE0Hのときに’1’になります。

●VRAMアドレスのための補正回路

垂直表示に関してはもう1箇所変更するところがあります。
VGAIFでは垂直表示期間は400ラインです。
これに対してCRTIFでは200ラインです。
両方とも表示文字数に注目すると、どちらも25行の表示です。
つまりVGAIFでは垂直方向1文字を16ラインで表示するのに対してCRTIFでは8ラインで1文字を表示します。
なおキャラクタジェネレータの文字パターンは縦方向は8ドットなので、VGAIFでは連続する偶数奇数の2ラインは同じキャラジェネパターンを出力することになります。

下はcntr2とcntr3の出力からRAMアドレス信号とROMアドレス信号を生成する部分のVGAIF用のVHDLプログラムです。
(1)の行が16ラインごとにVRAMのアドレスを更新する部分です。

--ramadrs
process(cntr2,cntr3,vblnkwk)
begin
                if vblnkwk='0' then
                        ramadrswk<="0000000";   
                        ramadrswk0<="0000000";
                elsif cntr3(3 downto 0)="1111" and hblnkwk = '0' then --(1)
                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;
ここでは2つの7ビットレジスタramadrswk、ramadrswk0を使ってVRAMアドレスをカウントアップし、出力しています。
何をやっているのか理解しにくいところです。
この部分については[第51回]で説明をしていますので参照願います。

ここでもramadrswkとramadrswk0という2つの信号を1つのPROCESS文のなかで記述しています。
うーん。
ここを別々のPROCESS文にするのはちょっとむつかしい気がします。
ま、ここも今のところ特に問題は出ていないようですので、このままで様子を見ることにいたします。

それで。
この部分をCRTIF用に変更します。
変更するのは上の(1)の行だけです。

--ramadrs
process(cntr2,cntr3,vblnkwk)
begin
                if vblnkwk='0' then
                        ramadrswk<="0000000";   
                        ramadrswk0<="0000000";
                elsif cntr3(2 downto 0)="111" and hblnkwk = '0' then --(1)
                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;
VGAIFは16ラインごとにVRAMのアドレスを更新しますがCRTIFでは8ラインごとに更新します。

●映像信号出力回路

最後のところです。
VGAIFでは映像信号と水平同期信号と垂直同期信号は別々に出力します。
このインターフェース回路の場合、赤、緑、青の映像出力信号はそれぞれ別の信号出力端子に出力しますが、それは同じ映像信号です。
映像信号はキャラジェネROMから出力される水平方向の8ビットのビットパターンをシフトレジスタで受けて、それをビットクロックに合わせてパラレルからシリアルに変換して出力します。
キャラジェネ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);
そういえば水平同期信号と垂直同期信号はここではなくて、プログラムの先頭部分で記述しています。

        Hsync<=hsyncwk;
        Vsync<=vsyncwk;
プログラム作成の過程でこういうことになってしまったのですが、本当は1箇所にまとめて記述したほうがいいですねえ。
ま。順序回路ではありませんから、プログラムのどこで記述しても構わないのですけれど。

それで。
上の部分をCRTIF用に書き換えます。

        rgbout<=sftrgstr(7) and hblnkwk2 and vblnkwk and vactive;
        --RGB_ROUT<=rgbout;
        --RGB_GOUT<=rgbout;
        --RGB_BOUT<=rgbout;
        ROMadrs<=cntr3(2 downto 0);

--crt out
process(rgbout)
begin
                if rgbout='0' then
                        CRTDSP<='0';
                else
                        CRTDSP<='Z';
                end if;
end process;

process(hsyncwk,vsyncwk)
begin
        if hsyncwk='0' or vsyncwk='0' then
                CRTVHSYNC<='0';
        else
                CRTVHSYNC<='Z';
        end if;
end process;
CRTIF回路では映像信号と水平同期信号と垂直同期信号を1本のアナログ信号に合成します。
その合成はEPM7128SLC84の外部でトランジスタ回路によって行ないます。
その合成のために映像信号と同期信号はオープンドレイン出力(H出力時はハイインピーダンス)にします。
ハイインピーダンス出力は’Z’を使って記述します。

CPLD入門![第56回]
2019.6.3upload

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