Turing Complete “RAM” and “Push and Pop”

RAM

Turing Complete、やってます。
RAM追加したところです。
とりあえず突貫で作りましたが、単純にin1、in2、outを3bit decoderでスイッチ制御で選択しているだけですね。

5番レジスタへの接続をRAMへとつなぎ変えてみました。
RAMのaddressへは4番レジスタを常に入力しています。
5番レジスタへほかのRAMと同様にSave、Loadできるのはいいですが、addressも指定したいとなると引数をどう指定すればいいか、というのが変更量を抑えたいときに思い浮かばないための苦肉の策ですね。

次がStack追加で、少しいろいろ窮屈になってきているのでここで思い切ってリファクタリング。

Stack追加するとなると、少し1byte目、2byte目がひっ迫してるのが嫌になってきます。
4bit decoderを使うようにした方がいいかもしれません。
まあこれは、4bit目で二つの3bit decoderをスイッチすればいいだけ。

さて、RAMへのアクセス方法を変更しましょう。

4byteあるので、RAMについてはこんな感じを想定。

0123
RAM Op
xx001xxx
コピー元
値格納regアドレス
or Intermediate
コピー先
RAMアドレス格納regアドレス
or intermediate
Write
xxxxxxx0
RAM Op
xx001xxx
コピー元
RAMアドレス格納regアドレス
or intermediate
コピー先
値格納regアドレス
Read
xxxxxxx1

1byte目のうち、bit0-2はCalculation、bit5はif文、bit6・7はimmediate指定なので、空いているのはbit3-4のみ。
なので、ここでRAMかStackの操作であることを意味するようにします。8ならRAM操作、16ならStack操作。
Intermediateも使えるようにしたい。
3-5bit目が立っているときはふつうのCalculation出力は必要ないのでそちらはスイッチで無効にしておきます。
4byte目でひとまずRead/Write決定(だいぶもったいない使い方ですが・・・)。
2、3byte目は、Fromが先、Toが後の方が自然な気がします。

ひとつずつ実装する必要があるところを見てみます。

RAM Write


RAMに書き込むときは、4byte目のbit0=0とします。2、3byte目の取り扱いは変わらず、それぞれの計算ユニットへの出力ラインにaddress箇所registerを出力してRAMのsave valueとaddressに引っ張ってくるだけなので、intermediate含めすでに実装されています。

RAM Read

RAMに書き込むときは、4byte目のbit0=1。
2byte目はAddressへの入力になるので、RAM Writeの時と合わせてmuxで切り替え。
3byte目は、計算するときとかの4byte目に相当するので、RAM操作の時はmuxで切り替え。

で、RAM周りはこんな感じになりました。いい感じ。

label loop_read
# Load in to reg0
addi2 in 0 0
# Save reg0 to RAM
#  with address reg1
ram 0 1 write
# Use reg1 as RAM addr
# Add Memory Addr
addi2 1 1 1
if_eqi2 1 32 begin_dump
if_eq _ _ loop_read

label begin_dump
addi12 0 0 1
if_eq _ _ loop_dump

label loop_dump
# Load from RAM
ram 1 out read
# Add Memory Addr
addi2 1 1 1
if_eq 0 0 loop_dump

Push and Pop

次のstackを追加するという課題。Stackのコンポーネントは綺麗に正方形に収まりました。

0123
Stack Op
xx010xxx
コピー元
値格納regアドレス
or Intermediate
Not UsedPush
xxxxxxx0
Stack Op
xx010xxx
Not Usedコピー先
値格納regアドレス
Pop
xxxxxxx1

これはだいたいRAMと同じ感じで実装できそうです。
ただ、2byte目の方の3bit decoderはStack Popのときは無効にして、3byte目の方のdecoderはStack Pushの時に無効にしておきます。勝手にアクセスされたくないですからね。

結局、あまり大きな変更をせずに実装できました。RAM+αくらい。プログラムも簡単。

label loop_main
copy in _ reg0
if_eqi2 reg0 0 loop_pop
if_eq _ _ loop_push

label loop_pop
stack _ out pop
if_eq _ _ loop_main

label loop_push
stack reg0 _ push
if_eq _ _ loop_main

おしまい

結構変更点は多かったもののすんなりいきました。
次はFunctionということで、ちょっとcounterまわりも改善しなくちゃいけませんね。

コメント

タイトルとURLをコピーしました