先週は、マイコンを知るのに最適なプログラム言語がアセン マイコンはどう動いている
ブリ言語であると教えられた哲さん。今週はじめに、子供の
ある質問で窮してしまいました。コンピュータは、どう動く
のかと質問されて、うまく答えられなかったのです。動作の
カラクリがわかれば、よりプログラムを作成しやすいのでは
考えて、今日は愛犬ロボを引っ張るようにして、やって来ま
した。
哲 :おーい、いるかい。 啓二:いるよ。早速、今日のお題に入るか。 哲 :いや、今日は質問があるんだ。 マイコンって、どうやって動いているんだ。 啓二:どうって、普通のコンピュータと同じだよ。 マイコンは、マイクロコンピュータの略だもの。 大小には関係ないんだ。 哲 :じゃあ、あの4つの動作でいいのか。 命令取得(Fetch)→解読(Decode)→実行(Execute)→結果保存(Write) というので。 啓二:ああ、それでいいよ。ただし、命令を取出したり、実行したり するためには、PC(プログラムカウンタ)が必要だし、高速 動作させるために、いろいろと工夫しているけれど。 哲 :どんな工夫なんだ。 啓二:まず、パイプライン処理と言って、4つの動作を並列に動作 させるようにしている。 命令取得→解読→実行→結果保存→命令取得→解読 命令取得→解読→実行→結果保存→命令取得 というようにさ。 あとは、命令とデータを別個のメモリに入れておいて、 命令とデータを1クロックで取得可能なようにする、 ハーバードアーキテクチャを使ったマイコンもある。 哲 :ふーん。そうなんだ。 啓二:で、前に話したと思うんだが、実際には、マイクロプログラム と呼ぶ、クロックで、カウンタとレジスタ内容を移動する順序 回路でコンピュータを動かしている。 哲 :ハーバードアーキテクチャにするメリットは何だ。 啓二:命令とデータの利用できる幅を、変えてしまえるし、 1クロックで命令とデータを同時に取得できる。 命令を12ビット幅、データを8ビット幅になんかも できるなあ。確か、PICがこの形式だ。 哲 :命令とデータの幅を8ビットにして、同じメモリに 入れておくと命令取得に、2回メモリアクセスしない と駄目で、ハーバードアーキテクチャの2倍時間が 必要か。 啓二:そういうこと。でも、何事も一長一短があるんだ。ハーバード アーキテクチャの場合、自分自身で命令を書き換えたりする ようなプログラムは作成するのは、すごく難しいんだ。 哲 :前にMAR、MDRとかいうレジスタで説明してくれたよな。 あれを、もう少し、詳しく説明してくれないか。 啓二:いいよ。プログラミングモデルの中にはPCが出てくるが、 他にもマイコン内部には、たくさんのレジスタがあるんだ。 MAR:Memory Address Register MDR:Memory DataRegister IR :InstructionRegister が、最初にでてくるかな。 哲 :PCの内容を、そのままMARに入れるのか。 啓二:そういうときもあるが、実際に命令があるのが、PCが 指しているアドレスではないこともある。まあ、PCの 値が、そのままMARに行くとしてよいよ。 命令を取得するときは、PCの値をMARに入れて、MAR からメモリにアドレスが出て、命令がデータとして出てくる。 哲 :そのデータをMDRに入れるんだ。 啓二:そういうマイコンもあるけれど、高速動作のために、 IRに直接入れる方が多い。MDRに入れてから、 IRに移すと、2度手間でクロックが余計になるんだ。 哲 :そうか。でも、ビットサイズが異なることもあるから、 まずいんじゃないか。 啓二:ワンチップマイコンは、メモリもI/Oも、ひとつのパッケージ 内に入れてあるんで、内部でビット幅が異なっても問題はないの。 複数チップでの構成だと問題になるが、パッケージ内部で線を 引くのは、何も問題ない。 哲 :IRに入ってきた命令を、解読するとしているけれど、実際には どう動かしているんだ。 啓二:IRには、1と0を組み合わせたパターンが入ってくる。 どこかのビットが立っていれば、それに対応した内部が 動作を始めるようにしておく。 1ビットのトリガーで、対応するシーケンサを走らせる という方が正確かな。 哲 :シーケンサって、MIDIや何かのシーケンサと同じようなものか。 啓二:うん、そうだよ。自動販売機の動作をイメージするとよい。 自動販売機は、お金とボタンで指定された商品とお釣を出す だろう。お金とボタンが、シーケンサのトリガーになるのさ。 C言語のコードで記述すると、こんな感じになる。 switch ( state ) { case 0 : /* お金とボタン待ち */ if ( start_trigger == ENABLE ) { state++ ; } break ; case 1 : /* 商品出力 */ send_goods(); state++ ; break ; case 2 : /* お釣計算 */ calc_change(); state++ ; break ; case 3 : /* お釣出力 */ if ( return_change > 0 ) { send_change(); } state++ ; break ; case 4 : /* お釣出力 */ state = 0 ; break ; } 哲 :フラグのstart_triggerが、このシーケンサを起動して、 自動的に停止するのか。うまくできているなあ。 啓二:これをデジタル回路で実現すると、シーケンサになる。 関数で記述している部分も、実際はフラグを利用して別の シーケンサを動かしているんだ。 哲 :カウンタとレジスタの値を操作するというのが、よくわかるなあ。 啓二:そうだろう。これが、コンピュータの内容動作ってこと。 運動会の借り物競争と同じかな。 自動販売機の中には、PLC(Programmable Logic Controller) っていうのが、入っている。これが、コンピュータと 同じような処理をやっている。 哲 :そう言えば、自動販売機の中をあけたときに、弁当箱 くらいの大きさの装置を見たことがあるなあ。中身の 詰まった缶を持ってきた担当者が、何やら数字を打ち 込んでいた。あれば、PLCだったのかな。 啓二:多分そうだよ。打ち込んでいた数字は、自動販売機に 入っている缶の数だろうなあ。コーラの缶が全部なく なれば、「売切」ランプが点灯するだろう。あれは、 PLCがやっているんだ。 哲 :PLCって、どうやってプログラムを入力するんだろう。 アセンブリ言語かな。それともC言語かな。 啓二:ラダーっていうリレーの動作を記述する言語でプログラムする。 実際には、PLCに内蔵しているコンピュータの機械語に変換 されるんだが、有接点回路の動作記述用ラダー言語で書いて いるはず。 リレー動作を理解できる機械屋さんや、プログラム言語を 知らない技術屋でも、1週間程度の訓練でPLCのプログラム を作成できるようだよ。 哲 :へえー、そうなんだ。子供には、自動販売機の動作で説明 するよ。今度から、自動販売機でビールを買うときは、PLC のことを思い出しそうだ。 啓二:お前、何でもビールに掛けてしまうんだな。 ビール漬けの頭じゃいいアイデアもでないぞ。 少しは、節制しろ。