![見出し画像](https://assets.st-note.com/production/uploads/images/173717718/rectangle_large_type_2_3c32efd2452baa2584bf7cfcddb30503.jpeg?width=1200)
シーケンシャルアクセス専用ROMを使いこなすための案
シーケンシャルアクセス専用ROMを使いこなすための案
動画です。内容は同じです。
前置き
今回は、今後使うかもしれないシーケンシャルアクセス専用ROMを使いこなすための案を思いついたので、ここに残しておこうと思います。
シーケンシャルアクセスと条件分岐
ちなみに、シーケンシャルアクセスとは、ROMの0番地から1番地、2番地、3番地、、、と順番にアクセスすることです。
その逆が、ランダムアクセスで、順番に関係なく1番地、3番地、2番地、5番地のようにランダムにアクセスすることです。
これまでの僕のCPUのROMは、初代を除いてランダムアクセス対応ROMでした。
なぜ初代がランダムアクセスに対応していないのかというと、ただ単に条件分岐の存在を知らなかったからです()
条件分岐とは、演算の結果で次に実行する命令が変わる命令です。
この命令を実行するには、ランダムアクセスに対応していることがほぼ必須の条件になります。
なので、これまでのレッドストーンCPUのROMは、初代を除いて全てランダムアクセスに対応したROMでした。
ですが、ここにきてシーケンシャルアクセス専用のROMに魅力を感じ始めたのです。
さらなる小型化の必要性
なぜなら、Switch時代から続く64×64の制約の中で、
小型化の限界が訪れようとしていたからです。
64×64以下にするという制約があって、その制約の中でCPUを制作してきました。
この制約は、僕にとってとても重要なものであって、僕のCPUのクオリティ向上に大きく貢献しているといっても過言ではありません。
そんなメリットだらけの64×64の制約ですが、CPUの高性能化やGPUの搭載が進んだ今、むしろデメリットの方が大きい可能性が浮上してきたのです。
CPUを高性能化させるとき、回路を追加する必要があります(多段階アキュムレータなど)。
つまり、CPUの大型化が進んでいるのです。
そんな中、さらにGPUを追加しているので、必要なスペースはかなり大きくなっています。
いくら制約が小型化に繋がるとはいえ、限界はもちろんあります。
そして、回路は上や下に大きくなっていきました。
ですが、それはレッドストーンが苦手な上下方向の配線が増えるということになります。
そうなると、配線の割合が増え、サイズも遅延も大きくなります。
なぜROMを小型化させるのか
ROMは部屋が大量にあつまってできています。
なので、部屋1つのサイズを少しでも小型化できれば、全体で見たときに大幅な小型化に繋がります。
また、ROMを小型化させなければならない理由がもう一つあります。
ROMの容量はまだまだ小さい
今のCPUのROMは、まだまだ小さいです。
実際に、sammyuriさんのCHUNGUS 2は16bitのISA(Instruction Set Architecture)で4KiBのROMまで対応しています。
ところが、僕の統合版CPUは、最も容量が大きいNX RED VIでも20bitのISAで640ByteのROMまでしか対応していません。
僕は実際にプログラミングしたことが無いので分からないのですが、どうやらテトリスなどを動かそうと思ったら、この容量では全然足りないらしいです。
ROMの小型化の恩恵は相乗効果で大きくなる
つまり、ROMはまだまだ足りないからROMの部屋の数は増えていきます。
そうなると、ROMの部屋をわずかでも小型化できた時の恩恵は、さらに大きなものになっていく、、、という訳です。
そんな時、シーケンシャルアクセス専用ROMなら、機能が少ない分小型化が出来るため、全体で見たときの大幅な小型化が期待できる、、という感じです。
本題
今回思いついた仕組み
それでは、本題に入ろうと思います。
今回思いついたのは、ROMから常に命令を読み出し続け、命令キャッシュに保存し、命令キャッシュから命令を読み出して実行する、、、というものです。
![](https://assets.st-note.com/img/1739023476-UJYkDM6ygvLl5rES2IC1fcnV.jpg?width=1200)
これだけでは伝わらないと思うので、まずはROMの動作から説明します。
ROMは、常に命令を読み出し続けています。
最初の0番他から読み出し始めて、最後の番地に到達したら、また0番地から読み出す、というのを繰り返します。
次に、命令キャッシュです。
命令キャッシュは、最後にアクセスされたアドレスの命令と、少し先までの命令を保存します。
なぜ少し先の命令も保存するのかというと、
シーケンシャルアクセス専用ROMは、順番に読み出すことしかできません。
ですが、CPU側は独自高速化技術により、それよりも高速に処理できます。
その結果、ROMの読み出し待ちになってしまいます。
ですが、命令キャッシュに次の命令も保存しておけば、その待ち時間を短縮できます。
なので、0番地を実行する場合は、0番地から3番地くらいまでの命令を保存します。(どこまで保存するかは、CPUとROMの速度から計算します。)
もちろん、ROMからはシーケンシャルアクセスされた命令しか送られてきません。
なので、目的のアドレスの命令が送られてきたタイミングで命令キャッシュを書き換えます。
最後に、PC(Program Counter)から出力されたアドレスが命令キャッシュ内にあれば出力し、無ければ命令キャッシュが更新され目的の命令が保存されるまで待ちます。
こうすれば、ROMの小型化と命令キャッシュによる高速化を実現できるはずです。
命令キャッシュに命令を保存しておくことで、レジスタデリートなどの従来の高速化技術も利用できるようになるはずです。
まぁ、心配なのは命令キャッシュの搭載によるサイズの相殺です。
ROMを小型化しても、キャッシュが大きければ小型化ができなくなってしまいます。
これまで考えていた方法
実は、これまで考えていた方法と比べると、これでも無駄な回路は減らされているのです。
元々は、1回だけROMから命令を読み出して、その命令をsushi memory architectureに保存しようと考えていました。
そうすることにより、帯域の制限をほぼ無くすことで、高速化につながると考えていました。
帯域の制限が無くなることで、マルチコアマルチスレッドにしても、問題なく命令を読み出せるようになると思っていました。
![](https://assets.st-note.com/img/1739023539-yFNPEQ0cmjDendi8k1hur2KC.jpg?width=1200)
ですが、ある日気づいたのです。
sushi memory architectureを使うのではなく、ROMから何度も読み出し続ければいいのでは?
…と。
sushi memory architectureに保存することで、無限の帯域を手に入れられると考えていましたが、動作はROMから常に読み出し続けてる時と変わらないので、それなら無駄なメモリは削除して、ROMから読み出し続ければいいと考えました。
そして、今考えている方式になりました。
命令キャッシュは必須ではない
命令キャッシュは、高速化のために搭載しようと考えていました。
シーケンシャルアクセス専用になることでただでさえアクセスに時間がかかるようになったROMが、小型化によりさらに大容量化して、相乗効果で大幅に低速化されることが予想されます。
なので、高速化のために必須だと考えていましたが、実際は違いました。
もう一度考え直してみれば、命令キャッシュはあくまで高速化のためにある回路で、必須の回路ではありません。
命令キャッシュが無い場合は、目的の命令が送られてくるまで待つ感じになります。
なので、64×64という制約がある統合版のレッドストーンCPUの場合なら、あえて無くすというのも手だと考えるようになりました。
まぁ、先ほども言った通り相乗効果で大幅に低速化することが予想されるので、あった方がいいとは思いますが、最悪無くしても動きます。
出来れば、この方式の全てのCPUに命令キャッシュを搭載したいですが、それよりも容量重視だったりする場合は、無くても十分かもしれません。
……仮にROMのアドレスが8bitだとしたら、次の命令の実行に25.6秒近くかかることになるので、やっぱりほぼ必須かも?
でも、命令キャッシュは回路サイズが少し大きいので、バランスが大事かもしれません。
例えば、最初から低速で動かすものだとして設計すれば、アキュムレータなども必要なくなり、その分のスペースを命令キャッシュに割り当てたりなど……
今後のレッドストーンCPU開発は、よりスペースの配分が大事になっていきそうです。
![](https://assets.st-note.com/img/1739023609-eipk0Ir3zWmP2TMOahtvE64L.jpg?width=1200)
まとめ
シーケンシャルアクセス専用ROMは、これまで使っていたランダムアクセスが可能なROMと比べて、高度な制御が必要になりそうだということがわかりました。
命令キャッシュが無くてもある程度の速度が出せたランダムアクセス対応ROMと比べて、命令キャッシュがほぼ必須で、読み出したパルスの命令を扱わないといけないため、遅延調整も非常に重要になってきます。
言い忘れていましたが、シーケンシャルアクセスということは、命令が次々送られてくるので、1つの命令は短いパルスの信号です。
ですが、パルス信号の命令も、命令キャッシュに保存しておくことで、これまでのランダムアクセス対応ROMを前提とした高速化技術が使えることや、sushi memory architectureを使った時と同様の大きな帯域を得られることもわかりました。
シーケンシャルアクセス専用ROMは、工夫すれば小型化や高速化に繋がるということもわかりましたし、小型化できたその分を使ってROMを大容量化できそうであることも分かりました。
このように、一見デメリットが大きそうなシーケンシャルアクセス専用ROMでしたが、このROMは使いこなせば大きな武器になるとわかりました。
まだ、実際にシーケンシャルアクセス専用ROMを搭載したちゃんと動くCPUは作ったことがないですが、今後作るのが楽しみになってきました!
では、最後まで読んでいただき、ありがとうございました。