2023年9月18日月曜日

自作CPUで遊ぶ 8

前回のデザインをベースにしてCPUをMicroBlazeに変えてzumi32版との違いを色々と見てみた。MicroBlazeの設定はzumi32と同等にするために乗算器等は入れずにBarrel Shifterのみとした。
このデザインでImplementしUtilizationを見てみた。MicroBlazeの部分はSlice LUTsが1053だった。これに対してzumi32は1066と同程度の規模だった。但し、規模は同程度だが内訳はかなり違う。レジスタ数は770(MicroBlaze)に対して512(zumi32)。LUT as Logicは851(MicroBlaze)に対して1022(zumi32)。LUT as Memoryは7(MicroBlaze)に対して0(zumi32)。zumi32はF/Fをあまり使っていない。これが動作速度を上げられない要因なのかも知れない。
次に前回と同等のプログラムをMicroBlazeに実装し、生成されるコードの規模や処理速度を見てみた。コンパイルされたelfのtext、data、bssのサイズはそれぞれ 1588、276、3112だった。 これに対して、zumi32はLinkerが出力したmapファイルから各セグメントのサイズを見ると、textが0x284 (644)、dataが0xc (12)、bssが0 とかなり違う。textは約1KByteもの開きがある。最適化オプションは何れも-O2にしている。
MicroBlazeのelfを逆アセンブルしてmain()の部分を見てみた。命令数は31なのでかなりコンパクトだ。これで何故text sizeが1.588Kバイトになるのか謎だが、もしかするとstartup部や例外処理などのコードが大きいのかも知れない。 1KByteは1命令32bitなので命令数にして256命令分。。小規模なFPGAにCPUを実装する場合等は結構厳しいサイズかも知れない。
一方、zumi32をコンパイルして得られたアセンブラは以下のようだった。命令数が38もあるが、while loopの部分のみを抜き出してMicroBlazeのコードど比較すると以下のようだった。
zumi32の命令数が多いのは命令セットの違いもあるが、gccをzumi32にportingした時の私の工夫が足りていないのが要因だろう。 zumi32は遅延分岐があるが遅延スロット部をnopで埋めている。最適化の部分をもっと工夫すればMicroBlazeと同等にはなる筈だ。ちなみに手動で最適化すると命令数は14まで削減できる。
次に、それぞれのデザインとプログラムでXsimでsimulationしてwhile loopを1回実行する時間を見てみた。zumi32のプログラムはgccでコンパイルしたコードをそのまま使った。 上がzumi32、下がMicroBlazeの波形だ。MicroBlazeが11.37usecに対してzumi32は18.31usecと1.6倍も遅い。上で見たとおり命令数の差はあるが19:22なので1.15倍程度の差でしかない。したがって遅い要因は命令数の差だけでは無い。
速度を遅くしている要因はload命令のlatencyと分岐時のfetch unitとexecution unit間のlatencyにあった。そこでそれらを修正し、且つzumi32のコードを手動最適化したコードに入れ替えて再度simulationをしてみた。 その結果、while loop1回の処理時間は10.1 usecまで短縮することが出来た。
MicroBlazeより約12%速くなった。但し、手動で最適化したコードを使った場合なので現状のgccを使い続ける限りはMicroBlazeと同等になるんじゃないかな?と思う。 

前向きに捉えるとzumi32-gccにはまだまだ伸びしろがある。!!!ってことだが。。。これを改善するのは大変なんだよな。 portingに数年を要したからなー。

まぁ・・・、でも 最小構成とは言えベンダー製のCPUの性能にかなり近づけているというのは嬉しいことではある。

2023年9月10日日曜日

自作CPUで遊ぶ 7

外では鈴虫が鳴き始めている。酷暑も少し和らいできているが残暑はまだまだ厳しい。去年から私の部屋のエアコンが故障していてまったく冷えない。今年も在宅の時は部屋の温度は平気で36℃に到達していた。今この瞬間も32℃もある。まぁでももう少し辛抱すれば涼しくなるんじゃないかな。

さて、今日はモーターからちょっと離れて別のことをしてみた。

zumi32にAXI Master I/Fを付けてVivadoのIPを接続できるようにして見た。私はIPは可能な限り自作する派でベンダー製のIPはできることなら使いたくないと思っている。また、趣味で遊ぶ分にはそれで十分というのもあるのだが、ふと思い付いて zumi32にAXI Master I/Fを付けて見たくなった。 AXIにはPeripheral I/Oを接続することを考えていて、主記憶となるMemoryの接続は考えていない。そのためアクセスはシングルアクセスのみになるのでAXI-Lite相当のAXI-I/Fにした。それにAXI-Lite-Masterなら簡単にサクッと作れる。

以下のようなブロックデザインにした。AXI-GPIO2つとAXI-Timerを接続した。プラットフォームはCMOD S7を使っているので、それに実装されているカラーLEDと4つの単色LEDをそれぞれ別個のGPIOで制御できるようにした。
このデザインでまずはLEDを点滅させるプログラムを書いて実行してみた。以下はプログラムとBSPだ。
実機にダウンロードして動かしてみた。
   

普通に動いた。
これが出来るとAXI-I/Fを持った色々なIPを簡単に接続してシステムを構築できるってことだよな。

2023年9月3日日曜日

自作CPUで遊ぶ 6

手持ちのモーターの内どれが一番高速に回せるか見てみたら下の写真の左上のやつが一番高速に回せた。
これを無負荷(円板とか何も付けない状態)で回してみたところ 45000 [rpm]まで回せた。電源電圧は通常は5Vにしているがこの時は12Vにした。5Vだと27000 [rpm]位が上限だった。zumi32のプログラムは基本的に前回と同じで、回転数の上限だけを変えた。

次に磁気ディスクを装着して回してみることにした。そしたらこれまでと全く様相が変わりαx^4の制御曲線では回せなくなった。負荷が重くなったためと思う。モーターを脱調しないで起動出来る回転数の上限は無負荷時は300[rpm]位だったのだが、これが60[rpm]、つまり 1 [rps]になった。また制御曲線は一次式のαxにする必要があった。αの値は0.01になった。この曲線での回転数の上限は10500 [rpm]だった。(電源電圧は5V) ディスクが重いので慣性力(イナーシャー)が大きく、駆動を停止してもディスクの回転がなかなか下がらない。 当然だがこのディスクは偏心していないので高速に回しても音はそれほど大きくならない。

負荷の有り無しで結構違う。勉強になった。 
Youtubeに壊れたHDDを改造してディスクグラインダーにする動画があって、ウソクセーと思っていたのだが、これくらいのイナーシャーの付き方ならもしかしたら出来るのかも知れない。


ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...