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についてはこんな感じを想定。
0 | 1 | 2 | 3 |
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のコンポーネントは綺麗に正方形に収まりました。

0 | 1 | 2 | 3 |
Stack Op xx010xxx | コピー元 値格納regアドレス or Intermediate | Not Used | Push 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まわりも改善しなくちゃいけませんね。

コメント