VerilogでJSONフォーマットを読み込む

はじめに

VerilogでJSONフォーマットを読み込みます。

JsonのパースにはJSON11を使用します。JSON11はC++なので、VPIでVerilogとデータのやり取りを行います。

サンプルコード

まずはCコードを作成します。JSONフォーマットをパースするSystemタスクを作成します。

json_read.cpp
#include <iostream>
#include <fstream>
#include "json11.hpp"
#include "vpi_user.h"

int _json_read(std::string filepath, std::string key){
    std::ifstream fileStream(filepath);
    if (!fileStream.is_open()) {
        std::cerr << "JFailed to open JSON file." << std::endl;
        return 1;
    }
    std::string jsonString(
        (std::istreambuf_iterator<char>(fileStream)),
        std::istreambuf_iterator<char>()
    );

    std::string err;
    auto jsonObject = json11::Json::parse(jsonString, err);
    if (!err.empty()) {
        std::cerr << "JSON parse error: " << err << std::endl;
        return 1;
    }

    return jsonObject[key].int_value();
}

int json_read(char *userdata) {
    vpiHandle systf_h, args_iter, arg_h;
    s_vpi_value value;

    // Init
    systf_h = vpi_handle(vpiSysTfCall, NULL);
    args_iter = vpi_iterate(vpiArgument, systf_h);

    // Arg1
    arg_h = vpi_scan(args_iter);
    value.format = vpiStringVal;
    vpi_get_value(arg_h, &value);
    std::string filepath = value.value.str;

    // Arg2
    arg_h = vpi_scan(args_iter);
    value.format = vpiStringVal;
    vpi_get_value(arg_h, &value);
    std::string key = value.value.str;

    // Return value
    arg_h = vpi_scan(args_iter);
    value.value.integer = _json_read(filepath, key);
    value.format = vpiIntVal;
    vpi_put_value(arg_h, &value, NULL, vpiNoDelay);

    // Release
    vpi_free_object(args_iter);
    vpi_free_object(arg_h);

    return 0;
}

// Make SystemTask
void get_sum_register() {
    s_vpi_systf_data task_data = {vpiSysTask, 0, "$json_read", json_read, 0, 0, 0};
    vpi_register_systf(&task_data);
}

// Register SystemTask
void (*vlog_startup_routines[])() = {
    get_sum_register,
    0
};

作成したSystemタスクを使用するVerilogコードを作成します。

sample.sv
module sample;
    string a, b;
    int c;
    initial begin
        a = "data.json";
        b = "k1";
        $json_read(a, b, c);
        $display("%s [%s]: %d", a, b, c);
    end
endmodule

入力となるJSONファイルを用意します。

data.json
{
"k1": 11,
"k2": 22
}

準備が整ったので、コンパイルして実行します。

iverilog-vpi json_read.cpp -I/json11 /json11/json11.cpp
iverilog -g2005-sv sample.sv
vvp -M. -mjson_read a.out
# 出力
# data.json,  11

まとめ

Verilog+JSON11でJSONフォーマットを読み込みました。

コメント

タイトルとURLをコピーしました