ASAP Top ざんていばん written by tsuru (2015/08/28)
PEACH3の話もしたいので新しく作り直し。とりあえず更新 written by tsuru (2017/02/14)

ハードウェア編

自作モジュールを作る

  • 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を起動

  • PEACH2 or 3ボードの種類を確認する
  • デフォルトでは(p2g_512_140606a.tgzを解凍後)はEP4SGX530NF45C2になっている
  • ふんが研にあるボードはEP4SGX290NF45C2なのでこれに変更
    • EP4SGX530NF45C2 → 筑波にあるPEACH2(たぶん)
    • EP4SGX290NF45C2 → hunga lab
  • PEACH3
    • 圧縮ファイル解凍後のボードをそのまま使う。

Qsysでモジュールを繋げる

  • File-Open で 作業ディレクトリ-nios_sys_next-nios_sys.qsysを開く
  • PEACH3でもらってるディレクトリだと 20.ip--nios_sys_next-nios_sys.qsys
  • 左のLibrary内のProject-New Componentで新しいコンポーネントを開く
  • verilogファイルを書き換えたらコンポーネントも作り直す

New Component

  • Component Type
    name, Display nameを設定
  • File
    synthesis Files に自作モジュールを追加
    一応Analayse Synthesisする
  • signals
    入出力名をきちんと設定していれば自動的にs1になる・・・はず
  • interfaces
    clock-parameter を150000000(150 MHz)に設定
    irq0-Associated Reset をnone->resetに設定(これやらなくていいぽい?)

Qsys

  • nios2_qsys_0をダブルクリック
    select a Nios II core にてNios II/e を選択
  • 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でコンパイル

  • そこそこ時間がかかる
  • ここでFPGAの使用率とかでる
  • コンパイルがうまく行かないときはtopファイル(rtl/peach2_logic.v)の最初のところにある
    //`define NOGBE
    を変更し
    `define NOGBE or `define NOGBE 1
    にするといいかもしれない

design space Explorerで完成

  • quartusのtoolタブから
  • やばいくらい時間がかかる
    以下某所からコピペ

日立超Lおすすめ設定

日立超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は素数列です.)

ソフトウェア編

結局は割り当てた番地へのDMA
基本的に転送の方法は普段と同じ

  • 初期化
  • メモリの確保
  • ハンドルの作成
  • ディスクリプタの生成・セット
  • 通信開始
  • 終了検知
    この中で通常の転送と違うのはハンドルの作成について

自作モジュール用ハンドル作成

筑波大藤田様様に作成していただいた自作モジュール用ハンドル作成関数

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
Last-modified: 2019-08-29 (木) 00:03:48