Article #1136

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

メモリをBSVで書く (5)

posted by sakurai on October 5, 2026 #1136

メモリをBSVで書く (5)

4点目 運用

bsc付属のライブラリVerilogが3つ増えました。mkFIFOF1のFIFO1.v、mkBRAMCore1LoadのBRAM1Load.v、mkSyncBRAMCore2LoadのBRAM2Load.vで、bscはこれらを生成せず、インストール先のlib/Verilogにあるものをインスタンスします。教科書版のMakefileはこれをsrcに写して、生成Verilogと同じ扱いにします。

# bsc 付属の Verilog ライブラリ。mkBlitter が使う FIFO1 と BRAM1Load、
# mkVram が使う BRAM2Load はここから src に写す
BSC_VLIB     ?= $(abspath $(dir $(shell which $(BSC)))../lib/Verilog)
BSC_LIB_V    := FIFO1.v BRAM1Load.v BRAM2Load.v
$(addprefix $(RTL_DIR)/,$(BSC_LIB_V)): $(RTL_DIR)/%.v: $(BSC_VLIB)/%.v
	@mkdir -p $(RTL_DIR)
	cp $< $@

1つのソースから2つのモジュールを出す規則は、グループターゲットで3つの生成物を1回のレシピに結びます。Blitter.bsvからはmkBlitter.vとmkProm.vとBlitter.bo、SoundFSM.bsvからは変種ごとにmkSoundFSMn.vとmkSoundROMn.vです。

$(RTL_DIR)/mkBlitter.v $(RTL_DIR)/mkProm.v $(VOBJ_DIR)/Blitter.bo &: $(SRC_DIR)/Blitter.bsv
	@mkdir -p $(RTL_DIR) $(VOBJ_DIR)
	$(TIME) $(BSC) $(BSC_RT_OPTS) $(VLOG_FLAGS) $(PFLAGS) $(STEPFLAGS) \
	    -bdir $(VOBJ_DIR) -vdir $(RTL_DIR) -g mkBlitter -g mkProm $(SRC_DIR)/Blitter.bsv
$(RTL_DIR)/mkSoundFSM0.v $(RTL_DIR)/mkSoundROM0.v &: $(SRC_DIR)/SoundFSM.bsv $(SRC_DIR)/SoundCodes.vh
	$(call BSC_GEN_D,mkSoundFSM0 mkSoundROM0,$(SRC_DIR)/SoundFSM.bsv,FSM0)

make checkはライブラリ3つの所在も確認します。ライブラリが別の場所にあるときはmake BSC_VLIB=場所で指定します。Vivadoには、srcの他の.vと同様にこの3つと、新しく増えたmkProm.v、mkVram.v、mkSoundROM0.vから3を登録します。memの.memはライブラリのVerilogの中から同じ名前で読まれるので、登録は今までのままです。

手書きVerilogからはvram.v、rom.v、sndch.vが消え、master.vからROMのインスタンスが消えました。残るのはtop.v、clock.v、master.v、sound.vの4つで、clock.vのMMCMと分周以外は配線です。

Yosysで試すときは1つ注意があります。read_verilogに-deferを付けないと、BRAM1Load.vがパラメータの既定値である空のファイル名で$readmemhを評価して止まります。-deferを付けると、パラメータが確定してから本体を解釈します。

まとめ

比べる前は、ブリッタの起動をFIFOにした版で、ROMとVRAMは手書きVerilogです。後はこの記事の3点を入れた版です。LUTとFFはYosysのsynth_xilinxでフラットに合成した概算で、mkGameFSMの行はmkBlitterとmkPromを含みます。動作はVerilatorでmkGameFSMを1,200万サイクル回し、VRAM書き込みとサウンドコードの系列と時刻を比べました。

メモリのBSV化前後 前 後 備考
ソース Blitter.bsvとGameFSM.bsv[行] 1,870 1,883 mkPromを足し、ポート2つとレジスタ1つが消えた
Vram.bsv[行] 0 41 vram.vの34行が置き換わった
SoundFSM.bsv[行] 261 306 rom.vの26行とsndch.vの65行が置き換わった
生成Verilog[行] 32,863 32,911 mkBlitter.v、mkProm.v、mkGameFSM.vの合計
mkBlitter LUT 183 198 ROMを3個のBRAMに分ける選択論理
FF 160 149 p_addrの15ビットが消えた
RAMB36 0 3 mkProm 25728 x 4
mkGameFSM LUT 5,695 5,790 後はROMを含む
FF 2,168 2,157
mkVram RAMB36 8 8 前はvram.v
mkSoundFSMn ポート 2本 0本 rom_addressとrom_dataが消えた
動作 mkGameFSMの系列と時刻 一致 1,200万サイクル
サウンド4チャネルの出力 一致 300万サイクル、852コマンド

mkGameFSMのLUTが95増えていますが、前の値にはmaster.vにあったROMが入っていません。ROMの3個のBRAMを選ぶアドレスの比較と出力の選択がmkGameFSMの側に移った分で、設計全体では増えていません。FFの減りはp_addrの15ビットそのもので、読み出しデータのレジスタはBRAMの出力レジスタに置き換わりました。

メモリをBSVに移して得たものは、ブリッタのインタフェースからROMが消えたことです。ROMを読むのはブリッタだけなのに、アドレスとデータの2ポートがブリッタ、mkGameFSM、master.vの3階層を貫いていました。使う側の中に置けば、その経路は丸ごと要らなくなります。一方でFSMとROMは機能が別なので、ブリッタの中でもmkProm、サウンドFSMの中でもmkSoundROMnという別のモジュールにし、FSMはそれをメソッドで呼びます。パターンROMとサウンドROMが同じ形になりました。VRAMは2つのクロック域にまたがるのでトップに残りますが、クロックを引数で受けるBSVのモジュールになり、手書きVerilogは配線とクロック生成だけになりました。


左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.