2012年7月31日火曜日

cross gcc for zumi32 9

画面に胡麻塩のようなノイズが描画されたり時間が経過するとハングアップしてしまうのは、zumi32のバグだった。
構造上、割込みによる分岐でも遅延スロットが発生してしまうがこの場合の遅延スロットは無効にしているつもりだったのだがその処理が不完全だった。いやーややこしい。
zumi32_exec.vの該当個所を以下のような感じに修正した。


修正の結果正常動作するようになった。
以下はAtlysとDE0で同じFreeRTOSプログラムを動作させている様子だ。OSのTickTimerの時定数はAtlys用(100MHzクロックで1msec)になっていて、まったく同じバイナリをDE0でも動作させている(DE0側は80MHzクロック)ため、DE0側のLEDの動きが遅くなっているが、どちらも正常に動作している。(ディスプレイのアナログ側で表示されているのがDE0のVGA出力、デジタル側がAtlysのDVI出力) また、DE0のLCDに表示されている文字列はEPCSに入っているプログラムによるものだ。 DE0起動後、fpgaデータのsofを直接Cyclon IIIにダウンロードし、プログラムでもLCDは触っていないため、起動時に表示された文字列がそのまま残ってしまっている。

今回のバグはホントにややこしくて、何故か条件分岐命令のbnzを使った場合ハングアップし、それ以外の分岐命令、例えばbzとbrの組み合わせで代用したりした場合はハングアップし無かったりという現象の見せ方をしたりしていて手間取ってしまった。でも、何とか修正できたのでよかった。

先日公開したsnapshot版は修正版に更新した。
今回はFreeRTOS部も含めたのでファイルサイズが18MBになってしまった。

FreeRTOSも動くようになったので今後の展開としては、あんなことやこんなことそんなことまで色々考えられるがソフトばかりだとつまらないので、ここらでgccの移植は一休みにして今度は別のテーマをやろうかなと考えている。一晩寝たらまた気が変わるかも知れないが・・・


2012年7月23日月曜日

cross gcc for zumi32 8

割込みも問題なく動いたのに気をよくして、リアルタイムモニタの移植に挑戦してみている。
移植するリアルタイムモニタはFreeRTOSというものだ。
FreeRTOSはWikipediaによれば組み込みシステム用のリアルタイムオペレーティングシステムだそうで、多数のマイクロコントローラに移植されている。
ライセンスはGPLで、ソースはhttp://www.freertos.org/から入手できる。
ただし、ドキュメントは購入しなければならないようだ。上記freertos.orgかまたはアメリカのamazonで購入可能のようだが、私のカードは非対応のため購入できなかった。日本のamazonでも買えるようにしてくれたらいいのに。。
しかたがないので、ソースツリーの各種マイクロコントローラ用の実装例を参考にして移植を進めることにした。また、FreeRTOSの使い方(PIC32MX版)というページが見つかったので、そちらのページを参考にさせていただいた。
で、何とか動き出すところまできた。
現状、マンデルブロー描画タスクとナイトライダータスク(LEDをナイトライダー風に点灯させるタスク)の2タスクを作って動かしてみている。tickタイマーの周期は10msecとしている。

以下はマンデルブロー描画タスク部、時間待等はせずにひたすら描画処理を行う。

以下はナイトライダータスク部、vTaskDelayを利用して100msec周期に起床して動作する。

以下はmain関数
ハードウェア初期化後上記2タスクの生成後、スケジューリングを開始している。
2タスクとも同じ優先度にしている。


このプログラムをビルドしたところ、コードサイズが命令メモリの容量を越えてしまったため、メモリサイズを倍の16KBに拡張した。

以下は動作の様子
LEDの点滅と平行して描画処理も動作している。

一見うまく動いているように見えるのだが、描画の方をよく見ると胡麻塩ノイズのような点々があり何か変だ。また、この状態でしばらく放置しておくと停止(ハングアップ?)してしまった。
時間経過でハングすることからスタックまわりの移植がバグっているのかも知れない???
さーて、あたしゃどうやってこれをデバッグすればいいんでしょう。。(-_-);
でも、、、、楽しい。ムフフフフ・・・


2012年7月17日火曜日

cross gcc for zumi32 7

DE0にも実装してみた。

システムアーキテクチャは以下のようにした。


プログラムは以下のとおり


プログラムはAtlysで動かした物と基本的には同じだが、DE0はLCDがあるのでそこへの文字列出力もするようにした。また、DE0ではコアクロックが80MHzになるため、タイマーへの設定値も変えている。(pwm_init内部で換算している。)

以下動作している様子

コンパイラの方はまだ改善の余地があると思っているが、この辺でスナップショット版を公開することにした。
例によって以下に置いた。(表の最上段)

http://www.hi-ho.ne.jp/bravo-fpga/

コンパイラはパッチのみで、GCC自体のソースは含んでいない。
ビルド手順はREADMEに書いてある。

詳細ドキュメントは・・・そのうち書きたい。


2012年7月15日日曜日

cross gcc for zumi32 6

zumi32には4種の例外がある。reset例外、address error例外、interrupt例外、syscall例外だ。
reset例外はzumi32が動作を開始するときに発生する例外で0x0番地から命令を実行する。address error例外はワード境界以外で命令フェッチが発生したときに発生する例外で0x40番地から命令を実行する。interrupt例外は割込み例外で0x20番地から命令を実行する。syscall例外はsyscall命令により発生する例外で0x80番地から命令を実行する。reset例外以外の例外発生時は戻り番地がEPCレジスタに退避される。EPCレジスタの値はld_epc命令で汎用レジスタにロードすることが出来る。また、除算命令を実装していないので、0除算例外は組み込んでいない。今回はハードウェア割込みを使ったプログラムがちゃんと動くかを見てみた。割込み機能はCAN IPの実機検証時にも使ったので動作するだろうと思っていたのだが、zumi32のw_interrupt信号の生成論理にバグが見つかり、条件によってはEPCに正しい戻り番地が退避されない場合があることがわかった。いやーハマったハマった。
以下は修正後の論理。


上記修正後、正常動作するようになった。
Cのプログラムは以下のようにした。


フォアグランドではマンデルブロートの描画を行わせる。バックグランドは10msec毎にタイマー割込みが発生し、その割込みルーチンで計時しsprintfで時計表示形式の文字列に変換しdraw_strで画面表示する。 sprintfはコードサイズを小さくしたかったので自作版を使った。これは浮動小数関係をサポートしていないが、その代わりコンパクトだ。 また、interrupt例外からhw_interruptへ至る部分はアセンブラで書いている。例外時のアドレス間隔をもっと広くすればinterrupt_entry部のコードをそこに置けるようになるのだが、それだと例外を使わない簡単なプログラムの場合もその領域を空ける必要がある。アクセス速度の関係で命令用メモリはFPGAの内蔵RAMを使いたいので、なるべく無駄な領域は取りたくない。ということでこの様な実装になっている。


以下は動いている様子




割込みが動くようになったので、簡単なリアルタイムモニタなら動かせるかも知れないな。


2012年7月10日火曜日

cross gcc for zumi32 5

ASCII文字のFONT ROMを追加して、文字列の描画をやってみた。

以下はプログラム

以下はその結果

Cでの開発環境ができればプログラムの作成効率が格段に上がると予想してはいたのだが想定以上だ。 普通にコードを書いてコンパイルしてFPGA側にダウンロードすれば普通に動く。この過程で躓く箇所は全くない。PC上でプログラムを作って動かす感覚と何ら変わらない。
なんか不思議な気分だ。


2012年7月7日土曜日

cross gcc for zumi32 4

幾つかプログラムを作成して実機で走らせてみた。
実機はSpartan6用DDR2 SDRAMコントローラの時に作成したDigilent Atlys用RTLを使用した。


まずは簡単な物からということで、LEDをナイトライダーのように点滅させるプログラムを試してみた。


コンパイルされたtest.elfから .text セクションと .rodata セクションをobjcopyで抽出し、これを、
odコマンドで32bit hex形式のテキストデータ列に変換している。


命令用メモリとデータ用メモリは上記のシステム図からも判るとおりバックドアからも読み書きできるようになっており、ローダプログラムでこのデータ列をダウンロードしzumi32を起動する。
で、無事動作した。


次に、LEDの動きに合わせてDVIの画面に垂直線を描画するようにしてみた。




これだけだと、何だか物足りない (^^);

そこで、マンデルブロー集合を描画させてみることにした。
プログラムは「C言語によるアルゴリズム事典」という本を参考にした。
演算は固定小数方式にした。


ここで、bootstrapルーチンでbss領域のゼロクリアを忘れていたり、gccの__mulsi3という整数乗算用関数をバグっていたりという初歩的なミスが発覚したりして手間取ったが最終的に以下のように描画させることが出来た。



表示画像(4:3)とディスプレイ(16:9)のアスペクト比が合っていないため横方向に膨らんで見えているが、アスペクト比が合って入れば以下のように見えるはずだ。
 → ディスプレイの設定を変更してアスペクト比を自動で変えるようにした。色味が上(撮影画像)と下(期待値・・・プログラムでppm形式のファイルを生成し、それをjpegに変換した)とで違うのは撮影に使用したデジカメの設定の問題だ。目視では下の期待値と同じ色味で見えている。



このプログラムでは乗算があるが、zumi32は乗算器を持っておらずソフトウェアでエミュレートしている。そのせいもあると思うが一画面描画するのに結構時間がかかる。画素数 1024 x 768 で演算のmax iteration数は64で1分30秒位だ。 gccのmachine descriptorもまだ全然洗練されてなくて、-O2オプションでコンパイルして生成されるコードも今一な出来なのでそのせいもあるのかも知れない。もっと効率の良いコードが出力されるmdファイルを書けるようになりたいもんだ。

でも、ここまで出きるようにはなった。  やったー \(^_^)/


2012年7月3日火曜日

cross gcc for zumi32 3

なんとか、zumi32用gccのビルドが通るようになった。
gccのソースは全部込みの場合、fortranやjavaやobjc, ada等も含まれるが、今回はgcc-coreとgcc-g++のみを対象にしている。また、newlib-1.19.0もビルドした。



試しに以下のプログラムのコンパイルをしてみた。



生成されたa.outを逆アセンブルして確認。



良さげな雰囲気だ。 (^_^)

でも、多分まだ実装漏れや間違いがあると思うが、そこそこのプログラムはコンパイル出来そうな気がする。後は使いながらバグ出し&修正するしかないかな?

自作CPUで遊ぶ 22

今使用しているモータードライバはDM556Dというものだが、このドライバはMicro Stepが 800 [pulse/rev] 〜 40000 [pulse/rev]の範囲で設定できる。 Mi...