組み込まれたエンジニア

我輩は石である。名前はまだ無い。

VHDL対応強化

2009-01-27 21:54:56 | Weblog
やりはじめたら、中途半端に止められない性格のため、sfl2vlのVHDL対応の強化をしてしまった。(といっても、Verilog版に追い付いただけだが…)

強化点は、次の通り


  1. セレクタ最適化オプション導入
  2. メモリ合成のサポート
  3. generic/generic mapのサポート


これらの対策で、Apple-I互換機のVHDL版がXilinx社ISEの合成を通るようになった。

この回路では、最適化で、クロック周波数は約15%向上する。
これに対し、LUT数は、1.4%程多くなっている。

まぁ、いい感じのトレードオフではないかな?

VHDLが嫌いな点の追加(;-p) なぜに、奴らは、予約語をこんなに増やしたのか?
inやoutも気持ち悪いが、ror,rolなどまで予約語にしなくてもいいだろ?

このところ、毎日のように午前3時すぎまで、仕事をしていたので、さすがに少々くたびれてきた。戦士の休息が必要ですね。(まだ休むめどは立たないけれど…)

VHDLでのセレクタ最適化

2009-01-27 13:13:04 | Weblog
VHDLは構文上、プライオリティエンコーダを含むセレクタを推奨する本が多く、サンプルで見かける例にも、whenを使った、プライオリティ付セレクタ使用例が多いので、おそらく、VHDLユーザは高速回路にあまり興味がないだろうと思っている。

Verilogユーザはスピードにクリティカルなので、SFLからVerilogに変換する場合、最適化を指示すると、AND-ORによる高速セレクタを生成していた。一方、VHDLへの変換では、先の理由から、最適化を指示しても、Verilogほどの突っ込んだ最適化はせず、推奨構文を用いて、分りやすい生成しかしてこなかった。

VHDLのユーザはあまりいないので、これで問題になることもなかったし…

ところが、自分のプロジェクトで無料のレイアウトツールとして、Allianceを使おうと思うと、高速なVHDL回路が欲しくなる。もちろん、VerilogからEDIFに変換するツールを用いて、EDIF経由でレイアウトする方法もあり、以前、テストチップ作成したときには、Verilogの合成ツールを自分で書いて対応した。

だが、EDIFレベルの論理合成をライブラリの属性を見ながら最適化するツールを作るのは、無駄な気がして、あまりメンテナスしていない。

そこで、自分のプロジェクトで使うために、sfl2vhでのセレクタ最適化が可能となるようにした。

回路実装までは試していないが、完成したとしても、今まで、VHDLユーザーには、その手のリクエストはなかったので、一般公開はしなくてもいいかも?

SystemCの分割コンパイル

2009-01-24 01:53:16 | Weblog
ふと、思い出したが、SystemC(というか、C++)では、分割コンパイルする時に、インクルードするヘッダファイルに、コンストラクタを書く必要があった。

SystemCのコンストラクタは、実質内部処理を記述しており、IP記述としては、役に立たないと、その昔、仕様を読んだ時に思ったのだった。

コンストラクタまで入れたヘッダファイルは、処理部分を入れたファイルと大きさ的にも大差ないので、ファイル丸ごとインクルードという今の仕様でもいいのかも?


sfl2vl SystemCサポートβ版リリース

2009-01-23 17:38:37 | Weblog
モジュールの基本動作、状態遷移マシンの自動生成、階層モジュールの動作など、ざっとではあるが、一通りの確認ができたので、sfl2vlの SystemCサポートβ版をリリースする。 (Windows GUI版のみ)

もう少し確認を終えたら、正式リリースをする予定。

今回はざくっとSystemCのファイルを作ることが目的なので、生成コードの効率に関しては目をつぶっている。もっとも、同一 SFLからVerilogに落ちるので、論理合成に持っていきたい人はいないと踏んでのことだが。

確認のため、いくつか、SystemCのテストベンチを書いたが、SystemCは、かなり面倒だ。SystemCを用いるテストベンチの簡単な作成方法を考えないと、(私のようなオールド)ユーザに優しくない。

SystemCでシミュレーション

2009-01-22 22:03:13 | Weblog
SFLから自動生成したSystemCのコードにmainルーチンを付け、コンパイルして実行してみた。

一日忙しかったのと、本日は、体調不良のため、階層モジュールで動くかどうかはまだ試していないが、とりあえず、レジスタを含む単純なモジュールは動いている。

C++に慣れていないので、分割コンパイルがうまくいかず、mainから合成したファイルをインクルードしてしまったが、分割コンパイルの方法を調べなくては…


備忘録:
モジュール端子のバインディングでは、型をきちんと合せる必要がある。
c++だから仕方ないが、自動キャストできる場合とできない場合、あまり一貫性がないのが気持ち悪い。というか、代入の時だけかな、キャストが自動的に行なわれるのは?

SFLでのマルチビットの端子は、sc_uintにしていて、シングルビットの端子は、boolに変換したので、バインディングの受け側のシグナルも同じ型にすること。

SFLからSystemCへの変換

2009-01-22 07:10:44 | Weblog
sfl2vlに機能追加で、SystemCへの変換が可能となるようにした。(未公開)
まだ細かなチェックはしていないれど、コンパイルは通るようになった。

systemc.h へのインクルード指示を生成ソースに入れるかどうか迷っている。もちろん、インクルードがないと動かないのだけれど、自動生成で入れるべきものか、ユーザが入れるべきものか、どちらなのだろう?


CQのVerilog本に、Apple-I互換機を実装中

2009-01-21 09:56:26 | Weblog
CQの本付録のボードには、Spartan3E100が実装されているので、容量的に、Apple-I互換機が載る。もちろん、IOはあまりないので、シリアルポート、7SEG, LED, SW程度で使うのだ。

FPGAボードで学ぶVerilog HDL


拡張用に汎用IOポートのパターンがあり、これを使ってみよう。拡張ポートは16本しかないので、入出力の双方向ポートにする。方向レジスタと出力レジスタを定義し、双方向ポートを実装した。

XSTの合成レポートでは、スライス数60%程度とまずまずである。クロック周波数は少し落ちているが、これは、QFPと関係するのかな…

さて、プレース&マップしよう…として、GPIOの5ピンが実装できないエラー?
他のピンではエラーはないので、もしやと回路図確認。

このピンだけ、GPIO5ではなく、GPIN5と書かれている(!)。う~む、どうせなら全部のピンを入出力可能にしてほしかったぞ。まだFPGAには空いたピンも残っているんだから。

気を取りなおして、5番だけ入力専用に変更して、プレース&マップ。

あれ?再びエラー?DCMがどうのこうの言っている?

--------------------------------------------------------
この問題は、クロック配置ツールで各 DCM サイトのあるチップの辺が正しく識別されないことが原因で発生します。DCM を適切なサイトに制約すると、この問題を回避できます。

この問題は、Spartan-3 のすべてのファミリで発生する可能性があります。

この問題は、最新版の 10.1 サービス パックで修正されています。サービス パックは次のサイトから入手できます。
http://japan.xilinx.com/xlnx/xil_sw_updates_home.jsp
この修正は、10.1 サービス パック 1 以降に含まれます。
--------------------------------------------------------

おぃ…


追記:

長い時間をかけて、サービスパックをダウンロードしインストールしたけれど、結局、エラーは直らない。
しかたないので、次の行をUCFに挿入。

NET "m_clock" CLOCK_DEDICATED_ROUTE = FALSE;
PIN "dcm_2.CLKIN" CLOCK_DEDICATED_ROUTE = FALSE;

DCMを使わなければいいんだけれどね~

クロックが低く見えるのは、遅延のフォルトパスの問題だった。

とりあえず、これで合成できたが、残る問題は私はパラレルポートのあるPCを持っていないので、このボードにはダウンロードできない(;-p)

80MHzの6502

2009-01-20 00:24:52 | Weblog
お正月に開発したAISoCは、Apple-I互換機と言っているが、互換なのは、キーボードとモニタのIOポートの仕様(アドレスとデータのビットマップ)だけであり、それ以外はまるっきり無関係である。

そもそも、その頃には存在していなかったIOもかなり搭載している

こいつのCPUは、自分で開発した6502互換CPUであり、論理回路はすべてフルスクラッチで自分で書いたものだ。


今日、VRAMを2ポートに変更したついでに、変更後のXilinxの合成結果を眺めていて、ふと、クロック周波数の上限が、80MHzとなっていることに気が付く。


Timing Summary:
---------------
Speed Grade: -5

Minimum period: 12.457ns (Maximum Frequency: 80.274MHz)
Minimum input arrival time before clock: 7.711ns
Maximum output required time after clock: 9.172ns
Maximum combinational path delay: No path found


AISoCは、この周波数で実際に動かしているのでなくスターターキットの50MHzのクロックをDCMで4分周した12.5MHzで動作させているのだが、それにしても、80MHzである。 あのApple-IやApple-IIが80MHzで動作していたら、IBM PCなど束になってもかなわないスピードでプログラムが動作するだろう♪

低価格FPGAもあなどれない。

Apple-I互換機、画面出力ハード完成

2009-01-18 00:10:26 | Weblog
キャラクタジェネレータ経由で画面に文字を表示するハードウェアは完成だ。
とりあえず、フォントではなく、適当なパターンをキャラクタに設定してみる。

1400: 18 66 99 A9 A5 24 42 81

VRAMは0番目に1を設定し、それ以外は0のままとしている状態で、キャラジェネに上の設定をする。

と、画面の左上だけブランクで、それ以外に同じパターンが展開される(!)。
狙いは、左上だけに表示するつもりだったが、キャラジェネの設定のアドレスを間違えて、0番目のフォントデータとして、絵を描いてしまったのだ。

追記:ちょっと、まぎらわしいが、要するに、ハードには問題がないということだ。単に、私がキャラクジェネレータにデータを書き込むアドレスを8バイトずらしてしまっただけ。

8×8のパターンを目一杯記述しているので、隣同士がくっついているが、ビットマップが表示されていることが分る。

今回から、Spartan3 Starter KitとSpartan3E Starter Kitのアーカイブを統合した。

VGAモニタ出力の実装

2009-01-16 04:15:38 | Weblog
XilinxのData2memで、二つのメモリブロックをISEから自動的に別々のデータで初期化する方法が見つからないので、フォントデータは登録できていない。手動で書くなら、data2memを2回通せばいいような気がするが、マウスだけで簡単操作の原則に反するので、もう少し検討。とりあえずは、折角実装した動作の確認をオシロでする。

水平同期と垂直同期の信号は正しく出ているので、タイミングの計算は間違っていないことが分る。

追加メモリブロックが読めなかったり、いくつか原因不明のトラブルがあったので、実験的に、DCMを用いて、クロックの分周をしてみた。再現性が高い不具合なので、クロックの問題でないのは明らかなのだが、DCMを使う例題を作りたかったので、ちょうどよい。

SFLからDCMなど既存のモジュールを使う時には、プロトタイプ宣言に interface 修飾を付ける(sfl2vl限定)。

declare BUFG interface{
 output O;
 input  I;
}

declare DCM interface{
 param_int CLKDV_DIVIDE;
 param_str CLK_FEEDBACK;
 input RST, PSINCDEC, PSEN, PSCLK, CLKIN, CLKFB;
 output PSDONE, CLK0, CLK90, CLK180, CLK270,
        CLK2X, CLK2X180, CLKDV, CLKFX, CLKFX180,
	LOCKED, STATUS<8>;
}

モジュールにおけるDCMなどのインスタンスは、例えば、
 
 BUFG buff;
 
 DCM dcm_2(CLKDV_DIVIDE=4, CLK_FEEDBACK="1X");

と、宣言する。
共通動作宣言で、下記の様に接続を定義して使う。
(これは、4分周クロックを使う例となっている)

  dcm_2.RST = p_reset;
  dcm_2.CLKIN = m_clock;
  dcm_2.CLKFB = dcm_2.CLK0;
  dcm_2.PSEN = 0b0;
  dcm_2.PSCLK = 0b0;
  dcm_2.PSINCDEC = 0b0;
  buff.I = dcm_2.CLKDV;
  board.m_clock = buff.O;
  board.p_reset = p_reset;
 




VGAに文字が表示されたなら、プロジェクトをアップロードする予定だが、我が家には空いたモニタがないし、このところ忙しいので、いつになることやら…

パブリックドメインフォント

2009-01-14 00:08:25 | Weblog
Apple-I互換機で使用するための英文フォントデータをXfree86のBDFフォントファイルから抽出するためのawkスクリプトを作成。




                                        
BEGIN {enc = 0; fnt = 0;}
/ENCODING/ && $2 > 31 && $2 < 128 { enc = 1;}
enc == 1 && /BITMAP/ { fnt = 1;}
enc == 1 && /ENDCHAR/ {enc = 0; fnt = 0; print "00\n";}
enc == 1 && fnt == 1 && !/BITMAP/ {print $0;}




5x7.bdf専用であり、汎用性は皆無だが、とりあえずの目的には合致しているだろう。

あとは、VGAコントローラを作成して、実際に表示できるようにするだけだ。


Apple-I互換機にPS2 Keyboardを接続

2009-01-12 11:07:45 | Weblog
Spartan3EスターターキットにはPS/2コネクタを搭載しているので、これをApple-I互換機から使えるようにした。PS/2のインタフェースを入力線2本だけIOポートに接続してソフトでやらせてもいいのだけれど、ソフトの開発も自分でやるので、ここはPS/2用の小さなシリアル入力回路を作る。11ビットのシリアルデータをパラレルに変換し、ステータスビットを用意して、Apple-I互換機のメモリ空間にマップする。

とりあえずは、スキャンコードの変換はソフトに任せることとして、キーボードからデータが出力されることを確認。

文字と16進数の出力ルーチンはWozのモニタのサブルーチンを流用したので、確認プログラムはごく短い。

Apple-I互換機で、液晶パネル駆動

2009-01-11 12:17:40 | Weblog
Apple-I互換機の液晶パネルの制御プログラムをアセンブラで書き、FASMでアセンブルした。FASMはNES用のアセンブラであり、オブジェクトフォーマットはAAXと書かれていたが、中身を見ると単なるモトローラS形式だ。

そこで、CでS形式からApple-Iモニタメモリ入力形式への変換プログラムを書いて、TeraTermからファイル送信で、Apple-I互換機にアップロードする。

端末設定で、受信の改行をCR+LFにすることと、シリアル設定で、送信遅延を2mS以上取ることに注意する。(シリアルコントローラの受信部の問題?)

Spartan-3E starter kitのマニュアルを参考に、LCDパネルコントローラにコマンドを送るプログラムを作成。

遅延時間を微調整したりしたが、とりあえず、無事、画面表示はできるようになった。



ちなみに、プログラムは…

0800: A9 01 85 10 A9 03 20 E0 08 20 FB 08 A9 03 20 E0 08 20 F2 08 20 F2 08 20 F2 08 A9 03 20 E0 08 20
0820: F2 08 A9 02 20 E0 08 20 F2 08 A9 28 20 BD 08 20 F2 08 A9 06 20 BD 08 20 F2 08 A9 0C 20 BD 08 20
0840: F2 08 A9 01 20 BD 08 20 FB 08 A9 48 20 C7 08 20 F2 08 A9 65 20 C7 08 20 F2 08 A9 6C 20 C7 08 20
0860: F2 08 A9 6C 20 C7 08 20 F2 08 A9 6F 20 C7 08 20 F2 08 A9 21 20 C7 08 20 F2 08 A9 C0 20 BD 08 20
0880: F2 08 A9 41 20 C7 08 20 F2 08 A9 50 20 C7 08 20 F2 08 A9 50 20 C7 08 20 F2 08 A9 4C 20 C7 08 20
08A0: F2 08 A9 45 20 C7 08 20 F2 08 A9 2D 20 C7 08 20 F2 08 A9 49 20 C7 08 20 F2 08 4C 00 FF 48 A9 01
08C0: 85 10 68 20 D1 08 60 48 A9 03 85 10 68 20 D1 08 60 48 4A 4A 4A 4A 20 E0 08 68 29 0F 20 E0 08 60
08E0: 8D 21 D0 A5 10 8D 20 D0 EA EA EA EA A9 00 8D 20 D0 60 A9 C0 85 11 C6 11 D0 FC 60 A9 80 85 12 20
0900: F2 08 C6 12 D0 F9 60

SPARTAN-3E Starter KitでApple-I互換機

2009-01-09 01:28:28 | Weblog
Xilinx社のSPARTAN3E starter kitにもApple-I互換機(AISoCS)を移植した。
このキットには、7SEG LEDが付属せず、液晶パネルが付いている。そこで、液晶パネルのコントローラをアドレスデコードして、6502から読み書きできるようにしておく。その上で、液晶パネルをクリアするコマンドを出力するように、プログラムを作成する。
Apple-Iのモニタの上で開発するのはしんどいので、16進数を打ち込んだファイルをTeraTermPROのファイル送信機能を用いてアップロードする。
(ここで、文字ごとに少し遅延を置かないと、文字化けが生じた)

結果であるが、このプログラムの実行で、液晶パネルは何らかの影響を受けているらしい(;-p)

というのは、送ったのはパネルクリアのコマンドのはずだが、2回プログラムを実行しないとクリアしないのだ???(1回目もパネルの表示は変るのだが、クリアはしない)

Digilentの仕様書もいいかげんだし、ハンドアセンブルなので、初期化など完全にサボっている私のプログラムもいいかげん ということで、原因は追求していないが、時間ができたころにゆっくりと対策を考えよう。