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

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



[第58回]


●CRTIF用VHDLプログラムを80字/40字表示に変更(1)

CRTIF用のVHDLプログラムが出来上がったところで、続いてそれを80字表示と40字表示に切り換えて表示できるように変更する作業に取り掛かりました。
水平方向に80字を表示するところを40字表示にするには単純にドット表示周波数を1/2にすればよいだけのはずなので、まあ半日もあれば楽々完了、のつもりだったのですが…。
またしても泥沼、茨の道を歩くことになってしまいました。

毎度のことなのですけれど。
プログラムにおかしいところはないはずなのに(なにしろクロックを1/2にして、それに関係するところを変更するだけなので)、ああ、それなのに。
40字表示に切り換えると、画面が真っ暗。
何も表示されません。
「なぜだっ!」と、叫びたくなります。

ま。しかし。
そのように叫んでみても、問題が解決するものでもありません。
ここはやっぱり気を取り直して、あれこれ思いつくままにプログラムを直しつつテストを続けるしかありません。

そのようにしておりますうちに。
大体のところは、わかってきたように思います。
これはMAX7000S固有のことなのか、それとも一般にCPLD全般について言えることなのかはわかりませんが、たとえばある入力端子がオープンであるとか、信号入力にノイズが乗っているとか、あるいは信号の組み合わせ回路において遅延の影響が出るなどの場合に、いつでもそのことが動作異常につながるのではなくて、たとえばプログラムに何かの回路記述を追加したような場合に突然それが表面化して、もうめちゃめちゃの動作になってしまうことがあります。

今回のトラブルは一体何が原因だったのか?
そのことについては、プログラムの説明の中で書いていくことにしまして、とにかくは80字表示のみのCRTIF用VHDLプログラムと、それををもとにして、80字/40字表示切換型のVHDLプログラムに変更した部分を示しつつ、説明を加えていくことにします。

●80字/40字切換のための準備

下は前回お見せしました80字表示のみのCRTIF用VHDLプログラムでcntr1を定義している部分です。

      signal cntr1:std_logic_vector(2 downto 0);
cntr1はビットクロックをカウントして水平1文字(8ビット)分を規定するカウンタです。

ここに40字表示のための設定を追加します。

    SW80_40:in std_logic;

    signal cntr0:std_logic;
    signal cntr1:std_logic_vector(3 downto 0);
    
    signal ck:std_logic;    
まず最初に80字と40字を切り換えるためのスイッチ信号の入力を定義します。
SW80_40を外部入力端子として定義します。
それからcntr1の前段に置いて、40字の場合に入力クロックを1/2にするための1ビットカウンタcntr0を定義します。
cntr1はもともとは000〜111をカウントするため3ビットでよいはずだったのですが、少し理由があって4ビットに変更しました。

●入力クロックの選択

下は80字と40字を切り換えて表示できるように、入力クロックを選択するための記述で、80字/40字用のVHDLプログラムに新規に追加した部分です。

--clock select
process(CKIN,SW80_40)
begin
                if SW80_40='1' then
                        cntr0<=CKIN;
                elsif SW80_40='0' then
                        if CKIN'event and CKIN='0' then
                                cntr0<=cntr0+'1';
                        end if;
                end if;
end process;
EPM7128SLC84の外部でジャンパピンで設定することによって、SW80_40入力は80字のときに’1’、40字のときに’0’になります。
その入力を受けて80字のときはcntr0にはクロック入力CKINがそのままつながります。
40字のときは、CKINの立下りごとにcntr0がカウントアップされます。
cntr0は1ビットのカウンタなのでCKINを1/2分周した周波数のクロックになります。

●遅延が問題???

VHDLプログラムの流れからは少し飛びますが、説明の順序として、まずは「40字表示で画面が真っ黒」の件について書きます。
この問題の原因は水平表示文字数を決めるカウンタcntr2にありました。
80字表示と40字表示は、1文字に注目すると、ドット表示のクロック周波数を1/2にすればよいだけなので、1文字単位で動作する回路については同じ回路でいけます。
しかし1行に表示する文字数は80:40なので、水平方向の表示文字数、ブランキング期間などを文字を単位として決定するところでは、当然プログラムを変更しなければなりません。
水平方向の総表示文字数を決定しているのはcntr2です。
下は80字表示のみのCRTIF用VHDLプログラムのcntr2の記述です。

--cntr2
process(cntr1)  
begin                   
                if cntr1(2)'event and cntr1(2) = '0' then
                cntr2 <= cntr2 +"0000001";
                end if;         
                if cntr2="1110000" then 
                cntr2<="0000000";
                end if;          
end process;
水平方向の総表示文字数は112文字(=70H)ですから”1110000”(70H)のときにカウンタクリアしています。
その部分を80字/40字表示プログラムでは下のように変更しました。

--cntr2
process(cntr1,cntr2)    
begin
                if cntr1(2)'event and cntr1(2) = '0' then
                cntr2 <= cntr2 +"0000001";
                end if;
                if SW80_40='1' and cntr2="1110000" then 
                cntr2<="0000000";
                elsif SW80_40='0' and cntr2="0111000" and cntr0='1' then
                        cntr2<="0000000";
                end if;
end process;
40字表示では1文字を表示する時間が80字表示の倍になりますから、水平方向の総表示文字数は80字表示の1/2の56文字(38H)になります。
当然のこととして、cntr2は”0111000”(=38H)でクリアするようにプログラムすればよいはずなのですが…。
そこが問題でした。
水平方向のブランキング信号をオシロで確認すると、正規の期間よりもが短いことがわかりました。
どうも”0111000”ではなくて”0110000”あたりでクリアされてしまっているようです。
なぜだ?

そのようになる理由がどうにもわからず、あれこれ試行錯誤でおよそ半日を費やしてしまいました。
そのうちに、「どうやらビット6が関係しているらしい」ことがわかりました。
それも相当に摩訶不思議な絡み方です。
cntr2をクリアするための組み合わせ条件で、80字の場合のように”1110000”のとき(つまりビット6=1)のときはビット3が’0’、または’1’のいずれの場合にも正しい結果が得られます(”1110000”または”1111000”でクリアされる)。
ところがビット6=0のときはビット3を’1’にしても’0’にしても、どちらの場合も”0110000”のときにcntr2がクリアされてしまいます。

非同期カウンタの出力を組み合わせてAND(NAND)回路をつくると、上位ビットの出力が遅延するため、組み合わせによっては出力にヒゲが発生します。
組み合わせ信号の一部をNOTで反転させた場合には、NOTの分だけさらに遅延が加わるため、余計にヒゲが出やすくなります。
CPLDの場合でも同じことがいえるはず、ということは理解できます。
しかし、なぜビット6が奇妙な絡み方をするのか?
そこのところは全く謎です。
謎なのですが、どうやら組み合わせ回路の遅延が関係しているらしい、というところに目星がつきましたので、さらに試行錯誤した結果、上記プログラムリストのように”0111000”にさらにcntr0=’1’を加えたところ、40字表示でも正常に表示されるようになりました。

うーん。
こういうあたりは、やっぱりCPLDはブラックボックスだなあ、と思います。
しかし、今回の経験を通して、「組み合わせ回路では遅延に注意」ということを学んだように思います。
そういう意味では80字表示の場合の”1110000”も全く同様なのですが、こちらのほうは今のところ特に問題は出ていないので、しばらくはこのまま様子をみることにします。

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

CPLD入門![第58回]
2019.6.5upload

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