今さら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での記述説明:
ピン数制限によりプリセット機能はなし。
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]](https://m.media-amazon.com/images/I/51BB+TM6wSL._SL160_.jpg)