[[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);

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS