Home

除算(32bit÷16bit)のサンプルコードを追加しました。こちら


仕様書のダウンロード

説明が足りていない部分はあると思います。2019年6月16日版と同じと考えて問題ありません。 プログラムの先頭アドレスの決まり事を追加しています。

デジタル署名を検証するための.dsfファイルのサイト番号は0017です。 詳しくはこちらのサイト

アーキテクチャの全体図が入っています。 ICF3-ZがICF3をベースにしたものだということがわかると思います。


Verilogファイルと開発環境のダウンロード(Github)

FPGAの実機で動作させたVerilogファイル。アセンブラ。 C言語シミュレータ。Verilogシミュレータ。開発で使っていたものすべてが入っています。 Verilogファイルにデバイスに依存した記述はないのでXilinx以外のFPGAやASIC環境でも動作すると思われます。

ICF3-Zのオリジナル実装をZeviosと命名しました。 名前の由来は、アーケード版ゲーム XEVIOUS(1983年)のデッドコピーXEVIOSの頭文字XをZにしたもの。 XEVIOUSはBASICマガジンに連載されるなど当時、大人気でした。CPUは8bitのZ80が3個、使われているそうです。
ちなみにICF3-Zは完全独自な8bit CPUです。独自というより従来CPUとは構造が違う。

C言語シミュレータ、Verilogシミュレータでは、シミュレーションを終了させるためEXIT命令が使われています。 FPGAの実機ではEXIT命令はないのでJUMP命令で無限ループさせてください。

githubからダウンロードしたファイルをicarus verilogなどが動作する環境にコピーします。 OSはCentOS7が推奨です。Ubuntu18.04やFreeBSD12でも動作すると思われます。 tbフォルダにテストベンチが30個以上あります。C言語で書かれているアセンブラisimzを コンパイルしてバイナリをtbフォルダに置いてPerlのスクリプト
./tb.pl
のように起動すると、テストベンチ、全てを実行して、結果を出力します。 デフォルトはicarus シミュレータですが、オプションにxsimを入れると Xilinx Vivado のxsim でシミュレーションできます。 他に int オプション、spm16オプションがあります。 intはテストベンチ実行中、毎サイクル、割込みを入れても、 結果を間違わないことを確認するためにあります。


Xilinx FPGAデバイスを搭載したArtyで動作させる手順

XilinxのFPGA(XC7A35TICSG324-1L)を搭載したボード、 Artyの手順です。
fpgaフォルダの下にartyフォルダがあります。 Linuxではartyフォルダでmake copyをするとMakefileに書かれている通りに verilogファイルがartyフォルダにコピーされます。 Windowsでは手動でverilogファイルをコピーしてください。 コピーが終わったらczpmem.vをエディタで開いてUSE_XPMとUSE_XPM_10bitのdefineをコメントアウトしてください。 これはVivadoのプロジェクトにaddする前にしたほうが良いと思います。
Vivadoを起動して「File」-「Project]-「New ...」として新しいプロジェクトを開きます。 artyフォルダにある.vファイルとpmem.memをaddします。プログラムを実行する場合には pmem.memはisimzアセンブラを使って作成しておきます。 ここではあらかじめ用意しているpmem.memを使います。
ConstraintファイルとしてartyフォルダにあるArty-ICF3Z.xdcファイルをaddします。 先頭にあるcreate_clockで周波数を設定します。175MHzに設定してあります。
Synthesis [Change run setting]のMore Optionsのところに
-verilog_define PC_WIDTH=10
-verilog_define SPM_WIDTH=8
の2つのオプションを追加します。PC_WIDTHはプログラムアドレスの最大値を設定するためにあります。 ここを10bit(=1024)以外にした場合は、czpmem.vのdefineのUSE_XPM_10bitを同様に変更してください。
Vivado 2019.2で、Synthesisのオプション Flow_RuntimeOptimized
Implementationのオプション Performance_ExplorePostRoutePhysOpt
で実行すると175MHzが成功します。 githubにある2019/12/29のバージョン(2020/06/15もverilogは同じ)のファイルでもVivado 2019.1だと周波数が達成できません。 Vivado 2020.1ではVivado Synthesis Defaults、Performance_ExplorePostRoutePhysOptで実行すると175MHzに成功します。 2019.2よりもかなり小さいLUT数です。
Critical warningが1つ出力されますが、ボード上のSWやリセットボタンのタイミングなので問題ありません。

オプションLUT数FF数BRAM数LUT-RAM周波数Vivado
面積重視3901971.510150MHz2019.2
面積重視4061971.510160MHz2019.2
性能重視4811971.510175MHz2019.2
性能重視4291971.510175MHz2020.1

BRAM 1.5の内訳はプログラムメモリ 4KBとデータメモリ 2KB
データメモリの先頭32バイトがレジスタ、先頭256バイトがスクラッチパッドメモリ。この合成結果はデータのアドレス線を8bitにしたものです。11bitにすればBRAMを消費することなく2KBのデータメモリをすべて使えます。データのアドレス線を16bitまで設定可能ですがBRAMを消費します。圧縮命令(仮想マシン)を利用する場合はプログラムメモリの先頭の領域を消費します。圧縮命令の命令数によって消費する領域が変化します。


命令の組み合わせを変更して24bit÷8bitを演算可能に

ICF3-Zは任意の値の16bit÷8bitを17サイクルで演算できますが、 命令の組み合わせを変更することで24bitの上位8bitが除数8bitよりも小さい場合は、 24bit÷8bitを17サイクルで演算できます。 従来の命令セットでは、抽象化によってメリットを得ている半面、 ハードウェアの能力を十分に引き出すことができません。 ICF3-Zの命令セットは、抽象化のメリットを捨てることで、ハードウェアの能力を、最大限引き出せています。


限定公開してわかったこと

2019年6月16日~18日、Verilogのソースを含めたすべてのβ版を限定公開しました。 ネット上の反応からわかったことは既存のCPUのライセンス料を安くする目的に使えそうか?ということです。 ICF3-Zは従来CPUとはアーキテクチャが異なり、命令セットに性能レンジがありません。 低性能領域においてコア面積に対する性能がいい、という特性を持っています。 乗算器がないクラスのCPUでは、加算器1個を効率的に利用するICF3-Zの アーキテクチャによって既存のCPUの数倍から10倍以上の性能がでます。
既存のCPUのライセンス料に注目するよりは、 加算器1個で高性能が出せる効率のいいアーキテクチャや、まだ成功するか、わかっていませんが、 仮想マシンを効率良く実行できるアーキテクチャを注目していだだければと。


除算のサンプルコード

githubからダウンロードするとsim1のフォルダがあります。 pmem.asmzという名前のファイルが32bit÷16bitのサンプルコードになります。除算1回、約350サイクルの性能です。 他の8bit CPUの除算命令のないものより1.5倍以上の性能です。命令セットが良くできているということなのかも。 ただICF3-Zは命令コード長が32bitなのでプログラムメモリの消費量が多いです。 これは圧縮命令によって消費量が多い問題を解決します。 またICF3-Zは疑似パイプラインにより高周波数で動作するので、同じ半導体素子であれば、さらに倍の性能になることもあると思われます。
十分な検証をしていないため、今回、見送った32bit÷15bitの除算は約230サイクルで動作しました。
sim2のフォルダには32bit÷8bitの除算のサンプルコードがあります。除算1回、50サイクルの性能です。 除数が8bit×8bitに因数分解できる場合では、32bit÷8bitを2回したほうが高速です。
実際にサンプルコードを動作させる方法は、icarusが動作する環境で、アセンブラisimzを コンパイルして、そのバイナリをsim1フォルダにコピーします。 ./isimz a pmem.asmzとすると、pmem.binが生成されます。 makeコマンド使ってmake copyをします。次にmake icarusとします。 実行バイナリsimzが生成されます。実行するとpmem.binを読み込んでプログラムを実行します。
Perlスクリプトrandv.plを実行すれば、除算のサンプルコードを無限に乱数でテストします。
Perlスクリプトrandc.plはC言語によるシミュレータで乱数テストをしますが、C言語によるシミュレータは、信頼性がないうえに、 制限されている機能が多いので、あまり使えませんが、除算の性能を測定する程度には使えます。