MPUについての勉強~MPUの構成~

2020/11/14

組み込み

はじめに

最近マイコンなどに触れる機会が増えたのですが、今まで全く勉強したことをまとめていきたいと思います。今回はMPUの構成について調べたのでまとめました。

学生時代も情報系ではなかったため、マイコンについての知識も乏しいので間違っていることがあれば適宜教えていただきたいです。

ちなみに今回参考にした本はこちらです。
古い本ですが、基礎を勉強するうえでは問題ないと思ってます。

ちなみに私の知識ではこの本の中に知らない単語がたくさん出てくるので、適宜調べていきます。

 MPUとは

MPUとはMicro Processor Unitの略です。本でも"コンピュータ"と置き換えて差し支えがないと書いてあり、調べてみてMPU≒CPUとしているサイトもあり、定義があいまいです。

本に記載されていた図1を元に私の解釈ではCPUとメモリなどの周辺デバイスを追加したものがMPUで、CPUの上位互換だと認識しました。

図1:典型的なMPUの構成要素[1]

ここからは図1に記載の要素がそれぞれ何をしているかを見ていきます。

記憶装置(メモリ)とアドレス/データバス

MPUにはプログラムを保存するための記憶装置が必要となります。
記憶装置はメモリと呼ばれRAM(Random Access Memory)とROM(Read Only Memory)
の2つがあります。ROMは名前の通り、読み込み専用でRAMは読み書きできるという特徴があります。(私の知っている知識が正しければROMは電源ON/OFFに限らずデータが保持され、RAMは電源がOFFられるとデータが消去されてしまいます)

また、メモリは複数の保存場所の集合となっており、保存場所を特定するためにアドレス(住所のようなもの)が割り振られています。アドレスを指定するとそこに保存されているデータを読み込む(RAMの場合は書き込む)ことができます。

メモリは基本的にMPUの外部にあるため、メモリとMPUはバスと呼ばれる信号線で接続されています。アドレス情報をやり取りするバスをアドレスバス、データの情報をやり取りするバスをデータバスといいます。(図2参照)
図2:メモリの仕組み[2]

メモリ内の1つの保存場所(以下アドレス)に保存されるデータの大きさはいくつでもいいのですが、1 byte(8bit)となっているのが主流らしいです。(2004年の本なので、現在はどうなっているか不明ですが...)

しかし、MPUが扱うデータは16bitまたは32bitが多く使わるため、MPUでは16bit/32bitのデータをメモリから取り出せるようにしています。

1つのアドレスに1byte保存される形式をバイトアドレス方式といい、16bit/32bit保存されるのをワードアドレス形式といいます。

バイトアドレス形式とワードアドレス形式[3]
補足によりますが、1つのアドレスに16bitまたは32bitが保存されるかはMPUによるみたいです。16bitの場合は16bitをワード、32bitをダブルワードと呼び、32bitの場合は32bitをワード、64bitをダブルワードと呼ぶみたいなので、使用するMPUによって言葉が変わってくるので注意が必要です。

リトルエンディアン/ビッグエンディアン

バイトアドレス形式では気にしなくてよかったのですが、ワードアドレス形式ではバイト並びを気にしなくてはいけません。例えば32bitで0x12 0x34 0x56 0x78をメモリに格納する場合上位アドレスから格納するのか、下位アドレスから格納するのかを気にしなければいけません。上位から格納するのをビッグエンディアン、下位から格納するのをリトルエンディアンといいます。(名前の由来が気になった方は"エンディアン ガリバー旅行記"で調べてください)

図3:リトルエンディアン/ビッグエンディアンの違い[4]

この2つでアドレスの指定の仕方が違うだけなので、データバスを見ているMPUとしては
どちらでも0x12 0x34 0x56 0x78と読み取ることができます。

命令/データの取り込み

まず初めにメモリの中にはデータだけでなく、どんな処理をしなければいけないかの命令も保存されています。例えば3+5の計算をしたいとしたときにメモリには足し算をするという命令部(オペコード)と足し算の対象である「3」「5」というデータ部(オペランド部)が保存されてます。(次から命令 = 命令部 + オペランド部としてます。)
(補足:私が若干つまづいてしまったのですが、データ部には実際のデータ(ここでいう「3」「5」)は格納されている場合もあるのですが、どこのアドレスに対象のデータがあるかが格納されている場合もあるみたいです。詳しくは後ほど紹介します。)

なのでMPUがまず最初に行わなければいけないのはメモリに格納された命令を内部に取り込むことです。そのためにはどこのアドレスに命令が入っているかを指定してあげる必要があります。

MPUにはプログラムカウンタ(以下PC)と呼ばれる記憶機構(レジスタ)が備わっており、そこでアドレスの管理をします。

メモリはPCが指定したアドレスに格納された命令をデータバスを通じてMPUに送信します。
MPUは命令レジスタと呼ばれる記憶機構に命令を保存します。この命令を取り込むことを命令フェッチといいます。MPUが命令を取り込んだらプログラムカウンタの中身を次の命令が入っているアドレスに更新します。(通常はメモリから取り込んだ命令のバイト数だけ増加)

図4:命令の取り出し(フェッチ)[5]

命令実行制御/データの加工

命令実行制御

次に命令フェッチで読みだした命令を実行する作業に取り掛かります。
最初に命令の中から命令デコーダと呼ばれる装置で命令部を取り出します。

次にオペランド部から対象のデータを取り出します。
オペランド部からデータを取り出すためには対象データがどこに保存されているかアドレスを計算する必要があります。(アドレス部に計算対象のデータが入っている即値アドレス指定、対象データがどこのアドレスに格納されているかを提示する直接アドレス指定など。これらをアドレス修飾といいます。詳しくは参考文献[6]を見てください)
図5:アドレスの計算[5]

対象データのアドレスがわかった所で、次に実際にデータを取り出してれレジスタに格納します。この格納するレジスタのことを汎用レジスタ(本ではオペランドアドレスレジスタ(とりあえずそのように命名)と記載)といいます。この汎用レジスタに格納することをオペランド読み出しといいます。
図6:オペランド読み出し[5]

これで命令が取り出せたので命令を実行できるようになります。
命令の実行はクロックと呼ばれる周期的な信号の変化に合わせて実行されます。

例えばクロックの周波数が1kHzだと1秒間に1000回クロックが変化するので、単純に考えれば1000回の命令を処理することができます。
(1つの命令が1クロックで動作しない場合もあるらしいです。Intel 4004の場合は1つの命令を実行するのに最低8クロック必要とのこと)

以上をまとめると命令実行制御部は以下のような状態をクロックの周期に合わせて遷移していきます。

命令取り込み→命令デコード→命令実行

データの加工

最後にオペランド読み出ししたデータをALU(Arithmetic Logic Unit)と呼ばれる演算器に与えてデータの加工を行います。ALUは加減算を行うArithmetic Unitと論理演算を行うLogic Unitで構成されてます。

図7:レジスタとALU(オレンジ部分)[7]
ちなみに画像ではレジスタ2つからALUの入力をもってきていますが、本では外部メモリからも持ってくる場合があると記載がありました。

これはMPUの設計思想によって異なるみたいです。
外部メモリから取り込んだデータは必ずレジスタに保存し、ALUは必ずレジスタから入力を受け取りのはRISCの考え方で、どのメモリの組み合わせでも問題ないのはCISCの考え方らしいです。この辺は後ほど調べてまとめます。

データ加工が終わったら結果をメモリに保存して終了です。
今までの一連の流れをまとめたものが図8です。
図8:MPUの処理流れ[8]


命令形式

順番が前後してしまいましたが、命令レジスタに格納されている命令についてみていきます。MPUによって格納されているフォーマットが異なるみたいです。このフォーマットを命令形式といいます。図8に命令形式の例を示します。


図9:加算命令の命令形式例[9]
図8記載の用語について説明します。
op:オペコードが記載されているフィールド。加算する。データをコピーするなどの命令部が記載されてます。このフィールド長が2bitなら4種類、3bitなら8種類の命令を選ぶことができます。
rs,rt:第一/第二ソースレジスタのことです。「3」+「5」の3と5にあたる部分です。(先ほども説明しましたが、即値で入ってない場合もあるので注意です。)
rd:ディスティネーションレジスタ。計算結果をどこに格納するかを指定するところ。
shamt:シフト命令をした際のシフト量
funct:opフィールドで表現しきれない場合に補助オペコー ドとしてopフィールドを拡張する形で用いるフィールド。[10]

命令形式にはR形式、I形式、J形式などがあるみたいです。詳しく知りたい方は参考文献[11]を参照してください。

補足集

オペランド方式とは[13]

命令実行制御/データの加工の章で紹介したオペランド(データ部)ですが、指定の仕方に種類があります。何個のオペランドを指定するかによって種類があるので紹介します。

最初に紹介するのは3オペランド形式です。
命令形式の所で紹介した加算形式がこれにあたります。(先ほどの例は3つのオペランドの後に拡張部分が存在しているみたいです。)

オペランド3にオペランド1+オペランド2の結果を格納してくださいという風にできるので元のデータを残しながら計算をすることができます。
デメリットとしては命令が長くなってしまうので、メモリを食ってしまうことです。

次に2オペランド形式です。
こちらは元のデータの片方が消えてしまう形式です。
例えばオペランド1にオペランド1+オペランド2の結果を格納してくださいという風にするので、オペランド1にあった古いデータは上書きされてしまいます。

次に1オペランド形式です。
特定のアキュムレータを使ったものです。
例えばオペランド1とアキュムレータの中のデータを足し算してアキュムレータの中に戻すという形です。アキュムレータが何か不明で調べましたがレジスタのことみたいですね。[13]

最後に0オペランド形式です。
こちらはスタック形式の構造に使われる命令みたいです。スタックに格納されているデータを2つ取り出して加算などの処理をしたのちに再びスタックにデータを入れるもの見たいです。特殊なケースらしいです。

まとめ

今回はマイコンの知識を深めるためにMPUについて調べ、
MPUの構成とMPUが計算した結果を保存するまでの流れをまとめました。

参考文献

[1]マイクロプロセッサ・アーキテクチャ入門/CQ出版/中森 章/2004

今回は引用しなかったが、参考にした文献

自己紹介

はじめまして 社会人になってからバイクやプログラミングなどを始めました。 プログラミングや整備の記事を書いていますが、独学なので間違った情報が多いかもしれません。 間違っている情報や改善点がありましたらコメントしていただけると幸いです。

X(旧Twitter)

フォローお願いします!

QooQ