Sim's blog

電子工作はじめてみました

Qsysを使ってみた

2011-08-23 01:25:25 | FPGA

Qsysというのは、Alteraのシステム統合ツールの名前です(AlteraのQsysのページ)。以前あったSOPC Builderの後継となる開発ツールです。CPUやRAMを含んだシステムをFPGA上に簡単に構築できます。EclipseとCコンパイラもあってソフト開発も簡単にできます。
Qsysを使ってみたので使い方を簡単に紹介します。使った開発ツールはQuartus II 11.0sp1のweb editionです。FPGAボードはDE0 nanoを使いました。


おおまかな流れは以下のようになります

1. インストール

Quartus II ver11.0 sp1 web editionをインストールします。以前はsp1なしをインストールしないとsp1をインストールできませんでしたが、11.0からはsp1だけインストールすればいいです。また、以前はNios IIのソフトウェア開発ツールを別途インストールする必要がありましたが、これも必要なくなりました。ライセンス認証もありません。

2. Qsysを使う前にやっておくこと

Quartus IIを使った普通のFPGA開発と同じように以下を行います。
- プロジェクトの作成
- デバイスの設定
- ピン配置の設定
- SDCファイルの作成

今回は手抜きで、DE0 nanoのCD-ROMに入っているDE0_Nano_GOLDEN_TOPというプロジェクトをコピーしました。適当なフォルダを作ってDE0_Nano_GOLDEN_TOPというフォルダの中身をコピーするだけです。DE0_Nano.qpfというプロジェクトのファイルをダブルクリックすることでQuartus IIが起動します。

3. Qsysでシステムを作る

これは後述します。

4. 論理合成の前にやっておくこと

- できあがったQsysのファイルをプロジェクトに追加します。
- Qsysのモジュールを呼び出すようにメインのDE0_Nano.vを修正します。

5. 論理合成

Quartus IIの普通の論理合成を行います。

6. FPGAボードへの書き込み

できあがったDE0_Nano.sofファイルをDE0_Nanoに書き込みます。

7. ソフト開発

Nios II 11.0sp1 Software Build Tools for Eclipseを立ち上げてソフト開発します。

8. プログラムの実行

Eclipse内からプログラムを実行します。

以上になります。今回は3.を中心に書きます。


一応、今回の話はやってみたら、なんとなくできたというレベルなので間違った情報が含まれている危険性がたぶんにあります。ここは違うみたいなところはぜひとも教えてください。

3. Qsysでシステムを作る

(1) Qsysの起動

というわけで、まずはQsysの起動です。Quartus IIのツールボタンから起動できます。

(画像はクリックすると大きくなります。元の記事に戻るときはブラウザの戻るボタンで戻ってください)

(2) プロジェクト名を決める

Qsys起動直後の画面です。SOPC Builderはプロジェクト名を聞いてくるダイアログが最初に出ましたが、Qsysでは聞いてきません。プロジェクト名はモジュール名にもなるので、後で必要になります。どうやって決めるのかというと、セーブするときのファイル名がそのままプロジェクト名(= モジュール名)になります。ctrl+SもしくはFileメニューからSaveでセーブしてやると何もセーブされていない一番最初はファイル名を聞いてきます。とりあえずNiosSystemという名前でセーブしました。拡張子はqsysになるのでNiosSystem.qsysというファイルができます。

(3) システムの概要

今回作るのは、コンソールにHello, worldを表示してLEDチカチカするだけのシステムにします。RAMはDE0 Nanoに搭載されているSDRAMにして100MHzで動作させることにします。追加するコンポーネント以下の6つになります。

- Avalon ALTPLL (PLL) ... 倍速クロックとメモリ用クロック
- Nios II Processor (Processors) ... CPU
- System ID Peripheral (Peripherals → Debug and Performance) ... 必須
- JTAG UART (Interface Protocols → Serial) ... デバッグ通信用、必須
- PIO (Peripherals → Microcontroller Peripherals) ... LED用のPIO
- SDRAM Controller (Memories and Memory Controllers → SDRAM) ... RAM

クロックコンポーネントは最初から入っているので計7つになります。かっこの中はComponent Libraryのツリービューの中での位置になります。

(4) Qsysでの作業の概要

基本は画面左側のComponent Libraryから追加したいコンポーネントをダブルクリックしてシステムに追加し、パラメータを決めていきます。パラメータはコンポーネントそのもののダイアログで決めるものの他に以下が必要になります。

- Connection クロックやリセット、バスとの接続を決めます
- Name コンポーネントの名前を決めます。
- Export 外部信号の名前を決めます。これはQsysのモジュール(今回はNiosSystem)のパラメータに反映されます。
- Base cpuから制御するためのメモリマップドI/Oのアドレスを決めます。

SOPC Builderだと、ConnectionやBaseはデフォルトの動作である程度自動入力してくれていましたが、Qsysは全部手動で入力する必要があります。

(5) コンポーネントの追加 ALTPLL

Component LibraryのツリービューからPLL→Avalon ALTPLLを追加します(ダブルクリックもしくは+Add...ボタン)。

ALTPLLのダイアログが表示されます。

page 1/11では、speed gradeを6に、入力クロックを50MHzにします。


page 6/11ではPLLの出力クロックc0の倍率を2倍にします(入力は50MHzなので100MHz)


page 7/11では、Use this clockのラジオボタンをチェックして出力クロックc1を有効にします。それからc1の倍率を2倍にして位相(Clock phase shift)を-60度にします。

この-60度というのは、DE0のサンプルプロジェクトが-60度だったので、それにあわせました。全く根拠はありません。たまたま動いているのでこの値にしていますが、本当はちゃんと決めなければいけないはずです。残念なことに決め方はさっぱり分かりません。

ダイアログ内の設定は以上なのでFinishボタンを押して完了します。

c0はシステム全体のクロック、c1はSDRAM専用のクロックです。

ALTPLLを登録した直後のQsysの画面です。

Errorが2つとWarningが4つ出ています。ConnectionsとExportを決めてErrorとWarningを減らします。BaseはまだCPUがいないので入力できません。後で入力します(というか、最初にCPUを追加すればよかったと少し反省)

- clk_0コンポーネントのclk出力をinclk_interfaceに接続(Connectionsのあたりにマウスを持っていくと接続の絵が出るので白丸をクリックして黒丸に変えます)
- clk_0コンポーネントのclk_reset出力をinclk_interface_resetに接続
- altpll_0_c1のExport名を決定(シングルクリックで候補名が出るので必要なら修正してEnterを押します。今回は修正していません)
- 同じくareset_conduitのExport名を決定
- 同じくlocked_conduitのExport名を決定
- 同じくphasedone_conduintのExport名を決定

編集中の画面です。Connectionsのあたりにマウスカーソルを持っていくと表示される接続の図です。白丸をクリックして黒丸に変えます。また、Export名も決めています。


以上が完了したときのQsysの画面です。

警告が1つに減っています。ALTPLLのAvalon-SlaveをAvalon-MM masterにつないでいないという警告が出ています。CPU(マスター)がまだいないので、この警告は後で消します。

※Qsysはすべてのエラーと警告を消すようにしてください。消さないと大抵動作しません。

(6) コンポーネントの追加 Nios II Processor

Component LibraryのProcessorsにあるNios IIを追加します。

コンポーネント専用ダイアログでは、Nios II CoreをNioss II/eを選択します。ここで間違ってNios II/sやNios II/fを選ぶと、時間制限付きのコアになってしまって後が面倒です。また、後でNios II/eに戻しても時間制限付きのまま元に戻せなくなるので注意が必要です。

エラーが出ていますが、ここでは消せないのでFinishを押してダイアログを終了します。
Qsysの画面で(5)と同じようにConnectionsをつなぎます。

- nios2_qsys_0のclkをalt_pll_0のc0に接続します
- nios2_qsys_0のreset_nをclk_0のclk_resetに接続します
- altpll_0のpll_slaveをnios2_qsys_0のdata_masterに接続します((5)でつなげていなかったのでここで接続)。

6個のエラーと1つの警告が4個のエラーと警告なしになります。リセットベクターと例外ベクターを設定していないというエラーは、まだメモリがないので消せません。

各コンポーネントのほにゃ_slave(たとえばpll_slave)はnios2のdata_masterにつなぎます。resetはclk0のclk_resetにつなぎます。clkはaltpll_0のc0につなぎます。

(7) コンポーネントの追加 System ID Peripheral

Componet LibraryのPeripherals → Debug and PerformanceからSystem ID Peripheralを追加します。
Connectionsは以下の3つです。

- clkをalt_pll_0のc0に接続します
- resetをclk_0のclk_resetに接続します
- control_slaveをnios2_qsys_0のdata_masterに接続します

今回は、Connectionsの他にBaseも決めなければいけません。メモリマップドI/Oの番地がaltpll_0と重なっているからです。altpll_0が0x00000000~0x0000000fを占有しているので0x00000010ということにしました。変更はBaseの0x00000000の所をダブルクリックして編集します。

編集後の画面です。


(8) コンポーネントの追加 JTAG UART

Componet LibraryのInterface Protocols → SerialからJTAG UARTを追加します。
Connectionsは以下の3つです(System IDと一緒です)。

- clkをalt_pll_0のc0に接続します
- resetをclk_0のclk_resetに接続します
- control_slaveをnios2_qsys_0のdata_masterに接続します

Baseは重ならないように0x00000020にしました。

編集後の画面です。


(9) コンポーネントの追加 PIO

専用ダイアログではビット長や入出力を選択できます。デフォルトでは8ビット出力なのでそのままFinishします。
Componet LibraryのPeripherals → Microcontroller PeripheralsからPIO (Parallel I/O)を追加します。
Connectionsは以下の3つです。

- clkをalt_pll_0のc0に接続します
- resetをclk_0のclk_resetに接続します
- s1をnios2_qsys_0のdata_masterに接続します

Baseは重ならないように0x00000030にしました。
Exportで出力ポートを指定してやります。

編集後の画面です。


(10) コンポーネントの追加 SDRAM Controller

Componet LibraryのMemories and Memory Controllers → SDRAMからSRAM Controllerを追加します。

専用ダイアログでは、SDRAMのパラメータを設定します。

- PresetsはCustom
- データ幅は16bit
- Rowアドレスビットは13bit
- Columnアドレスビットは9bit



2ページ目ではタイミングの設定をしますが、今回は何もしなくてもそのまま動きました。本当はデータシートをちゃんと見て設定しなければいけません。

Connectionsは以下の4つです。

- clkをalt_pll_0のc0に接続します
- resetをclk_0のclk_resetに接続します
- s1をnios2_qsys_0のdata_masterに接続します
- s1をnios2_qsys_0のinstruction_masterに接続します(他と違う点です)。

Nios IIは命令(instruction)をSDRAMからfetchするので、instruction_masterにも接続してやる必要があります。他のペリフェラルからは命令を読み込まないのでinstruction_masterに接続する必要はありません。

Baseは0x02000000にしました。
Exportで出力ポートを指定してやります。

ようやっとメモリができたので、Nios IIのリセットベクタと例外ベクタを設定することでエラーを消してやります。


編集後の画面です。

エラーも消えています。
以上でコンポーネントの追加はおしまいです。

(11) システムの生成

まずは今までの結果をセーブしておきます(ctrl+S等)。
システムの生成はGenerationタブでGenerateボタンを押します。


システム生成中はダイアログが出ます。
問題がなければ以下のような画面になるはずです。

Warningが2つでています。このWarningの消し方はまだ分かっていません。ご存知の方は教えていただけるとありがたいです。

Warning: system: "No matching role found for jtag_uart_0:avalon_jtag_slave:dataavailable (dataavailable)"
Warning: system: "No matching role found for jtag_uart_0:avalon_jtag_slave:readyfordata (readyfordata)"


以上でQsysでシステムを作ることができました。

コンポーネントの名前の変更ですが、名前の場所をクリックしてからF2キーを押して編集します。


4. 論理合成の前にやっておくこと

まずは、できあがったQsysのファイルをプロジェクトに追加します。Settings(Assignmentメニュー→SettingsもしくはツールバーのSettingsボタン)のFiles Category(左側のペインの上から2番目)でNiosSystem.qsysを追加します(今回はNiosSystem.qsysというファイル名でセーブしました)。ついでにDE0_Nano.vも追加しておきます。


次にQsysのモジュールを呼び出すようにメインのDE0_Nano.vを修正します。QsysのHDL ExampleというタブにQsysのモジュールの呼び出し例ができています。

CopyボタンでクリップボードにコピーしてDE0_Nano.vに貼り付けてから修正します。以下が修正結果です。

//=======================================================
//  Structural coding
//=======================================================

    NiosSystem u0 (
        .clk_clk                           (CLOCK_50),   //                        clk.clk
        .reset_reset_n                     (KEY[0]),     //                      reset.reset_n
        .altpll_0_areset_conduit_export    (1'b0),       //    altpll_0_areset_conduit.export
        .altpll_0_locked_conduit_export    (),           //    altpll_0_locked_conduit.export
        .altpll_0_phasedone_conduit_export (),           // altpll_0_phasedone_conduit.export
        .altpll_0_c1_clk                   (DRAM_CLK),   //                altpll_0_c1.clk
        .pio_0_external_connection_export  (LED),        //  pio_0_external_connection.export
        .sdram_0_wire_addr                 (DRAM_ADDR),  //               sdram_0_wire.addr
        .sdram_0_wire_ba                   (DRAM_BA),    //                           .ba
        .sdram_0_wire_cas_n                (DRAM_CAS_N), //                           .cas_n
        .sdram_0_wire_cke                  (DRAM_CKE),   //                           .cke
        .sdram_0_wire_cs_n                 (DRAM_CS_N),  //                           .cs_n
        .sdram_0_wire_dq                   (DRAM_DQ),    //                           .dq
        .sdram_0_wire_dqm                  (DRAM_DQM),   //                           .dqm
        .sdram_0_wire_ras_n                (DRAM_RAS_N), //                           .ras_n
        .sdram_0_wire_we_n                 (DRAM_WE_N)   //                           .we_n
    );


以上で論理合成前にやっておくことは完了です。後は論理合成してから、できあがったDE0_Nano.sofをDE0 Nanoに書き込んでやります。

一つ注意点としてはsofファイルを書き込んだ後でprogrammerを終了しておかないと、programmerがUSB Blasterをつかんだままになって、Nios II Software Build Tools for EclipseがUSB Blasterを見つけられなくなることです。programmerは書き込みが終わったら終了しておきましょう。

7. ソフト開発

Nios II Software Build Tools for Eclipseを立ち上げます。起動はいくつかの方法があります。windowsのスタートメニュー、インストール時に作られるテスクトップのショートカット、Quartus IIのToolsメニュー、QsysのToolsメニュー等から起動できます。

Eclipseなので最初はworkspaceの場所を聞いてきます。場所は、今回のプロジェクトの一階層下にworkspaceというフォルダを掘って、そこにしました。9.0の頃はプロジェクトのフォルダそのものにすることもできましたが、10.0以降は一階層下にフォルダを作らなければいけなくなりました。

Fileメニュー → New → Nios II Application and BSP from Templateを選ぶと次のダイアログが表示されます。

- SOPC Information File Name欄。自分のプロジェクトフォルダにできているNiosSystem.sopicinfoを選びます
- CPU nameはsopcinfoファイルから読み取られて自動で入力されます。
- Project nameは今回はHelloSmallにしました。
- TemplateはHello World Smallにしました。

このまま実行すればHello from Nios II!というメッセージが見れます。今回はLEDチカチカもするのでソース(hello_world_small.cを修正します。


#include <stdint.h>
#include "sys/alt_stdio.h"
#include "system.h"

#define led (*(uint8_t *)PIO_0_BASE)

int main()
{
volatile uint32_t t;
alt_putstr("Hello from Nios II!\n");
led = 0x00;

while (1){
for(t = 0; t < 20000; t++) ;
led++;
}
return 0;
}


修正したらctrl+Sでファイルをセーブしておきます。

pio_0のI/OアドレスはQsysでは0x30番地にしました。system.hの中ではPIO_0_BASEが0x30で#defineされています。Qsysの中でモジュール名をpio_0でなくたとえばLEDとかにしておくとsystem.hの定義もPIO_0_BASEでなくLED_BASEという名前になります。PIO関連はソフト使用時にも影響があるので、ちゃんと名前を定義しておく方がいいです。


8. プログラムの実行

EclipseのProject Explorerでプロジェクト名(今回はHelloSmall)をクリックして灰色にしてから、Runボタンを押すとRun Asダイアログが表示されます。

Nios II Hardwareを選んでからOKを押すと実行開始です。


初めての実行のときや何かエラーがあるときはRun Configurationの画面が出ることがあります。Target ConnectionのタブでRefresh Connectionsのボタンを押すとエラーが取れて通信可能になる場合があります。Refresh Connectionsボタンは、FPGAボードに書き込まれているNios IIのシステムと通信してSystem IDの照合を行います。
何らかの理由でシステムが死んでいたり、programmerがJTAGをつかんでいて通信できなかったりといったときはRefresh Connectionsボタンを押しても復活しません。
また、Qsysでシステムの修正を行ってGenerateをやり直すとタイムスタンプが一致しなくなるのでRefresh Connectionsでエラーが出ます。この場合はGenerate BSPを行ってBSPを作り直してやると直ります。Generate BSPはBSP Editorの中や、Project Explorerのbspプロジェクト名を右クリックして出るメニューのNios IIにあります。BSP EditorはNios IIメニュー等にあります。


というわけで、やたら長い記事になってしまいました。間違いや、ここはこうした方がいい等コメントを頂けるとありがたいです。特にSDRAMに関してはデータシートもろくに見ずにやってみたらたまたま動いているという状況なので、ちゃんとしたパラメータはこうだ、というのを教えていただけるとありがたいです。


verilogのノンブロッキング代入

2011-08-17 21:36:02 | FPGA

この記事は書こうかどうか多少悩みました。ちゃんと裏が取れていないところが結構あります。原典のverilogの規格にあたるのがいいんでしょうが、そこまでできていません。色々と突っ込みどころがあると思いますのでコメントいただけるとありがたいです。

Verilogには2種類の代入文があります。私はノンブロッキング代入(<=)を順序回路に、ブロッキング代入(=)を組み合わせ回路に使っています。
今回の話は、同じ変数への複数のノンブロッキング代入があるときの動作とその応用についてです。

基本編(1)

まずは基本編です。同じ変数への複数のノンブロッキング代入があるときは、最後の一つだけが有効になります。

 

reg [3:0] a;
always @(posedge clk) begin
  a <= 4'h0; // (1) 無視
  a <= 4'h1; // (2) 無視
  a <= 4'h2; // (3) 有効
end

 

この例だと、(1)と(2)は無視されて(3)だけが実行されるので、aは4'h2になります。
単なる無駄ですね。

基本編(2) ifがある場合

ifがあるときは条件に従って最後の一つが有効になります。

reg [3:0] a;
wire flag;
always @(posedge clk) begin
  a <= 4'h0; // (1)
  if(flag) a <= 4'h1; // (2)
end


この例だと、flagが1'b1のときは(2)が一番最後、flagが1'b0のときは(1)が一番最後になります。
この例はelseを省略したときのデフォルトの動作を(1)が決めていると考えることができます。

基本編(3) caseがある場合

caseの場合も同じように一番最後の一つが有効になります。

reg [3:0] a;
wire [1:0] c;
wire flag;
always @(posedge clk) begin
  a <= 4'hf; // (1)
  case(c)
  2'h0    : a <= 4'h0; // (2)
  2'h1    : ;          // (3)
  2'h2    : if(flag) a <= 4'h2; // (4)
  default : a <= 4'h4; // (5)
  endcase
end


この例だと次のようになります。
cが2'h0のときは(2)が最後のaへの代入なのでaは4'h0になります。
cが2'h1のときは(1)が最後のaへの代入なのでaは4'hfになります。
cが2'h2のときはflagが1'b1のときは(4)が最後のaへの代入なのでaは4'h2になります。flagが1'b0なら、(1)が最後のaへの代入なのでaは4'hfになります。
cが2'h3のときは(5)が最後のaへの代入なのでaは4'h4になります。
この例は、(3)や(4)のelseのように省略したときのデフォルトの動作を(1)で決めていると考えることができます。

基本編のまとめ

ここまでをまとめると、複数ノンブロッキング代入は省略時のデフォルト動作を決めることに使えるということが分かりました。

ただし、複雑になるのでソースが読みづらくなったりバグの元になりやすくなります。基本的には複数ノンブロッキング代入は使わない方がいいです。
ここから後では、複数ノンブロッキングも使いようによっては便利になる場合もある、ということについて考えてみたいと思います。

応用編(1) エラーの検出

基本編(3)は考えようによっては、(3)のようにaへの代入を書き忘れたり、(4)のようにelseを書き忘れたりといった、書き忘れた系のエラー検出を積極的に行うことに利用できます。書き忘れたときには(1)が実行されるのでaの値が4'hfになります。

応用編(2) ステートマシン記述の簡略化

今までの例題ではデフォルトの動作として定数の代入しかしていませんでしたが、何か式の代入をしてもいいです。

reg [3:0] s; // ステート
wire start;
reg [7:0] ctr;
always @(posedge clk, posedge reset) begin
  if(reset)
    s <= 4'h0;
  else if(start) // start信号でステートマシン開始
    s <= 4'h1;
  else begin
    s <= s + 4'h1;       // デフォルトの動作 (1)
    case(s)
    4'h0 : s <= s;       // アイドルステート s <= 4'h0 (2)
    4'h1 : ;             // s <= 4'h2を省略 (3)
    4'h2 : ;             // s <= 4'h3を省略
    4'h3 : ctr <= 8'h00; // s <= 4'h4を省略
    4'h4 : ;             // s <= 4'h5を省略
    4'h5 : ;             // s <= 4'h6を省略
    4'h6 : begin         // 256回ループ (4)
           ctr <= ctr + 8'h1;
           if(ctr != 8'hff) s <= 4'h4;
           end
    4'h7 : ;             // s <= 4'h8を省略
    4'h8 : s <= 4'h0;    // s <= 4'h0 (5)
    endcase
  end
end


この例では、デフォルトの動作としてステートを覚えておくレジスタsを1増やしています(1)。リセット直後はsは4'h0なので状態はアイドルステートになります(2)。アイドルステート(2)では、ずっとsの値が4'h0のままなので無限ループになっています。start信号が1'b1になったときは、sは4'h1になるのでステートマシンが動作を開始します(3)。ステート4'h1ではsへの代入文を省略しているのでsに関してはデフォルトの動作をします。つまりsに1を足してsは4'h2になります。
分岐したいときは条件に応じてsに代入する値を変更します。(4)ではctrの値が8'hffでないときはsに4'h4を代入することで256回ループを実現しています。ifの条件が成立しないときはデフォルトの動作を行うのでsに1を足して4'h7へ状態遷移します。(5)は単純にsに直接値を入れることで4'0に状態遷移しています。
結局、ステートの状態遷移のデフォルトの動作を決めることで、ステートマシンの記述を簡略化したという例となっています。
ちなみにデフォルトの動作はelse節の最初に書いています。論理合成の際の非同期リセットの記述はパターンマッチングで行われるので、alwaysの直後には必ずリセットに関するifがないといけません。

応用編(3)

デフォルトの動作にifを使うこともできます。

reg [3:0] s; // ステート
reg wr; // 制御信号
wire start;
reg [7:0] ctr;
always @(posedge clk, posedge reset) begin
  if(reset) begin
    s <= 4'h0;
    wr <= 1'b0;
    end
  else if(start) begin // start信号でステートマシン開始
    s <= 4'h1;
    wr <= 1'b0;
    end
  else begin
    s <= s + 4'h1;       // sのデフォルトの動作
    if(wr) wr <= 1'b0;   // wrのデフォルトの動作(1)
    case(s)
    4'h0 : s <= s;       // アイドルステート s <= 4'h0
    4'h1 : ;             // s <= 4'h2を省略
    4'h2 : wr <= 1'b1;   // s <= 4'h3を省略(2)
    4'h3 : ctr <= 8'h00; // s <= 4'h4を省略、wr <= 1'b0を省略
    4'h4 :               // s <= 4'h5を省略
    4'h5 :               // s <= 4'h6を省略
    4'h6 : begin         // 256回ループ
           wr <= 1'b1;   // (3)
           ctr <= ctr + 8'h1;
           if(ctr != 8'hff) s <= 4'h4;
           end
    4'h7 : ;             // s <= 4'h8を省略
    4'h8 : s <= 4'h0;    // s <= 4'h0 (5)
    endcase
  end
end


この例は応用編(2)の例にwrという制御信号を追加しています。wrに関するデフォルトの動作は(1)になります。wrが1'b1のときは次のクロックで必ず1'b0になるという動作になります。ステートの4'h2ではwrを1'b1にしています。次のステート4'h3ではwrは1'b0になります。また、(3)では次のステートはctrの値に依存して4'h4または4'h7のどちらかになります。どちらに分岐してもwrの値は自動的に1'b0になります。
この例ではデフォルトの動作に記述することで、wrがHになるのは1クロックだけであることを保証しています。
さらに応用すると、ifの代わりにwrに関するステートマシンを書くといったこともできます。

まとめ

というわけで、同じ変数への複数のノンブロッキング代入を利用することでマニアックな記述ができることを長々と紹介してきました。あまり凝りすぎると可読性が極端に落ちることに注意が必要です。

この話について紹介しているサイトを見つけることができなかったので、禁じ手なのかもしれません。

 


Spartan6 LX45評価ボード Atlys

2010-12-11 11:40:17 | FPGA
ストロベリーリナックスさんでDigilentのFPGAボードAtlysの販売がはじまりました(販売ページ)。


DigilentはSpartan-3 Starter KitStartan-3E Starter Kitを開発した会社です。教育用のFPGAボードを作っているところのようです。AlteraだとTerasicみたいな感じでしょうか。
DigilentのFPGA製品のページはこちらになります。

搭載しているFPGAはSpartan-6 LX45CSG324Cです(XilinxのSpartan-6のページ)。6822slice、2.1Mbit block RAMです。Spartan-6は以前とスライスの構造が変わっているので単純に比較できないそうです。

ペリフェラルは以下です。
- メモリDDR2 SDRAM 128Mbyte(1Gbit)
- 10/100/1000 ether phy。MACはFPGAで作る必要があります。
- HDMI入力2個、HDMI出力2個。TIのTMDS141というHDMIバッファを経由してFPGAにつながっています。
- AC-97audio codec。ナショセミのLM4550からマイク入力、ライン入力、ヘッドフォン出力、ライン出力の4つのジャックにつながっています。
- SPI Flash 16Mbyte。configとデータの共用です。
- USB UART。XR21V1410というUSBシリアル変換ICを使っています。
- USB HID Host。マウスやキーボードをつなぎます。リファレンスマニュアルでは、PICマイコンPIC24FJ192を使っていることになっていますが、回路図ではPIC32MX440F256H-40I/MRを使っていることになっています。どちらが正しいんでしょう。もっとも2ページ目の写真にはしっかりPIC32が写っています。このPICはFPGAのconfigurationにも使っているようです。
- LED8個
- スライドスイッチ8個
- プッシュボタン6個(上下左右、センター、リセット)
- 100MHzの水晶
- 外部コネクタ 8pinのPMOD互換のものが1つ。こちらは2.54mmピッチです。
- 外部コネクタ 68pinのVHDCコネクタ(写真右側の大きめのコネクタ)。

Digilentは、VHDCコネクタにつながる拡張ボードも販売しています。
VmodWW - VHDC Wirewrap

ブレッドボードタイプもあります。
VmodBB - VHDC Breadboard

ストロベリーリナックスさんにも取り扱ってもらいたいものです。

PMODコネクタにつながるA/DとかD/Aみたいな色々な拡張ボードもDigilentで販売しています(PMODのページ)。

configurationですが、まずはXilinxと互換の普通のJTAGポートがあります。Xilinxの純正のPlatform Cableや互換品をつないで使えます。
もしくはDigilent独自のAdept Systemを使った書き込みもできるようです。こちらはUSBにケーブルをつなぐだけなのでPlatform Cableを持っていなくてもいいことになります。ただしISEからではなく独自のツールから書き込むようです。

いつもながら、盛りだくさんです。ちょっとショックだったのは、かなりレガシーフリーになっていることです。PS2もアナログRGBもありません。かなり心ひかれるものはありますが、私自身はしばらく様子見です。

ストロベリーリナックスさんからは、XC3S1600Eが搭載されたSpartan-3E Starter Kitの販売もはじまっています(販売ページ)。こちらも気になるところです。

DE0でNios IIのROM化

2010-11-07 05:48:39 | FPGA
すんさんの記事「terasic DE0基板 - NiosII/eのROMブート」に刺激されて、ROM化をやってみました。すんさんは、terasicのサンプルのプロジェクトを再利用することで実現されています。ここではゼロからプロジェクトを作ってやってみました(以前書いた記事「NIOSを使ってみました(1)」、「NIOSを使ってみました(2)」)。

思いっきり手抜きで申し訳ないのですが、分かる人にだけ分かるというか、重要そうな画面だけをピックアップしています。詳しくは「Flash Controllerを使ってみよう」を参照してください。
画像はクリックすると拡大します。

(1) SOPC Builderの設定では、EPCS Flash Controllerを追加してやります。


(2) SOPC BuilderのNios IIの設定では、Reset VectorをEPCS Flash Controllerにします。


(3) Quartus IIのデバイスの設定では、Dual-Purpose Pinsの設定でDCLK、DATA[0]、DATA[1]/ASDO、FLASH_nCE/nCSOの4つをUse as regular I/Oに変更します。この4つのピンは通常はProgram用ですが、普通のI/Oとして使えるように設定しています。

注意点としては、Quartus IIの10.0はバグのため、Dual-Purpose Pinsの設定ができません。10.0 sp1にアップグレードする必要があります。また、10.0 sp1にもバグがあって、okを押して上のダイアログを閉じて、もう一度開くと値が元に戻ってしまいます。実際は反映されています。
直接.qsfファイルに以下を追加してやる方法もあります。
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"

(4) Quartus IIのPin Plannerの設定です。Flash Controller用のピン配置はasdo(PIN_D1)、dclk (PIN_K2)、data0 (PIN_K1)、ncse(PIN_E2)です。DE0に載っているEP3C16F484のピン配置は、Alteraの「アルテラ デバイス用 ピンアウト・ファイル」というページからダウンロードできるEP3C16.pdfに載っています。


(5) verilogのソースコード(main.v)です。
`default_nettype none
module main(
output [9:0] led,
output dclk, nsce, asdo,
input data0,
input reset_n, extclk
);

nios nios_inst(
// reset
.reset_n (reset_n),

// clock
.extclk (extclk),

// altpll
.clk (),
.locked_from_the_altpll (),
.phasedone_from_the_altpll (),

// LED (GPIO)
.out_port_from_the_led (led),

// Flash Controller
.data0_to_the_epcs_flash_controller (data0),
.dclk_from_the_epcs_flash_controller (dclk),
.sce_from_the_epcs_flash_controller (nsce),
.sdo_from_the_epcs_flash_controller (asdo)
);

endmodule

(6) Nios II eds用のCのソースファイル(Lチカ)です。
#include "system.h"

#define led (*(unsigned *)LED_BASE)

int main()
{ 
    volatile unsigned t;

    while (1){
        for(t = 0; t < 50000; t++) ;
        led++;
    }
}

(7) Nios II Flash ProgrammerでDE0に載っているEPCS4にプログラムを書き込んでやります。

あらかじめ、Quartus IIのProgrammerから.sofファイルを書き込んでおく必要があります(Flash ProgrammerはNiosと通信してFlashに書き込むため)。
Flash ProgrammerはNios II EDSのProject Explorerの中のプロジェクト名を右クリックしたメニューから起動します。
追加するファイルは.elfと.sofに2つです。


以上で、EPCS4にはFPGAに書き込む回路とNios IIが実行するプログラムの2つが書き込まれて、電源オンで実行できるようになります。
Quartus IIのバグに悩まされましたが何とか動かすことができました。
今のところ解決していないのはNios II edsでワークスペースの場所を移動できないことです。インストールしたデフォルトの場所にしかプロジェクトを作成できていません。


ヒロセのコネクタFX2-100S-1.27DSLがマルツにありました

2009-11-17 23:00:55 | FPGA
XilinxのSpartan-3E Starter KitやSpartan-3A Starter Kitは拡張コネクタとしてヒロセのFX2-100P-1.27DSを搭載しています。自分で外に拡張ボードを作りたいときに使うコネクタはFX2-100S-1.27DS(PとSが違うだけ)です。このSの方をマルツで取り扱っています(FX2-100S-1.27DSL)。

こちらはSpartan-3E Starter Kitの拡張コネクタFX2-100P-1.27DS


こちらはマルツで売っているFX2-100S-1.27DSL


DSとDSLの違いはBoard prefixed pinの有無(Lがあり)みたいです。
ヒロセのカタログへのリンク(pdfファイルです)

千鳥足の100ピンを2.54ピッチに変換する変換基板はサンハヤトのICB-07があります。

マルツのSpartan-3E Starter Kit
マルツのSpartan-3A Starter Kit

Spartan-3E Starter Kitって、その昔は19000円くらいで売っていましたが、しばらく見かけなくなったと思ったら、いつのまにか値上がりしてますね。本家ザイリンクスでも$189と$149から値上がりしてます。というか、もう入手困難な類のアイテムになりつつありますね。

NIOSを使ってみました(2)

2009-11-05 22:49:19 | FPGA
NIOSを使ってみました(1)の続きになります。

NIOS IIのトリビアルな実装をしています。

(5) NIOS II eds(エンベデッド・デザイン・スイート)を起動してCのプログラムを作って、FPGAボードにダウンロード&実行する

いよいよ最後のステップです。

NIOS II edsを立ち上げると最初にworkspaceをどこにするかを聞いてきます。

Quartusのプロジェクトフォルダと一緒にするのがてっとりばやいです。一段階Softwareというフォルダを掘ってくれるので、ファイルが混ざったりすることもありません。

Fileメニュー → New → NIOS II Aplication and BSP from Templateを選びます。

SOPC Information File Nameの欄にはQuartusのプロジェクトのフォルダにあるnios.sopcinfoを選びます。niosの部分はSOPC Builderの一番最初で決めたシステム名になります。
Project名を決めてやります。niostest3にしました。
左下のテンプレートはHello World Smallを選びました。このテンプレートは使用メモリが少ないのでブロックRAM上でも動作します。
Finishボタンを押します。


左のProject Explorerツリービューのプロジェクト名(今回はniostest3)をクリックして灰色に変えてから、Projectメニュー → Build Projectでプロジェクトをビルドします。

Runメニュー → Runを選びます。

Run Asというダイアログが出るのでNIOS II Hardwareを選んで(クリックして灰色に変えて)、OKを押します。


下のNios II Consoleに実行結果が出ます。今回は"Hello from Nios II!"というメッセージを表示します。中のプログラムは以下のようなものです。
#include "sys/alt_stdio.h"
int main()
{
  alt_putstr("Hello from Nios II!¥n");
  while(1) ;
}

ペリフェラルはsystem.hにメモリの番地が書いてあったりしますが、今回は何もないのでincludeしなくても平気です。
リセット(ボタン2)を押すともう一度"Hello from Nios II!"を表示してくれます。
このプログラムは無限ループなのでNios II Consoleの右上にある赤い四角を押してプログラムを終了してやります。

さて、以上で駆け足でしたがQuartusのプロジェクト作成から始まってNIOS II eds上での実行まで眺めてきました。結構、長いですね。

FPGAの部屋さんのまとめサイトを見ながら、独自ペリフェラル(Avalon-MMのスレーブ)を作ってみたりしました。

これからやりたいのは、DE0に搭載されているSDRAMをNiosから使うことです。

分かっていないのは、Nios II上で開発したソフトをROM化する方法です。PCと通信しなくても電源オンですぐ動き出すようにしたいです。ブロックRAMと同じ名前の.hexファイルがあって、これがブロックRAMの初期値になるんじゃないかと思います。.elfファイルを.hexに変換するツールとかがあるのかもしれません。

それにしても、1週間たらずのうちに2度もQuartusをインストールすることになるとは思ってませんでした。


おまけです。


NIOS II edsをインストールしたフォルダの下のbinというフォルダにnios2-terminal.exeというプログラムがあります。このプログラムを使うとNIOS II edsを使わなくてもDE0ボードと通信できます。TeraTermのJTAG UART版みたいなプログラムです。

NIOSを使ってみました(1)

2009-11-04 23:05:04 | FPGA
Altera DE0のJTAG通信?の続きになります。

AlteraのQuartusは9.1から一番小さなNIOS/eが無料で使えるようになりました(marseeさん情報ありがとうございます)。9.0まではどうだったかというと、FPGAボードにsofファイルをダウンロードすると、Quartusからダイアログボックスが出て、ボタンを押すまでは使えるという変則時限使用が可能でした。

やたら手順は長いですが、覚書きがわりに手順を追っかけてみます。
おおざっぱな流れは、

(1) Quartusで新規プロジェクトを作る
(2) デバイスの設定をする
(3) SOPC Builderを起動してCPU(NIOS II)やメモリ、ペリフェラルの設定をしてシステムをGenerateする
(4) Quratusに戻って、トップモジュールやペリフェラルのRTLを作ってFPGAボードにダウンロードする
(5) NIOS II eds(エンベデッド・デザイン・スイート)を起動してCのプログラムを作って、FPGAボードにダウンロード&実行する

くらいになります。FPGAの部屋さんのまとめサイトを参考にしました。


(0) インストール
Quartus II web editionとNiosNios II エンベデッド・デザイン・スイートをAlteraのダウンロードページからダウンロードしてインストールします。昔と違ってライセンスを取得する必要はなくなりました。

(1) Quartus IIの新規プロジェクトを作る

Create a New Projectを押します。
次の画面はNextを押します。

プロジェクトのディレクトリ(d:¥design2009¥niostest3)、プロジェクト名(niostest3)、トップモジュール名(main)を入力してNextを押します。
次の画面はNextを押します。

デバイスを選択します。DE0ボードは、FamilyがCyclone III、Speed gradeが6、デバイス名はEP3C16F484C6です。Nextを押します。
次の画面はNext、その次の画面はFinishを押します。

これでprojectができました。

(2) デバイスの設定
後でやってもいいのですが、忘れないように、まずはsettingで、デバイス関連の設定をしておきます。

settingボタンを押します。もしくはメニューのAssignments→Settingを選びます。もしくはctrl+shift+Eを押します。

左側のCategoryというツリービューのDeviceをクリックします。
次にDevice and Pin Options...というボタンを押します。

Configurationというタブを選んでUse configuration deviceというチェックボックスをチェックしてから右のドロップメニューからEPCS4を選びます。こうすることでeeprom用の書き込みファイル(.pof)を生成してくれるようになります。

他にUnused Pinsというタブで未使用ピンのデフォルトの入出力を決めてやります。
またVoltageというタブでデフォルトのI/Oを選びます(3.3V LVTTL)。
OKを押してDevice and Pin Optionsのダイアログを閉じます。

OKを押してSettingsのダイアログを閉じます。

(3) SOPC BuilderでNIOSを設定する

右上のSOPC Builderのボタンを押して、SOPC Builderを起動します。もしくはToolsメニューのSOPC Builderメニューで起動します。


一番最初のダイアログでシステム名(nios)の入力、HDLの選択(Verilog)をしてからOKを押します。

今回は、システムを動かす最低限の設定だけをすることにします。


まずは左側のLibraryというツリービューのProssorsを開いてNios II ProcessorをダブルクリックしてシステムにNiosを追加します。もしくはAddボタンを押します。
ここのところは9.0と違っています。9.0ではNiosはLibraryの中にはありませんでした。


Nios II/eを選んでFinishを押します。
この画面には後で戻ってきてMemoryのプルダウンメニューを選びます。今はまだメモリーがないのでFinishにしておきます。Nextを進んでいくとデバッグのレベルを選べます。


LibraryツリービューのMemories and Memory Controllers → On-Chip → On-Chip MemoryをダブルクリックしてFPGA上のメモリを追加します。もしくはAddボタンを押します。


メモリーサイズを入力します。とりあえず32768バイトにしてみました。たぶん、もっと増やせます。Finishボタンを押します。


ここでエラーが出ます。32kバイトにしたときはメモリの開始番地を0x0または0x8000にしろというエラーです。現在の値は0x2000になっています。それとしなければいけないこと(To Do)としてcpu_0のリセットベクトルと例外ベクトルを指定しろと出てきます。

まずはonchip_memory2_0の右側の0x00002000をダブルクリックして編集します。0x00008000に変更すると、エラーが消えます。

次にcpu_0をダブルクリックしてNiosの設定に戻ります

Reset VectorのところとException Vectorのところのプルダウンメニューからonchip_memory2_0を選びます。Finishボタンを押して戻ります。
To Doも消えています。
方針としてエラーとかTo doが出たら、とりあえず消すようにするのがいいみたいです。

次にJTAG UARTを追加します。JTAG UARTは左側のLibraryツリービューのInterface Protocols → Serial → JTAG UARTにあります。ダブクリまたはAddボタンでJTAG UARTのダイアログを出してからFinishを押して、システムに追加します。

最後はSystem IDを追加します。System IDは左側のLibraryツリービューのPeripherals → Debug and Performance → System ID Peripheralsにあります。これもダブクリまたはAddボタンでSystem ID Peripheralのダイアログを出してからFinishを押してシステムに追加します。


ここでwarningが出ます。
System IDは追加するだけでは駄目でモジュール名をsysid_0からsysidに変更する必要があります。
sysid_0のところをクリックしてから、右クリックメニューでRenameを選ぶか、ctrl+Rを押すことで名前を変更できます。sysidに変更するとwarningが消えます。

今回はしませんが、この段階で考慮しておくべきこととして、クロックやモジュールの名前を分かりやすいものに変更しておくことがあります。また、複数のクロックがある場合には各モジュールに供給するクロックを選択する必要があります。

ここまでくると、後はシステムを生成(Generate)します。Saveするか聞いてくるのでSaveボタンを押します。しばらく時間はかかりますが、正常に生成し終わると次のような画面が出てきます。

一番下にはSUCCESS: SYSTEM GENERATION COMPLETEDというメッセージが出ています。
EXITボタンを押してSOPC Builderを終了します。


(4) Quartusで論理合成

とりあえず、ここまでで、5段階のうち3段階が終わりました。
(2)は、先にやっておかなくても、(4)のときに一緒にしてもいいです。
どどっと疲れてきたので、(4)は手抜きします。
まずは、main.vを作ります。mainという名前は(1)のときにトップモジュールとしてmainにしたからです。今回は何もペリフェラルの追加を行っていないので、mainはniosを呼び出すだけのモジュールになります。ここのniosというのは、(3)でシステム名をniosにしたからです。他の名前にしたときは、その名前になります。niosの呼び出し方はSOPC Generatorがnios_inst.vというファイルを作ってくれるので、これをコピペします。

nios_inst.vの中身です。
  //Example instantiation for system 'nios'
  nios nios_inst
    (
      .clk_0   (clk_0),
      .reset_n (reset_n)
    );

リセットとクロックしかいません。
コピペして作ったmain.vです。
`default_nettype none
module main(
    input rst_x,
    input clk);

    //Example instantiation for system 'nios'
    nios nios_inst (
        .clk_0   (clk),
        .reset_n (rst_x)
    );

endmodule

クロックをclk、リセットをrst_xという名前にしています。

main.vを追加するには、Quartusの外でテキストエディタを使ってmain.vを作ってからシステムに追加(Projectメニュー → Add/Remove files in Project)したり、Fileメニュー → New → Verilog HDL Fileを選んでから、中身を作ってFileメニュー → Save Asでmain.vと名前をつけてセーブする方法があります。

Pin Plannerを使って、ピン配置を決めます。clkはPIN_G21、rst_xはPIN_F1(ボタン2)にしました。

タイミング制約をつけてやります。50MHzです。

ようやっと論理合成できます。

warningが55個も出ています。
ロジックエレメント(LE)は1379 / 15408 (9%)でした。
Timing Analyzerを見てもfailしているパスはなく全てmetしています。
118MHzで動作する回路ができたようです。

Programmerを起動して、回路を書き込みます。
LEDがうっすらとついています。未使用ピンをハイインピーダンスにしたせいです。


というわけで、疲れてきたので続きます。

Cyclone IV

2009-11-03 17:17:08 | FPGA
アルテラがCyclone IVシリーズを出したそうです。

アルテラのニュースリリース
マイコミジャーナルの記事
アルテラのCyclone IVのページ

Xilinxは、ハイエンドがVirtexでローエンドがSpartan。アルテラはハイエンドがStratix、ミドルエンドがArria、ローエンドがCycloneということのようです。
Quartusもバージョンが9.1になるそうです。

Altera DE0のJTAG通信?

2009-11-01 19:17:06 | FPGA
Altera DE0で使えそうなLCDを探してみましたの続きになります。

Altera DE0がきましたのコメントでnsxさんから、USBを使ってPCアプリと通信できるんでしょうか、というコメントを頂きました。付属CD-ROMにある回路図を見てJTAGしかつながってないから駄目っぽいという返事をしました。でもでも、よく考えてみると付属アプリであるDE0_ControlPanelを使ってPC側からLEDを点けたりVGAの出力を変えるというデモがあります。

これがDE0_ControlPanelの画面です。チェックボタンでLEDを点けたり消すことができます。


DE0_ControlPanelが動作している最中にXPのデバイスマネージャを見てもCOMとかはいません。Altera USB-Blasterがいるだけです。

DE0_ControlPanel.exeのいるフォルダには他に3つのdllがいます。
- TERASIC_DOWNLOAD.dll
- TERASIC_JTAG.dll
- TERASIC_JTAG_DRIVE.dll
このdllが怪しげです。JTAGの通信にまぎれて、アプリ間通信をするような機能がいるような雰囲気です。dumpbin.exeを使って中身を調べてみました。

TERASIC_DOWNLOAD.dllがexportしているAPIです。
    ordinal hint RVA      name
          2    0 00006108 @@Download@Finalize
          1    1 000060F0 @@Download@Initialize
         15    2 000063E4 @@Ftdicontrol@Finalize
         14    3 000063D4 @@Ftdicontrol@Initialize
         10    4 00006350 TERASIC_AsDownload
          3    5 00006120 TERASIC_DownloadEEPROMByByteBlaster
          7    6 00006284 TERASIC_DownloadNios2
          9    7 000062F4 TERASIC_FlashProgrammer
         12    8 000063BC TERASIC_GetQuatusVersion
         11    9 000063A8 TERASIC_IsUsbBlasterDriverReady
          5    A 000061CC TERASIC_JtagDownload
          4    B 00006174 TERASIC_JtagDownloadByteBlaster
          6    C 0000622C TERASIC_JtagDownloadChain
          8    D 000062DC TERASIC_Nios2Terminal
         13    E 000063C4 TERASIC_SetQuartusProgrammerPath
         16    F 0006A0F8 ___CPPdebugHook

いかにもダウンロード用といった感じのAPIが並んでいます。

TERASIC_JTAG.dllがexportしているAPIです。
    ordinal hint RVA      name
          2    0 000018B0 @@Jtagport@Finalize
          1    1 000018A0 @@Jtagport@Initialize
          4    2 00001938 TERASIC_JtagClose
          7    3 000019F0 TERASIC_JtagGetInfo
          3    4 000018C0 TERASIC_JtagOpen
          6    5 000019B8 TERASIC_JtagRead
          5    6 00001980 TERASIC_JtagWrite
          8    7 0000A0F8 ___CPPdebugHook

ReadとかWriteがあって、いかにも通信用って感じです。

TERASIC_JTAG_DRIVE.dllがexportしているAPIです。
    ordinal hint RVA      name
          1    0 00001E94 jtag_atlantic_clearstall
          2    1 00001B9C jtag_atlantic_get_offset
          3    2 00001B70 jtag_atlantic_init
          4    3 00001DEE jtag_atlantic_read
          5    4 00001D56 jtag_atlantic_status
          6    5 00001E39 jtag_atlantic_transfer
          7    6 00001DA3 jtag_atlantic_write
          8    7 00002889 jtag_avalon_address
          9    8 00002773 jtag_avalon_get_offset
         10    9 00002745 jtag_avalon_init
         11    A 000028AC jtag_avalon_mode
         12    B 00002912 jtag_avalon_read
         13    C 0000282A jtag_avalon_status
         14    D 000028CF jtag_avalon_write
         15    E 0000192A jtag_close
         16    F 00001963 jtag_command
         17   10 00001000 jtag_init
         18   11 00002671 jtag_pio_init
         19   12 000026FF jtag_pio_read_outputs
         20   13 00002678 jtag_pio_status
         21   14 00002722 jtag_pio_write_inputs

avalonとかatlanticって何なんでしょう?

デバッガを使ってDE0_ControlPanel.exeを追いかけてみるとTERASIC_JTAG.dllが通信用でした。Openは2つのパラメータ、ReadとWriteは3つのパラメータ、Closeは1つのパラメータを使っています。送っているデータを覗いてみると、次のような形式になっていました。

先頭の1バイト 0xaa 固定
2バイト目 コマンド (LED関連は0x02、VGA関連は0x0d等)
3バイト目 送信するデータのバイト数をnとすると n - 6
4バイト目 0x00 固定 (用途不明)
5バイト目から 送信データ
...
n-1バイト目 チェックサム (2バイト目からn-2バイト目までの総和 mod 256)
nバイト目 0x55固定

LED点灯コマンドのときは5バイト目がLED7~LED0、6バイト目がLED9,LED8の点灯パターンを送っています。全部点灯するときは5バイト目が0xff、6バイト目が0x03になります。全点灯するときに送信するデータです。
aa 02 02 00 ff 03 06 55
初期化のときに送っているデータです。
aa 00 00 00 55
VGAのパターンを選択するときに送っているデータです。
aa 0d 01 00 00 0e 55
受信するデータも同じ形式です。内部処理では最初に先頭の4バイトを読み込みます。続きの長さが分かるので、続きを読むという感じで2回に分けて可変長のデータを受信しています。

ソースとかドキュメントといった情報が全然見つかっていないので、無理矢理リバースエンジニアリングしてしまいました。JTAGラインを使ってデータを送受信していることくらいまでは分かりましたが、そこから先はさっぱりです。そもそもFPGA側にどんな回路を作ればいいのかも分かりません。Terasicが情報を公開しないかぎりは、これ以上は難しそうです。


なんてことを↑で書きましたが、NIOS IIとかAvaronでぐぐってみると、Avaron BUSとかJTAG UARTみたいなキーになりそうな言葉がひっかかってきます。自分で使うときはTERASIC_JTAG_DRIVE.DLLを直接叩くのかもしれません。


Sasebo-GII

2009-10-31 14:55:37 | FPGA
マイコミジャーナルの記事「産総研、サイドチャネル攻撃評価ボードを開発 - 10年1月からの販売を予定」を見て産総研の設計したFPGAボードSasebo-GIIが一般発売になることを知りました。



FPGAが2つ載っているところが特徴でしょうか(Virtex-5とSpartan-3A)。サイドチャネル攻撃の評価ボードということですが、サイドチャネル攻撃についてはDesignWave 2006年2月号に「LSIを“盗聴”から守る」という特集がありました。DesignWaveに記事を書いている佐藤さんがSaseboを作ってる方です。最近はロケットを飛ばしている森岡さんも記事を書かれています。

東京エレクトロンデバイスニュースリリースによると95000円と150000円の2種類みたいです(東京エレクトロンデバイスの製品ページ)。DPAコンテストで採用予定なんて書いてあります。

産総研SaseboのページにはGII以外にも色々な評価ボードが載っています。GがXilinxでBがAltera、RがASICみたいです。Xilinxは無印、G、GIIと三世代目みたいです。
産総研のニュースリリース

Xilinxのホームページにもニュースリリースが出ています。

11/18-20に開催されるembedded Technology 2009で実物が見れるそうです。

Altera DE0で使えそうなLCDを探してみました

2009-10-30 20:06:18 | FPGA
Altera DE0がきましたの続きになります。

Altera DE0には16x2LCDをつなげるためのパターンが基板にあります。

写真中央の横一列の穴です。

キットそのものにはLCDは含まれておらず別売りになっています。製品ページの下の方に16X2 LCD Module (Backlight) [Part No.:MMC-3000-XXX]が$12と書かれています。

付属CD-ROM(ダウンロードも可)には別売りのLCDのデータシートもはいっています。それによると型番はCFAH1602B-TMC-JPとなっています。Crystalfontzというメーカーの製品です。残念ながらぴったしの型番のものはホームページには見当たりませんでした。

データシートを見る限りでは通常の5V動作のLCDモジュールです。あとはピン配置と大きささえ合えば他のメーカーのものでも代用ができそうです。サイズは36x80x14(mm)です。ピン配置は
1 Vss
2 Vdd
3 Vo
4 RS
5 RW
6 E
7~14 DB0~DB7
15 A (LED+)
16 K (LED-)
で横一列になっています。

秋月のはピン配列が違うのでで駄目でした。aitendoを見るとよさげなのが2種類ありました。

(1) JHD162A
(2) SC162A

どちらもピン配置、サイズともにぴったりです。

気になるのは、DE0の回路図を見てもLCDのバックライトLED用の抵抗が見当たらないことです。回路図のp.7の中央辺りにLCD BL(LCDのバックライトLED)の回路があります。LCDモジュールの裏側に電流制限用の抵抗を増設してやる必要があるかもしれません。DE0のユーザーマニュアルのp.31の写真ではLCDモジュールの16ピン(LED-)は接続していないようにも見えます。また同じ写真からすると縦幅の36mmはちょうどぴったりのサイズみたいです。

なくても、そんなに困るものでもないのですが、とりあえず調べてみました。

Altera DE0がきました

2009-10-30 00:43:10 | FPGA
digikeyに頼んでいたAltera DE0が届きました。26日に頼んで届いたのは29日でした。用途の所を日本語にしたので翻訳に1日余分にかかったみたいです。

こんな箱にはいってました。


中身はこんな感じです。


出してみました。


さっそく・・・、Quartus IIをインストールしてませんでした。まずはダウンロードから。USB Blasterの機能があるのでUSBケーブルをつなぐだけでコンフィグレーションできます。USB BlasterのドライバはQuartus IIをインストールしたフォルダにあります。

Quartus IIって、System Verilogも使えるみたいです。

DVDもついてきますが、Terasicから最新版のCDイメージをダウンロードします。バージョンが1.1になっていて少しだけ新しいみたいです。

さっそく、お約束のRTLを作成しました。
`default_nettype none
module main(
    output reg [9:0] LED,
    output reg [7:0] HEX0,
    output reg [7:0] HEX1,
    output reg [7:0] HEX2,
    output reg [7:0] HEX3,
    input rst_x,
    input clk);

    reg [20:0] ctr;
    reg [3:0] ctr2;

    wire ctr_en = ctr == 21'h0;

    always @(posedge clk)
        ctr <= ctr + 21'h1;

    always @(posedge clk, negedge rst_x)
        if(~rst_x)
            LED <= 10'h200;
        else if(ctr_en)
            LED <= {LED[8:0], LED[9]};

    always @(posedge clk)
        if(ctr_en) ctr2 <= ctr2 + 4'h1;

    always @(posedge clk)
        if(ctr2[3]) begin
            HEX0 <= 8'b10011111;
            HEX1 <= 8'b10011111;
            HEX2 <= 8'b10011111;
            HEX3 <= 8'b10011111;
            end
        else begin
            HEX0 <= 8'b10111101;
            HEX1 <= 8'b10111101;
            HEX2 <= 8'b10111101;
            HEX3 <= 8'b10111101;
            end
endmodule

Quartusって、あんまり使ったことがないせいか、よく分からないです。ピン配置って毎回pin editorで作らないといけないんでしょうか?

Spartan-6 LX16 評価キット

2009-10-28 19:56:00 | FPGA
アヴネットからSpartan-6 LX16 評価キット(型番 AES-S6EV-LX16-G)というSpartan-6とPSoC3を搭載したFPGAボードが出ます(米国のAvnetと米国の製品ページ)。価格は$225だそうです(日本法人の価格は不明)。

PSoC 3を使ってLCDパネルの表示ができて、なぜかリチウムイオン電池があります。

アブネットからは以前Spartan-3A+PSoC1というSpartan-3A評価キット(型番 AES-SP3A-EVAL400-G)が出ています(米国の製品ページ)。今回のは次世代バージョンということになるのでしょうか。

以前書いた記事によると、発売当時は$39でした。その後PSoCのminiprogを同梱するようになって$49になったようです。

とりあえず、どちらもちょっとだけ試してみたいという方にはよさそうです。ただし、現在の所情報があまり公開されていないので、このボードで遊ぶのに他に何が必要なのかがまだ分かっていません。最悪、Spartan-6のJTAGケーブルとPSoC3のプログラマがどちらも必要になるかもしれません。

Altera DE0

2009-10-22 23:36:53 | FPGA
FIAT500と洗車の日々・・・さんの記事「Altera FPGAボード DE0」でTERASICの新しいFPGAボードのことを知りました(製品ページ)。

FPGAはCyclone III 3C16 FPGAで、EPCS4 serial EEPROMというコンフィグレーションROMも搭載されています。15408個のLE(ロジックエレメント?)が搭載されているとのことですが、これってどのくらい大きいものなんでしょうか?
$119とやたら安い上に、色々なペリフェラルがついていて、なかなか楽しそうなボードです。

- 8MバイトSDR-SDRAM
- 4MバイトNOR-FLASH
- SDカードソケット
- プッシュボタンx3
- スライドスイッチx10
- LEDx10
- 7セグLED 4桁
- 16x2LCDコネクタ(LCDモジュールはなし)
- VGA出力(4096色)
- RS232シリアルポート(コネクタはなし)
- PS2ポート
- 40pinの拡張コネクタ(2.54mmピッチ) x2 (72ピンがI/Oで8ピンが電源)
- USBブラスタ機能搭載なので、ケーブルは不要でUSBのついたPCだけあれば開発ができる

digikeyだと11912円ですが、在庫0になっています。Ship date estimateは10/22になっています。って今日ですね。

digikeyでTERASICを検索してみると、ほとんどのボードが買えるようになっています。トラ技2008年12月号で使っていたMAX II MICRO KITなんかもあります。

DE3というハイエンドのFPGAボードも出ています。こちらはStratix IIIで$2695です。

Xilinx + ARM = ?

2009-10-22 22:54:50 | FPGA
マイコミジャーナルの記事「XilinxのFPGAにCortexの搭載が可能に - XilinxとARMが提携」を見ました(Xilinxのニュースリリース)。なんでもXilinxとARMが提携して、ARMコアを載せることができるようになったそうです。

ぐぐってみるとCortex M1というのがFPGA向けのARMみたいで、Actel、Altera、Xilinxの名前が出ています。

以前はVirtex II proにPowerPCのハードマクロが載っていたこともあるんですが、Xilinx的にはPowerPCは終息なんでしょうか。
10/23 追記 Virtex4や5にもPowerPCが載ってます。全然終わってないです。おおきさん、お知らせありがとうございました。

ISEもVirtex II proをサポートしているのはISE10が最後でISE11からはサポートが打ち切られています。
世の中、ARMだらけです。