VBAの勉強を始めてみた

色々試しています。

CPUよもやま話(マルチプレクサで転送先と転送元を切り替える)

前回までの記事に登場したモノをすべて繋いでCPUの形にしていきたいと思います。しかし「レジスタとクロック」の回でも書いたように、ただ単純に繋ぐだけでは回路が固定であり、処理内容が永遠に同じものになってしまいます。命令によって回路を切り替えできるようにしなければダメです。
ということで、マルチプレクサにご登場いただきましょう。

 

マルチプレクサの動作を見てみる

マルチプレクサとはふたつ以上の入力をひとつの信号として出力するためのモノです。文章で説明するよりも、下の図を見てもらったほうが手っ取り早いです。

2チャンネルマルチプレクサ

f:id:kouten0430:20190310182945p:plain

 

4チャンネルマルチプレクサ

f:id:kouten0430:20190310183021p:plain

 

このように、選択信号の組み合わせによって回路を切り替えることができるのがマルチプレクサです。選択信号=命令です。鉄道の線路がダイヤによって切り替わり、車両の進路を変更するようなもんです(たぶん)
上の図はあくまで概念図です。実際は複数の論理ゲートで構成されています。選択信号のビット数が増えれば、扱えるチャンネルが8、16、・・・・・・というふうに増えます。

 

転送先を切り替える(レジスタの自己保持・外部データ読み込みを切り替える)

下は、2チャンネルマルチプレクサを使ってレジスタの自己保持・外部データ読み込みを切り替えできるようにしたものです。(MUXはマルチプレクサの略)

f:id:kouten0430:20190310183328p:plain

~Loadが1なら、クロックの立ち上がりでOutputの値を自己保持
~Loadが0なら、クロックの立ち上がりでDataの値を読み込む

 

つまり、転送元となる何処かからのデータをレジスタに転送するのなら、該当レジスタの~Loadに0を与え、何もしないのなら~Loadに1を与えます。

 

転送元を切り替える(ALUの入力を切り替える)

次に、ALUの入力を4チャンネルマルチプレクサ2個で切り替えできるようにします。

f:id:kouten0430:20190310183632p:plain

例えば、図のマルチプレクサに下の選択信号を与えると、レジスタAとレジスタBの値を加算することができます。
SelectAに0
SelectBに0
SelectCに1
SelectDに0

ALUの出力は各レジスタのDataへ戻すので、このマルチプレクサ2個で実質、転送元の切り替えをしていることになります。(ちなみに4チャンネル目は不使用。GND〔接地記号のアレ〕と、即値をどう使うかは後で説明します)

 

4ビットCPUの形になるように繋いでみる

ここまでを踏まえ、前回までの記事に登場したモノ。つまり、加算器メモリレジスタクロックCフラグプログラムカウンタをマルチプレクサで切り替えできるように繋いでいきます。

f:id:kouten0430:20190310184539p:plain

※4ビット/配線(ただし、制御信号とフラグは 1ビット/配線)
※2チャンネルマルチプレクサはレジスタの中に隠した

書籍「CPUの創りかた」を参考にしたので、著者に敬意を表し、この回路をLTD4(Logisimで創ったとりあえず動作する4ビットCPU)と名付けます!(←あまり重要ではない)
処理の内容によって、信号の与え方とデータの流れがどうなるのか、次にまとめてみました。

 

MOV A,B を行う場合

f:id:kouten0430:20190310184912p:plain

f:id:kouten0430:20190310185011p:plain

説明:レジスタBの値をレジスタAに転送する。
ポイント:レジスタの値は必ずALUを通過するので、もう片方は即値(0000)となるようにする。

 

MOV B,A を行う場合

f:id:kouten0430:20190310185150p:plain

f:id:kouten0430:20190310185210p:plain

説明:レジスタAの値をレジスタBに転送する。
ポイント:レジスタの値は必ずALUを通過するので、もう片方は即値(0000)となるようにする。

 

MOV A,即値 を行う場合

f:id:kouten0430:20190310185334p:plain

f:id:kouten0430:20190310185356p:plain

説明:即値をレジスタAに転送する。
ポイント:即値は必ずALUを通過するので、もう片方はGND(つまり0000)となるようにする。

 

MOV B,即値 を行う場合

f:id:kouten0430:20190310185452p:plain

f:id:kouten0430:20190310185510p:plain

説明:即値をレジスタBに転送する。
ポイント:即値は必ずALUを通過するので、もう片方はGND(つまり0000)となるようにする。

 

ADD A,B を行う場合

f:id:kouten0430:20190310185554p:plain

f:id:kouten0430:20190310185606p:plain

説明:レジスタAの値とレジスタBの値を加算して、レジスタAに転送する。
ポイント:即値は使わないので0000にしておく。

 

ADD B,A を行う場合

f:id:kouten0430:20190310185645p:plain

f:id:kouten0430:20190310185700p:plain

説明:レジスタAの値とレジスタBの値を加算して、レジスタBに転送する。
ポイント:即値は使わないので0000にしておく。

 

ADD A,即値 を行う場合

f:id:kouten0430:20190310185738p:plain

f:id:kouten0430:20190310185750p:plain

説明:レジスタAの値と即値を加算して、レジスタAに転送する。
ポイント:即値は任意の値にしておく。

 

ADD B,即値 を行う場合

f:id:kouten0430:20190310185832p:plain

f:id:kouten0430:20190310185847p:plain

説明:レジスタBの値と即値を加算して、レジスタBに転送する。
ポイント:即値は任意の値にしておく。

 

JMP 即値 を行う場合

f:id:kouten0430:20190310185925p:plain

f:id:kouten0430:20190310185942p:plain

説明:Cフラグとは無関係に即値をプログラムカウンタに転送する。
ポイント:即値は必ずALUを通過するので、もう片方はGND(つまり0000)となるようにする。

 

JC 即値 を行う場合

f:id:kouten0430:20190310190027p:plain

f:id:kouten0430:20190310190043p:plain

説明:Cフラグが1の時のみ即値をプログラムカウンタに転送する。
ポイント:即値は必ずALUを通過するので、もう片方はGND(つまり0000)となるようにする。

 

JNC 即値 を行う場合

f:id:kouten0430:20190310190127p:plain

f:id:kouten0430:20190310190143p:plain

説明:Cフラグが0の時のみ即値をプログラムカウンタに転送する。
ポイント:即値は必ずALUを通過するので、もう片方はGND(つまり0000)となるようにする。

 

プログラムからマルチプレクサを切り替えできるようにしたい

とりあえず、各処理とフラグの状態とマルチプレクサに与える信号を一覧にしたものがこちら。

f:id:kouten0430:20190310190348p:plain

さあ、ここまでくれば、あとはメモリから取り出したプログラム(8ビット)から上位4ビットを使ってマルチプレクサを切り替えできるようにすればいいだけです。Cフラグも使わないとね。

f:id:kouten0430:20190310190440p:plain

あれ?マルチプレクサへの信号は7つ必要なのにオペコードは4ビットしかない・・・・・・どうすんのコレ?(@_@;)
ということで次回に続きます。