前ページでは「信号入力→演算→信号出力」という一連の流れを繰り返し行うことで外部で起きた現象に対して即座に反応するシステムを作ることができるという話をしました。ここではある信号が入力されてきた時に、その信号の内容によって実行するプログラムの内容自体を変化させる方法について見ていきたいと思います。例えば前ページで紹介した「信号入力→演算→信号出力」という一連の流れの中で、「演算」の部分の内容を「信号入力」の内容によって切り替えるような処理です。ここでは例としてP3入力端子の最下位ビットに接続されたスイッチがONの時とOFFの時で別の演算を行い「信号出力」の内容を変化させるプログラムを作ってみたいと思います。なお切り替える演算内容は次のようにします。
スイッチがONの時 :P4入力端子から入力した内容を1ビット分左へシフトした数値をP1出力端子より出力する。
スイッチがOFFの時 :P4入力端子から入力した内容を1ビット分右へシフトした数値をP1出力端子より出力する。
以下がそのプログラムのコードです。
【 0 】 INA 【 1 】 30
【 2 】 INB 【 3 】 31
【 4 】 LD 【 5 】 30
【 6 】 AND 【 7 】 32
【 8 】 JZC 【 9 】 20
【 10】 LD 【 11】 31
【 12】 SL 【 13】 33
【 14】 ST 【 15】 34
【 16】 OUTA 【 17】 34
【 18】 JUMP 【 19】 0
【 20】 LD 【 21】 31
【 22】 SR 【 23】 33
【 24】 ST 【 25】 34
【 26】 OUTA 【 27】 34
【 28】 JUMP 【 29】 0
【 30】 0 【 31】 0
【 32】 1 【 33】 1
【 34】 0
まずINA命令によってP3入力端子からの入力内容が30番地へ保存され、続くINB命令によってP4入力端子からの入力内容が31番地へと保存されます。
次にLD命令によって30番地に保存されているP3端子の入力内容をワーキングレジスタへと読み込み、続くAND命令によって32番地の内容とワーキングレジスタの内容をAND演算します。32番地の内容は”1”なので、P3入力端子の内容と”1”(8ビットの2進数表現では00000001となる)を各ビットでAND演算するという意味になります。
P3入力端子の内容と00000001を各ビットでAND演算すると、P3入力端子の最下位ビットが1の場合にのみ答えが1となり、それ以外の場合は答えは0となることが分かります。(AND演算では両方の数値がともに1の場合にだけ答えが1になるため。)
AND演算の結果が0になった場合、これはすなわちP3入力端子の最下位ビットに接続されたスイッチがOFFになっていた場合を意味しますが、この場合にはALUのフラグが「1」になるので次のJZC命令で処理の流れが20番地へと飛ばされます。逆にAND演算の結果が1になった場合、これはP3入力端子の最下位ビットに接続されたスイッチがONになっていた場合を意味しますが、この場合にはALUのフラグが「0」のままなのでJZC命令でのジャンプは起こらず、処理の流れはそのまま次の番地である10番地へと進みます。
JZC命令によって20番地へ処理が移動した場合、続くLD命令によって31番地に保存されていた内容がワーキングレジスタへと読み込まれます。ここで31番地に保存されている内容というのはP4入力端子から入力した数値です。この数値を次のSR命令によって右方向へシフトします。シフトするビット数は33番地に保存されている数値分だけということになります。33番地には1が書き込まれているので、ワーキングレジスタの値は1ビット分だけ右シフトされることになります。
スポンサーリンク
SR命令によって1ビット右シフトされたワーキングレジスタの値はその後、ST命令によって一度34番地へ保存され、続くOUTA命令によって34番地からP1出力端子へと出力されます。最後はJUMP命令によって処理が0番地まで戻されます。
次にJZC命令によってジャンプが起こらなかった場合、処理の流れはそのまま10番地へと進みます。この場合も同様に10番地のLD命令によってP4入力端子から入力した数値がワーキングレジスタへと読み込まれ、シフト命令によって値がシフト演算された後、P1出力端子へと出力され、18番地のJUMP命令によってプログラムの最初に戻ります。JZC命令によってジャンプした場合と異なるのはシフト命令がSR命令の右シフトからSL命令の左シフトへ変わっているところだけです。
上記のプログラムではP3入力端子からの入力内容によって右シフトを行う処理と左シフトを行う処理を切り替えていることが確認できたと思います。このような処理を「条件分岐」と言います。演算命令の結果によって変わるフラグの値とJZC命令を組み合わせて用いることによって様々な条件を判断し、処理の内容を変えることができるようになります。
次にアセンブリ言語で書かれたプログラムを以下の対応表に従って機械語へ変換します。
各命令の機械語への対応表
JUMP :1
JZC :2
LD :3
ST :4
SET :5
LHI :6
ADD :7
SUB :8
AND :9
OR :10
NOT :11
SL :12
SR :13
INA :14
INB :15
OUTA :16
OUTB :17
機械語へ変換されたプログラム
【 0 】 14 【 1 】 30
【 2 】 15 【 3 】 31
【 4 】 3 【 5 】 30
【 6 】 9 【 7 】 32
【 8 】 2 【 9 】 20
【 10】 3 【 11】 31
【 12】 12 【 13】 33
【 14】 4 【 15】 34
【 16】 16 【 17】 34
【 18】 1 【 19】 0
【 20】 3 【 21】 31
【 22】 13 【 23】 33
【 24】 4 【 25】 34
【 26】 16 【 27】 34
【 28】 1 【 29】 0
【 30】 0 【 31】 0
【 32】 1 【 33】 1
【 34】 0
※「FPGAとVerilog HDLで作るCPU」の方で実際にFPGA上にCPUを作った方は”cpu.mif”に上記の機械語を書き込むことでプログラムを実行することができます。”cpu.mif”の変更を適用するには再度、Quartusプロジェクトのコンパイルを行う必要があります。
<戻る 次へ>