0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonとJinja2で、FPGAのレジスタマップ作成から解放される話(ExcelからVerilog自動生成)

0
Last updated at Posted at 2026-02-05

1. はじめに

FPGA設計において、レジスタマップの定義や、構造が似たモジュールの記述といった「単純だけどミスの許されない作業」は、意外と設計者のリソースを奪います。

アドレスやビット幅を1つ間違えるだけで、作ったはずのレジスタが叩けなかったり、接続ミスでデバッグに数時間を溶かしたり……。その確認のためにテストベンチを書き、シミュレーションを回す時間だって馬鹿になりません。

2. なぜ自動化が必要だったのか

FPGA設計者はExcelに書かれた仕様書を読み解きながら、それを正確にVerilogコードに落とし込んでいくわけですが、そもそもこんな単純作業はエンジニアの本質的な仕事ではありません。

「Excelに仕様があるなら、そこから自動でVerilogコードを吐き出せばいい」

**「エンジニアは本質的な設計(ロジック)に集中すべき」**なのです。

3. ツールの構成と仕組み

この悩みを解決するために、Pythonを用いた自動生成ツールを構築しました。

Python 3.10
pandas: Excelの仕様書を解析するために使用
Jinja2: テキストベースのテンプレートエンジン。HDLのコード生成に最適

処理フロー
Excel定義: レジスタマップ(アドレス、ビット範囲、属性、初期値など)を作成
テンプレート作成: Jinja2でVerilogの「型」となるテンプレートを作成
自動生成: PythonでExcelをパースし、Jinja2にデータを流し込んでコードを出力

4. 実装のポイント

① 仕様となるExcelファイル
以下のような形式でレジスタを定義します。
image.png

② Jinja2テンプレート(抜粋)
単なる文字列結合ではなく、テンプレートエンジンを使うことで「rw/ro属性に応じた分岐」などをスマートに記述できます。

Verilog

always @(posedge i_cpu_clk or posedge i_areset) begin
    if (i_areset) begin
        {# rwまたはwo属性のレジスタのみ初期化 #}
        {% for reg in reg_list if reg.Type in ['rw', 'wo'] %}
        r_{{ reg.Name }} <= {{ reg.Reset|hex_verilog(reg.Width) }};
        {% endfor %}
        o_cpu_rddata <= 32'd0;
        o_cpu_rdvalid <= 1'b0;
    end else begin
        // 書き込み制御
        if (i_cpu_cs && i_cpu_wren) begin
            case (i_cpu_addr)
            {% for addr, group in reg_list|groupby('Offset') %}
            {% set write_fields = group|selectattr('Type', 'in', ['rw', 'wo'])|list %}
            {% if write_fields %}
                {{ addr_bits }}'h{{ "%X"|format(addr) }}: begin
                {% for field in write_fields %}
                    r_{{ field.Name }} <= i_cpu_wrdata[{{ field.MSB }}:{{ field.LSB }}];
                {% endfor %}
                end
            {% endif %}
            {% endfor %}
                default: ;
            endcase
        end
        // 読み出し制御
        if (i_cpu_cs && i_cpu_rden) begin
            o_cpu_rdvalid <= 1'b1;
            case (i_cpu_addr)
            {% for addr, group in reg_list|groupby('Offset') %}
            {% set read_ops = [] %}
            {% for r in group if r.Type != 'pulse' %}
            {% set src = "i_" + r.Name if r.Type == 'ro' else "r_" + r.Name %}
            {% do read_ops.append("(" + src + " << " + r.LSB|string + ")") %}
            {% endfor %}
            {% if read_ops %}
                {{ addr_bits }}'h{{ "%X"|format(addr) }}: begin
                    o_cpu_rddata <= {{ read_ops|join(' | ') }};
                end
            {% endif %}
            {% endfor %}
                default: o_cpu_rddata <= 32'd0;
            endcase
        end else begin
            o_cpu_rdvalid <= 1'b0;
        end
    end
end
 hex_verilog はVerilogの基数表現に変換するカスタムフィルタです

③ Pythonスクリプトでのパース(抜粋)
pandasを使ってExcelの各シート(モジュール単位)を読み込み、Jinja2に渡す辞書形式に整理します。

Python

import pandas as pd
from pathlib import Path

# ... (中略) ...

with pd.ExcelFile(xlsx_path) as xl:
    df_mod = pd.read_excel(xl, sheet_name=mod_name)
    reg_list_for_jinja = []
    
    # アドレス順にソートしてデータを整理
    df_mod['AddrInt'] = df_mod['AddrOffset'].apply(to_int_auto)
    df_sorted = df_mod.sort_values(['AddrInt'])

    for _, r in df_sorted.iterrows():
        msb, lsb, width = parse_bit_range(r['BitRange'])
        reg_data = {
            "Name": str(r['Name']),
            "Offset": int(r['AddrInt']),
            "MSB": msb, "LSB": lsb, "Width": width,
            "Type": r['Type'],
            "Reset": to_int_auto(r.get('Reset', 0)),
            # ... その他必要なパラメータ ...
        }
        reg_list_for_jinja.append(reg_data)

5. 自動化によって得られた効果

このツールの導入により、これまで数時間かかっていた「レジスタの実装からタイポによるバグ取り」までの作業が、わずか数秒で完了するようになりました。

何より大きいのは、**「仕様書(Excel)と実装(コード)が常に100%一致する」**という安心感です。仕様変更があってもExcelを直してスクリプトを叩くだけ。人為的ミスを恐れる必要はもうありません。

6. まとめ

ExcelのレジスタマップをVerilogに落とし込むという「非創造的な単純作業」を自動化したことで、より本質的なロジック設計やアーキテクチャの検討に時間を割けるようになりました。

7. 今後の展望

レジスタコードが自動生成できるなら、その情報を活用しない手はありません。 次回は、このExcelデータから**「評価用GUI(Python/Tkinter)を自動生成する」**取り組みについて書きたいと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?