アウトプットブログ

勉強したことをまとめていきます。

C関数で確保したメモリ領域にSystemVerilogからアクセス

DPI-Cを使用して、C言語malloc関数で確保したメモリ領域にSystemVerilogテストベンチからアクセスしてみる。最終的にはBMP等の画像ファイルをCで読み込んでテストデータとして使いたいと考えている。

以下ソース。今回は以下URLを参考にさせて頂いた。
Sharing memory between SV and DPI-C methods - Functional Verification - Cadence Technology Forums - Cadence Community

hoge_c.c

#include <stdio.h>
#include <stdlib.h>
#include "svdpi.h"

char *array = 0;
int i = 0;

void c_malloc (int array_size)
{
    int j = 0;

    array = (char *)malloc(array_size * sizeof(char));  // メモリ確保
    for (j = 0; j < array_size; j++) array[j] = j;      // インクリメントデータ格納
}

void c_free ()
{
    free(array);    // メモリ解放
}

char get_byte (int i, int array_size)
{
    char data;

    if ((i < 0) || (array_size < i)) i = 0; // 配列インデックスチェック
    data = array[i];    // 配列データ出力
    
    return data;
}

hoge_sv.sv

timeunit 1ns;
timeprecision 10ps;

module hoge_sv();
    import "DPI-C" function void c_malloc (int array_size);
    import "DPI-C" function void c_free ();
    import "DPI-C" function byte get_byte(int i, int array_size);
    
    bit clk_i = 1'b0;
    bit srst_i = 1'b1;
    int array_size = 64;
    int count;
    byte d;
    
    // クロック
    always begin
        #5ns clk_i = ~clk_i;
    end
    // リセット
    initial begin
        #100ns;
        @(posedge clk_i) srst_i = 1'b0;
    end
    // C言語/malloc関数でメモリ領域確保
    initial begin
        c_malloc(array_size);
    end
    // 1us後にC言語/free関数でメモリ領域解放
    initial begin
        #1us;
        c_free();
    end
    // 配列データインデックスカウント
    always @(posedge clk_i) begin
        if (srst_i == 1'b1) begin
            count = 0;
        end else
            if (count == (array_size - 1)) begin
                count = 0;
            end else
                count = count + 1;
    end
    // C関数にて生成したインクリメントデータを読み込み
    // 配列データを順番に読む
    always @(posedge clk_i) begin
        if (srst_i == 1'b1) begin
            d = 8'h00;
        end else
            d = get_byte(count, array_size);
    end
endmodule

シミュレーション結果が以下の通り。C関数で確保した領域にアクセスし、データを読み込めている。
f:id:HappyField:20151124001145p:plain

メモリ解放は問題なくできているのだろうか?1us後にfree関数を実行するはずなので確認すると、値がおかしい箇所がある。正直確認としては弱いが、関数の動作はしている気はするのでとりあえず良しとする。
f:id:HappyField:20151124001709p:plain