2023年12月17日日曜日

自作CPUで遊ぶ 15

さてさて、 petalinuxの方は何とか環境ができたのでロジック部の作業に戻った。 vivadoのブロックデザインは以下のようにした。右下のmycnc_topがCNC制御用のブロックで、これはIP化せずRTLを読み込ませている。
mycnc_topは以下のような構成にした。zumi32用の命令メモリとデータメモリの他にzynqとzumi32間のデータ交換用共有メモリももたせる。これらのメモリはZynqからもzumi32からもアクセスできる。また、Zynq、zumi32相互に割り込みを発生できるようにした。データ交換用メモリはDRAMの方が良いかなとも思ったが、まずはBRAMでやってみることにした。
現状、AXI側、zumi32側のアドレスマップは以下のようになっている。
と、今日はここで時間切れになってしまった。 

2023年12月16日土曜日

鹿

私は郊外に住んでいる。
先日夕方、車で外出したら出発して 1 〜 2分のところで何と鹿に遭遇した。 
前方に暗い塊があるなと思ってライトをアップビームにしたらそこには鹿がいた。
肉眼で見たときにはかなり大きく感じたのだが、ドライブレコーダーの映像を確認したらそうでもなかった。
うちの近所では猪はよく見かけるのだが、鹿を見たのは初めてだ。 
 この子も食べ物を求めてここまで進出して来ているんだろうか?
 なんとか生き延びて欲しいものだ。
   

2023年12月3日日曜日

自作CPUで遊ぶ 14

前回の続き、 

ウィンドウマネージャだが、ネットで軽量ウィンドウマネージャについて調べたところ幾つもあることが判った。 この中で、icewm、fluxbox、fvwmをインストールしてみた。 3種のソフトをビルドしてインストールするのにメチャクチャ時間がかかったが何とかインストール出来た。

以下は各ウィンドウマネージャの画面表示だ。 上からicewm、fluxbux、fvwmだ。画面の画素数は1024x768にした。

 
icewm
fluxbox
fvwm
どれも似たようなもんだがicewmが若干好みなので、icewmを採用しようと思う。 また、画面の画素数は1280x1024に増やすことにした。
petalinux-image-fullには**gears**という3Dで歯車が回転するプログラムが含まれている。その中のX11用のgears_x11を動かしてみた。 これを動かすことに特に意味は無いが、simple frame bufferでも3Dのアニメーションプログラムが動作するので何か嬉しい。

 

… ということで、ユーザーランドもpetalinuxのまま行くこととし、ウィンドウマネージャはicewmを使うことにした。

2023年11月26日日曜日

自作CPUで遊ぶ 13

最近 exhausted 気味で全ッ然作業が捗らない。 ... orz

FPGAボードにZYBOを使うことにしたので、今回はPetalinuxとzumi32用クロスGCCのインストール等を行った。 また、ZYBOはVGAとHDMIのコネクタを持っており将来的にはGUIのアプリも作りたいので、simple-framebufferも入れてX11が立ち上がるようにもした。デバイスツリーのsystem-user.dtsiは以下のようにした。
simple-framebufferを使うためには、Kernel ConfigurationのDevice Drivers -> Graphics support でSimple framebuffer driverとFrame buffer Devices の Support for frame buffer devices を有効にする必要がある。
vivadoのblock designは以下のようにした。今日は時間が無かったのでZYNQ-PS部とzumi32部間はUART接続にしたが、後に共有メモリ方式に変更するつもりだ。
petalinuxはpetalinux-image-fullを16GBのSDカードにインストールして動かしていて、FAT32部を2GB、ext4部を14GBにしているのだが、今回使用したバージョン2022.2はサイズが巨大でこれだけで使用量が97%位になっている。そのため、追加のアプリやクロスコンパイラ等が入らないので別のUSBストレージを繋いで /usr/local にマウントし使用することにした。これも後にインストールするアプリを選別してサイズの縮小を図ろうと考えている。 また、petalinux-image-fullにはmatchboxっていうwindow managerが入っているのだが何かショボくて実用性は無い。軽量のウィンドウマネージャーを自分でインストールするか若しくはユーザーランドはubuntuにしたほうが良いのかも知れない。以下はmatchbox-window-managerの表示画面だ。
GTKWaveのアイコンが写っているがこれは後からインストールしたもので最初から入っている訳ではない。

 zumi32用クロスコンパイラもインストールした。ビルドに数時間かかったが何とかビルドに成功しインストールできた。
今回画面の解像度を1900x1200にした。一応、X Windowも動くが解像度が高すぎるためかウィンドウをマウスでドラッグして動かす場合のレスポンスが非常に悪い。下げたほうが良さそうだ。

2023年11月5日日曜日

自作CPUで遊ぶ 12

そろそろ実機を動かしたいところだが、CNC4030付属のコントローラはなるべく改造したくない。パルスモータドライバは今まで実験に使ったやつがあるしスイッチング電源等もジャンク品を何個か持っているのでこれらを使ってデバッグ用コントローラを組み立てることにした。ベースになる板はダイソーの穴開きボードを使っている。一見すると木製の板に見えるのだが材質は"MDF、紙"って書いてあった。厚さが5mmあるのでそこそこ強度はありそうだ。スピンドルコントローラは無いのでそれだけは付属コントローラの物を使うことになる。
スイッチング電源は出力50Wの同じ型番の物が2個あったので、これの出力をダイオードを介して並列接続して使うことにした。
FPGAボードは当初 CMOD-S7を使おうと考えていたのだが、方針を変えてZYBOを使うことにした。GコードのインタプリタやMACH3やLinuxCNCの様なGUIも可能であれば作りたいと考えているのでアプリケーション層の部分はZYBO+Petalinuxにする。Zumi32はPL部に実装してARMとZumi32間は共有メモリ(RAM)を介して通信する。 電源の一部の配線が出来た。右側の7セグ基板とその下のスイッチ基板はこのコントローラに実装するか、独立してCNCペンダント的な物にするか思案中だ。
RTLの方はパルス生成部を書いている。 最下層は pls_gen というモジュール名にして主にパルスモータードライバへのパルスを生成する。一応 en信号とdir信号も出力するがこれは入力信号を1段F/F通しただけのものになる。前回の検討ではbeat信号もこの階層に入れるつもりだったが、これは加速度 accel を更新するタイミング信号なのでもう一つ上の階層の方が良さそうだ。ということで現状入出力は以下のような感じだ。


2023年10月22日日曜日

自作CPUで遊ぶ 11

CNCはG-codeで制御することになるが、主軸の移動を指示するコードにG00(位置決め)とG01(直線補間)がある。G00は主軸の原点復帰等のような位置決めに使われる。この時各軸は同期せず個別の設定値で移動する。起動/停止時の加速度もそれぞれの設定値を使うので、例えばX/Y各軸の設定値が同じ場合主軸は最初に45度の方向に移動し、何れかの軸が目標位置に到達すると今度はX方向またはY方向のみ移動して目標点に到達することになる。これに対してG01の直線補間(切削送り)は現在位置から目標位置までの直線上を移動する。前々回に検討したのはこの場合になる。
で、これらの処理のFPGAのロジックとソフトウェアの分担について検討した。 パルスモータードライバーへのパルス生成方式は基本的にはHDD用スピンドルモーター駆動時の方式をベースにするのだが、とりあえず以下のような入出力で考えている。
*_pm_***はパルスモータードライバへの制御信号だ。em_stopは非常停止信号でこれが1の期間は動作を停止し*_pm_enも0にする。s_beatはビートパルス信号で、起動/停止時の加減速はこのパルスに同期して行う。*_pcntは*_pm_pulseに出力されるパルスの計数値だ。*_pm_dirの値によって増減する。*_pcntは*_clrで0にリセットされる。*_clrは原点設定時に1になる。X/Y/Z各軸のパルスモーターの回転が各軸の移動に変換されるので、*_pcnt値に1パルス当たりの移動量を乗じれば原点からの座標になる。*_accelは起動/停止時の加速度、*_speedは目標速度だ。主軸が停止状態から移動が始まるとすると、速度0から *_accelのレートで増速していき *_speedに達する部分で *_speedに固定する。また、停止時は *_speedの速度から *_accelのレートで減速して行きやがて0になる。 *_enは起動/停止を制御する。 0から1に変化すると移動を開始し1から0になると停止する。停止時は直ちに停止する訳ではなく減速しながら停止する。起動から完全停止迄の期間のパルス数が移動量になるので停止のタイミングはちゃんと計算する必要がある。 

で、FPGAのLOGIC側をこうするとすると、zumi32側の処理は少なくとも以下のことをする必要がある。
数値計算はfloatで行う必要があるが、これは問題ない。Dpを求めるのに√演算が必要になってしまった。これを何とかする必要がある。zumi32は演算用リソースとしては加減算器とバレルシフタしか持っていないのでfloatの四則演算はそれなりにステップ数を要する。√演算となると尚更だ。そこで、この部分はハード化することにした。√演算器は10年くらい前に趣味で自作した。最初のやつはパイプライン式で組んだが回路が大きくなるのでその後に非パイプライン化版も作った。これは1bit@1clockで計算する。32bit floatの仮数部の√を求めるのでトータルで26クロック掛かる。これだとちょっと掛かりすぎな気がするので、今回2bit@1clockで計算するように変更した。
この演算器をzumi32に組み込み、sqrt命令を追加することも出来るが、他のfloat系演算命令は未実装なのでこれだけ入れるのはバランスが悪すぎる。今回はfp_sqrtモジュールとしてi/o busに接続して使うことにした。また、こうするとfp_sqrtにデータを書き込んだ後、結果がでるまでzumi32で他の処理をさせることも可能で処理を並列化することも出来る。といってもfp_sqrtのレイテンシーは13なのでその期間だけの話だが。。。 以下は動作確認のために現状のプロジェクトに組み込んだ様子。
zumi32のプログラムは以下のようにした。
simulationの結果
vivadoでimplementして見た。100MHzで動作させるがタイミングエラーは無くMetした。回路規模も意外と小さい。

2023年10月15日日曜日

自作CPUで遊ぶ 10.5 ? (卓上旋盤)

YouTubeでCNCや旋盤でのものづくり動画を見るのが好きで、見ると止まらなくなっちゃうので普段は見ないようにしているのだが、今日うっかり見てしまったら無性に自分でも何かを組み立てたくなってしまい、気がついたらジャンクのアルミ材を無心にネジ締めしてた。 ふと、我に返って笑ってしまった。何やってんだ俺?・・・と。
しかし、組み立ているものを見たら先週実験した卓上旋盤のベース部分に使えそうな気がしたので、そのまま組み上げることにした。
卓上旋盤化するにはベースにするアルミフレームを購入する必要があり、金掛かるしどうすっかなーと悩んでいたのだが、まさか手持ちの部材で出来るとは。。。考えもしてなかった。やっぱ、人生持つべきものはジャンクだわ。と改めて思う。 

上の写真の状態ではまだ完成ではない。制御基板(FPGAボード)や電源も必要だし刃物台も必要だ。 所有しているCmod7は1枚だけでこれはCNCの方で使うつもりなので、この卓上旋盤用には別のFPGAボードが必要だ。回転数や正転・逆転の設定や表示、非常停止制御ぐらいは出来るようにしたい。 もちろんzumi32を実装する。

ま、これもぼちぼちやってくつもりだ。


2023年10月9日月曜日

自作CPUで遊ぶ 10

所有しているCNC3040には三つ爪チャックが付属している。モーターはパルスモータでチャックとモーターとのプーリー比は1:3だ。 これを回してみた。このチャックは購入してから一度も動かしていなくて今回初めて動作させてみた。

普通に回すだけなので問題無く動いた。ベースボードに固定すれば卓上旋盤的な物が作れそうだ。
何かワクワクする。 (^_^)

CNCでX-Y2軸を制御してスピンドルの位置を移動させる場合、移動先の座標値の与え方には幾つかの方法が考えられる。普通に考えればX,Yの直交座標系で各軸の移動量を与える方法だろうが、極座標系で角度と目標位置までの直線距離を与える方法もあるだろう。 何れの方法も座標値は絶対座標の場合と相対座標の場合が考えられる。 何れの方式にしても、実際に制御するのはX/Y各軸のパルスモーターになるので、最終的にはこれらのモーターに印加するパルス数とパルスレート(周波数)に変換することになる。パルスモーターには最大自起動周波数という特性があって、いきなり起動・停止できる最大パルスレートに制限がある。なので、パルスモーターを起動・停止するときは徐々に加減速する必要がある。つまり、加速度に上下限値が存在する。CNCを制御するソフトウェアにはMach3やLinuxCNCがあるが、これらのソフトウェアでもこれらを設定するパラメータがある。

 Mach3の設定画面

即ち、X/Y各軸のモーターに対してこの加減速制御をする必要がある訳だが、如何なる場合にも同じ値とは行かずこれらの値は点P0からP1への直線移動の加速度とし、これをX/Y軸の加速度に変換する必要がある。
スピンドルの移動速度もG-code等で設定されるので、X/Y軸の移動速度は以下のようになる筈だ。
つまり、G-code等で与えられた各値からXpulse、Xspeed、Ypulse、Yspeedを求めてパルス発生部に入力する必要がある。どこからどの部分までをFPGAロジックに実装し、他の部分をzumi32に実装するかを検討する必要がある。


2023年10月1日日曜日

自作CPUで遊ぶ 9

定年になって再雇用社員になったというのに何故か仕事がめちゃくちゃ忙しい。給料はほぼ半減したのに下手したら定年前よりも忙しい。先日は仕事帰りに急に喉がヒリヒリ痛く微熱も出てきた。職場で高熱で休んだ人がいるという話も聞いていたので、これはいよいよ私も何かに感染したかしら?とか思ったのだが一晩寝たら回復した。かなり疲労が溜まっているので免疫力が低下しているのかも知れない。 こんな時は好きことをやって気分転換だ。…やってることは仕事とあまり変わっていない気がするが… 全部、自分の思い通りに・好きなように・作りたいものを作る。というのが気分転換になる。 

さて、今度はステッピングモーター(パルスモーター)を制御して見たくなってジャンク箱からモーターを出して来た。 パルスモーターの制御を習得したいなーと思って集めていたら、いつのまにか沢山所有してしまった。 ここに写っているのはその内の一部だ。
モータードライバはDM556Dというやつを使うことにした。これもいつかこれで遊ぼうと思い数年前にAmazonで購入して死蔵していたやつだ。 回転させるだけならHDDのスピンドルモーターと同様の方法で良いが、位置決め制御等もやってみたいので今回はこれを使うことにした。
なので、FPGAからはEnable、Dir (回転方向)、Pulseの3種の信号をDM556Dに与える。
7年位前にCNC4030Zという中華製のCNCを購入した。今はまったく使っていないがまだ所有している。 この装置のコントローラはI/Fが古く、PCのプリンタポートと接続する必要がある。また制御するソフトウェアもWindows95用のものなので今動かすの色々と難しい。 最終的には、コントローラと制御ソフトウェアを自作してこれを動かしたいと考えている。これで最高4軸迄は制御してみることが出来る。
とりあえず、普通に回転させてみた。プログラムはHDD用スピンドルモーター用のやつをベースに若干手直しして使った。 とても容易に回せた。このモーターの場合、回転数は9000 [rpm]が上限のようだ。

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の性能にかなり近づけているというのは嬉しいことではある。

自作CPUで遊ぶ 25

まだ制御ソフトが完成していないので今まではスピンドルを移動するために一々簡単なプログラムを書いて移動させていたのだが、非常に面倒なのでCNCペンダント的なものを作ることにした。 右側の縦に2つ並んでいるスイッチ...