2018年04月03日

キーパッドめも

操作用のキーパッドを付けたい場合どうしたら良いかという話。1〜3 個ぐらいなら直結すれば良いわけだが、それ以上の場合。ただし、キーボードはまた別の話とする。

1) パラレル入力シフトレジスタ

74lv165a.png

74HC165 (など) を 1つまたは 2つ使って 〜8個 または 〜16個のキーを入力する。このやり方は FPGA で扱うには実に簡単そうである。また、このやり方は、ファミコンやスーファミのコントローラで採用されている。

    ファミコンは、CD4021B などが使われているが、74系165でも機能は同じである。また、入力はプルアップ。ボタン押下で L になるようにする。新規で作るのであれば、今は 74LV165A がある。ただ、tiny2313 で同じ機能を作ったほうが安上がりな上、機能拡張も可能。ただし、クロックは、6us でトグルされるので、適当なコードではまずい。

操作用といっても似たようなものになるわけだから、いっそのこと、そのものを使ってしまっても良いかも知れない。

    < 7 6 5 | 4 3 2 1 ]
    1 VCC , 2 CLK, 3 P/S,4 DATA,7 GND
    こういう接続らしい。(ケーブルの信号が 5本なので、他は NC ?)

    P/S を H にして、ボタンの状態を取り込む。(ボタンを押せばL)
    P/S を L にすると 取り込んだデータを シフトするモードになる。CLK の立ち上がり でシフト。
    出力されるデータは、負論理で B,Y,SELECT,START,UP,DOWN,LEFT,RIGHT,A,X,L,R の順。

      165 では SH/~LD の論理がP/S と逆で L にしたときの値を取り込むので注意。

      なお、実機では 60Hz でスキャンしているとのこと。

    ハードオフでジャンクを買える可能性もあるが、未だに、サードパーティーの コントローラも 本体側コネクタや延長ケーブルも aliexpress で売っている。
続きを読む
posted by すz at 20:20| Comment(86) | TrackBack(0) | MachXO2

2018年03月29日

高速通信の検討

FPGA で、高速通信をしてみたいと書いた。それについてのメモ:

世の中のインターフェイスは、みな数Gbps になってしまった。SATA が 6Gbps, USB が 5Gbps , イーサネットは 1Gbps だが、同じ RJ45 のタイプで、2.5/5 Gbps もある。そんなものは、(安物の FPGA) では 扱えない。たとえ扱えたとしても、電子工作では電気特性的に無理だろう。

映像系の一方向通信では、HDMI 2.0 が 18Gbps ! カメラインターフェイスの CSI-2 とかも G2a - 2.5 Gbps/G2b - 2.9 Gbps 。

どれもこれも、電子工作では手も足も出ない感じ。しかも普及しているから安価に使えるのである。電子工作の出番はない。

では、電子工作で扱えるレベルは、どれぐらいなのだろうか?続きを読む
posted by すz at 21:02| Comment(1) | TrackBack(0) | MachXO2

2018年03月25日

ΣΔDAC (2) オーバーサンプリング

ΣΔDAC (1) の続き

ΣΔDAC はできたとして、普通のサウンドDAC として使うには、オーバーサンプリングが必須である。それをするためには、デジタルフィルタ(LPF) が必要だそうだ。もとのサンプリングデータに 0 のデータを挿入したものに LPF をかけると、綺麗に補間されたデータが出来るとのこと。デジタルフィルタには FIR フィルタというものを使う。この FIR フィルタを作ってみよう。

おさらい

    14.314 MHz から作った 45.8 MHz を 16 x 65 で分周して 44.056 kHz を作る。オーバーサンプリングは 65 で 16 までのタップ数の FIR フィルタを使う。

    もし NTSC 画面表示と同時に使うのであれば、44.056 kHZ の 15/16 にサンプリング周波数を下げる。
    (外部 PLL が使えれば、44.056 kHZ も可能になる。クロックが変わるだけで、コードは変えない。 )

    NTSC 画面表示は、14.314 MHz の 3倍クロックで検討する。
続きを読む
posted by すz at 16:55| Comment(0) | TrackBack(0) | MachXO2

ΣΔDAC (1)

次は、サウンド用 ΣΔDAC を設計してみよう。

ハードウェアのおさらい
icedip-dac.png

4bit DAC で スピーカ用 BTL アンプに接続。負帰還でゲイン2倍。(片側1倍)
テスト用なのに音が大きすぎるかも、そこは RI(R61) か RF(R60) で調整する。RI を N 倍にすれば、それだけ小さくなる。

とりあえずスピーカーに直結するつもりだが、LC LPF を入れたほうが良いだろう。でもそれは、音が出るというレベルをクリアした後で考える。

4 bit フルに使うつもりはない。1 bit もしくは 3 bit を予定。
続きを読む
posted by すz at 15:37| Comment(0) | TrackBack(0) | MachXO2

2018年03月22日

NTSC エンコーダー(1)

さて、NTSC エンコーダーを設計してみよう。

ハードウェアのおさらい
icedip-vdacpng.png

4bit DAC で 1Vp-p DC出力。0 = -40IRE , 4 = 0 0IRE, 14 = 100IRE (のつもり)。
輝度信号は、4 - 11 の 8 レベルしか使わない。U,V 信号は、-4 〜 +4 で 合成したときに 15 になる場合が出てくる。続きを読む
posted by すz at 22:44| Comment(90) | TrackBack(0) | MachXO2

2018年03月20日

iCEDIP 基板

iCEDIP-02ct.png
iCEDIP2-elec.jpg
 ・icedip-02-out.zip(発注ファイル)
 ・icedip-02.zip (EAGLE ファイル)
iCEDIP 基板の2つめを発注。iCEDIP24 基板の周囲に実験用回路と電源を配置した。大きさは 63mm x 37mm 。本当は、モジュールだけ作るつもりだったのだが、iCEDIP24基板 も付けて配線してしまった。電源は、MINI-360 を使う。モニタが 12V なので 12V が使えるものを選択。

これは、基本テスト用で モニタに画像が出力できて、ちょっと音を鳴らせたら良いなと考えている。その先は考えていないが、なにか入力する手段が必要だろう。一応ピンは、左上の 6 本と右中央の 2本が空いている。また、SPI 通信ができるホスト -- SBC を使って開発すれば、お手軽にテストできそう。

異種面付けのように見えるが、ばらせるようにしただけで、本来一枚の基板。寄せ集めなので、取り付け穴は付けられなかった。スリットを使って、ずれないようにしたうえで、ねじ穴を空けて固定する -- というのを考慮はした。左下、右のコーナーにある端子は、潰しても良い。また、0.1 インチにアラインしている。

    (メモ)画像は、Fusion PCB の Viewer 。 https://gerber-viewer.easyeda.com/ がオリジナル。

    elecrow で発注したが、63mm x 37mm 10 枚で、$4.9 + 送料$6.06 = $11.96 のところポイントが使えて $9 = 991 円だった。 昔は 50mm 角に収めようとがんばったものだが、気にしなくて良くなったのはありがたい。一方送料が上がった気がする。大元の中国郵便が値上げしたのかも。
続きを読む
posted by すz at 19:28| Comment(87) | TrackBack(0) | MachXO2

2018年03月17日

iCE40 を使ってみる

手始めに iCE40 UP5K で 以前作った MachXO2 QFN32 用の Verilog ソースを論理合成してみようと思う。iCE40 は、iCEcube2 というツールを使う。論理合成エンジンは、Synplify Pro と Lattice LSE で Diamond と同じである。だが、iCE シリーズは、買収した SiliconBlue Technologies が開発元であり、なにかと違うものと思われる。

    iCEDIP-01t.png

    icedip.png

alu181

    // iCEDIP24 modified 74181 iCEDIP24
    // 37 B0 1 24 VCC
    // 43 A0 2 23 A1 36
    // 44 S3 3 22 B1 35
    // 45 S2 4 21 A2 34
    // 46 S1 5 20 B2 32
    // 47 S0 6 19 A3 31
    // 48 Cn 7 18 B3 26
    // 2 M 8 x 17 N.C. 25 (/P)
    // 3 F0 9 16 Cn+4 21
    // 4 F1 10 x 15 N.C. 20 (/G)
    // 9 F2 11 14 EQ 19
    // GND 12 13 F3 18

大昔の 4bit Arithmetic Logic Unit(ALU) 74181 である。本物は今や超高価で取引されている。せっかく 24 pin にしたのだから互換品を作ってみよう。ただし /P と /G は、carry-lookahead generator 74182 と共に使用するもので、パス。
ALU は、FF を持たないただの組み合わせ回路で非同期に動作する。
1) alu181,v を デザインファイルに入れて、論理合成 -- 問題ない。
2) pin Constants Editor で ピンアサインを変更。

    不思議なことに、制限がある信号が出てきた。とりあえず割り当てられたものをロックして、再度やりなおすと 制限がなくなっている。さらに不思議であるが、とりあえずロックして pcf ファイルを作成。(alu181.pcf: 以降使用可能)
続きを読む
posted by すz at 12:58| Comment(0) | TrackBack(0) | MachXO2

2018年03月13日

最近の lattice FPGA

以前 QFN32 の MachXO2 について記事を書いたが、久しぶりに製品をみたら、いろいろと興味深いものが出ている。

    ピン数が多い FPGA は、BGA が主流で もはや 電子工作で扱える感じではなくなっている。QFP はまだあるが、沢山の線を使うということは、たいへんな配線をしてなにかデバイスをつなぐということであり、予算と気合いがいる。QFN は配線が結構難しく、はんだづけも厳しいのだが、それゆえに電子工作としては楽しいと思っていて興味があるのだ。

MachXO2 1200HC 4SG32C(QFN32) - 509円(mouser)

QFN32 パッケージの MachXO2 に 1200HC が追加されていた。256 では出来ることが限られていたが、これだとマイクロコントローラが入る。しかも、256 と比べてそう高くない。

ICE40 LP384 SG32 - 195円(mouser)

もうひとつ QFN32 のチップが出ていた。384 だからたいしたことは出来ないが、お安い。ただし、多電源だったりして MachXO2 のように お手軽な感じではないようだ。

ICE40 UP5K (QFN48) - 876円(mouser)
ICE40 LP1K (QFN48) - 462円(mouser)

UP5K は、1Mbit - 128KB の RAM がある。それとは別に 120kbit の RAM(EBR) も。LUT 規模も 5K だからそこそこ。 さらに DSP ブロック(16x16乗算器 or ACC)が8つ。多電源ではあるが、規模が大きいし、これなら許容できる。
LP1K は、安い。UP5K 用の基板を作る場合 LP1K でお試ししてみるのも良いかも知れない。(LUT 1100, EBR 64kbit,DSP 2)

    DSP は、16x16乗算器 または 32bit アキュームレータの機能があるそうだ。メモリもあって演算が出来るわけだから、なにか面白いものが作れそうではある。が、私はあまり知識がない。とりあえず MIPS 32bit プロセッサを作ってみたい程度。あるいは、相互に高速通信が出来るようにして、多数つなげる。。。みたいな何か。

    LP1K も MachXO2 1200HC とあまり変わらないから、自作 AVR いけると思ったが厳しい。せっかく乗算器があるんだから、 と思ったが使いこなせてようやくシュリンクできる気もする。

また、これらを載せた小型ボード TinyFPGA というものもある。
type A は、MachXO2 で部品がほとんどない。type B は、iCE40 LP8K だが、なにやら部品が沢山。三端子レギュレータが2つに、SPI FLASH 。あと書き込むための USB とコントローラ(おそらく PIC)。
続きを読む
posted by すz at 21:24| Comment(35) | TrackBack(0) | MachXO2

2012年10月13日

MachXO2ボード秋月で取り扱い開始!

MachXO2 1200ZE Breakout Board を秋月が取り扱い開始した。2600 円と FPGA ボードにしては安い。FT2232H 搭載で FT2232H 単独のボードより安いぐらい。今まで記事を書いてきたが、手軽に入手できるようになって嬉しい。

    追記 2013/04/26
    秋月の MachXO2 Breakout Board が 1200ZE → 7000HE にグレードアップ。価格は 3000円。

    規模は、1280 LUT → 6864 LUT と大幅に増えた。価格はあまり変わらない。

    規模が増えるとブロック RAM も増える。26個 26KB だが、Lattice では多いほう。あと HE だから 速度的には有利(というか普通)になった。

    調べてないけど、たぶんチップを置き換えただけで、前のと互換性がある(はず)。

この機会に Lattice の FPGAボード (興味があるもので 現行品)についてまとめておこう。

MachXO2 1200ZE Breakout Board [LCMXO2-1200ZE-B-EVN]
MachXO2 7000HE Breakout Board [LCMXO2-7000HE-B-EVN]



    ・秋月 2600 円
    デジキー : 2593円
    ・Mouser: 2572円
    ・秋月 3000 円
    デジキー : 3035円

    追記 2013/04/26
    1200ZE → 7000HE にグレードアップ 旧製品はなくなった。秋月価格は 2600円 → 3000円だが 円安が理由。デジキーで見るとチップ単価は、1200ZE 886円→ 7000HE 1462円。

    さて、7000HE となったことは、大変喜ばしい。1200ZE で CPU を作ると規模がネックで厳しかったのが解消される。それだけではない。2組の CPU を入れて通信してみることもできる。同期させても良いが、外部に一旦出して 引き込むことにより非同期もテストできる。SDRAM を付けて、キャッシュ付き 32bit CPU なんてのも可能だろう。いずれトライしてみたいものだ。

MachXO2 Pico Development Kit [LCMXO2-1200ZE-P1-EVN]

LatticeXP2 Brevia2 Development Kit [LFXP2-5E-B2-EVN]

MachXO 2280 Breakout Board [LCMXO2280C-B-EVN]

まず、Lattice 社の開発ツールの Lattice Diamond は、他社のものと比べると 専有 DISK 容量が少ない。普段使っている SSD の ノートPC に入れられるので重宝している。容量が少ない理由のひとつは IP が膨大ではないこと。使い勝手はむしろ良いと思う。容量が第一の理由で Lattice で済むものは Lattice にしている。

    というか当面 Lattice を使う予定。XilinX はまたいずれ。

    初心者むきかというと .. そうでもあり、そうでもないような ... 。XilinX だと 分からない メッセージがあっても、ググれば見つかったりするが、Lattice はその面でだいぶ厳しい。開発ツールは使いやすいと思うしその点は残念。秋月での取り扱い開始で、使う人が増えて、情報が増えることを切に願う。

Lattice FPGA の中で MachXO2 は、FLASH 内蔵だし、ブロックRAM がそれなりにあるし、結構使いやすい。乗算マクロがないとか、シフトレジスタの規模が極小にならないとか Dual-Port の ブロックRAMのコストが大きいとか、少々不満はあるが、良い点も多いのだ。

良い点としては、クロック内蔵で お手軽。QFN32 や LQFP のパッケージがあって、電子工作でボードを起こしやすい。FLASH 内蔵とか レギュレータ内蔵なのも、電子工作にはメリット。さらに、JTAG を通じて通信できる。XilinX と同じ機能が使えるのは便利。

以上はチップについてだが、上記の開発ボードは、もれなく FT2232H 採用の USB ポート付き。しかも安い。USB に差し込むだけで使えるし、とにかくお手軽。

    これらのボードには JTAG コネクタも付いている。JTAGENB にスライドスイッチを付け、JTAG を無効にするコンフィグを書き込めば、出力としての転用も可能。-- 要するに JTAG ケーブルにできるのだ。( LCMXO2280C-B-EVN 以外)

LFXP2 は、使ったことがないのだが、乗算マクロがあるし、LFXP2-5E-B2-EVN では SRAM も付いている。ちょっと興味がある。(ただ、プロセッサを設計するときしか必要ないし、当面は手が回らない。)

LCMXO2280C-B-EVN は、MachXO で古い。ブロックRAM も少ない。だが、これもメリットがある。I/O ピン 数が多いのだ。こういう BGA のチップを 電子工作で使うわけには行かないので、ありがたい存在。

紹介したなかで、お薦めなのはやっぱり LCMXO2-1200ZE-B-EVN ではないかと思う。余計なものは付いていないしすなお。スイッチを組み込めるエリアもある。4000ZE/7000ZE といった大規模チップに換装可能だと思うし改造の楽しみもある。

関連記事
posted by すz at 18:44| Comment(20) | TrackBack(0) | MachXO2

2012年06月06日

QFN32の FPGA

ふと、MachXO2 でググってみたら、あらたに 32pin QFN が出るらしい。



デジキーでも LCMXO2-256HC のエントリーが出来ている。製品ページを見ても、なにやら情報が出ている。

Mouser では、1個買いの単価が出ている

    330円 (4 グレード)
    371円 (5 グレード)
    418円 (6 グレード)
    まだ在庫なし。工場リードタイム すら出ていない。

      (2012/7/3) 6 グレードだけだが、リードタイムが出ていた。9 週間。価格も安くなっていた。
      244円 (4 グレード)
      279円 (5 グレード)
      314円 (6 グレード)
      256 なんだし、これぐらいでないと。お、4 グレード は、25個時 単価 214円 か。これぐらいだと、AVR とかのサポート用に使える。


  • I/O 数は 22 -- これはどういう計算なんだろう?

    BSDLファイル は既にある。VCCIO が 4 バンクあって 電源だけで 10 pin 。残りが I/O という計算らしい。

    JTAG を専用にすると .. 18 I/O 。それに、PROGRAMN/DONE/JTAGENB の扱いをどうするか。

WLCSP25 は、1200 なのに、QFN32 は、256 のみ。1200 だったら大喜びしてたのに... 残念。

... とここまで書いて、以前の自分の記事に QFN32 のことが載っていることに気がついた。 忘れていたのか。

まぁ、そのことは置いておいて、今は、実際に 電子工作で扱える小ピンの FPGA が出ることはすなおに嬉しい。



これは、ストロベリーリナックスの CP2103 USBシリアルボードだが、こんな風に変換基板を作ることができれば、ナローDIP FPGA ボードになる。ただし、作ることができるとは限らない。CP2103 は、QFN28 なので QFN32 だとより条件が厳しい。1個分のホールを潰せば、ナローDIP化はできそうだが、ランドが少ない。果たして手ハンダが可能なのか? リフローもやってみたいが、それしか方法がないのもどうかという気がする。

    QFNパッケージのはんだ付け

    この記事には、『位置合わせさえ確実であれば無洗浄タイプのフラックスを使ってはんだ付けが可能です。』と記されている。楽々だったとも。

    ランドは、標準より少し 広げているようだ。パッケージの端から 0.5mm ぐらい?

それは後にして、そもそも この LCMXO2-256HC は何に使えるのだろう?

  • 4LUT 数 256
  • ブロック RAM なし
  • I2C, SPI, タイアカウンタ ハードマクロあり
  • PLL なし
  • 内蔵 クロック あり

まぁ ALU ぐらいは出来るだろう。ならば 74HC181 ピン互換が可能になるような、ピン配置にして 24pin の DIP モジュールにするのはどうか? 出来れば、データシートすら、なかなか見つからない 74LS281 互換にもしてみたい。

『CPUの創りかた』で 74HC181 を使っているらしいのだが、入手困難らしい。価値のある使い方がひとつできることになる。ランドも大きくすることが出来て、手ハンダも可能になるはず。

    電源を 3.3V 専用にして、2 pin 分にし、残りの 22 I/O を出すことは可能。

    ただ、Config で JTAG を Disable にすると、JTAGENB が JTAG を強制的に enable するための専用ピンになる。-- 要するに I/O が足りず完全互換にするのは無理。

    出力のうち めったに使われない P または G に JTAGENB を割り当てることでごまかそう。

    あとの問題は、電圧範囲で 3.3V 専用になることぐらい。



    こちらは、aitendo の CP2103モジュールだが、ちょうど 24pin 。こんな風に部品を載せる余裕が随分ある。

そうそう 低容量(128B)の ROM/RAM にはなる。

    8KB ROM と 2KB RAM は、

    A7 (1) (24) VCC
    A6 (2) (23) A8
    A5 (3) (22) A9
    A4 (4) (21) A12 /WE
    A3 (5) (20) CS /OE
    A2 (6) (19) A10
    A1 (7) (18) A11 /CE
    A0 (8) (17) D7
    D0 (9) (16) D6
    D1 (10) (15) D5
    D2 (11) (14) D4
    GND (12) (13) D3

    こんな ピン割り当て。(9) または (11) に JTAGENB を割り当てるので、互換にするのは無理。

    D2 を A8/A9/A10 のどれか に持っていくしかないかな。

    低容量(128B)でも、CPU を創るなら役にはたつ。マイクロプログラムなら 容量よりビット幅だし。

    訂正: 256B が行けるかと思ったのだが、実際にやってみると 128B までしか作れなかった。

    1LUT は、16bit (2B) の容量のはずで、256 LUT あれば 512B 分。ロジックに使う分があるから 256B の計算だったのだが ...

あとは ... 折角 I2C やら SPI やら付いているのだから、なにか デバイスを作ってみるとか。CPUは、入らないから、ステートマシンで作ることになる。内蔵クロックは、最大 133 MHz なので、超高速 PWM ってのも可能。

差動入力もある。コンパレータがわりに使えるかも。

ところで、こいつの電圧範囲はどうなるのだろう? 上限が 3.3V なのは良いとして下限は?
VCCIO は、3.3V/2.5V/1.8V/1.2V は行けそうなのだが、Config で決めた電圧でないといけないのだろうか? それとも、半端な電圧でも良いのだろうか?

ちなみに、ライタは、FT232RL が使えるものを 作った。デバイスを追加しないといけないし、実際には FT232RL での動作を確認していないが、たぶん大丈夫。論理合成ツールは、Diamond 1.4.2 以降で対応済みだそうだ。

追記: 74281 (P/G なし)を合成してみる。

    ピン配置
    XO2-256 74281 74281 XO2-256
    27 A1 1 24 VCC
    28 A2 2 23 A0 25
    29 RS1 3 22 CP 23
    30 RS0 4 21 SIO0 21
    32 RC 5 20 AS0 20
    1 SIO3 6 19 AS1 17
    4 A3 7 18 AS2 16
    5 Cn 8 17 M 14
    8 ~G 9 16 F0 13
    9 Cn+4 10 15 F1 12
    26 ~P 11 14 F2 11
    GND 12 13 F3 10

    以前 74281 の コードを XC2C64A 向けに作ってあったので、試してみることにした。

    実は基板は、eagle で設計済みで、モジュールへのピンアサインも決めてしまっている。

    実際にピンを割り当てるときに、まず JTAG_PORT を DISABLE にしないといけなかった。次に JED ファイル生成でエラーになった。どうやら MUX_CONFIGURATION_PORTS を ENABLE にしないといけないらしい。

    Number of registers: 4
    Number of SLICEs: 24 out of 128 (19%)

    Number of logic LUT4s: 42
    Number of ripple logic: 3 (6 LUT4s)
    Total number of LUT4s: 48


    CPLDだと厳しかったが、小規模でも FPGA だけあって 楽勝 のようだ。74181 は作ったことがないが、これも P,G なしにするし 楽勝だろう。

    基板は、もうすこし練りたい。例えば TDO は出力 だが、JTAG を Disable にし忘れると 回路を壊してしまう恐れが ... 抵抗ぐらいは入れておきたい。他にもオプションとして仕込んでおきたいものもある。

    思ったより回路が入るようだし、サンプルをいくつか用意出来るといいなと思っている。

    ALU と ROM/RAM は作るとして、後は?

    4桁7セグを使った時計とか? 電流は多少流せるようだし、いけるかも。あと、周波数カウンタなんかも出来そう。

基板の設計(1)



    まだ部品も手に入らないわけだが、基板を設計してみた。

  • QFN は、デザイン優先で(というかワザを覚えたので)ナナメにマウント。
     ただ、ちゃんとしたパッドの作り方がわからないので、そこは適当。
     シルクもナナメを使ってみたり。

  • コネクタ部分は、0.8φで小さめの径。秋月の細ピンヘッダを想定。

  • 今回は、裏に部品を付けない。いずれ リフローやってみたい。

      ホットプレートを使うらしいが、小型の電気鍋 (鍋 MG-500 とか 鍋 KG-152 とかでググると多数みつかる) ではダメなんだろうか? 保管場所を取るのはちょっと避けたい。

  • I2C は、プルアップ抵抗を付けられるように。XO2 は、I2C からコンフィグできたりするので実験用。 (普通は)付けない。
  • TDO は、ミスで出力がぶつかるのを危惧して抵抗付き。LED を付けるのにも便利なように配慮。
  • セラミック(or 水晶)発振子を付けられるようにしてみた。
     もうひとつ端子間に抵抗を入れられるようにしてある。
     この 2 つ -- 1M Ωを入れてしまうと、使い方に制限が出るわけだが、私が作るものは、配慮する。

    いつもの gerbtool で画像はつくれなかった。ナナメの部品には対応できていないようだ。



      原因だけは、分かった。ナナメの部品を使うと G36 というコードが使われるようになる。これは、多角形の塗りつぶしを指定するもの。

      そんなアルゴリズムは持っていないので、おかしくなっていたのだった。とりあえず G36 で アパーチャ を小さな矩形にしたところ上のようになった。対応するのは面倒なので、放置になりそう。

  • xo2qfn-05.zip

    eagle の ソース。部品が手に入るまで寝かせておく。(最新版に更新)

      更新: JTAGENB の位置が違うパターンを追加。

  • ここまで作って 74HC181 に合わせられないことが分かった。P/G のピンアサインを確認したつもりが ... 違った。どうしたものか。...



    結局、74HC181 の互換にできるように変更。281 互換にできたとしても、設計できる人しか有用である可能性がない。設計できるなら、ピン互換であることは重要でないだろうし、そもそも こういうものは使わないだろう。

    JTAGENB は、G である 17pin に移動。

    ところで、74HC181の コードを作るのは (P/G なしでも) 結構面倒だと分かった。そもそも Cn+4 の論理が分からない。回路図があるんだから、追っていけば分かるのだろうけど。

    追記: 多角形のフィルに対応。ちょっとインチキで形に条件が付くのだが、多分大丈夫。



    ナローDIP 版も設計してみた。1pin 分潰すだけではダメで 2pin 分になった。でも DIP28 だしソケットは使える。ブレットボードなんかでは、N.C. があるのは逆に便利かも。信号の並びは、ワイド版と同じだが ... おまけの部品は付けられず。まだまだ FPGA が手に入るのは先だろうから、これをベースに練っていこう。



    追記: 練ってみたら、こんなものに ... 。ワイドとナロー両方いけるうえに、1 列だけのユニバーサルエリア付き。切ればナローにもなる。なにか不恰好だが、発注するならこれか。

  • gerbtool-0.8.zip

    多角形のフィルに対応したので、gerbtool 単体もアップデート。

74HC181 とかの コード

  • qfn32samples.zip

    書いてみただけで、ピンアサインも前の案ベースになっていたりするのだが、74281, 74HC181, ROM, RAM のコードをまとめた。

    74HC181 は、とりあえず、回路図のロジックをそのまま組んでみた。

    追記 : ALU については、別記事にした。→ 『TTL ALU 74181』 。
    結構わかってきたので、拡張したりしてみている。

  • qfn32samples-03.zip とりあえず更新版 (2012/06/12)

    ALU だけではなく、いろいろ作ってみたいと思っている。ちなみに、I2C や SPI のモジュールは、バスから使う仕様なので、マイクロコントローラが必須に思えてきた。なので、256 では無理。何故 256 にこんなものが付いているのか? .. とも思ったのだが、コンフィグに使えるから意味はあるのだろう。

    次は、7seg 使った時計 .. かな? 時計自体は楽勝で入るのだが ... 時刻設定のインターフェイスが必要。ここが難しそう。チャタリング対策も要りそうだし。

    追記: 『FPGA時計の設計』設計はできてしまった。思いの外簡単だった。規模もまだ余裕がある。

  • qfn32samples-04.zip 更新版 (2012/06/17)

    なんと 無理だと思っていた CPU の実装が出来た。EFB にもアクセス可能。ただしメモリは、プログラム 128B(最大) + RAM 16B 。これでまともなコードが書けるかというと 無理そう。もうひとひねり要りそうだ。

    あと、FPGA時計にアラーム機能を追加したり、ALU の検証をしたり。

    後はなにを設計しよう --- 周波数カウンタ? 全然違うものとしては、DC/DC コンバータ? 高速 PWM も可能だし、コンパレータも 差動入力の流用で可能。面白いかも。

      そう言えば 『簡易シグマデルタ ADC』なんてものが、リファレンス・デザインにある。規模は 54 LUT だそうだから、載らないことはなさそう。温度計とか作れないかな? 一体 どれぐらいの周波数(sps)で AD変換可能なのだろう? 手軽に買える範囲だと PIC32MX が 1.1Msps だそうだ。それ以上になると AD9283BRS-80 の 80Msps 。10 Msps 程度がない。6bit でも良いから 簡単にできるのなら、(各種)液晶を RGB モニタに出来るかも。 まぁこの FPGA で作る必要はないのだが、何種類か ADC のモジュールを持っていると応用範囲が広がりそうな気がする。

      ... 高性能なのは、やっぱり無茶か。温度計とかが精々?

      コンパレータとして使うには、LVDS25 などを設定する。設定できるピンには制限がある。xxxT2_0 , xxxC2_0 とか T/C が含まれるピンのペア。T が非反転入力で このピンにアサインする。C は反転入力で指定しなくとも自動で選ばれる。QFN32 では、4/5 , 11/12, 13/14, 21/20, 28/27 の 5 ペアのみ。

      コンパレータとして使う場合、入力電圧の範囲が広いかどうか? ドキュメントには、LVDS を使ったときは、わずかに 低くなると書いてある。 VCCIO - 0.5V まで?

      MachXO2 のデータシートには、 (VCCIO=3.3Vのとき)入力コモンモード電圧 は、0.05V 〜 2.6V と書いてあった。(2.5V のときは 0.05V 〜 2.0V ) あと差動入力閾値 は、± 100mV だそうだ。

      入力電圧の範囲が問題になるのは、非反転入力に ダイレクトに ADC入力 を接続する場合。オペアンプと同じような話で、抵抗を直列に入れて (ADC入力 + 生成電圧) を 仮想GND と比較する場合は関係なくなる。

      ところで ADC が出来たとして データを 10進数に変換するのは、どうしよう? MachXO2-256 の規模では、無理なんじゃないかと思えてきた。可能にする方法として思いつくのは、内部形式を 出力形式に合わせることぐらい。そんなことが出来るものなのかどうか?

追記(2012/6/21)

  • qfn32samples-06.zip 更新版 (2012/06/21)

    ADC は置いておいて ... DAC が出来ないか検討。なんかいけそうなので、コード追加。

    あと MCPU 。オリジナルベースは捨てて、rewrite 版のみ残した。何種類もあってもメンテできないし。

    ところで、Mouser で、1個買いの単価が出ているが、6 グレードが発注可能になった。リードタイムが9週間になっているが、ボチボチか。基板を発注する時期が近づいている。

    アナログ回路を組むなら、VCCIO のいくつかを別電源にしたいところ。なのだが ... ナロー型では、無理だった。ワイド型なら とも思ったのだが、なかなか難しい。VCCIO1 と VCCIO3 の 4pin 分をパターンカットで分離可能にするのが精一杯。

追記(2012/6/23)

    基板変更。VCC, VCCIO 0/2, VCCIO 1/3 をパターンカットで分離可能にした。VCCIO 1, VCCIO 3 だけもさらに分離可能。追加したコンデンサが 4 つになったが、全部裏側。従来どおり 追加コンデンサなしでも使えるのだが、位置の関係で、パターンをいくつかショートさせた方が良い ... という変なものに。まぁ 追加コンデンサ付けるし。

    電源は、VIA を寄せて 2mm ピッチのコネクタにしてみた。

    これをIteadStudio (新サイト)に、ついに発注。発注したのは 2 つで 最初に作ったワイド版と ナロー版。IteadStudio の DRC でチェックしたら、0.3mm のドリルが DRC でエラーになった。0.4mm に変更。

    送料は、$5.59 。

    6/30 : 発送の連絡

    実は、ナロー版について、『問題が出るかもしれない、そのときは相談させてくれ』という内容のメールをもらった。が、なにごともなく製造できたようだ。

    7月9日 20:27 国際交換支店に到着

    来ても眺めるしかないが、いよいよか。
    実を言うと Muser で 6 グレードのやつを 6/24 に発注した。8/27 に発送できる見込みだそうだ。

    7月13日 基板受け取り。

    来た。書くのを忘れていたのだが、両方 1mm 厚にした。大きい方は 10 枚ぴったりで、テープで巻いてあるだけだった。小さい方は 16 枚でパックされていた。

    一見しただけだが、とても作れそうに見えない。まぁチップが来たら頑張ってはみるが。

    8 月 1日 Shipment Notification がキタ。予定よりずいぶんはやい。



追記: 2012/8/26 ようやく組立て



    はんだ付けは、位置さえ決まれば、簡単だった。足がないためか .. ハンダがとなりとくっつかず切れが良い。吸い取り線を使うまでもなかった。

      (注意)簡単なのは、底面と側面のパッドがつながっているタイプなので QFN ならなんでも簡単というわけではない。あと PIC32MX にも QFN があって興味が出てきたのだが、こちらのピッチは、0.65mm 。基板を起こすときに注意しないと。

    今は、とりあえず組み立てただけ。PIC32MX が終わったら、こちらに戻ってくる予定。

    LC など部品についてすっかり忘れていた。

      R2/R3/R5 -- I2C のプルアップや、セラミック発振子を使うときピン間に入れる 1MΩ用。これは今後も使わないようなオプションなので付けない。

      右下のソケットと R1/C5/C6 は、水晶振子を付けるためのもの 1MΩ/22pF で一応付けてみた。

      忘れていたのが、ジャンパなのだが、左下 と 右(ナナメ)の VIA は、電源の引き回しがながいのを嫌う場合のショートカット用。裏面にパスコンを付けるなら不要だし、そもそも不要かも知れない。様子見するので、ショートカットしない。

      あと、上の2x3の VIA は、I/O電圧を 3.3V 以外にする場合に使う。ウラのパターンをカットして使うが、3.3V 以外は考えていないので変更なし。

      左の 300mil 幅のやつは、オプションがほとんどない。(あっても裏面を使う) 。付けたのは、コンデンサ 3 つのみ。

    作ったは良いがどう書き込むかについて。

      JTAGツールとSYNCBB』にある、rtavr_tools-0.10 を使って 書き込む予定だが、MachXO2-1200 しか対応していない。ちょっと修正が必要。

      あと、『MachXO2 1200ZE Breakout ボード』 も 少しの改造でライタにできる。Diamond から直接書き込めるからお薦め。JTAGENB を有効にする オプションで なにもしない回路をコンフィグし、JTAGENB を L にするスライドスイッチを付けるだけ。JTAG 用のコネクタがあるので、そこから 出力。JTAG をチェーンする方法もあるが、パターンカットとか配線とかが面倒。

eagle の ソース

関連記事
posted by すz at 22:11| Comment(1) | TrackBack(0) | MachXO2

2012年03月23日

LPCインターフェイスめも

Lattice のリファレンスデザインのなかに

があるのを見つけた。そういえば、自作FPGA ボード を相互に接続するのに I/O が 7本 + 1(入力専用)しかなく、これで実装できるインターフェイスを探したときに LPC を知ったのだった。

    簡単に説明すると、最低 LRESET, LCLK, LFRAME , LAD[3:0] の 7 本の線で接続できる バス規格。周波数は、33 MHz 。

LPC は Intel が提唱した規格で PC の SUPER I/O 用に実際に使われていた。SUPER I/O というのは、所謂レガシーインターフェイスをまとめたもので、今でもデジキーで入手できるチップがある。

もの自体には興味がないが、データシートは実装を実際にどういう風にするのかという参考になる。

    ちょっと見てみたところ、LDRQ , SERIRQ といった DMA や割り込み要求の線がある。実際には 7 本では済まないわけだが、イベントを通知する線は まぁ必要だろう。

    SUPER I/O のデバイスは、シリアル/パラレル/ゲームポート/MIDI/FDC など。あと ハードウェアモニタ関連で、ファンとか 電圧監視用 ADC とか GPIO とか。

    そういえば、PC の bios の FLASH にも使われていた。LPC を初めて知ったのは、これかも知れない。

    こっちのデータシートは、どういう風にアクセスするのか詳細が書いてある。

LPC の詳細

    さて、RD1049 をひもといて見る。ドキュメントは RD1049 自体のもの以外に LPC の仕様書が入っている。規模は、MachXO2 で HOST 用が 84 LUT , デバイス用が 73 LUT 。

    どうも、アドレス 16bit / データ 8bit の ISA バスのような 仕様で使っているようだ。

    次に 仕様書をちょっと見てみた。

    16bit の I/O アドレス以外に 32bit のメモリアドレスが定義されていて、いろいろな転送モードがある。どうも ISA バスの機能を包含することが(もともとの規格では)重要らしい。

      Host Initlated Memory Read
      Host Initlated Firmware Memory Read
      Host Initlated I/O Read

      Host Initlated Memory Write
      Host Initlated Firmware Memory Write
      Host Initlated I/O Write

      Peripheral Initlated Memory Read
      Peripheral Initlated I/O Read (8bit , 16bit, 32bit)

      Peripheral Initlated Memory Write
      Peripheral Initlated I/O Write (8bit , 16bit, 32bit)

      DMA Read (8bit , 16bit, 32bit)
      DMA Write (8bit , 16bit, 32bit)

    RD1049 がサポートしているのは、Host Initlated I/O Read/Write のみのようだ。どんなアクセスをするのか、DMA も加えて表にしてみた。

      START CYCTYPE+DIR ADDR TAR SYNC DATA TAR total
      Host Initlated I/O Read H1 H1 H4 H2 P1 P2 P2 13
      CHANNEL+SIZE
      DMA Write Cycle (8bit) H1 H1 H2 H2 P1 P2 P2 11
      DMA Write Cycle (16bit) H1 H1 H2 H2 P2 P4 P2 14
      DMA Write Cycle (32bit) H1 H1 H2 H2 P4 P8 P2 20

      START CYCTYPE+DIR ADDR DATA TAR SYNC TAR total
      Host Initlated I/O Write H1 H1 H4 H2 H2 P1 P2 13
      CHANNEL+SIZE
      DMA Read Cycle (8bit) H1 H1 H2 H2 H2 P1 P2 11
      DMA Read Cycle (16bit) H1 H1 H2 H4 H4 P2 P4 18
      DMA Read Cycle (32bit) H1 H1 H2 H8 H8 P4 P8 32

    必ずホストが、転送を開始する DMAも同じで、デバイス側の要求が受け付けられたら HOST が転送をスタートさせる。

    H1 というのは、Host 側が 1 回(4bit の)転送を行うという意味。P2 は デバイス側は 2 回。
    DMA では ADDR の代わりに CHANNEL と SIZE が送られる。あと LFRAME は、START の 1 クロックだけ L になる。

    33 MHz 4bit だから 16.5 MB/sec の帯域だが、転送にはこのシーケンスが必要なので、実際の帯域は随分落ちる。Host Initlated I/O Read/Write では 13 クロックで 1 バイトだから 2.56 MB/sec 。

    ちょっと思ったより帯域が少ないのでがっかりだが ... 仕様など知ったことではないというスタンスでプロトコルを 再定義すれば 512B のバースト転送とかで、16 MB/sec ぐらいにはなるかも知れない。

      よく分かって書いているわけではないが、DMA の TAR を 2 クロックに限定して DMA のサイズを 再定義してやるとか。ついでに書くと DDR も CHANNEL か SIZE で指定できるようにしたりして。

      追記: DMA の TAR のクロック数は、上記の表の通りである必要はない。TAR の後に来るのは、SYNC か START で DATA 待ちみたいな感じ。


    以下 START 等の意味。(関係なさそうなものは省略しているので注意)

    START

      0000 Start
      1111 Stop/Abort

      普通 0000 でスタートする。スタートは LFRAME が L になる。Stop/Abort は、wait のタイムアウト時に使う。

    CYCTYPE + DIR

      000x I/O Read
      001x I/O Write
      100x DMA Read
      101x DMA Write

      x は 0 にせよということだが、読む方はきにしない?

    SIZE

      xx00 (0) 8bit
      xx01 (1) 16bit
      xx11 (3) 32bit

      2 のべき乗ルールなら良かったのだが、N+1 になっているようだ。

    SYNC

      0000 Ready
      0101 Short Wait
      0110 Long Wait
      1001 Ready More
      1010 Error

      Short Wait/Long Wait で 所謂 Wait が挿入できるようだ。Short /Long で Timeout のパラメータを変えるものらしい。Short は 数クロック / Long でも 1 マイクロ秒 (30 クロック)程度。

      Timeout したときに HOST は、LFRAME を L にするのだが、数クロック後に 1111(START:abort) を送出して H に戻す。LFRAME=L と同時に 1111 を送出すると信号がぶつかるからダメ。

    TAR (Turn Around)

      1111 zzzz ...

      LAD も weak pull-up だそうだ。最初だけ 1111 にせよということらしい。

    CHANNEL

      なんでも良いかと思ったらルールがあった。0-3 が 8bit で 5-7 が 16 bit 4 が バスマスタ用って書いてある。あと bit3 は、TC(Terminal Count) で 1 だと 最後の転送であることを指示する。

      そして、LDRQ もルールがあった。LCLK に同期したシリアルで、

      LCLK ____ ____ ____ ____ ____ ____
      _____| |____| |____| |____| |____| |____| |____

      LDRQ __________ _________
      |_________| bit2 | bit1 | bit0 |

      こんな風に送るものらしい。

      書き忘れたが、他のデータも negedge LCLK でデータ送出、posedge LCLK で受け取り。

      ちなみに、SERIRQ (Serialized IRQ) というのも プロトコルがあり、LDRQ より複雑そう。
      ( LPC の仕様書には詳細は記述されてない。PCI の仕様書で定義されているらしい。)

おわりに

    なかなか難しいものようだ。だが完全オリジナルよりは、LPC ベースに検討した方が良さそう。

    やりたいことは、もともと 7bit + 入力 1 での デバイスの拡張なのだ。DMA の使い方を変更・拡張して、自分の目的にあったものを作ってみたい。

    あと、lattice のリファレンスデザインは、 lattice のデバイスにインプリメントする場合に限り自由なのであって、本当に自由にしたければ自分で作らないといけない。あくまで参考として使うようにしないと。

おまけ

    RD1049 レベルのものを書いてみた。

  • lpc_master.v
  • lpc_slave.v

    本当は、Host-Peripheral の関係だが、なんとなく master-slave というネーミングにした。あと用語で LAD とすべきところを LDA にしてしまった。(未修正) 。まぁプロトタイプというか書いてみただけだから ... 。もちろん動く保証もない。

    基本的に posedge で state を変更し 入力処理をして、negedge では、state に応じた出力処理になるよにしている。規模は master が 80 LUT , slave が 65 LUT 。RD1049 と似た様なもの。

    これを元にどう膨らませようか思案中。

    まず slave 側。I/O 空間にレジスタをマッピングして定義したデバイスを動作させるようにして、512B ぐらいのバッファを DMA の手順でバースト転送できるようにしたい。あと、クロックは、LCLK をマスタークロックとして全部同期させる。

    slave 側のデバイスとして SDカードをサポートするのをまず想定している。それ以外に複数の slave で共通のデバイスをもたせたりもしたい。なかなかに難しそうな...

    master 側は、LCLK を マスタークロック にしないで ハンドシェークさせるつもり。master 側が数分の1 のクロックで動作しても問題ないようにしたいが、master 側 の方が速かったりするケースにも対応したいような... これもやっぱり難しそう。

追記: OpenCores の LPC モジュール

  • wb_lpc -- Wishbone LPC Host and Peripheral Bridge

    というのがあった。Features を見てみると DMA や firmware アクセス , Serialized IRQ など フルスペックのように見える。

    DMA の DIR (Read/Write の方向) をどう設計すべきか、参考になるかと期待したのだが ... よくわからなかった。より上位で決めるような設計のようだ。

    serirq については、少し分かった。

      START FRAME -- IRQ0 FRAME ... IRQN FRAME -- STOP FRAME --

      START FRAME 0 ... 0 1 1 (6 - 12 clocks)
      P/H H
      IRQN FRAME 0/1 1 1 (3 clocks)
      P
      STOP FRAME 1 0 0 1 1 (5 clocks)
      H H
      IRQ : IRQ0 ... IRQ15 IOCHECK ( INTA INTB INTC INTD .. )

    最初は、Peripheral が 0 にする場合もあれば Host が 0 にする場合もある。続く 3-7 clock Host が 0 にする。0 の期間は、4,6,8 clock だそうだ。どちらも出力しなくても 1 になるから オープンドレイン?

    ちなみに、信号は、posedge で出力、negedge で取り込み。

    次に 3 clock (S - R - T)づつの FRAME が続く。 IRQ15 までの 16 個かと思ったが、未定義を含めて 17個 - 32個分ある。(数は設定で決まる。)

ちょっとコードを書いてみた。

    module serirq_slave (
    input LCLK
    , input LRESET
    , inout SERIRQ

    , input [7:0] irq_req
    );

    reg [3:0] state;
    reg [1:0] sub_state; // S R T
    reg serirq_out;

    assign SERIRQ = serirq_out ? 1'b0 : 1'bz;

    always @(negedge LCLK)
    begin
    if (sub_state == 2'b01)
    begin
    if ((state == 4'h1) & (irq_req[0])) serirq_out <= 1'b1;
    else if ((state == 4'h2) & (irq_req[1])) serirq_out <= 1'b1;
    else if ((state == 4'h3) & (irq_req[2])) serirq_out <= 1'b1;
    else if ((state == 4'h4) & (irq_req[3])) serirq_out <= 1'b1;
    else if ((state == 4'h4) & (irq_req[3])) serirq_out <= 1'b1;
    else if ((state == 4'h5) & (irq_req[4])) serirq_out <= 1'b1;
    else if ((state == 4'h6) & (irq_req[5])) serirq_out <= 1'b1;
    else if ((state == 4'h7) & (irq_req[6])) serirq_out <= 1'b1;
    else if ((state == 4'h8) & (irq_req[7])) serirq_out <= 1'b1;
    else serirq_out <= 1'b0;
    end
    else if (sub_state == 2'b00)
    begin
    serirq_out <= irq_req[0] | irq_req[1] | irq_req[2] | irq_req[3]
    | irq_req[4] | irq_req[5] | irq_req[6] | irq_req[7]
    ;
    end
    else serirq_out <= 1'b0;
    end // always

    always @(posedge LCLK)
    begin
    if (LRESET)
    begin
    state <= 4'h0;
    sub_state <= 2'b00;
    end
    else if ((sub_state == 2'b00) & ~SERIRQ)
    begin
    state <= 4'h0;
    sub_state <= 2'b01;
    end
    else if (sub_state == 2'b00)
    begin
    state <= 4'h0;
    sub_state <= 2'b00;
    end
    else if ( (sub_state == 2'b01) & (state == 4'h0) & SERIRQ)
    begin
    state <= 4'h0;
    sub_state <= 2'b10;
    end
    else if ( (sub_state == 2'b01) & (state == 4'h0))
    begin
    state <= 4'h0;
    sub_state <= 2'b01;
    end
    else if ( (sub_state == 2'b11) & ~SERIRQ )
    begin
    state <= 4'h0;
    sub_state <= 2'b00;
    end
    else
    begin
    sub_state <= sub_state + 2'b01;
    end
    end // always
    endmodule


    簡単に説明すると、posedge LCLK で ステート制御。ステートは 3 の倍数で進むので 2 つに分けている。スタートビット検出をきっかけに進む。( 最初のスタートビットは、slave 側が作っている。)

    ストップビットは、2bit 目の 0 を検出したところで IDLE に戻る。

    sub_state は、0 → 1 → 2 → 3 → 1 → 2 → 3 と進む。0 になるのは IDLE だけ。

    master も状態制御は、同じようなもの。スタートストップビットの送出と irq_req が取り込みに変わる。

    冗長な書き方だが、14 スライス/27 LUT 。

LPC マザー

    LPC HOST をいくつか接続できるものを作ってみたい。

    HOST 毎に制御するデバイスが GPIO , SDIO , シリアル とか。共有するデバイスが LCD とか キーボードとか。

    あと入れたいのが、HOST 間通信。4 つ HOST が付けられるとしたら 12 個の FIFO でも実装可能か。
    共有を考えなければ簡単?

    ただ、そんなものを作るぐらいなら、SDIO という気も。

    ちょっとググってみると Posedge SDIO device controller (pdf) なんてものが見つかった。

    SD bus を AHB Bus に変換する IP。チップだと思ったら違った。

    中華Android / 中華PMP に使われている CPU(SoC) は、超低価格なのだが PCI みたいな バスは持っていない。最も高速なインターフェイスが USB device (640Mbps) で次が SDIO (〜 80Mbps x 4 とか) というパターンも多い。これになにかデバイスを付けようとすれば、SDIO のデバイスコントローラが欲しくなるのだった。

      S-ATA が付いているものもある。(Allwinner A10) 。Ethernet は一般的だが 100Mbps で上記より遅い。

    で、公開されている SDIO Simplifyed Specification を見てみた。

       I/O の方式は、SPI , 4bit-SD 以外に 1bit-SD がある。(これはメモリカードも同じ)

       割り込み(IRQ) は、DAT[1] を使うが 4bit-SD では、特定のタイミングでのみ有効(optional) 。詳細は削られている。

       DAT[2] にも Read Wait という機能が割り当てられている(optional)

       I/O 電圧変更は、SPI でも可能なようだ。

      SDIO は、基本的に CMD52(IO_RW_DIRECT), CMD53(IO_RW_EXTENDED) を使う。CMD52 は、レジスタアクセス+I/O 制御。CMD53 が I/O (サイズは 1-512B)

      レジスタ の仕様で 0-FF は、OCCR(Card Common Control Register) といって、いろいろ決まりごとがある。
      256B 単位で Function 1-7 の FBR(Function Basic information Registers) が続く。

      Function の定義には、USB の標準クラスのようなものがある。UART , BlueTooth Type A, BlueTooth Type B, カメラ, GPS, WLAN , SDIO-ATA など。

      CMD52,CMD53 以外で発行されうるコマンドは、

      CMD0 Pin1=High (CS=Low : SPI)
      CMD8
      CMD5 Arg=0 Get IO OCR
      CMD5 Arg=WV
      ACMD41 Arg=00 Get memory OCR (CMD58 : SPI)
      CMD3 (SD only)

      初期化シーケンスから拾ってきただけなので、詳細は知らない。ACMD41 はエラー(OCR invalid)になる。
posted by すz at 22:33| Comment(85) | TrackBack(0) | MachXO2

2012年03月10日

MachXO2コンフィグめも

MachXO2のコンフィグについてのメモ。

rtavr_tools で持っている FPGA の コンフィグが出来るようにしようと思っている。MachXO と LatticeXP2 は、一応書いてみたもの(ただし不動)があるが、MachXO2 は、ほぼこれから。

MachXO2 と MachXO , LatticeXP2 の違い

    MachXO , LatticeXP2 は、RAM にコンフィグするデータがそのまま FLASH に格納されている。ちょっと手続きとか コマンドとかが違うものの、RAM へのアクセスと FLASH へのアクセスを統合できる。jed データを元に RAM に書くこともできる。

    MachXO2 はというと FLASH のデータは圧縮されている。そのデータを FPGA 内部の伸張エンジンで RAM に展開している。伸張アルゴリズムは不明なので、自作の rtavr_tools では、jed は、FLASH のみが対象。

      ... と思ったが、実をいうと RAM への アクセスコードは、MachXO/LatticeXP2 とよく似ていて統合可能で、そういう風にコードは作っていた。

    ついでに書いておくと Xilinx は、FLASH がなく RAM に書くデータだけがある。このデータは SPI FLASH に書くデータと 同じ(bit のオーダーは違う) で、SPI FLASH に対応したとしても 1 種類の内部データで扱える。

    構想では、扱うデータはこんな分類になると思う

    internal FLASH RAM SPI FLASH file format
    Xilinx FPGA x O O bit,mcs
    MachXO,XP2 O O ? jed
    MachXO2 O x ? jed
    MachXO2(RAM) x O ? ? (サポートしない)

    O は作ろうと思っているもの。? は未定だが、やるとしても後回し。

MachXO2 のデータ と FLASH の 読み書き

    MachXO2 のデータには、以下の種類があり、それぞれ別の手続きになる。( () 内は、1200 のサイズ )

    • CFG データ (128bit x 2175 )
    • UFM データ (128bit x 512 )
    • USERCODE ( 32bit)
    • FEATURE (64bit)
    • FEABITS (16bit)

    FLASH は、128bit の column と 2688 の row からなっていて、USERCODE , FEATURE , FEBITS は 最後の row に入っている。UFM は、ユーザ回路で使えるが、CFG データがはみ出す場合がある。また、ブロック RAM の初期データも UFM に圧縮されない形で入っている。

  • CFG データ (128bit x 2175 )

    XO2_INIT_ADDRESS(0x46)
    SDR(0x04);
    idle(10ms)

    # 1 column 分
    XO2_PROG_INCR_NV(0x70)      XO2_READ_INCR_NV(0x73)
    SDR(128 bit)           idle( 1ms)
    idle( 0ms)  SDR(128 bit)           
    idle( 1ms)
    # check busy (10)
    XO2_CHECK_BUSY(0xF0)
    for (i=0; i&ft;10; i++)
    idle(1ms)
    if (SDR (1bit 0) == 0 ) break;


    read の場合、最初の row だけ XO2_INIT_ADDRES を発行し、SDR していく。PROGRAM の場合は、row 毎に XO2_INIT_ADDRES し、SDR 後 CHECK_BUSYする。
    コマンドは、SIR(8bit) コマンドの値は、MachXO2 独自のものがほとんど。

  • UFM データ (128bit x 512 )

    XO2_INIT_ADDR_UFM(0x47)
    idle(10ms)

    UFM の場合、最初の指定のみが変わる。PROG/READ の方法は同じ。

  • USERCODE ( 32bit)

    XO2_USERCODE(0xC0) XO2_USERCODE(0xC0)
    SDR (32bit) SDR (32bit)
    XO2_PROGRAM_USERCODE(0xC2)
    idle(10ms)

    # check status bit
    XO2_READ_STATUS(0x3C)
    idle(1ms)
    SDR (32bit) & 0x00003000 == 0


  • FEATURE (64bit)

    XO2_INIT_ADDRESS(0x46) XO2_READ_FEATURE (0xE7)
    SDR(0x02) idle(1ms)
    idle(10ms) SDR (64bit)

    XO2_PROG_FEATURE( 0xE4)
    SDR (64bit)

    # check busy (略)

  • FEABITS (16bit)

    XO2_PROG_FEABITS(0xF8) XO2_READ_FEABITS(0xFB)
    SDR (16bit) idle(1ms)
    idle(0ms) SDR (16bit)

    # check busy (略)


    これらを実行する前後で、初期化と後処理が必要。あと erase の手続きがある。


    # check IDCODE

     XO2_IDCODE(0xE0)
    SDR(32bbit) == 0x012B2043 (1200の場合)

    # Program Bscan register
    PRELAD(0x1C)
    SDR(208 bit: all 1 , 1200の場合)

    # enable flash
    XO2_ISC_ENABLE(0xC6)
    SDR(0x08)
    idle(10ms)

    (ここまで共通)
    --- erase ----

    # check status bit

    --- program/read

    (Write のみ , erase で実行しないこと)
    # Program DONE bit

    XO2_PROGRAM_DONE(0x5E)
    idle(0ms)
    # check busy (略)

    (ここから program/read 共通)
    # Exit the programming mode
    BYPASS(0xFF)
    XO2_ISC_DISABLE(0x26)
    idle(1000ms)

    BYPASS(0xFF)
    idle(0ms)

    erase 手続き

    XO2_ISC_ENABLE(0xC6)
    SDR(0x00)
    idle(10ms)

    XO2_ISC_ERASE(0x0E)
    SDR(0x01)
    idle(1000ms)

    BYPASS(0xFF)

    XO2_ISC_ENABLE(0xC6)
    SDR(0x08)
    idle(10ms)

    XO2_ISC_ERASE(0x0E)
    SDR(0x0E)

    # check busy (350)


    ちなみに、XP2 や MachXO も似ていると言えば似ている。ただ、共通化できるほどは似ていない。FLASH への書き込みでは UFM はないし、RAM と同じ column , row で書き込むのも違う点。

rtavr_tools への実装

    rtavr_tools の内部データは、ただの配列になっている。なので、次の順で格納するようにした。

    CFG 128bit x 2175 = 34800 bytes
    UFM 128bit x 512 = 8192 bytes
    FEATURE 64bit 8 bytes
    FEABITS 16bit 2 bytes
    USERCODE 32bit 4 bytes
    合計 43006 bytes

    デバイスによって CFG,UFM の row が変わるが これは 別にデータベースを持っている。Preload での bit 数も データベースに持つ。

      LCMXO2_1200.tgt_type = lscc
      LCMXO2_1200.device_type = 0x12B2
      LCMXO2_1200.address_size = 333
      LCMXO2_1200.data_width = 1080
      LCMXO2_1200.boundary_width = 208
      LCMXO2_1200.flash_col = 128
      LCMXO2_1200.flash_cfm_row = 2175
      LCMXO2_1200.flash_ufm_row = 512

      こんな形式で config ファイルを作っている。address_size , data_width は RAM の column , row。
      address_size, data_width, boundary_width は、BSDL ファイルに記載がある。
      flash_col, flash_cfm_row, flash_ufm_row は、SVF ファイルを生成すると分かる。( 他の記載は 信用できない。)

    作るべきプリミティブは、erase_flash_xo2 , write_flash_xo2 , read_flash_xo2 。サブルーチンとして xo2_check_busy(ループ数) と xo2_read_status() を作る。

    あと、FEABITS の jed ファイル読み込みが未対応。

rtavr_tools-0.8

  • rtavr_tools-0.8.tar.gz

    とりあえず、最新版。

    これは、MachXO2 用の コンフィグのコードを入れた版。デバッグ中のもの。

    FLASH への書き込みは、

      cmd> fl xxxx.jed
      cmd> w flash

    FLASH からの読み込みは、

      cmd> tl flash

    とかで出来ることを期待したのだが、全然ダメ。読み込みすらちゃんと動かない。

    RAM への読み書きは、以前に作ったコードが大分対応していたので、作ってみた。

      cmd> tl ram

    とすることで、なにやら読める。

      cmd> w ram

    で書き戻す操作になるのだが、ERASE はできるが、書き込みでエラーして ERASE された状態になる。
    ただし、電源を入れなおすことで、元に戻る。

      cmd> w flash

    FLASH についての ERASE も動くようだ。

RAM への コンフィグについてのメモ

    うまく動かないのであれこれ調べていたら、直接は関係ないことがいろいろ分かってきたのでメモしておく。

    SRAM Fast Program というのがあって、

    XO2_BITSTREAM_BURST(0x7A)

    というコマンドで書き込んでいる。このコマンドでは、どうも 圧縮 bit ファイル と 非圧縮 bit ファイル のデータの 2 種類を流し込めるようなのだ。たぶん、FLASH からのパスを利用しているのだろう。

    実際の bit ファイルとどういう関係にあるか調べてみた。
    非圧縮 bit ファイル のデータは、47371 バイトで、 XO2_BITSTREAM_BURST で送りこむデータは、47739 バイト。差分の 368 バイト分の 0xff を先行して 送り 非圧縮 bit ファイル のデータ を送っている。

    ついでに SRAMのデータ 44959 バイト(1080x333/8) と 非圧縮 bit ファイル のデータ の関係も調べてみた。


    0000: ff ff bd cd ff ff dc 00 00 00 ff ff ff ff ff ff
    0010: ff ff 62 00 00 00 41 07 80 b2 00

    非圧縮 bit ファイル は、このような 0x1A(26) バイトが先行して格納され、SRAMのデータ が続く。 残り は、2386 バイトだが、

    2e ce ff ff ff ff ff ff ff ff 43

    こういうデータで始まっている。ブロック RAM に 2KB の初期値を入れたので、2386 バイトのうち 2KB ? (2K x 9bit ?) 分の値もそのなかに含まれているはず。

    圧縮 bit ファイル のデータは、10170 バイト だった。XO2_BITSTREAM_BURST で書き込むデータは、84152 bit(10519 バイト) 349 バイトの差があるが、これも同様で、差分は、0xff が頭につく。

    0000: ff ff bd cd ff ff dc 00 00 00 47 00 00 00 80 d4
    0010: 04 c2 40 00 00 00 50 0a 0c c0 12 14 90 ff 44 00
    |
               :
    2790: fd fb f7 ef df bf 7f ff fe fd fb f7 ef df bf 7f
    27a0: ff fe fd fb f7 ef df bf 7f ff 44 00 00 00 02 00
    27b0: 00 00 7a 00 00 00 ff ff ff ff

    圧縮 bit ファイルはこんな風なデータ。非圧縮同様 0x1A バイトがヘッダなのかも知れない。

    さて、jed ファイルと 圧縮 bit ファイルは 同じなのか? というのが気になったので見てみると... 似ている感じだが、厳密には だいぶ違う。

    0000: ff ff bd cd ff ff dc 00 00 00 40 00 00 00 50 0a
    0010: 0c c0 12 14 90 ff 62 00 00 00 1d 07 80 b2 00 00
    :
    2790: fb f7 ef df bf 7f ff fe fd fb f7 ef df bf 7f ff
    27a0: 44 00 00 00 02 00 00 00 7a 00 00 00 ff ff ff ff

    そもそもヘッダーがちょっと違う。だが、最後は 同じっぽい。もっとも 非圧縮 bit ファイルも同様。

    最後の部分の最初だが、

    jed ファイル:
    1e60: 39 39 00 a4 c3 e7 e4 00 00 00 e9 ee
    1e70: ff ff ff ff ff ff ff ff 43 01 00 00 4a 2a 0c 8c
    1e80: 67 90 44 00 00 00 03 00 00 00 ff ff ff ff 6f 00
    圧縮 bit ファイル:
    1e50: 39 39 00 a4 c3 e7 e4 00 00 00 c8 cc ff ff ff ff
    1e60: ff ff ff ff 43 01 00 00 4a 2a 0c 8c 67 90 44 00

    こんな風にずれている。"e9 ee" と "c8 cc" は、たぶん CRC かチェックサム。ずれるルールは分からないが、ff が挿入されている感じ。

    ところで、圧縮 bit ファイルを生成するのは、意外にも簡単だった。制約ファイルに

    SYSCONFIG GENERATE_BITSTREAM=ENABLE ;

    この行を入れておけば良い。

    ... なんだか、XO2_BITSTREAM_BURST だけが動けば良いような気がしてきた。FPGA を汚さずにコンフィグできるし、ブロックRAM もちゃんと初期化できる(はず) 。しかも 圧縮したデータを一気に書くから高速にできる。SPI-FLASH への書き込みでは、それようの回路をコンフィグしないといけないのだが、実装の目処も立つ。

    bit ファイルの生成が面倒だと思っていたが、簡単ということも分かった。


    XO2_BITSTREAM_BURST

      これが動いた。圧縮 bit ファイル, 非圧縮 bit ファイル ともに OK 。それどころか、jed を読み込んだ内部形式のデータまで OK だった。

      重要なのは、最初に十分な数の 0xff を送ること と 正しいデータを続けて送ることのようだ。後にごみがあっても問題ない。verify はできないが、失敗すると初期化状態のままになる。


        cmd> fl test_hdl.bit
        Lattice Semiconductor Corporation Bitstream
        Version: Diamond_1.4_Production (87)
        Bitstream Status: Final Version 1.80
        Design name: MachXO2_Breakout_test_hdl_xo2.ncd
        Architecture: xo2c00
        Part: LCMXO2-1200ZE-1TQFP144
        Date: Thu Mar 15 23:49:02 2012
        Rows: 333
        Cols: 1080
        Bits: 359640
        Readback: Off
        Security: Off
        Bitstream CRC: 0xA2F6
        memory loaded size = 10170
        cmd> w ram
        Programming :################################################## 1.151 sec
        program success

      書き込みはわずか 1.151 秒。しかも ERASE の待ちが そのうちの 1 秒。

      bit ファイル のフォーマット

        ちょっと説明しておく。

        0xff 0x00 で始まり ストリング 0x00 がいくつか続く。最後に 0xff が来てここまでがヘッダ。その後は バイナリでデータが続くのだが、バイト内の ビットが反転 している。(bit0 ⇔ bit7)。

        もともと、Xilinx 用の bit ファイル の読み込みを作っていたのだが、自動判別して読み込むようにした。内部データは、ビットの反転を元に戻したもので、そのまま XO2_BITSTREAM_BURST(0x7A) にかけられる。


      書き込みは格段に早いが、RAM にしか書かないので、使用目的は主にテスト。複数の config を切り替えて動作を確認するとか...。あとは、仮の回路を組み付けるときに使う。ツールでは、SPI ライタのサポートで使うつもり。

      FLASH への書き込みは、コードは出来たものの全然だめなまま。目的は達したので、当面寝かせるかも。

    rtavr_tools-0.9

    • rtavr_tools-0.9

      最新版を置いておく。

      あと SPI FLASH への書き込みコードを作れば、コードだけは予定していたものをだいたい作ったことになる。自作 Xilinx ボード用のコードは形だけは入っている。

      次は、rtavr のデバッグに進もう。

    rtavr_tools-0.10

    • rtavr_tools-0.10

      最新版を置いておく。

      rtavr のデバッグを少し始めているのだが、なかなか。1回合成するのに、2 時間ぐらいかかるし。

      ちょっと息抜きに、SPI FLASH への書き込みコードを作ってみた。もとは、ATUSB162 で Mass Storage Class を作ったときのコードだが、移植というより書き直しになったので、ちょっとデバッグが必要そう。

      あと、SPI 用の HDL も作っておいた。手順的には、これをまず SRAM に書き込んで 仮コンフィグし、mcs ファイルを読み込んでSPI FLASH に書き込む。ただしオフセット 0 から書き込んでいるので、mcs ファイルによっては、アドレスがずれる。

      ちょっと MCS ファイルの調査:

      UFW で bit ファイルを MCS に 変換できる。0x000000 と 0x010000 という アドレスが表示されている。XO2 や XP2 は、0x010000 から ロードするので、0x010000 に Insert するようだ。

      *** dump ***
      0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      *
      10000: aa 76 96 6e a6 4e ce 86 36 04 62 96 36 a6 04 ea
      10010: 4e 96 2e a6 4e 04 6a 4c 74 2c 1c 50 22 86 2e a6
      10020: 5c 04 2a 16 ae 04 0c cc f4 4c 4c f4 8c 4c 04 8c
      10030: 0c 5c ac 2c 5c ac ec 04 50 ff ff ff ff ff ff ff
      10040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
      *
      10150: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff bd
      10160: cd ff ff dc 00 00 00 47 00 00 00 80 d4 04 c2 40
      10170: 00 00 00 50 0a 0c c0 12 14 90 ff 44 00 00 00 02
      10180: 00 00 00 ff ff ff ff 62 00 00 00 1d 07 80 b2 00
      10190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

      できたファイルを 見てみるとこんな感じ。10150 からお馴染みの パターンが入っている。... jed ファイルと全く同じような ...

      その上は何かというと テキストなのだった。bit の MSB/LSB を反転すると ...

      Universal File Writer V2.48
      Date: Thu 03/22/12 5:54:57

      こんなようなデータが入っている。ごみはスキップして、ビットストリームだけ取り込んでくれるようだ。

      ところで.... 論理合成する時間が MachXO2 だけ圧倒的に長いことに気がついた。1200 だとぎりぎりなので遅いのかと思っていたのでは、そうではない。XO や XP2 は結構速い。

      ここまで MachXO2 でやったが、rtavr のデバッグの最初は、MachXO breakout を試してみようかと思っている。ただ、結構忘れてしまっている。

        rtavr_tool -p LCMXO2280

      rtavr_tool では、こんな風にチップ名を指定するようにしている。さて、XO の場合は、どこまで出来ていたのだっけか。

      まず、基本的な話から思い出す。

        XO は、flash と ram の構造が一致する。圧縮もない。さらに flash に書くデータと ram に書くデータは同じ。jed ファイルのデータと flash のデータも一致する。ただし、ram から読み込んだデータは、書き込んだデータとは一致しない。svf ファイルを見ても違うデータでベリファイしている。

      で、動作を確認したところ..

      • flash の erase は大丈夫。
      • flash の書き込みも 基本 OK なのだが、USERCODE が何故か一致しない。先頭が 0x00 になっってしまう。そのために config をエラーにしてしまっていた。USERCODE が不一致でも成功扱いにすることで、一応は flash に config できるようだ。
      • flash の read も OK 。正しいデータと jedから読み込んだ内部データは一致した。
      • ram への書き込みは、正しいかチェックできない。コンフィグした回路が動かないことから失敗しているようだ。

      まぁ、こんなところ。flash への操作はひと通り可能にしたので使えないことはない。

      これで、少しやるきが出た。まずは、MachXO2 と同じレベルまでもっていこう。
posted by すz at 12:47| Comment(0) | TrackBack(0) | MachXO2

2012年03月09日

MachXO2のJTAG通信

MachXO2 , MachXO ともに JTAG を通して SPI (のような方法)で通信できることになっている。MachXO2 breakout ボードでは、MPSSE で JTAG と接続されているから、理想的には、30Mbps までの速度での通信が可能。シリアルのように 外付けクロックにも依存しないからお手軽でもある。

  • LatticeXP2のFPGA回路内部へJTAGで通信する

    これは、XP2 に付いての記事だが、MachXO2もほぼ同じらしい。XP2 では、JTAGE を使うが、MachXO2 では、JTAGF , MachXO では、JTAGD を使う。

    /c/lscc/diamond/1.4/cae_library/synthesis/verilog/machxo2.v

    このあたりを見ると、インターフェイスがわかる。HOST 側での使い方はまったく同じ。

というわけで、通信しようとしているのだが、なかなか思うようにいっていない。何が間違いなのか分からなかったのだが ...どうも根本的なミスをしていたらしい。

    そもそも SPI は、双方の出力は同じタイミングで切り替わる。JTAG 経由の場合もそれは同じ。だから、8bit 目の SCK の立ち上がりで、入力処理をしたら、SCK が立ち下がるまでに次の出力処理も完了させなければならない。
    (補足: 普通に作ると出力が先行する。8 bit のデータを受け取る前に、出力を確定させないといけないが、そうはしたくないのが前提としてある。)

    だいたいが、そういう処理にしていなかった。だが、次の条件があり、なかなか面倒なのだ。

    上の記事には、SCK と MOSI は同時に変化するから、SCK の立ち上がりをトリガーにする 『@(posedge SCK)』 と MOSIは読み込めない。ようなことが書いてある。

で、困ったわけだが ... もっと高い周波数の CLK で 駆動して SCK MOSI ともにデータとして扱うことにした。(SCK はエッジを検出して処理)。もともと ISP として使いたいので、CLK が別にあるのが前提になるから、こうした方が都合がよい。

SCK と MOSI は同時に変化するので、SCK は、CLK でサンプリングして遅延させるようにする。具体的には、top モジュールで次のようにする。

    always @(posedge CLK)
    begin
    r_jtck_prev <= JTCK_IN;
    if (r_jtck_prev == JTCK_IN)
    r_jtck <= r_jtck_prev;
    end
    wire JTCK1 = r_jtck;
    wire JTDI = JTDI_IN;

JTCK_IN だけ ひとまず CLK で同期する。2 クロック連続で同じ値ならという論理なので、これだけで遅延されている。次に下位モジュールで、半クロックずらして処理をする。

    always @(negedge CLK)
    begin
    r_sck <= SCK;
    if (CS)
    :
    else if (~r_sck & SCK) // posedge SCK : INPUT
    begin
    入力処理
    :
    end
    end

これで、JTDI_IN の値は読めるはず。さて、SCK の立ち上がりですべてを行わないといけない 。これは次のようにした。

    else if (~r_sck & SCK) // posedge SCK : INPUT
    begin
    req_shift <= 1'b1;
    入力処理
    end
    else if (req_shift) // next
    begin
    req_shift <= 1'b0;
    :
    出力処理
    end

CLK を複数クロック使って 処理するわけだ。通信速度は、CLK の 1/10 以下でないとダメそうだが、CLKは普通 10 MHz 以上で、1Mbps 程度ならいける。
 
CLK
___ ___ ___ ___ ___ ___ ___ ___ ___
__| |___| |___| |___| |___| |___| |___| |___| |___| |___|

: : :
SCK : : :
_______________________________ ___
_____| |________________________________|


r_valid : : :
_________________________________________________________________
_________| |
: : :
r_req : : :
_______
_________| |_________________________________________________________
@ SPI_DATA_I input

これは、8bit 目を受け取ったときのタイミング。出力処理を他のモジュールで行うなら、CLK の立下りで 行うのが良さそう。

    always @(negedge CLK)
    begin
    if (SPI_DATA_REQ)
    r_data <= SPI_DATA;
    end
    assign SPI_DATA_I = r_data;

こんな風にして、エコーするだけのものは、動いた。(ラッチは必要なく、入出力をつないでも動く。)

実際の応用回路として、ISP を作ろうとしているのだが、こちらは、うまく動いてくれない。

SCK
___ ___ ___ ___ ___ ___ ___ ___
__| |___| |___| |___| |___| |___| |___| |___| |.....
: :
CS _______
|_____________________________________________________.....
: :
data
<bit7 ><bit6 ><bit5 ><bit4 ><bit3 ><bit2 > .....


随分長い間悩んでいたのだが、CS が L になってから 余計な 1bit があるのが原因だった。エコーするだけのものは ずれても問題ないのだが、通信できていると思い込んでいたのが敗因。


CLK
___ ___ ___ ___ ___ ___ ___ ___
__| |___| |___| |___| |___ .... __| |___| |___| |___| |___|

SPI_DATA_REQ
_______ _______
_________| |______________________ .... ___| |__________

r_req
_______ _______
_____________| |__________________ .... ______| |______

(a) (b) (c) (d)

コマンド データ

ISP のモジュールを設計しているのだが、こんな風に 2 バイト のデータ (コマンド , データ) 組みにしようとしている。処理のタイミングは それぞれ 2 つ作る。

(a) , (c) で 出力をラッチすると SPI_DATA_REQ の立下りで受け取られて 次の フェーズで HOST に出力される。(a), (b) で入力データを受け取ることが出来るが、(a) で解析してすぐに次のデータを決めるのは、タイミング的に厳しい。あらかじめ決めておいたデータを送ることにしよう。

といっても、アドレスが決まるのは、(c) でデータを受け取った後。演算する場合もあるので、(d) になる。

    ここで ISP の仕様を書いておく。

    // SSTPR 0110 100a PR[a] ( PR[0] : low byte of PR )
    // XXXX XXXX XXXX XXXX ( PR[1] : high byte of PR )
    //
    // SLD 0010 0I00 XXXX XXXX ( if I == 1 , PR = PR +1 )
    // XXXX XXXX load_data
    //
    // SST 0110 0I00 store_data ( if I == 1 , PR = PR +1 )
    // XXXX XXXX XXXX XXXX

    まぁたいしたことはない。ポインタをセットする命令と、ロード・ストアがあるのみ。


always @(posedge CLK)
begin
if (CS)
:
else
begin
r_req <= SPI_DATA_REQ;
(a) if (SPI_DATA_REQ & ~SPI_COUNT[0])
begin
r_data_out <= ISP_LOAD_DATA;
end
(b) if (r_req & ~SPI_COUNT[0])
begin
r_pr_inc <= f_pr_inc;
r_sstpr_hi <= f_sstpr_hi;
r_sstpr_lo <= f_sstpr_lo;
r_store <= f_store;
end
(c) if (SPI_DATA_REQ & SPI_COUNT[0])
begin
r_data_out[0] <= r_pr_inc;
r_data_out[1] <= r_load;
r_data_out[2] <= r_store;
r_data_out[3] <= 1'b1;
r_data_out[7:4] <= SPI_DATA[7:4];
end
(d) if (r_req & SPI_COUNT[0])
begin
if (r_pr_inc) r_pr <= r_pr + 1;
else if (r_sstpr_hi) r_pr[15:8] <= ISP_STORE_DATA;
else if (r_sstpr_lo) r_pr[7:0] <= ISP_STORE_DATA;
end
end

コードの一部を紹介するとこんな風になった。

ちなみに、コードで ISP_STORE_DATA となっているのは、SPI からの入力データで、ISP_LOAD_DATAは、メモリからの読み出しデータ。

f_pr_inc などは、デコードの結果。

HOST 側のコード

    HOST 側のコードは、随分前から用意してある。(rtavr_tools-0.x.tar.gz)。ちょっと解説。

    もともとは、Xilinx の自作ボード用として作っていたものだが、MachXO/MachXO2 にも一部対応。ISP を使ってプログラムメモリを書き換えるのと config の 両方の機能を想定している。

    MachXO2 は、FT2232H なので MPSSE が使えるのだが、FT232R でも使えるように Bitbang モードを使っている。

    使い方なのだが、少々くせがある。

    target_load タイプ [サイズ]

    これで、バッファに タイプで指定したものから読み込む。

    fpga_ram fpga_flash spi_flash rtavr_isp

    タイプには、以上のものを指定できるが、コードが出来ているのは、rtavr_isp のみ。

    erase タイプ
    program タイプ
    verify タイプ

    書き戻したり、ベリファイする場合は、こういう風に指定する。

    ファイルから読み込む場合は、次のコマンド。

    file_load [ファイルタイプ] file
    filetype: bit jed mcs mem

    MachXO2 に関係するのは、jed と mem 。isp の場合は、mem を使う。jed をコンフィグするコードも用意してあるが、未テスト。... というか未完成。

    mcs も読み込めはするが、SPI FLASH に書き込むには、先に専用の config を書きこまないとだめで、コードは全然。構想では、RAM のみ config して ... みたいなことを考えていたのだが ... MachXO2 では RAM 用のデータを用意するのが面倒そう。

    ちなみに、Xilinx も JTAG を通して通信することが可能。Xilinx 用のコードも入れてはあるのだが、実際に動かすのは随分先の話になりそう。

    他に テスト用のコードも入れてあって

    spi_test
    isp_test

    のコマンドがある。ついでなので、API に付いてもちょっと紹介。

    isp_test(TARGET tgt, CABLE cbl) {

    uint32_t s,r;

    jtag_reset(cbl);
    (tgt->sel_chan)(tgt, cbl, ISP_CHAN);

    s = (TPI_SETPR_LO << 8);
    jtag_SDR32R(cbl, s, 16, JTAG_RECV|JTAG_CONT, &r);
    :

    こんな感じで使えるようになっている。jtag_SDR32R が MSB first の SPI 通信で 32bit までを指定できる。JTAG_CONT は、最後に TMS を H にしないオプションで SPI 通信では必須。

    JTAG_RECVを指定しないと、戻り値不要。書き方も変わりバッファリングされる。

    tgt, cbl の初期化は、ちょっと面倒なので割愛。

rtavr_tools 最新版

  • rtavr_tools-0.7.tar.gz

    上記の内容に対応するコードを rtavr_tools 最新版として置いておく。


    rtavr_tools-0.7/
    /src -- HOST 側プログラム (MinGW , Linux 用)
    /rtavr_tools.exe -- プログラム 実行形式 (CUI)
    /test_hdl/ -- HDL ソース (tool_test.v , jtag_spi.v , isp.v)
    /out/test_hdl_xo2.jed -- MachXO2 breakout ボード用 (CLK 10 MHz)


    さて、これでようやく、ISP のベースが出来た。これがないと rtavr のデバッグが出来るような気がしなかった。ぼちぼち rtavr も実機でのデバッグを進めていこうと思う。

    あと、この ISP は、内部のメモリ(と アドレス可能なデータ)を読み書きするものでもある。調停がまだ出来ていないが、ロジアナとかフレームバッファの通信に応用できるはず。これをベースにしてなにか作ってみたい。

    fpga flash への 操作も できたほうが便利そうな気も。 開発のフェーズによっては、いちいち Diamond で書くのも面倒だろうし。プログラムとハードウェア(HDL) を入れ替えてデバッグしたりするとき なんかは役に立ちそう。ちなみに、fpga flash への 操作は、SVF を作って解析して作る。根気はいるが難しいことではない。気が向いたときでもやっておこう。

タイミング変更

    せっかく動かせたのだが、JTAG 通信の都合に合わせていったので、タイミングはやはり標準的なものではなくなっている。いずれは、rtavr の SPI モジュールに接続したりもしたいので、これでは困るのだ。それで、大胆な変更をあえて行うことにした。

    変更するのは以下のところ。

    • CS の遅延

      CS と通信開始までの 1 クロック(SCK) の空白は 困るので、CS を遅延させることにした。

    • 入力/出力のタイミング

      ISP 向けのコードを作って 入力 した後に 出力を確定できるという特徴は利用しなかった。タイミングが厳しくなるのが嫌なのが、その理由。そうであれば、出力先行で 普通のタイミングにした方が良い。それに合わせて SCK も反転させる。

    • SPI_DATA_VALID の有効化

      いままで SPI_DATA_REQ だけで制御してきたが、タイミングが全く変わるので SPI_DATA_VALID も 使うようにする。


    変更後 タイミング

    ___ __________________ _____
    SCK |___________________| |_________________|

    SPI_DATA_VALID: ____________________________________
    _______________________| |____

    SPI_DATA_REQ:
    _ _
    ___| |______________________________________________________| |__

    コードも随分変わったが、すんなり動かせた。今後は新方法に全面置き換え。以前のコードについて せっかく説明も書いたのだが、rtavr_tools-0.7 のみのコードになる(予定)。

付録: 外部 SPIデバイスとの通信

    `define TARGET_MachXO2
    //`define TARGET_MachXO
    //`define TARGET_LatticeXP2

    module spi_lattice (
    // JTAG
    input TOP_TDI
    , input TOP_TCK
    , input TOP_TMS
    , output TOP_TDO
    // EXTERNAL SPI PORT
    , output CS
    , output SCK
    , output SI
    , input SO
    );

    `ifdef TARGET_MachXO
    `define JTAG_BSCAN JTAGD
    OSCC osc_internal (.OSC(CLK)); // 18 MHz - 26 MHz
    `elsif TARGET_MachXO2
    `define JTAG_BSCAN JTAGF
    OSCH #(.NOM_FREQ("24.18")) osc_internal
    (.OSC(CLK), .STDBY(1'b0));
    `elsif TARGET_LatticeXP2
    `define JTAG_BSCAN JTAGE
    OSCE #(.NOM_FREQ("20.0")) osc_internal
    (.OSC(CLK));
    `endif

    `JTAG_BSCAN bscan (
    .JSHIFT(BSCAN_SHIFT)
    // .JRSTN(BSCAN_RESET) // H : in TestLogicReset State
    // , .JUPDATE(BSCAN_UPDATE)

    , .TDI(TOP_TDI)
    , .TCK(TOP_TCK)
    , .TMS(TOP_TMS)
    , .TDO(TOP_TDO)

    , .JTDI(JTDI_IN)
    , .JTCK(JTCK_IN) // negedge capt, posedge shift

    // signals for IPA
    , .JRTI1(JRTI1)
    , .JCE1(SEL1)
    , .JTDO1(JTDO1)

    // signals for IPB
    , .JRTI2(JRTI2)
    , .JCE2(SEL2)
    , .JTDO2(JTDO2)
    );

    reg r_jtck;
    reg r_jtck_prev;
    reg r_cs1;
    reg r_cs1_prev;
    reg r_cs2;
    reg r_cs2_prev;

    always @(posedge CLK)
    begin
    r_jtck_prev <= JTCK_IN;
    if (r_jtck_prev == JTCK_IN)
    r_jtck <= ~r_jtck_prev;
    if (r_jtck_prev & r_jtck & (r_jtck_prev == JTCK_IN)) // negedge JTCK
    begin
    r_cs1_prev <= ~(SEL1 & BSCAN_SHIFT);
    r_cs1 <= r_cs1_prev;
    r_cs2_prev <= ~(SEL2 & BSCAN_SHIFT);
    r_cs2 <= r_cs2_prev;
    end
    end
    wire JTCK1 = r_jtck;
    wire JTCK2 = r_jtck;
    wire JTDI = JTDI_IN;
    wire CS1 = r_cs1;
    wire CS2 = r_cs2;

    assign CS = CS1;
    assign SCK = JTCK1;
    assign SI = JTDI;
    assign JTDO1 = SO;

    endmodule

    たぶん、このコードで XO/XO2/XP2 で JTAG を通じて SPI デバイスと通信できる。XO2 で確認済みのコードをベースにしているのでたぶん大丈夫だろう。

    ちなみに、XP2 / XO2 だと SPI FLASH からのブートが可能。接続した SPI FLASH にプログラムするためには、こういったものを 一時的に config する必要がある。(バウンダリスキャンでも良いが遅い)

    XilinX も似た様なことは可能だが、内蔵クロックを使えないので、内蔵クロックを使わない やりかたに変更しないといけない。
posted by すz at 00:24| Comment(0) | TrackBack(0) | MachXO2

2012年02月23日

Lattice Diamond メモ

MachXO2 の論理合成をするには、Lattice Diamond というツールを使う。

使いこなしているとは到底言えないレベルだが、使い方とか分かったことを忘れないようにメモしていこうと思う。

テーマの選択

    ついでなので、どうやって 使うかを順に説明しておこうかと思う。サンプルとして何を作るかについては、乗算回路にしようと思う。32bit の CPU も作ってみたいのだが、乗算器のない MachXO2 でどれぐらいの規模になるのか見ておきたいのが理由。ちなみに MachXO2 は、LUT4 の代わりに 2b x 2b 乗算器にできる。単純な LUT4 よりは規模を縮小できそうな機能がある。

プロジエクトの生成

    "Start Page" という タブに Open とか New があるので、New をクリック。
    ダイアログが現れるので、例えば

      Project:
      Name: diamond_test1
      Location: D:/diamond/diamond_test1
      Implementation:
      Name: xo2
      Location: D:/diamond/diamond_test1/xo2

    と入力してみる。Next の ソースの追加はスキップ して "Select Device" で LCMXO2-7000ZE-1FTG256C になるように入力する。そうすると 左側の "File List" は次のようになる。

      実際に動かす場合、MachXO2 Breaout ボードなら、LCMX2-1200ZE-1TG144C を選ぶのだが、今回は、入出力を全部ポート に割り当てると 必要ポートが多すぎで Map できないケースが出る。動かすつもりもないので、大きな規模のものに変更。

      ちなみに、後で変更できるので、間違っても気にしなくて良い。



    この時点で作成されたファイルは、diamond_test1 をカレントディレクトリとして

      xo2/diamond_test1_xo2_summary.html
      diamond_test1.lpf
      diamond_test1.ldf
      Strategy1.sty
      diamond_test1.pty


ソースコードの追加

    "Input Files" を右クリックして、ソースコードを追加していく。新規ファイルは New を選ぶ。のでトップレベルから。

      module mult_test (
      input [31:0] DataA
      , input [31:0] DataB
      , input Clock, ClkEn, Aclr
      , output [63:0] Result
      );

      wire [63:0] Result;

      `define USE_PMI
      `ifdef USE_PMI
      pmi_mult #(.pmi_additional_pipeline(0)
      , .pmi_dataa_width(32)
      , .pmi_datab_width(32)
      ) MU (.DataA(DataA[31:0])
      , .DataB(DataB[31:0])
      , .Clock(1'b0)
      , .ClkEn(1'b1)
      , .Aclr(1'b0)
      , .Result(Result[63:0])
      );
      `else
      assign Result = DataA * DataB;
      `endif
      endmodule

    この内容を mult_test_pmi.v で生成すると、"Input Files" に xo2/source/mult_test_pmi.v が追加される。

    さて、pmi というのは、Parameterized Module Instantiation の略で、プリミティブのようなもの。ただし、定義したファイルを 追加しないといけない。

    Diamond をインストールするディレクトリは、lscc/diamond/1.4 のような階層になっているが、そこから pmi_mult.v を検索すると ...

    ./examples/MachXOBoard-SWDemo/Demo_MachXO2_Control_SoC/LatticeMico8_v3_1_Verilog/models/pmi/pmi_mult.v
    ./ispfpga/verilog/data/pmi/pmi_mult.v
    ./cae_library/simulation/verilog/pmi/pmi_mult.v

    の 3 つが見つかる。ispfpga と cae_library/simulation の 2 つは同じもので最新版。examples/MachXOBoard-SWDemo/Demo_MachXO2_Control_SoC に Mico8 が付属するのだが、最新版ではなく、pmi_mult.v も少し古い。(Mico8 自体を最新版にしても pmi は古い)

    ispfpga のやつを Add することにしよう。"Exsiting File" で 追加するのだが、"Copy file to ..." のチェックボックスにチェックする。

論理合成

    `define USE_PMI をコメントにして合成してみる。

    "Process" のタブを選んで実行していくと次のような画面になる。
    (実際に動かす場合は、JEDEC file にチェックして作成する。その後は、Tools の Programmer で)



    出来たところで、Map の Design Summary を見てみると次のようになった。

    Design Summary
    Number of registers: 0
    PFU registers: 0
    PIO registers: 0
    Number of SLICEs: 581 out of 3432 (17%)
    SLICEs(logic/ROM): 581 out of 858 (68%)
    SLICEs(logic/ROM/RAM): 0 out of 2574 (0%)
    As RAM: 0 out of 2574 (0%)
    As Logic/ROM: 0 out of 2574 (0%)
    Number of logic LUT4s: 36
    Number of distributed RAM: 0 (0 LUT4s)
    Number of ripple logic: 563 (1126 LUT4s)
    Number of shift registers: 0
    Total number of LUT4s: 1162
    Number of PIO sites used: 128 out of 207 (62%)

    581 スライスも使っている。1200ZE なら全部で 640 スライスしかないから、これでは使い物にならない。

    次に `define USE_PMI を有効にして再度 合成してみる。

    Design Summary
    Number of registers: 0
    PFU registers: 0
    PIO registers: 0
    Number of SLICEs: 64 out of 3432 (2%)
    SLICEs(logic/ROM): 64 out of 858 (7%)
    SLICEs(logic/ROM/RAM): 0 out of 2574 (0%)
    As RAM: 0 out of 2574 (0%)
    As Logic/ROM: 0 out of 2574 (0%)
    Number of logic LUT4s: 64
    Number of distributed RAM: 0 (0 LUT4s)
    Number of ripple logic: 0 (0 LUT4s)
    Number of shift registers: 0
    Total number of LUT4s: 64
    Number of PIO sites used: 64 out of 207 (31%)

    64 スライスと規模が小さいのだが、PIO を 64 しか使っていない。どうも 16bit 乗算までで .pmi_dataX_width になにを書いても良いというわけではないようだ。失敗。

    失敗はしたが、16bit 乗算はどうも 64 LUT らしい。2b x 2b が 1LUT なら 4b x 4b が 4LUT 、8b x 8b が 16LUT となって 16b x 16b は 64LUT 。そうであれば、うまく作れれば 32b x 32b は 256 LUT 。ただし今のところうまく作れない。

    実際にうまく作れたとしても、1 クロックで 32bit 乗算をするのが現実的なのかどうか... やはり 乗算器がある FPGA に乗り換えるのが現実的に思える。MachXO2 で、なんとかするとしても テストぐらいにしておいた方が無難そうだ。

      MachXO2 Breakout ボードは気軽に使えて便利なのだ。使えるものなら使いたい。TQFP 144 の 1200ZE と 7000ZE ならピンコンパチだと思うので、載せ替えが可能なはず。載せ替え出来れば 回路的には余裕。ただ性能が出せないので、テストぐらいしか使えないと思う。テストなら無理して 最適化する必要もないし、すなおなコードで十分。

    大体分かったので、今回はこれぐらいにしておこう。

プロジェクトのtarball

    ところで、一旦 合成すると非常に多数のファイルが作成される。Make clean 相当のことをして 再現するのに最低限のファイルのみにして tarball にしたいのだが、どうしたら良いのだろう?
    一応 *.* xo2/source xo2/*.html でファイルを指定すると ...

      Strategy1.sty
      diamond_test1.ldf
      diamond_test1.lpf
      diamond_test1.pty
      xo2/source/
      xo2/source/mult_test_pmi.v
      xo2/source/pmi_mult.v
      xo2/diamond_test1_xo2_mrp.html
      xo2/diamond_test1_xo2_pad.html
      xo2/diamond_test1_xo2_par.html
      xo2/diamond_test1_xo2_summary.html
      xo2/diamond_test1_xo2_synplify.html

    これを違うディレクトリにもっていって Project を Open することは出来た。

    ただし、Input Files は、再指定しないといけない。( xo2/source にあるファイルを全指定するので、楽ではある)。あと、html ファイルは、summary 以外 report では、見ることができない。ブラウザなどで見ないといけないのだが、最後の状態が残っているので セーブする意味はあるだろう。

      追記:
      reportview.xml も 作成されていたので、これも セーブ。あと xo2/*.prf (Preference File) もセーブすれば良いみたい。


    ところで、Implementation とは何だろう? プロジェクトに対して右クリックで "New Implementation" を Add できるから 、いくつもの バージョンを持てるようだ。ただ、lpf とかは共有しているから 『同じハードウェアに対するもの』 というのが前提らしい。

    さらに言うと、同じトップディレクトリに 多数のプロジェクトを置いたらどうなるのだろう?

    Strategy1.sty は共有されるが、一応は置くことができる。Implementation を同じにしても プロジェクト名+Implementation で主なファイルが作られているから 整合性は問題なさそう。

    こういうことを前提にして、どうプロジェクトを組み立てたら良いか考えてみよう。

プロジェクトの構成

    いま、MachXO Breakout ボード と MachXO2 Breakout の 2 つのボードを持っている。それぞれに対して、rtavr の バリエーションがいくつか考えられる。(ただし ソースコードは共有)。また、全然違うソースのテスト用コードがある。

    ひとつの Top ディレクトリに 構成していくとするならどうしたら良いか。今の案を書いてみる。

    • まず、Top に rtavr と rtavr_tools のソースコードを展開する。いくつかの例外を除いて、この ソースコードを Copy せずに 使うことにする。

    • 例外とは、Include するファイル。rtavr だと rtavr_defs.v , rtavr_common.v , rom_data.mem の 3 つ。これらは、Implementation/source にコピーして使う。

        注意) Include するパスは、ソースを Add する前に 定義しておかないと面倒なことになる。Implementation名の Properties で 指定しておく。

        あと、ソースと同じディレクトリにあるファイルの方が優先されるので、都合が悪い場合は、ソースの方もコピー指定が必要。

    • プロジェクト名は、ボード名を元にしたものにする。この先に Implementation をぶらさげる。( Implementation はボード名が違えば 別名になるようにする。)

    とりあえず ...

    (Project) (Implementation)
    MachXO2_Breakout --- rtavr_isp_xo2
    +- test_hdl_xo2

    MachXO_Breakout --- rtavr_isp_xo
    +- test_hdl_xo

    こういう風に構成できるようにしてみよう。



    お、なんかできた。Implementation は、いずれか1つを Active にして使うようだ。

    ソース(rtavr-0.9.5.tar.gz , rtavr_tools-0.6.tar.gz) を除いて tarball にしてみたところ 4MB になった。これを違うマシンの パスが違うディレクトリに作成しなおしても 大丈夫のようだ。

    ただ、調子に乗って Implementation を作ってしまうと tarball が どんどん大きくなってしまう。

      プロジェクト名.*
      reportview.xml
      Strategy1.sty
      インプリテーション名/*.prf
      インプリテーション名/*.html
      インプリテーション名/source

    だけをセーブすると 100KB 程度と随分小さくなった。再ビルドも出来るみたいだし、プロジェクトのバックアップは これのみにしよう。

  • rtavr_diamond-sample.zip (2012/2/25 更新)

    プロジェクトのサンプルを ここに置いておく。(動かすためのものではなく、論理合成の確認用として) 今の最新版の rtavr と rtavr_tools も入れてある。

Warningのチェック

    例えば rtavr_isp_xo2 を合成すると Synthesis Design だけでも 相当な Waring が出る。これをチェックすることにした。

    まず、連鎖的に Waring になるものがある。とりあえずそれを除いて整理してみる。

      s/".*\\rtavr-0.9.5\\/"/
      /enable tied to GND/d
      /Undriven input .*, tying to 0/d
      /Found undriven nets .*, mapper will optimize them/d

    こんな sed スクリプトで、何種類かのものを削除。あとファイルのパスが長すぎるので 相対パスに変換。


      @W: MT420 |Found inferred clock xo2_isp|CLK0_OUT_inferred_clock with period 1000.00ns. Please declare a user-defined clock on object "n:CLK0_OUT"


    クロックの定義が必要らしい。JTM08_007(Spreadsheet ViewでのConstraint設定),JTM08_010(タイミング制約および検証に関する注意事項) を読んでも正直良く分からない。

      とりあえず、PLL 出力で位相差がある場合は、ちゃんと計算してくれることは分かった。ただ、この Warning が出るということは、周波数は計算してくれないようだ。全部に 同じ周波数を設定してやれば良いのだろうか?

      さて、CLK0_OUT_inferred_clock とは何だろう? コード上は、CLK0_OUTで 余計なサフィックスは付いていない。しかも、"n:CLK0_OUT" という別の名前が出ている。これで随分混乱している。

      いろいろやってみると、Spreadsheet View を使うと設定したものを 制約ファイル(lpf) に書いてくれる。あと、Synplity Pro と LSE では、設定が違うようだ。

      ちなみに、Spreadsheet View は、Translate Design が終わらないと設定変更できない。また、制約ファイル(lpf)は、 # でコメントを書けるようだ。

    なにをやっても埒があかない。ひょっとして、制約は基本 LSE 用であって、Synplity Pro 向けでは制限があるのかも。

      追記: JTM08_005(SynthesisのStrategy設定と制約記述) の 30p あたりから説明があった。少し分かってきているが、当面 LSE を使うつもり。

    クロックに関係する他の Warning で要チェックなもの。

      @W: MT462 :"soc\rtavr_rom_4p.v":110:16:110:67|Net RTAVR.ROM.CLK_B appears to be an unidentified clock source. Assuming default frequency.
      @W: MT462 :"soc\rtavr_rom_4p.v":156:18:156:31|Net RTAVR.ROM.CLK_L appears to be an unidentified clock source. Assuming default frequency.
      @W: MT462 :"soc\rtavr_sram.v":80:20:80:57|Net RTAVR.RAM.CLK_90_270 appears to be an unidentified clock source. Assuming default frequency.

    これらは、特殊なことをしているので、クロックとして認識されてしまう。READ と WRITE でタイミングを変えたり、 1クロックに 2 回アクセスしていたりする。

      @W: CG532 :"isp_sample\isp.v":215:4:215:10|Initial statement will only initialize memories through the usage of $readmemh and $readmemb. Everything else is ignored
      @W: CG532 :"soc\rtavr_rom_4p.v":283:2:283:8|Initial statement will only initialize memories through the usage of $readmemh and $readmemb. Everything else is ignored

    rom では、$readmemh 使っているのだが、まだ出る。rom_data.mem のサイズが違うのかとも思ったが合っていた。要調査。

    isp では、initial 文を register の初期値に使っていた。

    reg r_cs = 1'b0;

    の記述方法で書き換えると消えはする。

      @W: FX474 |User specified initial value found in some of the sequential elements in the design. Applying an initial value to a register may not deliver the best synthesis results. For example, registers with initial values may be preserved and retiming/pipelining may not be performed. To improve synthesis results you may want to remove the register initialization from the RTL code

    この諭すような、Waring は何なのだろう? とりあえずパス。

    これでもまだ多数の Warining が残る。だが、かなりの部分は規模を減らすオプションの結果。

      `define IOR_SPHBITS 2 // SPH bits 1-8 (-15 slices)

    例えば、スタックポインタの上位ビットを定数化するオプションを入れると ...

      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[2] is always 0, o
      ptimizing ...
      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[3] is always 0, o
      ptimizing ...
      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[4] is always 0, o
      ptimizing ...
      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[5] is always 0, o
      ptimizing ...
      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[6] is always 0, o
      ptimizing ...
      @W: CL189 :"soc\rtavr_ior_ps.v":403:4:403:9|Register bit r_sph[7] is always 0, o
      ptimizing ...
      @W: CL279 :"soc\rtavr_ior_ps.v":403:4:403:9|Pruning register bits 7 to 2 of r_sp
      h[7:0]
      @W: CL246 :"soc\rtavr_ior_ps.v":56:18:56:22|Input port bits 15 to 10 of SP_IN[15
      :0] are unused

    これだけの Warning になるのだ。この手のものは、フル機能にすることでのみ Waring が消える。

    面倒だが、上の sed スクリプトを増強して、分かっているものを消していくのも手か。


      s/".*\\rtavr-0.9.5\\/"/
      /enable tied to GND/d
      /Undriven input .*, tying to 0/d
      /Found undriven nets .*, mapper will optimize them/d
      /rtavr_ior_ps.*Pruning .* r_sph/d
      /rtavr_ior_ps.*Register bit r_sph.[0-7]. is always 0, optimizing/d
      /rtavr_ior_ps.*Input port bits [0-9]* to [0-9]* of SP_IN.[0-9:]*. are unused/d
      /rtavr_ior_usart.*Pruning bit [0-9]* of rx_ps.* -- not in use/d
      /rtavr_ior_usart.*Pruning bit [0-9]* of tx_ps.* -- not in use/d
      /rtavr_ior_usart.*Pruning bits [0-9]* to .* rx_data.* -- not in use/d
      /rtavr_ior_usart.*Pruning bit [0-9]* of tx_data.* -- not in use/d
      /rtavr_ior_usart.*Pruning register bit 1 of r_count_max_x/d
      /rtavr_ior_usart.*Pruning register rx_parity/d
      /rtavr_ior_usart.*Register bit UPE is always ., optimizing/d
      /rtavr_ior_usart.*Register bit r_count_max_x.1. is always ., optimizing/d
      /rtavr_ior_usart.*Removing register 'RXB8' because/d
      /rtavr_ior_usart.*Removing register 'TXB8' because/d
      /rtavr_ior_usart.*Input WE_ubrrl is unused/d
      /rtavr_ior_usart.*Input WE_ucsrc is unused/d
      /rtavr_ior_usart.*Input WE_ubrrh is unused/d
      /rtavr_ior_usart.*Input XCK_IN is unused/d
      /rtavr_ior_usart.*Input XCK_DDR is unused/d
      /rtavr_ior_timer0.*Pruning register bit.* of r_prescaler/d
      /rtavr_ior_timer0.*Input WE_ocr0b is unused/d
      /rtavr_ior_timer0.*Input WE_ocr0a is unused/d
      /rtavr_ior_timer0.*Input WE_tccr0a is unused/d
      /rtavr_ior_port.*Input WE_pin is unused/d
      /rtavr_ior_port.*Input DI_pin is unused/d
      /rtavr_ior_spi.*Input SS_DDR is unused/d
      /rtavr_ior_spi.*Input MISO_IN is unused/d
      /rtavr_ior_spi.*Pruning register r_count_en/d
      /rtavr_ior_spi.*Pruning register r_ps/d
      /rtavr_ior_spi.*Input WE_spsr is unused/d
      /rtavr_rom_4p.*Pruning bit.* of r_addrb/d
      /rtavr_rom_4p.*Input port bit.* of ADDRA.* is unused/d
      /rtavr_rom_4p.*Input port bit.* of ADDRB.* is unused/d
      /rtavr_rom_4p.*Input OEA is unused/d
      /rtavr_s1_decode.*Pruning register r_wdr/d
      /rtavr_sram.*Pruning bit.* of r_addrb/d
      /rtavr_sram.*Input port bit.* of ADDRB/d


    十分ではないが、だいぶ見やすくなった。

      @W: CL157 :"soc\rtavr_ior_ms.v":71:18:71:20|*Output DDR has undriven bits -- simulation mismatch possible.
      @W: CL157 :"soc\rtavr_ior_ms.v":72:18:72:21|*Output PORT has undriven bits -- simulation mismatch possible.
      @W: CL246 :"soc\rtavr_ior_ms.v":73:18:73:20|Input port bits 15 to 0 of PIN[23:0] are unused
      @W: CL118 :"soc\rtavr_rom_4p.v":163:1:163:2|Latch generated from always block for signal r_doa[15:0]; possible missing assignment in an if or case statement.

    残ったのには、こんなものがある。チェックしていかないと。

    上 3 行の port 関係だが、

    // external I/O
    , output [23:0] DDR
    , output [23:0] PORT
    , input [23:0] PIN

    パラメータにこういう定義をしておいて、PORTC/PORTB/PORTA に割り当てている。PORTB/PORTA を有効にしていないので、ビット 15 - 0 が未定義のまま。上位レイヤーも 未定義な bit は使わない。

    これでも良いかということにしたのだが、論理合成では問題ないものの、Active-HDL でまずいかも ... ということか。
    下のやつは、これ。

    `ifdef ROM_USE_LATCH
    `ifdef SYS_DRIVEN_CLK4PH
    wire CLK_L = CLK_180 | OEB;
    `else
    wire CLK_L = CLK | OEB;
    `endif

    always @(ROM_DO_AB or CLK_L)
    begin
    if(~CLK_L) r_doa <= ROM_DO_AB;
    end
    assign DOA = r_doa;
    `else

    ROM_USE_LATCH というローカル define を有効にしていて、正に ラッチを作ろうとしている。遅延の最適化がそうした理由だった。まぁ目的どおりだから良いのかな?

LSEに切り替え

    デフォルトが Synplify Pro だったので、そちらがお薦めなのかと思って使っていたが、残念なことに良くわからない。 Tools に Synplify Pro for lattice なんてのがあって、これを立ち上げると、Diamond と同じような window が出てくる。Synplify Pro 専用の制約ファイル(sdc)なんてのもあるようだし、上記の "n:CLK0_OUT" とかは、その制約ファイルで使うものらしい。

    お気軽に使うのなら、LSE の方が良さそうに思えてきたので、合成ツールを 切り替えることにした。


      Preference Summary

      FREQUENCY NET "CLK_INT" 2.080000 MHz (0 errors)
      FREQUENCY NET "CLK_IN0" 24.000000 MHz (0 errors)

      FREQUENCY NET "CLK0_OUT" 33.000000 MHz (4096 errors)
      4096 items scored, 4096 timing errors detected.
      Warning: 12.772MHz is the maximum frequency for this preference.

      FREQUENCY NET "CLK90_OUT" 33.000000 MHz (1024 errors)
      2395 items scored, 1024 timing errors detected.
      Warning: 14.775MHz is the maximum frequency for this preference.

      FREQUENCY NET "CLK180_OUT" 33.000000 MHz (1726 errors)
      4096 items scored, 1726 timing errors detected.
      Warning: 15.232MHz is the maximum frequency for this preference.

      FREQUENCY NET "CLK270_OUT" 33.000000 MHz (737 errors)
      4096 items scored, 737 timing errors detected.
      Warning: 19.077MHz is the maximum frequency for this preference.

      FREQUENCY PORT "EXTOSC" 24.000000 MHz (0 errors)
      Report: 150.150MHz is the maximum frequency for this preference.

      PERIOD PORT "TOP_TCK" 0.100000 nS (1 errors)
      0 items scored, 1 timing error detected.

    LSE を使ったらクロックの設定が認識された。33 MHz にしてみたが、それは無理そうだということも分かった。まぁ HE と中身が同じなら 4 グレードレベル程度まではオーバクロック出来そうな気もするが。

    ちなみに Strategies を Space に変更した上で、GPR_16 を有効にして スペースを稼ぐ設定にしたから最遅
    という条件。

      "CLK0_OUT": 18.491MHz is the maximum frequency

      4 グレードの HC でやってみたらこうなった。ざっと 1.5 倍か。

      strategies を Strategy1 に戻し、GPR_16 も無効にすると 20 MHz ぐらい。

      FREQUENCY NET "CLK0_OUT" 22.000000 MHz (0 errors)
      Report: 25.938MHz is the maximum frequency for this preference.

      FREQUENCY NET "CLK90_OUT" 22.000000 MHz (0 errors)
      Report: 28.073MHz is the maximum frequency for this preference.

      REQUENCY NET "CLK180_OUT" 22.000000 MHz (0 errors)
      Report: 32.356MHz is the maximum frequency for this preference.

      FREQUENCY NET "CLK270_OUT" 22.000000 MHz (0 errors)
      Report: 29.255MHz is the maximum frequency for this preference.

      さらに、22 MHz で制約を変更すると 25.9 MHz 。

rtavr_diamond-sample.zip(2012/2/25 更新) を試す

    大分脱線してしまったが、すぐ試せるものをリリースできるかどうかは、重要だ。それにクロックも。どれぐらいで動くものなのか知らないと動かすのが難しい。

    さて、上記のものを展開して、MachxO2_Breakout.ldf を open すると test_hdl_xo2 がターゲットの インプリメンテーションになっている。

    project の JEDEC File にチェックを付け、ダブルクリックをすると ... なにやら出来上がる。

    で、programmer で書き込みしようとすると、xcf ファイルがないと言われてエラーになる。この場合は、Scan 実行すると xcf ファイルが生成されて オペレーションが出来るようになる。(Check XCF File だったかも)

    動かしてみると ... LED0/1 と LED 2-5 が 1 秒毎ぐらいで点滅し、LED 2-5 の点滅が遅れて ずれるために光が流れるような動きをする。これが予定通りの動き。

    warning について

    沢山 warning が出るのだが、

      OSCH 'osc_internal' has mismatching FREQUENCY preference value of 2.08 MHz and NOM_FREQ value of 24.18 MHz.

    まず気になるのはこれ。24.18 MHz だと 1 秒ぐらいの点滅間隔なので、コードに書いた NOM_FREQ が有効のようだ。

    2.08 MHz というのは、デフォルトで勝手に設定される。Spread sheet View の Timing Preferences で NET "CLK" を modify するか、制約ファイル(lsf)に

    FREQUENCY NET "CLK" 24.180000 MHz ;

    を追加するかすれば、直るはず。


      ERROR - <E0055> Port 'TXD' is unconnected.
      ERROR - <E0055> Port 'RXD' is unconnected.

    なんてエラーが出る場合がある。これは、rtavr と同じ制約ファイルを使っているため。# でコメントすれば一応は出なくなる。ただ、インプリメンテーションを変更する毎にいちいち編集はしてられない。

    さて、

      WARNING - trce: Output clock frequency on pin CLKOP of pll is 12.0 MHz, whichwith divider 16, requires internal VCO frequency to be 192.0 MHz ( 12.0 MHz x 16), outside VCO valid range [400, 800] MHz.

    この手の warning がやたら出てうるさい。


      FREQUENCY NET "CLK" 24.180000 MHz ;
      FREQUENCY NET "CLK_IN0" 24.000000 MHz ;
      FREQUENCY NET "CLK0_OUT" 24.000000 MHz ;
      FREQUENCY NET "CLK90_OUT" 24.000000 MHz ;
      FREQUENCY NET "CLK180_OUT" 24.000000 MHz ;
      FREQUENCY NET "CLK270_OUT" 24.000000 MHz ;
      FREQUENCY PORT "EXTOSC" 24.000000 MHz ;
      FREQUENCY PORT "TOP_TCK" 0.100000 MHz ;

    まずは、制約ファイル。一応近い値にしてやる。これだけだと 400 MHz 以下なので、too_test.v の

    , .CLKOP_DIV(32)
    , .CLKOS_DIV(32)
    , .CLKOS2_DIV(32)
    , .CLKOS3_DIV(32)

    CLKOP_DIV 等の値を全部 2 倍の 32 にすると 見事消えてくれる。

    これで、Warning は随分見やすくなる。

      WARNING - synthesis: logical net 'TXD' has no load
      WARNING - synthesis: input pad net 'TXD' has no legal load
      :
      WARNING - map: input pad net 'TXD' has no legal load
      WARNING - map: input pad net 'RTS' has no legal load
      WARNING - map: input pad net 'DTR' has no legal load
      WARNING - map: input pad net 'RXD' has no legal load
      WARNING - map: input pad net 'CTS' has no legal load
      WARNING - map: IO buffer missing for top level port TXD...logic will be discarde
      d.
      :

    これは、top モジュールの引数に書いてあるのに使っていないため。エラーになることはないので無視。

      WARNING - synthesis: logical net 'clk_count1_113_add_4_1/CI' has no driver
      WARNING - synthesis: logical net 'clk_count1_113_add_4_1/S0' has no load
      WARNING - synthesis: logical net 'clk_count2_114_add_4_25/CO' has no load

    これは、加算器のキャリー関係。明示的に記述もしてないし、勝手に作られて、勝手に消される。これも無視。/CI /CO /S0 /S1 あたりが対象。

    こうやって直していくのは良いのだが ... インプリメンテーションを変更した時どうするのが良いのだろう?

    lpf ファイルは、複数持てる。で、インプリメンテーション同様に 1 つをアクティブにするという使いかたをする。よく分からなかったのだが、JTM08_002(プロジェクト管理) 29p あたりに書いてあった。

付録

    どこでどんなファイルを使っているか、抜けはあると思うがまとめてみた。

    synpwrap: Synthesize Design (Synplify Pro)
    MachXO2_Breakout_test_hdl_xo2_synplify.tcl
    MachXO2_Breakout_test_hdl_xo2.srf
    synlog/MachXO2_Breakout_test_hdl_xo2_premap.srr
    synlog/MachXO2_Breakout_test_hdl_xo2_fpga_mapper.srr
    MachXO2_Breakout_test_hdl_xo2.srm

    edif2ngd:
    MachXO2_Breakout_test_hdl_xo2.edi
    MachXO2_Breakout_test_hdl_xo2.ngo

    ngdbuild:
    MachXO2_Breakout_test_hdl_xo2.ngo
    MachXO2_Breakout_test_hdl_xo2.ngd

    synthesis: Sythesize Design (LSE)
    MachXO2_Breakout_test_hdl_xo2_lattice.synproj
    MachXO2_Breakout_test_hdl_xo2.ngd

    map: Map Design
    MachXO2_Breakout_test_hdl_xo2.ngd
    MachXO2_Breakout_test_hdl_xo2_map.ncd
    MachXO2_Breakout_test_hdl_xo2.prf
    MachXO2_Breakout_test_hdl_xo2.mrp

    mpartrce:
    MachXO2_Breakout_test_hdl_xo2.p2t
    MachXO2_Breakout_test_hdl_xo2.p3t

    MachXO2_Breakout_test_hdl_xo2.pt
    MachXO2_Breakout_test_hdl_xo2_map.ncd
    MachXO2_Breakout_test_hdl_xo2.ncd

    par: Place & Route Design
    MachXO2_Breakout_test_hdl_xo2.p2t
    MachXO2_Breakout_test_hdl_xo2_map.ncd
    MachXO2_Breakout_test_hdl_xo2.dir
    MachXO2_Breakout_test_hdl_xo2.prf

    # Dumping design to file MachXO2_Breakout_test_hdl_xo2.dir/5_1.ncd.

    trce: Place & Route Trace
    MachXO2_Breakout_test_hdl_xo2.pt
    MachXO2_Breakout_test_hdl_xo2.twr
    MachXO2_Breakout_test_hdl_xo2.ncd
    MachXO2_Breakout_test_hdl_xo2.prf

    iotiming: I/O Timing Analysis
    MachXO2_Breakout_test_hdl_xo2.ncd
    MachXO2_Breakout_test_hdl_xo2.prf

    bitgen: Export Files (JEDEC File)
    MachXO2_Breakout_test_hdl_xo2.t2b
    MachXO2_Breakout_test_hdl_xo2.ncd
    MachXO2_Breakout_test_hdl_xo2.prf (Preference File)
    MachXO2_Breakout_test_hdl_xo2.jed

参考資料

  • Lattice Diamond 1.3 マニュアル

    JTM08_001 インストールとライセンス設定
    JTM08_002 プロジェクト管理
    JTM08_003 GUIのカスタマイズと環境設定
    JTM08_004 デザインフローとRun Mangerによる並列処理
    JTM08_005 SynthesisのStrategy設定と制約記述
    JTM08_006 Translate DesignのStrategy設定と注意点
    JTM08_007 Spreadsheet ViewでのConstraint設定
    JTM08_008 Package Viewによるピンアサイン
    JTM08_010 タイミング制約および検証に関する注意事項
    JTM01_009 SSO Analyzerユーザーマニュアル
    JTM08_012 Map DesignのStrategy設定と注意事項
    JTM08_015 Map Traceとシミュレーション
    JTM08_013 Place & Route DesignのStrategy設定と注意事項
    JTM08_016 Place & Route TraceとI/O Timing Analysis
    JTM05_001 Power Calculatorユーザマニュアル
    JTM08_018 シミュレーション・ユーザガイド
    JTM08_014 書き込みデータ生成


  • file:///C:/lscc/diamond/1.4/docs/webhelp/eng/start_page.htm オフラインドキュメント(1.4)
posted by すz at 23:48| Comment(38) | TrackBack(0) | MachXO2

2012年02月22日

MachXO2のクロック

MachXO2 Breakout ボードを使ってみて覚えたことをメモしておこうと思う。

内蔵オシレータ

    MachXO2 は、MachXO と同じくオシレータを内蔵している。MachXO2 から良くなったのは、周波数を設定できること と 精度が規定されたこと。

    MachXO は、18 〜 26 MHz と なっているだけで とりあえずクロックが使えれば良いという用途でしか使えなかった。

    MachXO2 では、133 MHz を 1 , 1.5 , 2, 2.5 ... 62 で分周した周波数を出力可能。64 通りの設定がある。精度は±5% で、あまり良いわけではないが、それでも 目安にはなる。

    分周比は、1 〜 16 の範囲では、0.5 刻み。16 〜 32 は 1 刻み、32 〜 62 では 2 刻み。

    OSCH #(.NOM_FREQ("24.18")) osc_internal
    (.OSC(CLK_INT), .STDBY(1'b0));

    こんな風に使う。NOM_FREQ の値は、TN1199 の表に書いてあるものと同じでないといけないことになっているが、本当かどうか 未確認。

PLL

    PLL は、EHXPLLJ というのを使うのだが、

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40) x CLKOP_DIV(1-128:default 8)

    の周波数が VCO の周波数になる。実際に合成して Warning を見ると、VCO 周波数は、400 〜 800 MHz の範囲でないといけないらしい。... が、多分間違いで、データシートを見ると 200 〜 800 MHz の範囲。CLKOP_DIV が 8 なら CLKOP の範囲は、 25MHz 〜 100 MHz ということに。

    CLKOP の出力は

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40)

    だが、CLKOS, CLKOS2, CLKOS3 は、

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40) x CLKOP_DIV(1-128:default 8) / CLKOSn_DIV(1-128:default 8)

    になるようだ。

    あと、これらは、ENCLKOSn を 1 に設定してやらないと出力されない。

    (いろんな使い方をして構わないが) 基本 四相のクロック出力をするときに使う。その場合は、CLKOSn_DIV の値は、CLKOP_DIV に一致させる。

    位相は、CLKOSn_FPHASE パラメータで 0-7 を指定する。45°単位。

    さて、 ちゃんと記述しても Waring が出る。

      WARNING - par: Output clock frequency on pin CLKOP of pll is 100.0 MHz, which with divider 16, requires internal VCO frequency to be 1600.0 MHz ( 100.0 MHz x 16), outside VCO valid range [400, 800] MHz.

    こんなメッセージ。ここの 100.0 MHz は、制約による指定で、

    FREQUENCY NET "NET名" 24.0 MHz

    というのを制約ファイル(.lpf) に記述することで指定する。

    あと、正しいレンジは、200 - 800 MHz のようなので、400 MHz を切る設定をしても良さそうなのだが、Warning を消すのは難しいかも知れない。

    ついでに書いておくと、MachXO や LatticeXP2 も PLL を持っている。MachXO では、EHXPLLC LatticeXP2 では、EHXPLL1 というのを使うらしいのだが、MachXO2 のものほど 高機能ではない。

PLLの動作確認


    OSCH #(.NOM_FREQ("24.18")) osc_internal
    (.OSC(CLK_INT), .STDBY(1'b0));

    DCMA clk_selector (.CLK0(CLK_INT)
    , .CLK1(EXTOSC)
    , .SEL(1'b0) // 0: CLK0 1: CLK1
    , .DCMOUT(CLK_IN0)
    );

    EHXPLLJ #(
    .CLKI_DIV(24)
    , .CLKFB_DIV(24)
    , .CLKOP_DIV(16)
    , .CLKOS_DIV(16)
    , .CLKOS2_DIV(16)
    , .CLKOS3_DIV(16)
    , .CLKOP_FPHASE(0)
    , .CLKOS_FPHASE(2)
    , .CLKOS2_FPHASE(4)
    , .CLKOS3_FPHASE(6)
    ) pll
    (.CLKI(CLK_IN0)
    `ifdef SYS_DRIVEN_CLK4PH
    , .CLKOP(CLK0_OUT)
    , .CLKOS(CLK90_OUT)
    , .CLKOS2(CLK180_OUT)
    , .CLKOS3(CLK270_OUT)
    , .ENCLKOS(1'b1)
    , .ENCLKOS2(1'b1)
    , .ENCLKOS3(1'b1)
    `else
    , .CLKOP(CLK_IN)
    `endif
    );

    完全には正確ではないのだが、こんな感じで使ってみた。

    それぞれのクロックに カウンタを付けて、1 秒程度おきに点滅させてみたところ、おなじ周期で点滅した。ただし、PLLの出力が (CLK_IN0に対して) ずれていく現象になった。

    原因は PLL の ロック が外れまくるため(のはず)。内蔵オシレータを基準クロックに使うのは、さすがに無理があるようだ。ただ、水晶なら問題ないとして、セラミック発振子を使ったり RC 発振だとどうなるのだろう? いずれ実験してみたい。

    ちなみに DCMA (Dynamic Clock Mux) は、おまけ。ドキュメントに書いてあったので使ってみただけ。

PLLの出力周波数の設定

    切りの良い周波数を 出力するのに

      CLKI_DIV : 入力周波数と同じにする。(1-40)
      CLKFB_DIV:出力周波数と同じにする。(1-40)
      CLKOP_DIV: 出力周波数 x CLKOP_DIV が 200 (400?) を超えるように 8/16/32 .. から選ぶ。

    基本の考えかたを、こんな風にしようかと思う。そうするなら、入力周波数は、切りが良ければなんでも良い。ただ応用できる範囲を広げるには、5x4 MHz とか 6x4 MHz とかが良さそうな気がしている。

PLL周波数をユーザ回路で変更

    MachXO2 だとこれが出来る。

    lscc/diamond/1.4/cae_library/synthesis/verilog/machxo2.v に EHXPLLJ に定義がある。インターフェイス仕様は WISHBONE。ドキュメントは、TN1199(J) の付録 D 。

水晶発振器

    MachXO2 Breakout ボードには、5mm x 7mm のオシレータのパターンもある。

    EXTOSC 27 PL9A_PCLKT3_0
    EXTOSC_EN 32 PL10A

    クロック出力だけでなく、Enable ピンにも接続されている。(R54 でジャンパされている)。

    回路図には、CB3LV-3C の 50MHz が記載されているが、消費電流が 40mA と大きく、±50ppm と精度もいまいち。16mA で ±10ppm の ASYMB の方が良いかも。

    秋月だと 『クリスタルオシレーター 40MHz』というのがある。いつなくなるかも分からないが ..

    J4

    (EXTOSC)PL9A 27 (33) (34) 28 PL9B
    GND (35) (36) GND
    (EXTOSC_EN)PL10A 32 (37) (38) 33 PL10B
    PL10C 34 (39) (40) 35 PL10D

    この信号は、20x2 のコネクタにも出ている。場所は、内側の 左(J4) の下。

    ユニバーサル基板を載せるのなら、こちらを使っても同等になる。その場合は、DIP 品(3.3V)が使える。といっても秋月でも 300円

その他の発振回路

    例えば、(EXTOSC)と (EXTOSC_EN) は、GND を挟んで配置されているのだが ... ここに 水晶とか セラミック発振子を付けて発振させられないかと思っている。単なるインバータなら 簡単に実装できるが、なんとかなるものなのか? 入出力にはいろんな設定があるので、設定次第なのかも知れない。

    追記: オシレータが入手できたので、(EXTOSC)と (EXTOSC_EN)を使っての実験はヤメ。

    J2
    (1)(2)
    NC VCCIO0
    PT17D/DONE 109 110 PT17C/INTn
    PT17B 111 112 PT17A
    GND GND
    PT16D 113 114 PT16C
    PT16B 115 117 PT15A
    PT15D/PROGn 119 120 PT15C/JTAGen
    GND GND

    J2 左側の外側上あたり。PT17A と PT16C が良さそうな。

      設定できるのは、プルモード、ヒステリシス、クランプ動作 あと ドライブ強度。これらは、制約ファイル(.lsf) にも記述できるし、プリミティブもあるようだ。

      それに加えて DELAYE とかのプリミティブもある。なにがどう使えるかは良く分からない。

      追記:



      こんな回路で、XIN , XOUT にインバータを入れれば良いらしい。水晶+コンデンサをセラミック発振子に変えても良い。

      村田製作所の FAQ 『発振回路部の各部品の役割について教えてください。』を見ると、R1(1M) は、帰還抵抗で C-MOS ICでは100k〜10MΩ (通常1MΩ) とのこと。『大きすぎると帰還量が減って動作点が不安定になり、小さすぎるとゲインの低下や、電流の増大につながります』と書いてあるから、入れないと発振が不安定になるかも知れない。

      XOUT 側 帰還抵抗 R1 と 水晶(セラミック発振子)の間に抵抗を入れる場合がある。『負荷容量とローパスフィルタを形成し、高域のゲインを低下させることで、高周波の異常発振を抑えられます。』なんて説明があるが、通常不要らしい。もともと数十Ωが入っているようなものだし ... それにドライブ強度の変更で調整できるかも。

      ... というわけで FPGA でも 単なるインバータ + この回路で良さそうだ。(1M は省略しないこと)

      さて、『セラミック発振子 40MHz (YIC社)』というのは、使えるのだろうか? 周波数が高めで AVR とかでは使えないが FPGA なら丁度良いかも知れない。

      最も 『クリスタルオシレーター 40MHz』なんてのもあるのだが ... いつまでもあるとは限らないし、水晶発振子やセラミック発振子の回路も押さえておきたい。

      ちなみに、安い YIC社のやつは、8,12,16,20,25,32,40,48 MHz と各種ある。PLL が使えそうだからなんでも良さそうだが ...

      いつか実験しよう。

      RC発振器(1)



      シュミットトリガ入力 と オープンドレイン出力がある MachXO2 だとこういう回路もあり?
      (シュミットトリガ入力 = HYSTERESIS : LARGE ?)

      R1 = 10k , C1 = 20pF ぐらいで数MHz ?

      原理は、コンデンサに充電されていって 入力の電位が上がってくると 出力が L になって コンデンサが放電される。ただ 0 になる前に Hi-Z に戻る。入力の波形はのこぎり波(に近い三角波)。シュミットトリガ入力 でないと 波高が 0 だから使えない。

      RC発振器(2)



      むしろオープンドレイン出力を使わないこっちのが普通?

      こっちの原理は、入力 L のときは、 充電で H になると反転して 放電。入力の波形は三角波。こっちも、シュミットトリガ入力必須。

      出力強度を変えたり、 HYSTERESIS : SMALL にすると周波数が変わるはず。

      いずれにしてもあまり高い周波数向けではないような.. それに定数が分からない。

    ところで、 PL9A は、PCLKT3_0 というクロック入力用 ピンが割り当てられている。こういったピンは、他にもあって 1200 の LQFP144 は、

    PT12B_PCLKT0_1 128
    PR5C_PCLKT1_0 92
    PB9A_PCLKT2_0 49
    PB11A_PCLKT2_1 55
    PL9A_PCLKT3_0 27
    PL5A_PCLKT3_1 19
    PL3A_PCLKT3_2 5

    という割り当てになっている。

    これらのピンは、外部回路と同期を取るのに重要そうだが、PLL にクロックを供給するだけなら、これを使う必要はないはず。たまたま DCMA を使ってみたが、DCMA は、PLL にクロックを供給できる。DCMA の入力は、general routing が使えるみたいだから、要はなんでも良いみたいだ。

    RC発振器は、単なるインバータで良かったはず。そういえば、フランクリン発振器もそう。

四相クロックについて

    普通 四相クロック が欲しいなら PLL で良いわけだが、内蔵オシレータをクロック元にすると PLLのロックが外れることが頻繁に起きる。通信でこういうことが起きると少々具合がわるい。分周して 四相クロックを作る方法も 検討しておこう。


      reg [3:0] r_clk_0 = 4'b0110;
      reg [3:0] r_clk_90 = 4'b0011;
      reg [3:0] r_clk_180 = 4'b1001;
      reg [3:0] r_clk_270 = 4'b1100;

      always @(posedge CLK_IN0) // CLK4X
      begin
      r_clk_0 <= { r_clk_0[2:0] , r_clk_0[3] };
      r_clk_90 <= { r_clk_90[2:0] , r_clk_90[3] };
      r_clk_180 <= { r_clk_180[2:0] , r_clk_180[3] };
      r_clk_270 <= { r_clk_270[2:0] , r_clk_270[3] };
      end

      wire CLK0_OUT = r_clk_0[3];
      wire CLK90_OUT = r_clk_90[3];
      wire CLK180_OUT = r_clk_180[3];
      wire CLK270_OUT = r_clk_270[3];

    Xilinx だとこんなコードが良さそう。SRL16 を使っていることになるから 4LUT しか消費しないんじゃないかと思う。

    だが、Lattice では、SRL16 相当の機能はないようだ。MachXO2 では、カウンタとか 比較機能を持っているから素直なロジックのコードが良いのかも知れない。

      reg [1:0] r_clk_cnt = 2'b00;
      reg [3:0] r_clk_out = 4'b1100;

      always @(posedge CLK_IN0) // CLK4X
      begin
      r_clk_cnt <= r_clk_cnt + 1;
      r_clk_out[0] <= (r_clk_cnt == 0) | (r_clk_cnt == 1);
      r_clk_out[1] <= (r_clk_cnt == 1) | (r_clk_cnt == 2);
      r_clk_out[2] <= (r_clk_cnt == 2) | (r_clk_cnt == 3);
      r_clk_out[3] <= (r_clk_cnt == 3) | (r_clk_cnt == 0);
      end
      wire CLK0_OUT = r_clk_out[0];
      wire CLK90_OUT = r_clk_out[1];
      wire CLK180_OUT = r_clk_out[2];
      wire CLK270_OUT = r_clk_out[3];

    あと POWER ON RESET 関係。すこし遅延させたい。


      reg [15:0] reset_sft = 16'h0000;
      always @(posedge CLK)
      begin
      reset_sft <= { reset_sft[15-1:0] , 1'b1 };
      end
      wire RESET = reset_sft[15];

    Xilinx だと 16bit まで 1 LUT だから、こんなのもアリだと思うのだが、他は具合がわるい。


      reg [3:0] reset_cnt;
      reg r_reset;
      always @(posedge CLK)
      begin
      if (reset_cnt == 4'b1111)
      r_reset <= 1'b1;
      else
      reset_cnt <= reset_cnt + 1;
      end
      wire RESET = r_reset;

    素直な コードだとこう?

    ところで、MachXO2 だと、シフトを使った コードはどちらも期待どおりにならない。初期値の設定がどうやっても出来ず、最終的に 定数 になるようだ。Synplify Pro も LSEも同じ。

    上記の reset_cnt のコードだと Synplify Pro は定数でないものを合成してくれる。が、LSE はダメ。


      reg [15:0] reset_sft = 16'h0000;
      reg r_reset = 1'b0;
      always @(negedge CLK_IN)
      begin
      if (r_reset != 1'b1)
      begin
      r_reset <= 1'b1;
      reset_sft <= 16'h0000;
      end
      else
      reset_sft <= { reset_sft[14:0] , 1'b1 };
      end
      assign RESET = reset_sft[15];

    このコードだと Synplify Pro は定数でないものを合成してくれる。が、LSE はダメ。
    r_reset を使わずに、( reset_sft != 16'hFFFF) なんて条件を使うと、Synplify Pro でもダメ。

    Warning をしっかり見ないと 期待どおりかどうか分からない。

    WARNING: Register r_reset_11 is stuck at One

    LSE だとこういうエラー に注意。

    ちなみに、こういうコードは、クロックや RESET 自体の生成にしか重要でないように気をつけてはいるのだが...

参考資料
posted by すz at 22:53| Comment(60) | TrackBack(0) | MachXO2

2012年02月07日

MachXO2 1200ZE Breakout ボード

2572円と安価に買える FPGA ボードについて。

    追記: 2012/10/8 なんと秋月で取り扱い開始! 2600 円也

    追記: 2013/4/26 LCMXO2-7000HE-B-EVN にグレードアップ。チップ置換であとは同じ。秋月では 3000 円。

     ユーザーズガイドの回路図すら直してない。VCCIO4,5 が VCCIO3 のままになってる。



簡単な説明

    FPGAは、Lattice 社の MachXO2 1200ZE 。価格は $29.99。発表は 2012/1月

    このボードには、FT2232H が載っていて、非常に安易に使える。USB に接続するだけだ。Lattice 社の合成ツール Diamond でもサポートしていて、ビルドしてから、2オペレーションで書き込みが可能。

      (1) Tools→Programmer を選ぶと ダイアログが出る。
      (2) (一回設定した後は) Download ボタンを押す。

    FPGA に接続されているデバイスは、JTAG と シリアル と LED x 8 。

      5mm x 7mm のオシレータのパターンもある。(スタンバイモードがある) ASYMB 24 MHz あたり を Breakout ボードと同時に買っておくのが良さそう。ただし、300 円ぐらいであまり安くないので、後でマルツで買うのも良いかも。
      ちなみに、回路図に載っているのは、CB3LV-3C の 50MHz。

    製品 URL : MachXO2 1200ZE Breakout Board Evaluation Kit Resources

MachXO 2280 Breakout ボード との違い

    MachXO 2280 Breakout ボード もまた、同価格で安価に入手できる。こちらの方が規模が大きく、使えるピンの数も多い。ただし、EBR RAM は、9kb がたったの 3 つ。MachXO2 1200ZE は、7 つあり プログラムに使えるメモリを 4KB は割り当てられる。

    MachXO2 1200ZE Breakout ボード の方は、FT2232H の機能を流用しやすくなっている。JTAGENB ピンが コネクタに出ているので、Disable すれば JTAG ボードとして流用可能。Serial ( BDBUS0-6) も ジャンパすれば FPGA で使える。

    ちょっと FPGA を試してみるとかといった使い方には向いていそうだ。

      追記:JTAG として使えないようにするには、config で JTAG_PORT を DISABLE に設定する。その場合 JTAGENB ピンが専用ピンになり、H レベルにすることで、JTAG が使えるようになる。

      要するに JTAG 関係のピンを全部 HI-Z にして、 JTAG_PORT を DISABLEにした config データを書き込めば、JTAG を外部回路用に引き出せる。JTAGENB ピンを H レベルにするスイッチを付けて ON にすれば再度JTAG を使用できる。

      (追記2)JTAG コネクタは、Lattice 用 8pin タイプ

      (1) (8)
        3V3 TDO TDI NC NC TMS GND TCK

      こうなっている。 デジタルデザインテクノロジー No.1(ISBN:9784789849401 : ググるとまだ売っている)の XP2 基板 に接続する場合は、(1) を 除いて 接続すれば良さそう。

      追記(注意): 1200ZE は、低消費電力向けチップで、スピードグレードは 、1 。HC あるいは HE が最大周波数 150 MHz のところ ZE は、60 MHz 。趣味の範囲できっちり守るべきかどうかは分からないが、あまり高速で動かすものではないのは確か。

      追記: BDBUS のシリアルを使うには、裏面の R14〜R21 をジャンパするか、そのパターンを使って引き出す。割り当ては、

      R14 BDBUS0 TXD
      R15 BDBUS1 RXD
      R16 BDBUS2 RTS
      R17 BDBUS3 CTS
      R18 BDBUS4 DTR
      R20 BDBUS5 DSR
      R21 BDBUS6 DCD


MachXO2 7000 が購入可能になっている。

    思いのほか安くて驚いた。TQ144 の LCMXO2-7000HE-4TG144C が 1239 円。4000 までは EBR SRAM が少なく面白くないのだが、これは 9kb の EBR SRAM が 26 個付いている。

      Spartan-6 LX9 も 1346 円と同じような価格。こちらは 18kb の ブロック RAM が 32 個。規模も大きいんだろう。そういえば MachXO2 は 乗算器もない。いままで 1200 しかなかったのが、7000 になって喜んでみたが、実は大したことはないのかも。

      ちなみに、MachXO2 1200 は、Spartan-3A 50 より規模が小さい。50A は、704 スライスだが、1200 は、640。50A のブロックRAM は、18kb x 3 で 1200 の 9kb x 7 と同じようなもの。
      MachXO2 7000 は、3442 で 400A の 3584 スライス と同じぐらい。400A のブロックRAM は、18kb x 16 なので、9kb x 26 の 7000 はちょっと少ない。

    TQ144 の 7000ZE とか 7000HE とかを MachXO2 1200ZE Breakout ボード のチップと入れ替えられると便利なような気がするのだが ...

    外すのは、SMD取り外しキット:1575円を使うとして ... さて。

    追記: BSDLファイルを比べてみたが、載せ替え自体は可能なようだ。

      4000/7000 2000 1200
      30 VCCIO3 VCCIO3 VCCIO3
      7 VCCIO4 VCCIO4 VCCIO3
      16 VCCIO5 VCCIO5 VCCIO3

      15 v NC NC
      17 v NC NC
      31 v NC NC
      63 v NC NC
      87 v v NC
      89 v v NC
      103 v NC NC
      129 NC NC NC

      電源,NC の違いは、こう。2000 以上はバンク 4,5 があるが、VCCIO3 が割り当てられている。あと、1200 は、NC が多いため、載せ替えると使えないピンが出てくる。ちなみに信号名の割り当ては違うが、ピン番号で指定するからあまり関係ない。機能のピンの割り当ては同じようだが未検証。JTAG や I2C は同じだったが、他は見てない。

      ところで、HC の BSDL ファイルしかないが、HE,ZE も信号線は同じなんだろう。HC はレギュレータ付きだが、HE,ZE との違いは良く分からない。(レギュレータ用のピンが見つからない。むしろ HE,ZE 用に見える。) まぁ 7000HE,7000ZE の載せ替えは可能そうだ。

      ついでなので、機能のピンの割り当てに付いても調べた。

      4000/7000 2000 1200

      5 PCLKT5_0 PCLKT4_0 PCLKT3_2
      6 PCLKC5_0 PCLKC5_0 PCLKC3_2
      19 PCLKT4_0 PCLKT4_0 PCLKT3_1
      20 PCLKC4_0 PCLKC4_0 PCLKC3_1

      104 R_GPLLC_IN
      105 R_GPLLT_IN
      106 R_GPLLC_FB
      107 R_GPLLT_FB
      111 R_GPLLC_MFGOUT2
      112 R_GPLLT_MFGOUT2

      2000 以上は、バンクの関係でクロック入力の名前が変わった。あと、4000/7000 は PLL が増えた。

      違いは、これだけ。これなら、ターゲットデバイスを変更するだけで 1200 用の コードもそのまま動く。

      追記: HC と HE/ZE の BSDL ファイル がリリースされていたので比較してみた。

      どうも電源ピンの定義は同じようだ。違いは ID 。

      device code 0x012B 2043 -- 1200ZE/HE
      device code 0x012B 3043 -- 2000ZE/HE
      device code 0x012B 4043 -- 4000ZE/HE
      device code 0x012B 5043 -- 7000ZE/HE

      device code 0x012B A043 -- 1200HC
      device code 0x012B B043 -- 2000HC
      device code 0x012B C043 -- 4000HC
      device code 0x012B D043 -- 7000HC

Lattice (MachXO2) がお気に入りの理由

  • 開発ツールが小さい

    小さいといっても Lattice Diamond は、1.7GB もあるのだが ... それでも Xilinx の ISE なんかと比べるとはるかに小さい。使い勝手も良いみたいだし、気に入っている。

  • Digikey で買える

    Digikey で買えないものは候補にならないのだが、幸い購入可能。電子工作レベルで使える TQFP 100 や 144 品の種類も豊富にあるのが良い。

    TQFP 100 だと、2000 まで 、144 では 7000 まで。

  • お手軽

    FLASH を内臓しているし、レギュレータや 内臓クロックもあるので、チップ単体で 動かすことも可能。

    開発ツールもあわせて、総じてお手軽に使えるというのが良い。

    ついでに書いておくと ライセンスキーは、Mac アドレスに対して発行される。この Mac アドレスは、USB Wifi ドングルのものでもよい。要するに インターネットカフェのようなところでも実行が可能なのだ。プログラムも小さめなので、インストール時間は短めで 実際に 利用可能。

      内蔵クロックは、133 MHz を 1 , 1.5 , 2, 2.5 ... 62 で分周した周波数を出力可能。64 通りの設定がある。精度は±5% だそうで、あまりあてにできないが、とりあえずは便利に使える。MachXO も 持っているのだが、周波数は設定できず 20MHz (18 MHz - 26 MHz) 。( MachXO2 で設定できる近い周波数は 19.00 Mhz ?)

        分周比は、1 〜 16 の範囲では、0.5 刻み。16 〜 32 は 1 刻み、32 〜 62 では 2 刻み。

      ちなみに Breakout ボードには、3.3v 5mmx7mm のオシレータも載せられるようになっている。PLL もあるので、周波数を変換することも出来る。

  • 残念な点

    残念な点としては、規模が小さいこと。ブロックメモリも少ない。自作コアだと 1200 でようやく載るレベル。

    内臓の ハードマクロ の I2C /SPI/ TIMER を生かせば、結構規模を節約できそうだが、専用設計になってしまうのでちょっと面白くない。

    ただ、TQFP 144 に限ると規模の大きいものの品種は限られる。Spartan-6 LX9 , Lattice XP2-8 , MachXO2 7000 ぐらいか。それ以下だと XP2-5 , Spartan-3E 250E , MachXO2 4000 。Spartan-6 LX9 使えば良いのだが、xilinx の ISE が嫌なら MachXO2 7000 とかも良いかなという感じ。

  • 参考 文献

自作コアと MachXO2

    以前 AVR互換COREを作成したのだが、MachXO2 でとりあえず 合成できるところまで確認して 凍結していた。

      AVR互換CORE といっても、互換なのは、米粒AVR の ATtiny10 系統。Mega や Tiny 互換ではなく、AT90S の AVR とも互換ではない。

    最後のバージョンは、rtavr-0.9.3.tar.gz

    README を読み返すと

    (4-A) クイックビルド 『WebPACK ISE』

    以下に 3 種類の 標準的な構成を示します。

    (1) rtavr を top-layer にした 最小構成

    configs/50A/rtavr_defs.v と configs/rtavr_common.v , soc/*.v
    および、tests/tbi_001/rom_data.mem を使い 『WebPACK ISE』を使用して
    Implement します。

    この構成は、USART および SPI を含み実用的なものでありながら、
    XC3S50A で Implement 可能なように しています。

    なお、USART , SPI については、レジスタの定数化により機能を縮小
    しています。 使用する機能に適合しない場合は、rtavr_defs.v を
    編集する必要があります。

    と書いてあるが、MachXO2 では、configs/1200HC/rtavr_defs.v を使用することで 一応合成できるようになっている。できるのは 50A と同等の機能なのだが、MachXO2 では、ROM_PSEUDO_DP が define されて DUALPORT の ROM を使わないようにしている。DUAL PORT を使うと ROM データの READ で 8bit の 別ポートを使うが、define すると 16bit の ROM からデータを読み込むようになり、規模が少し増える。

      こうした理由は、Diamond が DUALPORT ROM を推論してくれないため。最新版の 1.4.1 でも試したがだめだった。

    で、できたものは、ちょっとのデバッグで動くような気がしているが、試していない。

    デバッグするためのツールを作成している段階で放置していたのだった。MachXO2 1200ZE Breakout ボード を reference として使うことにして 作成を再開したい。

PORTの実装

    実は、PORT の 入出力の動的変更がうまく行っていない(かも)
    Lattice のリファレンスデザインを見ると

    inout sda_pin;
    wire scl_pin;
    assign sda_pin = sda ? 1'bz : 1'b0;

    こんな感じで記述されていた。データバスも近い記述で 1'bz の部分が出力データで可変になっている。

    現在のコードをこれに準じた記述に変更したほうがよいかも。ただし、プルアップ/プルダウンを 制御するのは無理そう。制御用の線を割り当てて 信号線と 抵抗でつなぐしかないか。

rtavr 更新

  • rtavr-0.9.4.tar.gz
  • rtavr_tools-0.5.tar.gz

    ここで書くべき内容ではないのだが、XO2 Breakout ボードに対応したものを作って更新した。

    ... といっても対応しただけで、内容的には進展なし。

    rtavr の方は、JTAG ポート経由でアクセスできる 2 つのポートがあるのだが、ここに ISP と SPI(SLAVE) を接続。あと USART の TXD/RXD を シリアルに接続。LED の D1/D2 に PORT を接続。

    これが動けば結構すごいと思うのだが、残念ながら規模を見るのが目的のもので、動作は期待できない。

    device utilization summary: XO2
    PIO (prelim) 14/108 12% used
    14/108 12% bonded
    SLICE 590/640 92% used
    OSC 1/1 100% used
    JTAG 1/1 100% used
    EBR 6/7 85% used

    規模的には、Spartan-3A 50A より少し余裕がある感じ。 synplify Pro を使っているのだが、Xilinx の標準ツールより効率が良い?

      上記は、Diamond 1.1 の結果。1.4 だと 612 SLICE (95%) を消費している。

      あと、

    ISP は、attiny10 系のものをベースに簡易化したもので、ROM の読み書きだけができる機能。(ツールは未対応)

    rtavr_tools の方は、JTAG 経由の通信が本当にできるかのテストなど。JEDEC ファイル の書き込みとかベリファイも仕込んであるが、未テスト。MachXO2 はちょっと複雑で 大分デバッグが必要そう。セキュリティ関係の機能もあるので不用意にテストすると 書き込めなくなる恐れがあり、デバッグも慎重にやる必要がある。

      progname : [rtavr_tool.exe]
      cbl_name = mpsse
      cbl_type = ft245r
      port = ft0
      bitclock = 115200.000
      baudrate = 115200
      ispdelay = 0
      rtavr_tool.exe: BitBang OK
      rtavr_tool.exe: drain OK
      open OK
      bitclock = 102400.000
      ft245r: bitclk 102400 -> ft baud 38400
      ft245r: bitclk 102400 -> ft baud 38400
      load_conf LCMXO2_1200
      -- device_type 12b2
      -- sucsess
      -- device_id 012b2043
      cmd> spi_test
      spi_test -- sel_chan test
      spi_test -- spi_echo test1
      30 00 (00)
      31 30 (18)
      32 31 (18)
      33 32 (19)
      34 33 (19)
      5535 3455 (1a2a)
      aa5536 35aa55 (1ad52a)
      37 36 (1b)
      38 37 (1b)
      39 38 (1c)
      ff 39 (1c)
      ff ff (7f)
      spi_test done
      cmd>

    spi_test で 入力データを echo back させるぐらいは出来ている。といっても、rtavr の SPI と同じコードではなく簡易なものでのテスト。すり合わせも出来ていないので、rtavr の方で動くことは期待できない。

    まぁ、いまのところはこんな感じ。

SVF ファイルについて

    忘却が激しいのでメモ。

    SVF ファイルとは、コンフィグする際のシーケンスが記述してあるもので、これを解析してツールの機能を作ろうとしている。

    論理合成して作成されるのは、JEDEC ファイルで、SVF ファイルを作成するには、ispVM を起動する。SVF アイコンで SVF ファイルに変換するのだが、さまざまなオプションがある。Flash に対して Erase/Write/Verify の組み合わせがあるし、background モードというのもある。

    それに加えて SRAM への直接 Write という機能もある。Flash を汚さないし便利そうな気がするのだが、JEDEC ファイル を bit ファイルに変換しないといけない。変換は UFW アイコンで行う。

      ちなみに、Flash のデータは圧縮されている。SRAM へ直接書きこむデータはたぶん圧縮されていない。伸張ロジックを知っていないと JEDEC ファイルを書き込むようには出来ない。

      あと、EBR RAM は SRAM に含まれているのかどうか? EBR RAM は Flash からのロードしかできないような気がするのだがどうなんだろう?

      ちなみに、MachXO や XP2 は、Flash 用と同じデータを SRAM に書き込める。

    注意) 上記は、Diamond 1.1 での話。1.4 を試してみると ... Diamond に ispVM は組み込まれなくなった。ispVM は別のソフトとしてインストールすることができる。Programmer を動かすと xcf ファイルが作成されるようなので、これを ispVM で Open すると上記のオペレーションが出来るようになるようだ。

Lattice Mico8 について

    Lattice だと Mico8 / Mico32 という 2 つの IP プロセッサがある。このうち 8bit の Mico8 は、結構 AVR に近い感じ。驚いたことに gcc も移植されている。

    Mico8 は、レジスタ数 32 のタイプと 16 のタイプがある。16 のタイプは MachXO2 で 262 LUT で組めるそうだ。(32 は 313)

      自作コアの RTAVR は レジスタ数 16 だが configs/core_test で core のみ生成すると 660 LUT 。(GPR_16 というシュリンクオプションなしだと 690)。結構頑張ったつもりなのだが...

      まぁ、Mico8 の方は パイプラインプロセッサでないし、命令も 18 bit 使っていたり、AVR のような 特殊な命令コードないしで、差が出るのは仕方がない。

    ところで、Mico8 のアドレス空間は 8bit しかない。16bit あるいはそれ以上の空間にアクセスするには、Page Pointer というのを使うそうだ。要するにバンク切り替え。

    プログラム空間は、12bit ある。18bit x 4K であり 8KB の AVR Tiny などと同じぐらい。ただし、プログラム空間のメモリをデータとして使うことはできない。

    実をいうと、自作AVRコアは、gcc が使え、FPGA メーカを選ばない (規模が小さい)8bit のプロセッサを目指した。Mico8 で gcc が使えるのを知っていたら、違うものを作っていたかも知れない。まぁ、FPGA メーカが作るコアは、自社のデバイスに最適化するから 他社のデバイスに移植するようなものではない。移植性が特徴として残っているから これで良かったとは思うのだが...

MachXO2 Breakout ボードのピン配置

    J4 J3
    (1)(2) (1)(2)
    3V3 VCCIO3 1V2 VCCIO1
    3V3 NC 1V2 NC
    PL2A 1 2 PL2B (TXD)PR10C 74 73 PR10D(RXD)
    PL2C 3 4 PL2D (CTS)PR10A 76 75 PR10B(RTS)
    PL3A 5 6 PL3B GND GND
    PL3C 9 10 PL3D (DCD)PR9C 78 77 PR9D(DSR)
    GND GND PR9A 82 81 PR9B(DTR)
    PL4A 11 12 PL4B GND GND
    PL4C 13 14 PL4D PR8C 84 83 PR8D
    GND GND PR8A 86 85 PR8B
    PL5A 19 20 PL5B GND GND
    PL5C 21 22 PL5D PR5C 92 91 PR5D
    GND GND PR5A 94 93 PR5B
    PL8A 23 24 PL8B GND GND
    PL8C 25 26 PL8D PR4C 96 95 PR4D
    GND GND (LED D2)PR4A 98 97 PR4B(LED D1)
    (EXTOSC)PL9A 27 28 PL9B GND GND
    GND GND (LED D4)PR3A 100 99 PR3B(LED D3)
    (EXTOSC_EN)PL10A 32 33 PL10B (LED D6)PR2C 105 104 PR2D(LED D5)
    PL10C 34 35 PL10D (LED D8)PR2A 107 106 PR2B(LED D7)

    内側の2 列分の信号配置。

    5cm x 5cm で基板を作れば 使えるかと思ったのだが、コネクタ間の間隔は 5cm を超えていた。あと、内部機能との重複が多い。重複を退けると 37 pin 。SRAM には十分だが、SDR SDRAM 16bit には少し足りない。(1200ZE では、全然高速に動かせないのでオーバースペック)

      追記: 37 pin では、4Mbit (16bit幅) の CY7C1041DV33(10ns) の駆動は無理だった。一応訂正。

      追記: シリアルのピンは、実際には接続されていない。抵抗パターンが 7 つ並んでいる所があるのだが、そこをジャンパする必要がある。


    J2 J5
    (1)(2) (1)(2)
    NC VCCIO0 NC VCCIO2
    PT17D/DONE 109 110 PT17C/INTn +-PB20D 71 69 PB20B-+
    PT17B 111 112 PT17A (R39) +-PB20C 70 68 PB20A-+ (R37)
    GND GND +-PB18D 67 62 PB18B-+
    PT16D 113 114 PT16C (R35) +-PB18C 65 61 PB18A-+ (R33)
    PT16B 115 117 PT15A GND GND
    PT15D/PROGn 119 120 PT15C/JTAGen +-PB15D 60 58 PB15B-+
    GND GND (R31) +-PB15C 59 57 PB15A-+ (R29)
    PT15B 121 122 PT15A GND GND
    (SDA)PT12D 125 126 PT12C(SCL) +-PB11B 56 54 PB11D-+
    PT12B 127 128 PT12A (R41) +-PB11A 55 52 PC11C-+ (R40)
    GND GND GND GND
    PT11D/TMS 130 131 PT11C/TCK +-PB9B 50 48 PB9D-+
    PT11B 132 133 PT11A (R38) +-PB9A 49 47 PB9C-+ (R36)
    PT10D/TDI 136 137 PT10C/TDO GND GND
    GND GND +-PB6D 45 43 PB6B-+
         PT10B 138 139 PT10A (R34) +-PB6C 44 42 PB6A-+ (R32)
    PT9D 140 141 PT9C GND GND
    PT9B 142 143 PT9A +-PB4D 41 39 PB4B-+
    GND GND (R30) +-PB4C 40 38 PB4A-+ (R28)

    外側の2列はこんな感じ。(SDA),(SCL) は、外部抵抗でプルアップされている。こちらは、JTAG 関係を除いて 48 pin 分。

      訂正: 一番右の J5 は、全て差動受信用に 100 Ωのターミネータを入れられる(抵抗は空きパターン)。あるいは、10kΩとか入れて動的プルアップに流用するとかも可能。といっても 小さいのでハンダ付けはなかなか厳しい。

    EXOSC , EXOSC_EN は、5mm x 7mm のオシレータのパターンにつながっている。スタンバイモードがある ASYMB 24 MHz とか CB3LV-3C が digikey で買えるので、Breakout ボードと同時に買っておくのが良さそう。ただし、300 円程する。

    PLL があるので、発振周波数は、割りとなんでも良い。PLL は、EHXPLLJ というのを使うのだが、基本的に

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40) x CLKOP_DIV(1-128:default 8)

    の周波数が VCO の周波数になるようだ。実際に合成して Warning を見ると、VCO 周波数は、400 〜 800 MHz の範囲でないといけないらしい。... が、多分間違いで、データシートを見ると 200 〜 800 MHz の範囲。CLKOP_DIV が 8 なら CLKOP の範囲は、 25MHz 〜 100 MHz ということに。

    CLKOP の出力は

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40)

    だが、CLKOS, CLKOS2, CLKOS3 は、

      f = CLKI/CLKI_DIV(1-40) x CLKFB_DIV(1-40) x CLKOP_DIV(1-128:default 8) / CLKOSn_DIV(1-128:default 8)

    になるみたい。ただし、あくまで基本で、もっと多彩な機能がある。

これで何をしたいのか?

    MachXO2 breakout ボードは、1200ZE で高速でもなく、規模も小さい。自作AVRコアのテストには便利だから、当面その目的で使うつもりなのだが、実用として考えたときにこれで何が出来るのだろう?

    だいたい 100 pin の 1200 は、1 個 630 円ぐらい。( 256 まで規模を落とすと 365 円 まで下がる。) 随分安くなったものだが、AVR と比べると大分高い。32 bit の Coretex-M0 や PIC32 などと比べると価格差が大分小さくなるが、今度は実現できる機能差が大きい。

    ついでに書いておくと 100 pin だと 2000 がある。こちらは少しだけ高くなって 875 円。あと、144 pin だと単価が上がる。1200 で 751 円、2000 で 991 円。

    さて、こういう条件なのだが ...

  • とりあえず、MachXO2 Breakout ボードを使う方向で考えてみる。安く手に入るし、USB インターフェイスが付いているので、ソフトをなんとかすれば、HOST との通信ができる。シリアルだと最大 12Mbaud までだが、MPSSE だと 30Mbps (3.75 MB/sec)。接続されている範囲では、これが最高速度。(実は Fast Serial の方が速くできるかも知れないのだが、あまり使われているようには思えないし、とりあえず無視)

  • 開発専用だと、作ったモジュールの単体テストとかには便利そう。そういえば、FPGA 同士で通信するモジュールを作りたかったのだった。この場合 いったん外に出して外側で接続すれば、単体テストはできそう。

  • 秋月の480x272 LCD とかのインターフェイス。PC から垂れ流した データをそのまま表示してもなんとか見えそう。ただ帯域が少々足りない。キャラクタディスプレーとかだと内蔵 RAM でもいけるから、端末にするのも一興か。

  • ロジアナも工夫次第。圧縮して 内蔵 RAM をバッファにするとかすれば、測定対象次第で結構取り込めるかも。外付け RAM を付ければ良いのだが、ZE で遅いので 苦労しがいがない。内蔵だけで工夫するのが楽しそう。

  • チップ単体で使うにしても HOST との通信はクリアしておきたい。USB だと SPI で扱える MAX3421E とか SL811HSTが有名だが、1000 円ぐらいする。これなら USB が付いた MCU の方が安いと思える価格。作れるものなのかどうか分からないが、複数チャネルが扱える (12Mbps)USB コントローラなんてのが作れると良さそうな気がする。

Mouser で、WLCS-25 (1200ZE) が 出ている

    在庫 0 だが、1個単位で買える。20 個なら単価 400 円。これを使えば 24 pin DIP (とか)の モジュールを作れそう。最も、基板をなんとか出来たときの話。25 pin とは言え 0.4mm ピッチの BGA だから 趣味のレベルでは難しい。BSDLファイルを見ると、JTAG 4 , GND 2 , VCC 2, VCCIO0,VCCIO2 の 10 pin を除く 15 pin が 入出力に使える。JTAGENB もあるし、config 用の PROGRAMN/INITN/DONE もあるから 正確ではない。あと I2C,SPI のハードマクロの PIN も 。

    1.2V レギュレータ 載せた上で 24 pin ナロー DIP のモジュールとか、誰か作らないかなぁ ... と思ってみたり。


    こんなの(8ビット双方向ロジックレベル変換モジュール)があると 嬉しいような ...

      1 2 3 4 5
      A PT17C/INITN PT15D/PROGRAMN PT12D/SDA TCK TDO
      B PT17D/DONE PT15C/JTAGENB PT12C/SC TMS VCC
      C PT16A VCCIO0 GND VCCIO2 TDI
      D VCC PT12A/PCLKT0_1 GND PB6D/SPISO PB6C/MCLK
      E PB20D/SISPI PB20C PB11A/PCLKT2_1 PB9A/PCLKT2_0 PB4C

      とりあえず、ピン配置を作ってみた。(行と列は逆かも) 。外側の 16 ピンだけで なんとかならないかと思ったが無理。やっぱり 4 層基板 + 極小スルーホールでないと。

    ところで、これの最高周波数は 133 MHz になっている。最も遅いのは、1200ZE 100pin C の 104 MHz 。あと スピードクラス 4 の I は、550 MHz 。60 MHz/150 MHz というのは、実用回路の目安?

    追記: Aliexpress の基板作成サービス

      Aliexpress にも 基板作成サービスをしているところがある。

      Loision's PCB factory だと、4 層基板のサービスがある。Min. Hole Size: 0.2mm, Min. Line Width: 4MIL だそうで、 WLCS-25 のモジュール基板を作成できるかも知れない。
      基板さえ作ることが出来れば、ホットプレート・リフローとかの方法でハンダ付けは可能そう。

      ITeadStudio でも 4層基板 を扱っている。5cm x 5cm (10pcs) で $65 。2層 $9.9 なのと比べると大違いだが これでも安いのかも。ただ、ここだと Hole の最小サイズは 0.3mm で 0.4mm ピッチの BGA のパターンは無理。

Synplify Pro と LSE

    論理合成エンジンに Synplify Pro と LSE が選べる。デフォルトは、Synplify Pro だからそのまま使えば良さそうなのだが、ちょっと 気持ちが悪い Warning がある。

      Initial statement will only initialize memories through the usage of $readmemh and $readmemb. Everything else is ignored

    というもので、どうも initail 文は、$readmemh とかを使わないケースでは意味がないらしい。では、初期値は 0 固定なのか? ... というと良く分からない。まぁ、rtavr 本体は、GPR(汎用レジスタ) と RAM データの初期化にしか使っていないので良いのだが、isp.v の状態変数は、initial 文を使っている。初期値は 0 に統一しているので 0 固定なら問題ないのだが、気になる。

    LSE を使ってみると、そういう Warning は出ない。ただ、同じものを合成しても Synplify Pro は、612/640 スライスだったのが、LSE では、617/640 スライスとちょっと増える。Diamond 1.1 を使っていたときは、Synplify Pro は 590/640 スライスで、LSE はさらに規模が小さかった。増えるのはバグ修正が理由だとすれば、Diamond 1.1 は、結構バグがあったのかも。

    ただ、それでも XilinX の Spartan-3A より効率が良く、704 スライスの 50A より回路が入るようだ。

      Number of ripple logic: 81 (162 LUT4s)

    ひょっとすると、リップルモードの言うのが肝なのかも。LUT4 の代わりに、2bit カウンタとか 2bit 加算回路、乗算回路として使えるようになっている。

    GPR_16 というシュリンクオプションなしで合成すると 規模が 30 ほど増えるはず(24 スライス分 分散 RAM に 余計に使用する)なのだが、ためしにやってみたら Synplify Pro で 623/640 , LSE で 639/640 と なんとか収めて来た。ひょっとしたら余分な LUT が最適化(遅延低減)のために使われるのかも知れない。

MachXO2 Breakout ボードと 秋月 C 基板

    MachXO2 Breakout ボードと 秋月 C 基板を現物合わせしてみたところ、長辺 を横にして、外側の 1 列づつ まで覆えた。ただし、短辺のスルーホールは 17穴なので、20x2 コネクタ全部は使えない。 あと、外側だとギリギリなので、13 穴しかない。

    3V3 電源 は、上にしか出ていないので、1 番 PIN まで上に寄せて 装着することになりそう。そうすると使えないピンが出てきて面白くない。ここは、B 基板を使うのが良いのかも知れない。

    あと両脇について。両脇は C 基板がかぶさるので、上方向にピン/フレームを出すのはどうかと思う。横方向外側に出した方が良さそう。

    内側 の方は、フレームで良さそう。ちなみに、2 列のフレームを使っても全部のピンを接続する必要はない。80ピン 全部 接続する と外すのに随分力がいる。適当に間引いた方が良いと思う。

rtavr 更新

  • rtavr-0.9.5.tar.gz
  • rtavr_tools-0.6.tar.gz

    PLL を組み込んで 四相クロック化。rtavr_tools の方も PLL を組み込んだテスト回路にした。

    四相クロック化をすると何故か随分と規模が減った。Synplify Pro で 623/640 だったのが、 572/640 まで減った。これは、GPR_16 というシュリンクオプションなし。

    LSE でも 639/640 だったのが、607/640 に。

    以前は、2 倍クロック + ロジックで生成した 標準クロック。それを元にして、さらにタイミングを作っている。それ以外に シフトレジスタ x 4 を使った擬似四相クロック のモードもある。

    たぶん 四相クロック が一番すなおで、実際のクロックラインが少ないんだろう。... ということで納得しておこう。

追記 dealextreame の基板
posted by すz at 17:54| Comment(71) | TrackBack(0) | MachXO2

2011年06月29日

MachXO 2280 Breakout ボード

デジキーで 2700円 と安価に購入できる FPGA ボード について。



簡単な説明

    FPGAは、Lattice 社の MachXO 2280 。-- MachXO2 が出ているから、最新のチップというわけではない。といっても 発表は最近で 2011/4 。価格は $29.9 ということになっている。

    このボードには、FT2232H が載っていて、非常に安易に使える。USB に接続するだけだ。Lattice 社の合成ツール Diamond (最新は v1.2)でもサポートしていて、ビルドしてから、2オペレーションで書き込みが可能。

      (1) Tools→Programmer を選ぶと ダイアログが出る。
      (2) (一回設定した後は) Download ボタンを押す。

    FPGA に接続されているデバイスは、(JTAG 以外には) LED x 8 のみ。

規模は小さめで、特にブロック RAM が少ないのが苦しいが、気軽に使えるのが気に入ったので、rtavr の最初のリファレンスボードとして使うことにした。

こうなるとは、当初は思ってもみなかった。

合成ツールは Diamond を使用している。Xilinx から入ったのだが、使いやすい印象。メジャーどころの Altera や より 合成ツールの サイズが小さい -- それでも大きいが -- というのは、試用するの場合の利点。

    rtavr を動かす本命は依然として 自作の Artemis ボードのつもり。だが、Artemis ボードを使う前にツールの開発が必要なのだ。ツールの開発を 『MachXO 2280 Breakout ボード』をつかってやることにした。そして、ツールが動けば勢いで rtavr も 先にテストしてしまうだろう。

  • 自作ボードでしか rtavr を動かせないというのでは、都合が悪い。完成しても誰も試そうとはしないかも知れない。またバグが報告されても、共通のボードでないと確認できないかも知れない。そういう意味でリファレンスボードはあった方が良いのだ。

  • ツールでは、FT2232H を Bitbang モードで使う。こうすることで Artimis ボード の AE-UM232R とコードを共通化することができる。(ちなみに ツールは開発中だが、JTAG が使える所までは出来ている。)

  • 『MachXO2 Pico dev kit』(LCMXO2-1200ZE-P-EVN) も デジキーで買えるようになった。... が、4787 円と思ったより高い。このボードに興味がないわけではないが、今は組み込まれているデバイスを動かすような ことの優先度は低いし、リファレンスボードとしては使わないことにした。


入手先や資料について


コネクタの アサイン図:

MachXO 2280 Breakout Board Evaluation Kit(LCMXO2280C-B-EVN)

          TOP View

J10 J6 J5
(1) (2) (1) (2) (1) (2)
PB9B(P8 ) PB2A(P2) Lattice VCCIO GND PT2C(B2) PT9A(D8)
PB9A(P7 ) PB2B(P3) VCCIO GND PT2D(B3) PT9B(E8)
PB10E(N8 ) PB2C(N5) VCCIO GND PT3A(A2) PT9C(E9)
PB10C(P9 ) PB2D(N6) VCCIO GND PT3B(A3) PT10A(A10)
PB10D(P10) PB3A(T2) VCCIO GND PT3C(D3) PT10C(C9)
PB10A(M10) PB3B(T3) VCCIO GND PT3D(D4) PT10D(C10)
PB11C(R9 ) PB3C(R4) VCCIO GND PT4A(C4) PT10E(D9)
PB11D(R10) PB3D(R5) VCCIO GND PT4B(C5) PT10F(D10)
PB12A(T10) PB4A(P5) -- -- PT5A(D6) PT11A(B9)
PB12B(T11) PB4B(P6) -- -- PT5B(D5) PT11B(B10)
PB12C(N10) PB4C(T5) -- PT15A(E10) PT5C(B4) PT12A(A11)
PB12D(N11) PB4D(T4) -- PT15B(E11) PT5D(B5) PT12B(A12)
PB13A(R11) PB5A(R6) -- PT15C(B13) PT6E(E7) PT12C(B11)
PB13B(R12) PB5B(T6) -- PT15D(C13) PT6F(E6) PT12D(B12)
PB13C(P11) PB6A(T8) PT7C(A6) PT16A(B14) PT6C(A5) PT13C(C11)
PB13D(P12) PB6B(T7) PT7D(A7) PT16B(C14) PT6D(A4) PT13D(C12)
PB14A(T13) PB7C(M7) PT8C(B8) PT16C(A15) PT6A(C6) PT14A(A13)
PB14B(T12) PB7D(M8) PT8D(C8) PT16D(B15) PT6B(C7) PT14B(A14)
PB14C(R13) PB8C(R7) FTDI -- GND PT7A(B6) PT14C(D11)
-- PB8D(R8) Chip -- GND PT7B(B7) PT14D(D12)
(39) (40) (39) (40) (39) (40)
  (LED)
[D5] [D1]
PB15D(P14) PB16D(P16)
[D6] [D2]
PB15B(T15) PB16C(P15)
[D7] [D3]
PB15A(T14) PB16B(R16)
[D8] [D4]
PB14D(R14) PB16A(R15)

TP0 - TP10 : VCC10 (3V3)

J1 -- JTAG J9

(1) 3V3 (25) PD14D(R14) [D8]
(2) NC (27) PB15A(T14) [D7]
(3) NC (29) PB15B(T15) [D6]
(4) TCK --- R3 --- FT2232H ADBUS0 (31) PB15D(P14) [D5]
(5) TDI --- R4 --- FT2232H ADBUS1 (33) PB16A(R15) [D4]
(6) TDO --- R7 --- FT2232H ADBUS2 (35) PB16B(R16) [D3]
(7) TMS --- R9 --- FT2232H ADBUS3 (37) PB16C(P15) [D2]
(8) GND (39) PB16D(P16) [D1]

(R3,R4,R7,R9 = 70 ohm)


    20x2 の コネクタが 8 つ付けられるが、普通の使用方法で それを全部使うのはあまり考えられない。そこで、写真右サイドの 4 列(J6,J5)と 左サイド中央側の 2 列(J10)を 普段は使うようにしようと思う。そう考えて ピンアサイン図を作成した。

  • Lattice Diamond でのピンのアサインには、() 内の ピン番号を使用する。

  • 2x20 ピンソケット(低メス) を J10, J6,J5 に付けようと思う。

  • 実験用には、 C基板(旧: FR-4) を使うつもり。必要な信号の分だけ ピンヘッダを下向きに付ける。
    (注意) ピンヘッダを付け過ぎると 抜き差しが非常に難しくなるので注意

  • C基板(新: CEM-3) は穴が少ないので、横向き にしか付けられない。C基板(旧) だと 縦向きも可能。

  • J9 で基板をカットすると JTAG ケーブル として使えるかも知れないので、できるだけ J9 は使わないようにしようと思う。-- ちなみにカットしてしまうと、FPGA は再config できなくなる。FPGA を壊してしまったり、二度と使うつもりがない場合にしか カットするつもりはない。

  • ちなみに 上下のコネクタは、GND が多く 3V3電源 がない。信号線を引き出すような目的に合うと思う。実際に使う予定は今のところないが、拡張ボードを 作って 直付しようかと目論んではいる。

  • LED の信号は J9 (25) - (39) にも出ている。(位置は、左サイド 最外側の 下 8 pin)
    基板をカット する場合は、J9 の右側が良さそう。
    ここに ロジアナを接続すれば、波形を見ることが出来る。目測できないような信号でも LED に出力する意味はありそう。

      ロジアナで使うようにするには、JTAG の 8pin と LED の 8pin に 1列の ピンヘッダを付けるのが良さそう。


    いろいろ書いたのだが、とりあえずやりたいのは、水晶発振の実験ぐらい。
    デバッグのためになんらかの デバイスを付けるつもりはない。ツールでの通信が可能になれば不要になるはずなのだ。

    ちなみに、ツールでの通信は、まだうまく行っていない。そのデバッグのために ロジアナは必要になるかも知れない。

制約ファイル(.lpf)


      BLOCK RESETPATHS ;
      BLOCK ASYNCPATHS ;
      LOCATE COMP "LED_7" SITE "R14" ;
      LOCATE COMP "LED_6" SITE "T14" ;
      LOCATE COMP "LED_5" SITE "T15" ;
      LOCATE COMP "LED_4" SITE "P14" ;
      LOCATE COMP "LED_3" SITE "R15" ;
      LOCATE COMP "LED_2" SITE "R16" ;
      LOCATE COMP "LED_1" SITE "P15" ;
      LOCATE COMP "LED_0" SITE "P16" ;
      USERCODE ASCII "RT01" ;
      IOBUF PORT "LED_7" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_6" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_5" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_4" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_3" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_2" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_1" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;
      IOBUF PORT "LED_0" IO_TYPE=LVCMOS25 SLEWRATE=SLOW PULLMODE=NONE DRIVE=12 ;

    制約ファイル(.lpf)は、ピンの番号を書くらしい。PB16D とかではない。

    LED をドライブするだけなので、他の設定は適当。

      SLEWRATE は FAST と SLOW があり FAST がデフォルト。意味なく FAST にすることはないと思ったので、SLOW に変更。
      PULLMODE には、UP/DOWN/KEEPER がある。LED は L で点灯するだけなので、NONE にしておいた。
      LVCMOS25 と LVCMOS33 との違いが実際にあるのかどうかは、良く知らない。DRIVE 電流の値は、いくつかあるが、自由に選べるわけではないらしい。LVCMOS25 では 12mA が選択できたので、そのままにしてある。


rtavr_tools-0.1.tar.gz

    開発中のツール。test_hdl ディレクトリに テスト用の HDL コードを置いてある。これを書き込んで、src の basic_test をビルドして動かすと、テスト用の HDL コードと SPI で通信する。

      通信もちゃんと動いているわけではない。9 bit 送ると 8bit 受け取れるという変な状況。

      ... どうも FPGA 側で JTDI が ラッチされているような感じ。そういうものならば、8bit とか 16bit とか最低単位を書いたらいったん Shift-DR を抜けて入りなおすような、処理に統一した方が良さそうだ。いったん抜ければ CS がトグルされ bit 位置が リセットされる。

      rtavr の slave-SPI を使うような場合、2 バイト分を送りこむと AVR 側が間に合わないのでどうしようかと思っていたが、1 バイト書いたら CS トグルなら 余裕ができて好都合。

    作成中のコードは沢山あって、これから組み上げていく予定。

      ほとんどのコードはテストできていないが、

    • .bit(Xilinx) .mcs(Xilinx) , .jed(Lattice) , .mem(Verilog) のファイルの読み込み(パーザは いいかげん)
    • Lattice XO の Config, Xilinx の Config (作っただけ)
    • FT245R/232R BitBang Cable ドライバ(結構動いている)、serjtag Cable ドライバ(作っただけ)

      などが含まれている。

    一応かつて 雑誌の付録になったものはサポート可能にしたい。-- 結構持っているし。ただ Altera は 自分の NotePC に 合成ツールが入れられないし、チップ単体で買えない or 買いづらいのでパス。

    XP2 も チップが買えるし、サポートしたい。(DDT付録 はもっていないけど)

    ただ、無制限にチップをサポートするつもりはない。基本は、自分が使う予定があるもののみ。

MachXO 2280 について

    実は細かいことは知らないのだ。
  • Config 用 FLASH 内蔵
  • 4LUT x 2280 の規模
  • ブロックRAM は 8kbit x 3
  • 内蔵発信器と 2 つの PLL 。

    これぐらい。ブロックRAMの容量が少ないので、チップ自体には興味がない。ボードが入門用に最適だったので選んだだけ。

    Config のしかたは、SVF ファイルを読んでだいぶ理解した。XP2 とおなじようなやり方(違いはある) 。一方 MachXO2 の Config のしかたは、だいぶ違う。あと、FLASH と RAM でデータ形式が違う。.. ちょっと ツールで対応するのは面倒。

    MachXO2 には興味があるが、-1200 は 、規模が小さくブロックRAMの容量も少ない。いま Lattice の チップを買うとすれば(実際は買わないが) LFXP2-5E/8E が良さそうな感じ。

MachXO 2280 Breakout ボードの利用案

    JTAG を通して PC と通信できれば、結構応用範囲が広がる。BitBang では、最大でも 3.7Mbps 程度の帯域にしかならないが、MPSSE を使って通信すれば、24Mbps (3MB/sec の 同時入出力) が可能だ。4pin しか接続されていないから、FT2232H の他の機能は使えないのが残念ではあるが、この程度までなら、お手軽に使える。

    USB なので、うまくバッファリングしてやらないと 途切れなく データを送受信するのは難しいかも知れないが、ブロックRAM もバッファに使うなどしてやれば、サウンドデータを送受信することも可能かも知れない。

    あと、いろんなデバイスとの通信テストとか。ピンが沢山あるから、付ける一方にして、外さないという使い方が可能。PC で制御プログラムを作って確認後、ターゲットのマイコンに移植するやりかたもできる。

    月並みだが、ロジアナ系。低速で良いなら メモリとかなしで作れるだろう。その場合 PC のディスクに全部ログするような使い方もできる。FT2232H を生で使っても似たようなことはできそうだが、FPGA で作るメリットは柔軟性。高速だが 2bit のみとか、低速だが100bit みたいなことができる。

    メモリを付けてまで作るようなことは考えない。手間を考えれば メモリ付きのFPGA ボードにしたほうがお手軽そうだ。

    あと、いろんなライタに仕立てるのは可能。 通信ができる以上、工夫次第で JTAG すら可能だろう。

rtavr_tools-0.2.tar.gz


    spi_test -- spi_echo test1
    30 ff (7f)
    31 30 (18)
    32 31 (18)
    33 32 (19)
    34 33 (19)
    5535 3455 (1a2a)
    aa5536 35aa55 (1ad52a)
    37 36 (1b)
    38 37 (1b)
    39 38 (1c)
    ff 39 (1c)
    ff ff (7f)
    spi_test done

    ようやく通信できた。左から PC の出力データ (MSB first) 、PC への入力データ。() は参考用で 1bit 右シフトした値。8 bit のシフトレジスタがあるだけなので、1 バイト分後で出力されている。

    ググって見付けた 『よくわかるバウンダリスキャン試験解説講座』を読んで TCK の立ち上がりで シフトすることを理解した。SPI とは極性が逆だ。

    test_hdl も直してようやく動いた。

    これで JTAG の API も FIX 。

    void jtag_go(CABLE cbl,int state);
    void jtag_init(CABLE cbl);
    void jtag_reset(CABLE cbl);
    void jtag_IDLE(CABLE cbl, int ms, int count);
    void jtag_SIR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;
    void jtag_SDR(CABLE cbl, uint8_t *buf, int bit_len, int flags, uint8_t *rcv_buf)
    ;

    void jtag_SIR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv_
    data);
    void jtag_SDR32R(CABLE cbl, uint32_t code, int bit_len, int flags, uint32_t *rcv
    _data);

    32bit までなら コードが書きやすく分かりやすいように tag_SDR32 などを作っている。jtag_SDR32R は、SPI 通信用で MSB first 。

    flags は、1 : 受信も行う。2: 状態を移行しない。(最後の TMS==0)。

    いまのところ、API 間で非同期にI/O はしていない。受信をしない jtag_SDR を連続で call するような場合しか有効でないが、jtag_SDR を 1 つにまとめたほうが最適化になる。要するに非同期してわずかに高速化してもあまり意味はない。

    そういえば、

    int (* get_tdo_bits)(CABLE cbl, int bit_len, int tdi, uint8_t *rcv_buf);

    なんて (CABLE の) API を作ったのだが、使っていない。これは不要だった。(削除予定)
posted by すz at 21:52| Comment(0) | TrackBack(0) | MachXO2

2011年05月14日

MachXO2 Pico Dev Kit

Lattice 社の FPGA MachXO2 が気になって、Mouser を覗いたら 『MachXO2 Pico Dev Kit』(LCMXO2-1200ZE-P-EVN) が見つかった。値段は、\3,836.9 で、メーカから直接送られてくるそうだ。(英語のページでは、$29 となっていたから送料込みの値段?)

  • MachXO2 Pico Development Kit』 - Lattice社 英語ページ
  • MachXO2開発キット』 - Lattice社 日本語ページ

    追記: 11/19 現在 DigiKey で 2450 円だが 製造中止で 在庫 29
    モデルチェンジしたようで、後継は、LCMXO2-1200ZE-P1-EVN 。


  • ピコ開発キット

    コンスーマ機器のデザインのための、バッテリー駆動の低コスト開発プラットホーム
    - MachXO2 LCMXO2-1200ZE
    - 4キャラクタの16セグメントLCDディスプレイ (誤り:後述)
    - 容量性のタッチセンサ・ボタンが4つ
    - 1 Mbit SPIフラッシュメモリ
    - I2C温度センサ
    - MachXO2デバイスでデルタシグマADコンバータによって電源を測定
    - JTAG、SPI、およびI2C用の拡張ヘッダ

  • デジキーだと、4787円。(2011/06/28 現在 在庫 48)

    どうも正価は、$45 らしい。$29 というのはキャンペーン価格で、7月末までな上、高額な送料がかかるようだ。

まるで、AVR の評価ボードのようなデバイスが付いていて、バッテリー駆動なんてキーワードまである。



    写真は、『User's Guide』 からの抜粋。現物を 入手したが、この写真の REV.E が正しいものだった。大きさは 63mm 角(ぐらい)。

    『QuickSTART Guide』の写真 や 日本語ページの写真とは違うので注意。

    上記の説明には書いてないが、USB mini-B コネクタ が付いている。 コントローラは、FT2232H(Hi-Speed) 。ケーブルも付属しているので、これだけ買えば使えるもののようだ。

      接続は、Config 用に ADBUS 5 pin と User 用に BDBUS 8 pin 。Config 用は、ADBUS7 で I2C と JTAG を切り替えるようになっている。JTAGは、0 から順に TCK/TDI/TDO/TMS 。I2C は 0:SCL 1,2: SDA 。切り替えに使っているセレクタは、STG3693 。あと、EEPROMは、M93C46 。

    • AN8082: USB Programming and Circuit Guide』というドキュメントがある。これと Pico Dev Kit の FT2232H 周りは、ほぼ同じ回路 。

      気がついた細かい違い: (1) AN8082 では USB D+/D- に RC (27Ω/33pF) が入っている。Pico Dev Kit は直結。(2) AN8082 では 水晶に 1MΩと 1KΩが入っている。Pico Dev Kit はなし。

    • "4キャラクタの16セグメントLCDディスプレイ" の記述だが、7セグ に : 付きのような?
      少なくとも回路図を見る限り、[1-4]A-G , DP[1-3] , COL になっている。

      液晶モジュールにはコントローラはない。LC フィルタを介して 直接ドライブしている。
      LC フィルタは、5.49K + 0.1uF の LPF (cutoff 0.3 kHz) 。-- 好きな波形を PWM で出力できるから 全然問題ないわけか。

      ちなみに 型番は、LCD-S401M16KR 。Lumix (http://www.lumex.com) 社の製品だが、デジキーにあるのは だいぶ違いそうな LCD-S401C

    LCMXO2-1200 は、LUT 数 1280 。ブロックメモリ 9Kb x 7 , 分散メモリもあって 10Kb 。Spartan-3A 50A ぐらいの規模?
    ハードマクロ化したI2C、SPI、タイマ/カウンタがあるから、うまく使えれば 規模を減らせる。

いずれ.. なんて言っていたがこれは欲しいような...

    もちろん、AVR互換コアを載せるのが目的。

    -- ただ、デルタシグマADコンバータなんて書いてある。ADC も作らないと。..確か差動入力さえあれば 、HOLD 用のコンデンサぐらいでつくれたような。

ディスクの空き容量が厳しいし、ARTEMIS ボードが先だがら、やはり『いずれ』なのだが .. ADC は検討しておきたい。

しかし、こういうものが、FPGA で低価格で作れるようになってくるとは。バッテリー駆動なんてのも驚きだ。

追記:
デルタシグマメモ:

  • ΔΣ変調の部屋

  • AN283: シグマ・デルタ ADC/DAC の原理 (pdf)』 - アナログ・デバイセス社の アプリケーション・ノート

  • 簡易シグマデルタ ADC』 - Lattice 社のリファレンス・デザイン



    login すれば、ソースコードと ドキュメントをダウンロードできるようだ。
     - 差動LVDS入力 + RC だけ
     - 54 LUT と書いてある。



    コンパレータは 作動入力で代用して、R 2 つと C で良いのか...
    で、ADIN と足して Vref になるようにするわけか。
    Vref といっても PWM_OUT は 0 - VCCIO だから 1/2 VCCIO になるようにしないといけない。あとは、VCCIO が 安定していないとだいなし。

  • XAPP211: PN Generators using the SRL Macro』 - Xikinx 社: シフトレジスタを使った擬似乱数


      PN ジェネレータ というのは、シフトレジスタ を作って作る。N bit の 結果を得るのに N クロック必要になるわけだが、この条件なら、SRL16 が使われ LUT が少なく済む。

      また、N bit の 結果を得るのに N クロックかけて良いとなると、(LSB first の)bit-stream どうしの演算をベースにできる。

      加算なら 1 bit の FULL-ADDR と ラッチ1 つで 済む。
      積和でも 加算 x N と 遅延用の ラッチ N^2 / 2 があれば良い。そして遅延専用なら やはり SRL16 が使える。

      なかなか設計が楽しそうだ。

チップ単体の価格 (2011/05/27)

リードタイムは 10週間とかだが、Muoser で検索できるようになっていた。

    LCMXO2-1200を検索


    @1個 @25個
    LCMXO2-1200HC-4TG100CR1 695 618
    LCMXO2-1200HC-5TG100CR1 763 679
    LCMXO2-1200HC-6TG100CR1 839 748

    LCMXO2-1200ZE-1TG100CR1 694 618
    LCMXO2-1200ZE-2TG100CR1 763 679
    LCMXO2-1200ZE-3TG100CR1 839 748

    1200ZE というのは、1.2V で動作し 低消費電力が売り。Pico で使っているのは、ZE 。だが、普通は 高速な 2.5V/3.3V の 1200HC を使うと思う。(ちなみに、レギュレータがない 1200HZ もあるが、リストされていない)

    規模は、やはり XC3S50A ぐらい。Config 用の SPI-FLASH が不要だから 丁度 XC3S50AN のようなもの。XC3S50A-4VQ100 は 500円ぐらいだから、SPI-FLASH 分を上乗せしたような価格。

    AVR互換コアは、XC3S50A 向けの構成で 1085 スライス使っている。MachXO2-1200 向けに カスタマイズすれば、同じ機能が入りそう。

      Diamond をちょっとさわってみたのだが、Implement はエラーにならないものの、具合が悪いところがあった。

    • レジスタへの初期値代入は、$readmemh()/$readmemb() によるもの以外ダメだそうだ。
      GPR や RAM の初期値は必要ないし、ROM も $readmemh() を使うので、問題ないのだが、いくつか修正しないといけない。内部的に 4相クロックを作るオプションもひっかかるが、シフトレジスタ自体効率良く使えるかどうか怪しいのでサポートを外す。

    • 内部でクロック生成しているところ全般で Warining になる。なにかしないといけないようだ。内部的に4相クロックを作るオプションでもクロックを生成しているが、他に ROM/RAM の制御でもクロックを合成している。

    • FIFO の通信ポート機能では、シフトレジスタを使っている。Dual Port を使うオプションもあるのだが、いずれも Xilinx ならではの機能かも知れない。ちょっと検討が必要。

    • ブロック RAM は、Dual Port でないので、ROM が具合悪い。デフォルトでは、プログラムからのアクセスを 別ポートを使って実装している。これは SMP 化で使っている ROM_PSEUDO_DP オプションを付けることで 問題なくなるが、規模が増える。

    • 規模を減らすために、タイマーや SPI も MachXO2 の機能を使って実装しないといけないかも。

      XC3S50A 用のコンフィグをベースにして Implement してみた。

      Device utilization summary:

      PIO (prelim) 12/108 11% used
      12/105 11% bonded
      IOLOGIC 2/108 1% used
      SLICE 569/640 88% used
      EBR 6/7 85% used

      569 スライスで済んでいる。(XC3S50A は、Dual Port Block RAM を使うと 656 スライス。Single Port しか使わないオプション(ROM_PSEUDO_DP)で 682 スライス)

      試しに Synthesis Tool を デフォルトの Synplify Pro から Lattice LSE に変更すると 550 スライスになった。いずれも、なにか省略された結果、小さくなっている可能性がある(= 検証していない)。

      予想より効率が良く、タイマーや SPI といったハードマクロを使用しなくとも良さそうだ。
      これはこれで使ってみたいが、後回し。

    ちなみに、VQ100 以外に TQ144 もリストに出ている。VQ100 は -2000 までしかないが、TQ144 は、-7000 まであるから、何を作るか決まっていないもの(教育用・開発用ボードとか)の基板を起こすなら、TQ144 が良いかも知れない。

    2011/06/10 追記: Digikey でも扱っている! しかも在庫があったりするし。

    参考リンク:
  • 日本語ドキュメント
  • Lattice Diamond (日本語ページ)

追記: 『MachXO2 Pico Dev Kit』メモ

    rtavr やツールのテストには、『MachXO 2280 Breakout ボード』をメインに使うことにしたのだが、『MachXO2 Pico Dev Kit』も入手しておくことにした。

    入手先は、デジキー 型番 『LCMXO2-1200ZE-P-EVN』で、価格は、4787円と予想より高価だった。

    さて、このボード いろいろなデバイスが付いているが、それは置いておいて... PC の通信とか、外部との接続についてメモを取った。

    簡単に紹介すると、FT2232H が付いていて、MPSSE として使う ADBUS0-3 以外に、I2C のためのセレクタ (ADBUS7) がある。あと BDBUS の 8pin 、それに 12MHz の出力が MachXO2 に接続されている。(12Mhz は水晶(OSCO)から 直接取っている)

    BDBUS0 PL3C(E1)
    BDBUS1 PL3D(E2)
    BDBUS2 PL4A(E3)
    BDBUS3 PL4B(F2)
    BDBUS4 PL4C(F1)
    BDBUS5 PL4D(F3)
    BDBUS6 PL5A(G3)
    BDBUS7 PL5B(H2)

    USB_12MHZ PT12A(A7)

    拡張用のコネクタは、16x2列で次のようになっている。

    EXT_VCCIO (2) - R - (1) --- Battery or 3V3
    USB_TDI (4) - R - (3) XO2_TDI
    USB_TDO (6) - R - (5) XO2_TDO
    USB_TCK (8) - R - (7) XO2_TCK
    USB_TMS (10) - R - (9) XO2_TMS
    USB_SDA (12) (11) PL9A(K1)
    USB_SCL (14) (13) PL9B(K3)
    PT17C(B13)* (16) (15) PB11A(M7)
    PT17D(A13)* (18) (17) PB11B(N8)
    PT15D(C10)* (20) (19) PL2A(B1)
    XO2_SPI_SN (22) (21) PL2B(B2)
    XO2_SPI_CS0 (24) (23) PL2C(C1)
    XO2_SPI_CLK (26) (25) PL2D(C3)
    XO2_SPI_IN (28) (27) PL3A(C2)
    XO2_SPI_OUT (30) (29) PL3B(D1)
    GND (32) (31) GND

    PT17C(B13) DONE
    PT17D(A13) INITN
    PT15D(C10) PROGRAMN

  • R は、0Ωのジャンパ。取り外すと 外部のJTAG ケーブルを使ったり、逆にJTAG ケーブルとして使えるようになる。

    JTAG 端子をユーザI/O として使えるようにする JTAGENB という端子がある(PT15C)のだが、 無接続。

  • SPI も出力されている が、既に SPI_FLASH が接続されている (CS0 で Enable)

  • ユーザI/O も 13 本使える。ただし、左の 3 つは Config でも使用するピンなので注意。

ちょっと追記: 2011/12/15

    Digkey で MachXO2 の品種が増えている。 (TQFP-100, TQFP-144)

    まだ買えるわけではなさそうだが。7000 もリストされている。

    あと Lattice の MachXO2 の Webページを見ていたら、パッケージが増えている。

    WLCSP とかは、電子工作でどうにもなりそうにないのでパスするにしても、QFN-32 の LCMXO2-256 が追加になっている。この調子で 1200 あたりも QFN-32 で出てくれないかなぁ と思ったり。( QFN-32 でも厳しいけれども 扱える範囲という気もしてきた。)
posted by すz at 21:56| Comment(0) | TrackBack(0) | MachXO2