[[ASAP Top]] ざんていばん written by tsuru (2015/08/28)~ PEACH3の話もしたいので新しく作り直し。とりあえず更新 written by tsuru (2017/02/14) *ハードウェア編 [#ua6a4f40] **自作モジュールを作る [#n852cfe5] -verilogで自作のモジュールを書く -後々のことを考えて入出力幅を128 bit(PEACH3なら256 bit でも可。しかしやったことはない)にしておくと良し -ここでシミュレーションを行い、150 Mhzで動作することを確認しておく -シミュレーションがうまくいってエラーが無ければ入出力の名前を変更する 128 bit ver module top( input clk, input reset_n, input [127:0] avs_s1_writedata, //write data output [127:0] avs_s1_readdata, // read data input avs_s1_read, //read req input avs_s1_write, // write request input [20:0] avs_s1_address, //address output ins_irq0_irq); // 割り込み(使わない?) 修正後次へ **quartusを起動 [#a7e3c0c3] -PEACH2 or 3ボードの種類を確認する -デフォルトでは(p2g_512_140606a.tgzを解凍後)はEP4SGX530NF45C2になっている -ふんが研にあるボードはEP4SGX290NF45C2なのでこれに変更 --EP4SGX530NF45C2 → 筑波にあるPEACH2(たぶん) --EP4SGX290NF45C2 → hunga lab -PEACH3 --圧縮ファイル解凍後のボードをそのまま使う。 **Qsysでモジュールを繋げる [#naf9348d] -File-Open で 作業ディレクトリ-nios_sys_next-nios_sys.qsysを開く -PEACH3でもらってるディレクトリだと 20.ip--nios_sys_next-nios_sys.qsys -左のLibrary内のProject-New Componentで新しいコンポーネントを開く -verilogファイルを書き換えたらコンポーネントも作り直す *** New Component [#f42f7da2] -Component Type~ name, Display nameを設定 -File~ synthesis Files に自作モジュールを追加~ 一応Analayse Synthesisする -signals~ 入出力名をきちんと設定していれば自動的にs1になる・・・はず -interfaces~ clock-parameter を150000000(150 MHz)に設定~ irq0-Associated Reset をnone->resetに設定(これやらなくていいぽい?) ***Qsys [#m9e6b57b] -nios2_qsys_0をダブルクリック~ select a Nios II core にてNios II/e を選択 -TSE_MACのチェックを外して使わないようにする -TSE_MACのチェックを外して使わないようにする(PEACH3だとデフォルトで消えてる) -配線(PEACH2)~ clock -> mem_if_ddr3_emif0.afi_clk~ reset -> mem_if_ddr3_emif0.afi_reset~ s1 -> merlin_master_translatoer_0~3(4ヶ所)~ s1 -> nios2_qsys_0.data_masterとinstruction_master(2ヶ所)~ 自作モジュールのIRQ列をクリック~ s1のBaseアドレスを0x0600_0000に変更(調整可)~ -配線(PEACH3)~ clock -> mem_if_ddr3_emif_0.afi_clk~ reset -> mem_if_ddr3_emif_0.afi_reset~ s1 -> merlin_master_translator_2.avalon_universal_master_0~ s1 -> merlin_master_translator_3.avalon_universal_master_0~ s1 -> nios2_qsys_0.data_master~ s1 -> nios2_qsys_0.instruction_master~ irq0 -> nios2_qsys_0.irq~ s1のbase, endを0x0600_0000 ~ 0x07ff_ffffに設定。 -generateタブ-generate **quartusでコンパイル [#k206ec64] -そこそこ時間がかかる -ここでFPGAの使用率とかでる -コンパイルがうまく行かないときはtopファイル(rtl/peach2_logic.v)の最初のところにある~ //`define NOGBE を変更し `define NOGBE or `define NOGBE 1 にするといいかもしれない **design space Explorerで完成 [#j46dc4e0] -quartusのtoolタブから -やばいくらい時間がかかる~ 以下某所からコピペ ***日立超Lおすすめ設定 [#xcdadd5c] 日立超Lのおすすめ設定は ~ Options -> Stop Flow When Zero Failing Path Are Achieved~ (タイミングが入ったら停止)~ ~ seed:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71~ ~ Search for Best Performance をチェックし~ Effort Level:Selective を選択~ です.(seedは素数列です.)~ *ソフトウェア編 [#fb6f59cb] 結局は割り当てた番地へのDMA~ 基本的に転送の方法は普段と同じ~ -初期化 -メモリの確保 -ハンドルの作成 -ディスクリプタの生成・セット -通信開始 -終了検知 ~ この中で通常の転送と違うのはハンドルの作成について **自作モジュール用ハンドル作成 [#ra487a6d] 筑波大藤田様様に作成していただいた自作モジュール用ハンドル作成関数 tcaresult tcaCreateDDRHandle(tcaHandle* h, int nodeid) { if (!h) { return TCA_ERROR_INVALID_ARGUMENT; } if (nodeid < 0 || nodeid >= tcaMaxNodeCount()) { return TCA_ERROR_INVALID_ARGUMENT; } int myid; tcaresult err = tcaGetNodeId(&myid); if (err) { return err; } uintptr_t addr; if (nodeid == myid) { routing_args rargs; if (ioctl(tca__fd(), PEACH2_PCIE_IOCTL_ROUTE_GET, &rargs)) { perror("ioctl(PEACH2_PCIE_IOCTL_ROUTE_GET)"); return TCA_ERROR_UNKNOWN; } addr = (static_cast<uintptr_t>(rargs.internal.min) << 16) | PEACH_DDR_ADDR_BASE; } else { addr = PEACH_DDR_ADDR_BASE; } h->nodeid = nodeid; h->ptr = reinterpret_cast<void*>(addr); h->pure_ptr = NULL; h->size = PEACH_DDR_SIZE; h->type = tcaMemoryCPU; return TCA_SUCCESS; } 上記関数を使用する。~ PEACH_DDR_ADDR_BASE ならびに PEACH_DDR_SIZEは事前に定義しておく。 -PEACH_DDR_ADDR_BASE~ ベースアドレス~ DDRなら0x08000000ULL~ 自作モジュールなら設定した値 -PEACH_DDR_SIZE~ 転送サイズ~ DDR 32K転送例 static const uintptr_t PEACH_DDR_ADDR_BASE = 0x08000000ULL; static const size_t PEACH_DDR_SIZE = 32ULL * 1024; 第一引数にはtcaCreateHandle型の自作モジュール用の変数を事前に定義~ 第二引数にはノードIDを設定。~ 自ノードのIDを調べるにはtcaGetNodeId関数を用いて取得~ 外部ノードの値を使用したら外部のPEACHなりDDRに転送できる(未検証)~ ハンドル設定例 int nodeid; tcaHandle ddr; tcaGetNodeId(nodeid); tcaCreateDDRHandle(%ddr, nodeid);