[新連載]CPLD入門!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使うことになるだろうと思ってはいたのですが。
何を今頃になって、というようなものですが。
ようやく本気で、CPLDと四つに取り組みます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第61回]
●お電話をいただきました
前回をUPしましたところ、昨日メールをいただいたto…様から、重ねてメールをいただきました。
さらに本日になりましてから直接お電話までいただき、私が考え違いをしている点について、長時間をかけて丁寧にご説明いただきました。
どうやら私はprocess文についてevent文について大きな誤解をしていたようで、そこのところを丁寧にお教えいただきました。
私はprocess文のbegin〜end processの間は記述した順に実行されるもの、と思い込んでいたのですが、そこが間違っていたようです。
if −’event then
end if
の間は、そのなかにelsifがあればそこは前から順に実行(ifの真偽を判定)されるけれども、
if −’event then
end if
の外にある非同期回路の記述は記述順序に関係なく実行されてしまうということで、それはbegin〜end processの中にあっても、記述した順序とは無関係に実行される、という理解が必要でした。
前回私が書いた内容では、そこのところがわかっていない、ということでその点をあらためてメールでご指摘いただいたうえに、さらにお電話までいただいたのでした。
今回メールとお電話をいただいたto…様には、わざわざ前回のプログラムリストの最初から終わりまでの中で変更すべきところを全て直していただいたリストをメールにてお送りいただきました。
前回書きました−−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;
|
if cntr2=”1110000” then 以下の文はcntr1(2)クロックによって動いているときに常時実行されるためヒゲが発生します、とのご指摘でした。
私はそれはわかったつもりで、でもそうしなければ仕方がないとの認識でしたが、そこが考え違いでした。
いただいたメールでは、前回の80字/40字表示のリストをもとに、次のように直してありました。
--cntr2
process(cntr1)
begin
if cntr1(2)'event and cntr1(2) = '0' then
if SW80_40='1' and cntr2="1110000" then
cntr2<="0000000";
elsif SW80_40='0' and cntr2="0111000" and cntr0='1' then
cntr2<="0000000";
else
cntr2 <= cntr2 +"0000001";
end if;
end if;
end process;
|
メールのあとでいただいたお電話で、
ヒゲを出さないために、if cntr2=”1110000” then 以下の文を、if event文の中に入れるべきです、とお教えいただきました。
そのように説明していただいて、やっとそこのところの理解ができました。
私が書いたもとの記述では、cntr2=”0111000”をチェックするif文は非同期に常時実行されるため、ヒゲが発生して思わぬときにcntr2がクリアされてしまう可能性があります(実際にその通りでした)。
直していただいた文では、if cntr1(2)’event 〜 最後のend ifまでの文は、cntr1(2)が’1’から’0’になったエッジのときのみ実行されるため、その時点(瞬間)では
cntr2<=cntr2+”0000001”
は実行前なのでいわばラッチして固定している状態でcntr2=”0111000”のチェックができる、と理解しました。
あれ?
そうすると?
cntr2が”0111000”になったことがわかるのは、もうひとつ次のeventのときということになるのでは?
ということで、そこのところを上のリストのように直して、オシロで波形を見て、そうなることを確認しました。
写真に撮ったはずなのですが、その過程であれこれ試行錯誤をしていたものですから、あとで確認してみたところ、肝心の写真は撮れていませんでした。
しかしそういうことですので、下のようにあらためて直したところ、誤動作することなく期待した通りの画面表示が得られました。
--cntr2
cntr1_2<=cntr1(2);
process(cntr1_2)
begin
if cntr1_2'event and cntr1_2 = '0' then
if SW80_40='1' and cntr2="1101111" then
cntr2<="0000000";
elsif SW80_40='0' and cntr2="0110111" then
cntr2<="0000000";
else
cntr2 <= cntr2 +"0000001";
end if;
end if;
end process;
|
cntr1(2)の代わりにcntr1_2を定義して使っていますが、そこは今回の問題には関係していません。
どちらでも同じ結果です。
じつはto…様からいただいたメールでは、このほかのところも直していただいているのですが、そこについては私の理解が十分ではないところもあるらしくて、まだ問題ありという結果になりました。
本日は時間がありませんので、それについては次回に説明することにいたします。
それはそれとしまして、丁寧なメールをお送りいただいたうえに、長時間お電話にてお教えいただきましたto…様にはあらためて深く感謝申し上げます。
今後ともご指導ご鞭撻をお願いいたします。
CPLD入門![第61回]
2019.6.8upload
前へ
次へ
ホームページトップへ戻る