前回はSCR1のシミュレーション環境でシミュレーション実行時にモジュールが足りないというエラーが出たためその解析を行った。
最初のエラーは解決したが、その後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のインスタンス記述
コメントアウト後に再度シミュレーションを実行。
あ、動いた。。。
ということで原因はscr1_memory_tb_axi
の中の記述の何か、、ということで確定。
scr1_memory_tb_axiの解析
原因となっている、scr1_memory_tb_axi
の中身を見ていく。
大まかに書くと以下の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
うーーむ、特に気になる記述も無い。。。
アサーションか?と思って、コメントアウトしてみたけど、それでもエラーは変わらず。ってそりゃそうか、パースは通ってるっぽいんだし。
まさかと思って、メモリのサイズを変更してみた。
動いた!!
画像のscopeのとこのテストベンチ階層構造にscr1_memory_tb_axi
が入った状態でシミュレーションが出来ている。
初期サイズは1 * 1024 * 1024
で1MBの領域をメモリとして確保しているが、それだと大きすぎる様子。
サイズを振って調べてみたところ32KBなら動くみたい。
シミュレーションでは、riscv-testが動けばいいので32KBくらいなら大丈夫かな、たぶん。。
とりあえず、Vivadoシミュレータでのシミュレーションも可能になったので、次はRISCVのビルド環境の構築に取り掛かる。