ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

RISC-Vの実装の1つ - SCR1の解析 - Vivadoプロジェクト準備(3)

スポンサーリンク

前回はSCR1のシミュレーション環境でシミュレーション実行時にモジュールが足りないというエラーが出たためその解析を行った。

tech-diningyo.hatenablog.com

最初のエラーは解決したが、その後Vivadoのシミュレータがセグメンテーション違反で強制終了したため今回はそのエラーの解析を行っていく。

SIGSEGVの解析

Vivadoのバージョンの変更

現在使用しているVivadoは2017.4。Vivadoは1年に4回リリースが行われるので、この記事の執筆時の最新バージョンは2018.2となっている。 まずは、2017.4以降のリリースで改善されているかもしれないことに一縷の望みをかけて新しいバージョンで実行してみる。

Vivado バージョン 結果
2018.1 変わらずSIGSEGVで落ちる
2018.2 変わらずSIGSEGVで落ちる

ダメかぁ。。

ちゃんと原因を調査する

原因を確定させるために、もう一度ログを眺めてみる。

Compiling module xil_defaultlib.scr1_core_top
Compiling module xil_defaultlib.scr1_dp_memory_default
Compiling module xil_defaultlib.scr1_tcm
Compiling module xil_defaultlib.scr1_timer
Compiling module xil_defaultlib.scr1_imem_router(SCR1_ADDR_PATTE...
Compiling module xil_defaultlib.scr1_dmem_router(SCR1_PORT1_ADDR...
Compiling module xil_defaultlib.scr1_mem_axi_default
Compiling module xil_defaultlib.scr1_top_axi
Compiling module xil_defaultlib.scr1_memory_tb_axi_default
ERROR: [XSIM 43-3316] Signal SIGSEGV received.

xil_defaultlib.scr1_memory_tb_axi_defaultコンパイル中にSIGSEGVが発生しているので、このファイルの中に原因となる記述が入っているということになる。 とりあえず、このファイルが原因かを判断するためにテストベンチ上からモジュールscr1_memory_tb_axiインスタンス記述を削除する。 具体的には、scr1/src/tb/scr1_top_tb_axi.svの中の以下の部分をコメントアウト

  • L.168 - L.214 : シミュレーション制御用のinitial ~ endブロック
  • L.338 - L.390 : scr1_memory_tb_axiのインスタンス記述

コメントアウト後に再度シミュレーションを実行。

f:id:diningyo-kpuku-jougeki:20180819222209p:plain

あ、動いた。。。
ということで原因はscr1_memory_tb_axiの中の記述の何か、、ということで確定。

scr1_memory_tb_axiの解析

原因となっている、scr1_memory_tb_axiの中身を見ていく。

github.com

大まかに書くと以下の4つの構成。

  • L.8 - L.60 : モジュール宣言
module scr1_memory_tb_axi #(
    parameter SIZE   = 1*1024*1024,
    parameter N_IF   = 2,
    parameter W_ID   = 4,
    parameter W_ADR  = 32,
    parameter W_DATA = 32
)
(
    // System
    input   logic                          rst_n,
    input   logic                          clk,

~~
);
  • L.65 - L141 : パラメータと基本タスク(read/write)の実装
//-------------------------------------------------------------------------------
// Local parameters
//-------------------------------------------------------------------------------
localparam [W_ADR-1:0]                      PRINT_ADDR     = 32'hF000_0000;
localparam [W_ADR-1:0]                      IRQ_ADDR       = 32'hF000_0100;

~~

//-------------------------------------------------------------------------------
// Local functions
//-------------------------------------------------------------------------------

function automatic logic [W_DATA-1:0] mem_read (
    logic [W_ADR:0] adr,
    int             bytes_num,
    int             bytes_max
    );
~~
endfunction : mem_read

function automatic void mem_write (
    logic [W_ADR-1:0]      adr,
    logic [W_DATA-1:0]     data,
    logic [(W_DATA/8)-1:0] bytes_en,
    int                    bytes_num,
    int                    bytes_max
    );
~~
endfunction : mem_write
  • L.146 - L.149 : 実行バイナリの読み込み
//-------------------------------------------------------------------------------
// Load file to mem
//-------------------------------------------------------------------------------
always @(negedge rst_n) begin
    memory = '{SIZE{'0}};
    if(stuff_file.len()>0) $readmemh(stuff_file,memory);
end
  • L.151以降 : AXI I/Fの実装
enerate for(gi=0; gi<N_IF; ++gi) begin : rw_if

//-------------------------------------------------------------------------------
// Read operation
//-------------------------------------------------------------------------------
always @(posedge clk, negedge rst_n) begin

~~

end endgenerate

うーーむ、特に気になる記述も無い。。。
アサーションか?と思って、コメントアウトしてみたけど、それでもエラーは変わらず。ってそりゃそうか、パースは通ってるっぽいんだし。 まさかと思って、メモリのサイズを変更してみた。

f:id:diningyo-kpuku-jougeki:20180819224908p:plain

動いた!!
画像のscopeのとこのテストベンチ階層構造にscr1_memory_tb_axiが入った状態でシミュレーションが出来ている。 初期サイズは1 * 1024 * 1024で1MBの領域をメモリとして確保しているが、それだと大きすぎる様子。
サイズを振って調べてみたところ32KBなら動くみたい。
シミュレーションでは、riscv-testが動けばいいので32KBくらいなら大丈夫かな、たぶん。。
とりあえず、Vivadoシミュレータでのシミュレーションも可能になったので、次はRISCVのビルド環境の構築に取り掛かる。