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

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



[第73回]


●VHDLサンプルプログラム1 82C55(6)

前回まで82C55回路プログラムのポート出力について書いてきました。
今回はポートからの入力です。

●A、B、Cポート入力

入力回路の記述は出力回路に比べると簡単です。
しかし出力回路に比べると危険を伴います。

--in data from port
process(IOR)
begin
        if IOR='0' then
                if ADRSIN="11110000" then
                        if ainout='1' then
                                DINOUT<=PA;
                        else
                                DINOUT<=paout;
                        end if;
                elsif ADRSIN="11110001" then
                        if binout='1' then
                                DINOUT<=PB;
                        else
                                DINOUT<=pbout;
                        end if;
                elsif ADRSIN="11110010" then
                        if chinout='1' then
                                DINOUT(7 downto 4)<=PCH;
                        else
                                DINOUT(7 downto 4)<=pchout;
                        end if;
                        if clinout='1' then
                                DINOUT(3 downto 0)<=PCL;
                        else
                                DINOUT(3 downto 0)<=pclout;
                        end if;
                else
                        DINOUT<="ZZZZZZZZ";
                end if;
        else
                DINOUT<="ZZZZZZZZ";
        end if;
end process;

出力回路はデータの向きがCPUデータバス→出力ポートになっています。
プログラムにまずいところがあっても、正しい出力が得られないだけで、CPUシステムに影響は及びません。
しかし入力回路はそれとは逆にデータの向きがCPUデータバス←入力ポートになります。
もしプログラムにまずいところがあると、CPUデータバスに影響が及んで、CPUシステムが誤動作してしまう可能性が出てきます。
上のプログラムでCPUから82C55回路にアクセスするとき以外は
DINOUT<=”ZZZZZZZZ”;
と書いて、82C55回路の側からはデータバスへの出力をハイインピーダンスにしているのはそのためです。
この文がないと、82C55回路に接続したCPUシステムが暴走してしまいます。

CPUがIN命令を実行すると、I/Oアドレスがアドレスバスに出力され、IORがアクティブ(IOR=’0’)になります。
そのときにCPUはデータバス上の値を読み込みます。
そこでポート入力回路はIOR=’0’のときだけ実行されるようにプログラムを記述します。
Aポートに対するIN命令ではアドレスは”11110000”(F0)になります。
そのときにもしもAポートの向きを保持しているainoutの値が’1’ならばAポートが入力モードに設定されていますから、Aポートから読み込まれた値がデータバス(DINOUT)に出力されます。
if ainout=’1’ then DINOUT<=PA;
のところです。
そうでないならば(つまりainout=’0’ならば)データバスにはAポートに出力されている値(paout)が出力されます。
DINOUT<=paout;
のところです。

アドレスが”11110001”(F1)ならばBポートに対する入力命令です。
Aポートと同様の記述になります。
アドレスが”11110010”(F2)ならばCポートに対する入力命令です。
そこまではelsifでうけますが、その中では前回書きましたように、上位4ビットと下位4ビットに対する命令が同時に行なわれますから、そこは上位4ビットと下位4ビットに対するそれぞれ独立したif文で記述しています。

その次にあるelseは、「アドレスがF0、F1、F2以外のときは」を意味しています。
そのときはデータバスへの出力をハイインピーダンスにします。
DINOUT<=”ZZZZZZZZ”;
です。

もうひとつelseがあります。
これは「IOR=’0’以外のときは」を意味しています。
そのときもデータバスへの出力をハイインピーダンスにします。
DINOUT<=”ZZZZZZZZ”;
です。

プログラムの中で必要に応じていくつかのprocess文を書いてきました。
ここでひとつ忘れてはならない重要な約束事があります。
<=の左辺に置く信号名は、ひとつのprocess文の中で記述しなければならないという約束事です。
たとえば前回説明したCポートの通常の出力とビット出力を別々のprocess文に分けて書くとコンパイルエラーになってしまいます。
今回の例でいうと、Aポート、Bポート、Cポートの記述を特に工夫をしないでそのまま別々のprocess文に分けて記述するとコンパイルエラーになってしまいます。
DINOUT<=という文が複数のprocess文の中に出てきてしまうからです。
うっかりして気が付かないで2つ以上のprocess文か組み合わせ文で<=の左辺に同じ信号名を書いてしまうことがあります。
するとコンパイル時に下のようなエラーメッセージが出てしまいます。

Error (10028): Can't resolve multiple constant drivers for net "pclout[3]" at trngio1d.vhd(51)

信号名の二重定義が行なわれている、というエラーメッセージです。
複雑な回路をVHDLプログラム化しようとすると、そこをクリアするために悩む場面がでてくるかもしれません。
そんなときはちょいとした頭の体操と思って考えてみるのもよいかもしれません。

CPLD入門![第73回]
2019.6.20upload

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