まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

GAL

Fenestra6502の石数削減の検討

 @hatsugaiさんのFenestra6502。既存の6502にレジスタウィンドウ的なメカニズムを外付けして、関数呼び出しでの引数/結果の受け渡しに関わるコストを劇的に改善している。
 引数の受け渡しおよびローカルな作業エリアはダイレクトページ上に確保し、関数呼び出しとリターンに対応するJSR/RTS命令でこれらの領域がずれて割当てられる。256バイトのダイレクトページは以下の割当て。

%i $00-$3F  呼び出し元からの引数。RTSでもどる前に結果をここに置く。
%l $40-$7F ローカル作業エリア。
%o $80-$BF JSRで呼び出す先の引数を与える。JSR先では%iで参照。
%g $C0-$FF グローバルエリア JSR/RTSで割当ては変化せず。

%i,%l,%o,%gはSPARCアーキテクチャのレジスタウィンドウに合わせた分類で、役割も同様。
JSR前の$80-$BFが飛び先では$00-$3Fに対応する。

他にレジスタウィンドウを持つアーキテクチャはAMD Am29000、Intel i960、Intel Itanium、クヌースのMMIX。HITACHI H16も似たようなメカニズムを持つ。

 Fenestra6502の仕組みについて。128Kバイトのメモリについて、$100C0~$1FFFFを65C02のアドレス空間に割り当てている。65C02の$0000~$00BF(192バイト)については外付けの回路でアドレス変換を行い、$00000~をダイレクトページ領域として割り当てている。
 アドレス変換はJSR命令で+1、RTS命令で-1するアップダウンカウンタを持ち、ダイレクトページをアクセスするアドレス$0000-$00BFとこのカウンタの値(7bitオフセット:x128)を加算し128Kバイトのメモリ$00000~に変換する。
 カウンタは65C02のスタックが256バイトしかないので、0~127の7bitで充分。(JSR命令で2バイトのアドレスをスタックに積むため)


 Fenestra6502のハードウェアはW65C02Sと制御用のATMEGA164P、128Kx8 SRAM 628128。GAL 22V10 x2、LS74、LS191 x2、LS283 x2、LS257 x2。10cm x 10cmの基板に収めるのはちょっときびしい気がする。GALを活用すればさらに石の数を減らせるんじゃないかと検討してみた。

 Fenestra6502の回路図。(2020/10/14 Rev, 1.2)
Fenestra6502


検討1:U6 LS74の削減

 INSTDEC(GAL 22V10)はJSR/RTS命令をデコードして次段のLS191に対しカウントアップ/ダウンの指示をしている。このカウンターへの指示はLS74で1サイクル分保持されている。この程度ならINSTDECに吸収できそうだ。


 FFの初期化のためのRESETを追加。これでU6 LS74をなくすことができる。


検討2:デコーダとカウンタの統合

 カウンターは7bitあればよい。これと命令デコード部分を1つのGALでできないか?
 SYNC信号は命令フェッチのタイミングを示す。この立ち下がりのタイミングでデータバスに乗る命令をデコードし、そのままカウンタのアップ/ダウンを指示すればいけそうな気がする。SYNC信号を反転してその立ち上がりで動かせばよさそう。こういうのは昔の汎用ロジックの使い方っぽい。SYNC信号は!SYNCOUTとして反転出力し、それをGAL 22V10のCLK入力に与える。
 命令デコードは8bitのデータバスを扱うためこれをそのままカウンタ回路につなごうとすると項数オーバーでパンクしてしまう。そこでデコード結果はいったんDU,CTEN出力として割り当て、フィードバックループでぐるっと回して入力信号に与える。
 これで命令デコーダとカウンタはGAL 1個に入った。検討1での代わりに使うとLS74、LS191 x2の計3個を削減できる。そのかわりWR/RDなどの信号が扱えなくなるがこれは後で別のGALに追い出す。



検討3:加算器をインクリメンタに変更

 カウンタの出力7bitはアドレスA[13:7]に対応する。これにゼロページの変換対象となるアドレス$0000~$00BFが加算されるが、この下7bit A[6:0]はそのままスルーでA[7]のみカウンタの値と加算される。これは全加算器ではなく+1インクリメンタで充分。
A[14]はカウンタの値が繰り上がった時に'1'だけど実質常に'0'。A[15]は常に'0'。
SRAMに与えるアドレスYA7はGALのU4 ADDRDECで生成しているRA7と同等のもの。端子が空いていたので配線の都合がよいように定義しただけ。
インクリメンタが出力するアドレスY15~Y8(ついでにY7)はOEでアウトプットイネーブルの制御を行う。これに65C02からのA15~A8を接続したLS245(新規追加)の出力をSEL信号で選択することによりアドレス変換/無変換後のアドレスをSRAMに与えることができ、LS257 x2を削減できる。
 これで従来の加算器とアドレスセレクタはLS283 x2とLS257 x2の4個を削減、GAL +1、LS245+1。



検討4:その他の論理

 検討2ではみ出てしまった RAM OEとRAM WEをGAL ADDRDEC(22V10)に押し込む。


これで最終的にGAL 22V10 x3、LS245 x1になった。あとはレイアウトの都合で端子の配置を手直しすればよさそう。



※これは机上での検討のみで実際には作っていませんのでご注意ください。



 えっamazonにあるの?

GALでFFを使うための調査

 今さらGALを使う準備のつづき。前回でWinCUPLを使って組み合わせ回路をGALに書き込んで使えるようになったが内蔵しているFFも使えるようになったらさらによろしかろうと思いCUPLでの書き方を調査した。WinCUPLによるコンパイルのみで実チップに書き込んでの確認まではやってないので注意。

 現在入手が容易なのは以下の22V10、16V8。22V10は24ピンパッケージで22本の入力ピン、うち10ピンは出力に設定可能。16V8は20ピンパッケージで18本の入力ピン(制限あり)、うち8ピンは出力に設定可能。

GAL22V10(Lattice)
ATF22V10C(Microchip:旧Atmel)
ATF22LV10C(Microchip:旧Atmel) ←これは3.3VもOK

ATF16V8B(Microchip:旧Atmel)

 CUPLについてのドキュメント。その他、WinCUPLをインストールすると一緒にはいっているexamplesのソースが参考になる。CUPL自体はCPLDなどもターゲットにしているのでデバイス固有の機能が使えるような書き方ができるようになっているが、GALではその一部しか使わない。



 題材として8bitのLFSRを作ってみる。このWikipediaに書いてあるフィボナッチLFSRはXORの段数が多くなりコンパイルに不利そうなのでガロアLFSRを採用する。

 WinCUPLでコンパイルしエラーをなくしたソースは以下のGistに置いた。

仕様:
・入力クロックにしたがいQ0~Q7が変化する。
・CTEN入力がdisableの間はQ0~Q7をホールドする。
・OE入力がdisableの間はQ0~Q7をハイインピーダンス状態にする。
・RESET入力で非同期にQ0~Q7を0クリアする(LFSRの性質上ずっと0のままになる)。
・PR入力でS0~S7の値をQ0~Q7にセットする。


GAL22V10での記述説明:
Device  G22V10;
 GAL22V10をターゲットとする場合はDEVICE名にG22V10を指定する。
Pin 1 = CLK;
 G22V10はD-FFを10個持つ。FFを使う場合はPin 1がクロック入力となる。
Pin [16..23] = [Q0..7];
 CUPLによるピン宣言では変数名をピン番号に割り当てるだけで入出力は指定できず、式での記述で推定して決められる。例えばある変数が式の左側にあれば、その変数名に対応するピン番号は出力となる。出力となりうるピンはPin 14 ~ Pin 23の10本。[ ]で変数名+10進数のインデックスを付けてまとめて宣言できる。インデックスは0~31までだがGALでは問題にならない。
[Q0..7].ar = RESET;
 変数名の後に.を付けて拡張子を指定できる。G22V10の場合は出力となる変数名に以下を指定できる。このうち.oeは組み合わせ回路のみの場合でも指定できる。
非同期リセット .ar
同期プリセット .sp
アウトプットイネーブル .oe
D-FF .d
[Q0..7].sp = 'b'0; /" = [S0..S7] & PR;  NG ! "/
 同期プリセットについては当初 S0 & PRのようにプリセットできるような式を書いていたがWinCUPL
で" excessive number of product item"が出てコンパイルエラーとなった。ここはGALの構造上1つの信号しか接続できないので組み合わせ論理をともなう式が書けない。よって無効にした。

Q0.d = !PR & (CTEN & !Q7 # !CTEN & !Q0) # PR & S0;

 シフトレジスタ本体の記述の一部。Q0.dはD-FFの入力。同期プリセットを無効にしたのでここでプリセットできるよう式に記述。あと、CTEN入力でシフト動作とホールド動作の切り替え。

 LFSR8.simファイルでコンパイル結果を確認できる。

 GALで扱う論理くらいではあまり関係ないかもしれないが、WinCUPLにはコンパイルオプションで論理圧縮のアルゴリズムを選ぶことができる。

GAL16V8での記述説明:

 ピン数制限によりプリセット機能はなし。
https://gist.github.com/houmei/08b9eb0da63171cd523eec008b6110d5

16V8でD-FFを使うにはRegistered Modeを指定する。このときPin 1はCLK入力、Pin 11はOutput Enable入力固定となる。
Device  G16V8MS;
 デバイス指定でRegistered Mode を指定する。G16V8記述で自動推定もできるらしい。
/* [Q0..7].oe = OE; */
 拡張子.oeは指定できずPin 11決め打ちとなる。
/* [Q0..7].sp = 'b'0; */
/* [Q0..7].ar = RESET; */
 拡張子.sp、.arは指定できない。パワーオン時のD-FFの初期値はデータシート読んでみたけどわからなかった。
Q0.d = CTEN & !Q7 # !CTEN & !Q0;
 パワーオン時の初期値が'0'と仮定するとLFSRは0のままなのでD-FFの入出力を反転させた。昔どこのPLDか忘れたけど初期値が'1'のデバイスがあって悩んだ覚えが。
 いま気付いたがRESET入力を式に混ぜて初期化するのを忘れた。次の機会に。


 その他、状態遷移を記述するSequenced文を使うとFFの使用が推定される。ただしSequenced文は複数書けないようだ。よく考えたらそりゃそうだなんだけど、4bitCounterを2つ記述しようとして2つめのSequenced文が無視され失敗した。

 あと、WinCUPLがコンパイル後毎回落ちるのもちょっと困る。Windows10を色々アップデートする前は動いていたんだがもともとWindowsXP用のソフトなのでしょうがないか。



宇宙空母ギャラクティカ(劇場版1978年) [Blu-ray]
ローレッタ・スパング
ジェネオン・ユニバーサル
2013-11-27


今さらGALを使う準備

 2018年現在でDIP品のGALを使う準備。

 PLD(Programmable Logic Device)の一種であるPAL,GALは汎用ロジックICの置き換えとして使われていた。TTL 2〜3個を1個のパッケージに収めることができ、ゲートの段数を重ねることがないのでディレイも最小、面積も有利なので主要なLSI間をつなぐGlue Logicとして主に使われていた印象。GALの場合、DIP品は端子数と内蔵FFの数から16V8、20V8、22V10がよく使われていた。しかしより集積度の高いCPLD/FPGAの登場により終息しつつある。
 で、今GALを趣味で使うのは昔のマイクロプロセッサ関連を動かせるように作ったり修理したりするのに便利そうという理由。で、開発環境が用意できるかどうかやってみた。

・石の選定
 LatticeとAtmel(Microchip)が生き残っているが現在も生産しているのはAtmel(Microchip)のみ。DigiKey提携のマルツなどで購入できる。
ATF16V8B(Microchip)

・GALライタ
 アマチュアが入手容易なMiniPro TL866シリーズはLattice/Atmelに対応している。
サポートデバイス:
Microchip(ATMEL) ATF16V8B
Lattice GAL16V8/20V8/22V10

・開発環境
ATF16V8Bの開発にはWinCUPLを使用する。PALASM、ABEL、CUPLと色々独自言語があったけど回路規模は小さいし雰囲気で使えるはず。

 ということで ATF16V8B/WinCUPL/TL866CSの組み合わせでやってみます。

・WinCUPLのインストールとコンパイル
 WinCUPL(Microchip)からダウンロードしてインストール、再起動した後にライセンスキーを入力。ライセンスキーはWebページに掲載されています。インストールディレクトリはC:\Wincupl 。

 WinCUPL起動後、メニューの[File]→[Open]から C:\Wincupl\Examples\Atmel\ADDER.PLD を開く。次に[Run]→[Device Dependent Compile]でコンパイル。([Run]のメニューはファイルを開いていないと出ません) これで同じフォルダ内にADDER.jedなどのファイルが生成される。
GAL-compile

※私のWindows10pro環境ではコンパイル後にrun-time errorが出て終了しましたが他のWindows10home、Windows7(64bit)では正常にコンパイルできました。もともとWindowsXPまでの対応なので深追いせずにあきらめましょう。

・MiniPro TL866CSによる書き込み
 MiniPro TL866CSのソフトウェアは以下よりダウンロード。ver7以降はTL866II Plus専用なので注意。

 ブランクチェック。GALはPROMと同じような感じで焼けます。
2018GAL

 ADDER.jedを指定して書き込みOK。
GAL_atf16v8b

 ということで書き込みまでOK。

 GALは組み合わせ回路のみで使うと特に悩むようなことはありません。むかし別のメーカーのでFFを含む回路を作ったときはFFのリセット後初期値が'1'でハマった記憶が。そのときもなんとなく記述して動かしたので今後もまあできるんじゃないかなあという気持ちでいきます。


高速運作TL866CSプログラマ/USBついプログラマ EPROM FLASH AVR TL866シリーズプログラマ高速運作TL866CSプログラマ/USBついプログラマ EPROM FLASH AVR TL866シリーズプログラマ

Generic
売り上げランキング : 58538

Amazonで詳しく見る
by G-Tools

記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ