前回、FPGAボード(Sipeed Lichee Tang Primer)を使って設計しているMoscoviumシリーズマイコンにおいて、より小さいFPGAに搭載することを目指して、オリジナル8ビットCPUコアTennessineを設計しました。
「何か、比較可能なCPUコアが無いかな〜」と、探してみたところ、ZPUというCPUコアが見つかりましたので、このCPUとの比較を実施して見ようと思います。
オープンソースのCPUコアみたいです。以下URL(GitHub)から参照可能です。
ZPU: https://github.com/zylin/zpu
ライセンス形態は、以下の通りです。
プレゼンテーション資料なども置いてありました。上でリンクしたGitHubから、以下のパスで見つかります。
プレゼンテーション資料:
プレゼンテーション資料を参照してみると、特徴としては以下の様なコアだと判りました。
ZPUコアの特徴:
凄!440LUTって、小さいな〜(?!)。しかも、GCCツールチェーンが使えるのは良いな。
一体、どんなCPUなのか、興味が湧きましたので、RTLを覗いてみようと思います。
最初にリンクしたGitHubから、ドキュメントやRTLにも、アクセスすることができます。
ドキュメントパス:
RTLはVHDLですね。筆者はVHDLには明るくありませんが、コメントも含めて、たったの1,290行ほどですので、解らないなりに、ぼんやりと中身の様子は見て取れました。
※ちなみに、オリジナル8ビットCPUコアTennessineのRTLは、トータル2,114行(Verilog-HDL、執筆時点)です。
ZPUコアのRTLとドキュメントを、ざっと斜め読みしてみたところ、以下の知見を得ました。
ZPUのRTLおよびドキュメントから得た知見:
と、こんな所です。
折角RTLが入手できるのですから、論理合成して見ない手はありませんね。次節では、手持ちのFPGAボードに移植して、論理合成を試してみたいと思います。
手持ちのFPGAボード(Sipeed Lichee Tang Primer)で、ZPUをコンパイルして見ようと思います。VHDLのRTLをダウンロードしてきて、TD IDEに読み込ませましょう。
ディレクトリ構造:
リンクを張ってあるプロジェクトファイル(ZPU.al)とSDCファイル(MCOC.sdc)以外は、こちらから入手してください。
TD IDEでプロジェクトファイルを読み込ませてみた状態が以下図となります。
VHDLには明るくないので、良く解らないのですが、zpu_config.vhdと、zpupkg.vhdは、C言語で言う所のヘッダファイルみたいな感じで、定数等の定義が含まれていました。読み込んでおかないと、本体のRTLでエラーが発生します。
zpu_core.vhdが、CPUコアのRTL本体です。前の2ファイルは、その階層構造には含まれない様です(上図)。zpu_core.vhdの階層構造で、traceと言うモジュールが「?」マークとなっています。TD IDEでは、何らかのエラーが発生して読み込めなかった場合に、この様な表示になるのですが、結論から述べると、この状態で問題なくコンパイルが完了します。
そもそも、traceと言うモジュールは、シミュレーション用のビヘイビア記述で、何らかのログをファイルに書き出すような記述みたいです。RTLから論理合成するのに必要ないため、放置して大丈夫みたいです。
SDCファイル(MCOC.sdc)で、clk端子に24MHzの制約だけ張って、コンパイルした結果を以下に示します。
こちらのプレゼンテーション資料では、「Xilinx XC3S400(Spartan-3)で440LUT」と言うスライドが有りました。
ところが、手持ちのFPGAボード(Anlogic EG4S20)では上結果の通り、約3,100LUTと大きな数値がレポートされました。おや、まあ。
こちらで指摘した様に、FPGAメーカによって指標は「まちまち」なので、LUT数だけで直接比較はできません。
と言って、安直に老舗FPGAメーカXilinxと、中華FPGAメーカAnlogicの実力差、で片付けられるような差分値でも、ありません。後ほどもう少し分析してみましょう。
まずは、前回設計したオリジナル8ビットCPUコアTennessineと、論理規模の比較を実施してみたいと思います。
本ページで実施したかったのは、前回設計したTennessineコアとの論理規模比較なので、以下表にまとめて見ました。
CPUコア | ビット幅 |
LUT数 (論理規模) |
F/F数 |
DSP(乗算) マクロ数 |
備考 |
Nihonium | 32ビット | 5,400 | 950 | 4 | 32ビット符号付乗算/除算 |
ZPU | 32ビット | 3,075 | 361 | 3 | 32ビット符号無乗算(※) |
Moscovium | 16ビット | 2,900 | 650 | 1 | 16ビット符号付乗算 |
Tennessine | 8ビット | 1,300 | 220 | 1 | 8ビット符号付乗算 |
※VHDLなので自信は無いけれど、RTLを見る限り、ZPUは32ビット符号無乗算あり、除算無し、でした。
※また、Moscoviumシリーズでは、便宜上「符号付」とだけ記載しましたが、符号付/無両方の演算命令を持っています。
なるほど。まあ、順当ですね。以下に考察します。
考察:
話を少し巻き戻して、ZPUですが、本当にXilinxだと、440LUTで実装できるのかな??一度、Tennessineコアの方をXilinxでコンパイルしてみたいところ……。
さて、最後に残った課題は、ZPUのプレゼンテーション資料にある、以下の文言の真偽です。
「Xilinx XC3S400(Spartan-3)で440LUT」
少なくとも、Anlogic EG4S20(+TD IDE)でZPUをコンパイルしたら約3,100LUTだったのは事実なので、オーダが合っていません。
手元にXilinxのFPGAが有りませんので、まずは、FPGAチップXC3S400(Spartan-3)のデータシートを入手して、読み解いてみましょう。
XC3S400(Spartan-3)のデータシートを検索(別ウインドウが開きます)
データシートを読み進めると、まず、CLB(Configurable Logic Block)という論理単位(ブロック)が登場します。
つまり、
1CLB=4SLICE
1SLICE=2LUT
∴1CLB=8LUT
おやおや?ピンと来てしまいましたよ。もし、プレゼンテーション資料の「440LUT」が、「440CLB」の間違いだったとしたら、どうでしょうか?
440CLB=440×4SLICE=440×4×2LUT=3,520LUT
何と、Anlogicのコンパイル結果約3,100LUTと、オーダが合います。そう言う事、なのではないでしょうか?
もしかしたら、Xilinxのツールでは、ZPUをコンパイルした結果が「440LUT」とレポートされているのかもしれないし、別な単位でレポートされた値を、プレゼンテーション資料を作った人が勝手に「440LUT」と、書き換えて(思い込んで)しまったのかもしれません。
多分、これが真相。
比べる相手、ZPUが見つかって良かったです。新しい知見を得ることができました。今まで、「Moscoviumシリーズは、教科書に載っている様なシンプルなアーキテクチャで、コンパクトでしょ?」って、独り善がりに思っていました。でも、それは、「レジスタマシン」として見た時の話だったのです。そもそも、ZPUの様に方式の異なる「スタックマシン」だと、もっとシンプルでコンパクトにできるのですね。脱帽m(1__)m。