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に設定。
quartusでコンパイル †
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);