FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Vivadoにおいて論理合成で生成されたすべてのレジスタをリストアップする方法

追記:本当は[all_registers]のほうがいい。

Design Compilerとかだと結構あるけれども、Vivadoの論理合成スクリプトにおいて、フリップフロップがどの程度使用されたかを確認したい時がある。

このために、VivadoのDCPからすべてのフリップフロップのセルを抽出してファイルに書き出す方法を調査する。

まず、基本的にセルを抽出するためにはget_cellsを使用する。

docs.xilinx.com

set regs [get_cells -hier -filter {PRIMITIVE_TYPE =~ REGISTER*}]

フィルタを使用して、セルのタイプがレジスタのものを集めていくということだ。本当はget_cellsの結果を直接リダイレクトできればいいのだけれども、どうもそれができないっぽいので、抽出したセルのリストをファイルに書き出していくということにする。

set regs [get_cells -hier -filter {PRIMITIVE_TYPE =~ REGISTER*}]

set fp [open ${TOP_NAME}_ff_list.txt w]
foreach reg $regs {
    puts $fp $reg
}
close $fp

以下のようなフリップフロップのリストが生成される。

u_core_tile/u_lsu_top/u_ldq/ldq_stq_haz_loop[0].ldq_haz_check_if[0]\\.ex3_haz_valid_reg
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][0]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][10]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][11]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][12]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][13]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][14]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][15]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][16]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][17]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][18]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][19]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][1]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][20]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][21]
u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr][22]

例えば、LDQとSTQの各エントリでどれくらいフリップフロップを使用しているのかを調査してみる。 各ビットを示す[xx]を除去して、uniqコマンドで集約してカウントしてみることで、各フィールドでどの程度消費しているのかを見積もることができる。

$ grep "ldq_loop\[0\]" core_tile_wrapper_ff_list.txt | sed 's/\[[0-9]*\]$//g' | uniq -c | sort -n
      1 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[dead]
      1 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[is_committed]
      1 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[is_get_data]
      1 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[is_valid]
      1 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[paddr_valid]
      3 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[inst][grp_id]
      3 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[size]
      5 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[inst][cmt_id]
     39 u_core_tile/u_lsu_top/u_ldq/ldq_loop[0].u_entry/r_entry_reg[addr]
$ grep "stq_loop\[0\]" core_tile_wrapper_ff_list.txt | sed 's/\[[0-9]*\]$//g' | uniq -c | sort -n
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[dead]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[except_valid]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][rd_reg][ready]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][rd_reg][typ]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][rd_reg][valid]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_amo]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_committed]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_rmw]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_rs2_get]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_uc]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[is_valid]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[paddr_valid]
      1 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[st_buf_finished]
      3 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][grp_id]
      3 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[size]
      5 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][cmt_id]
      5 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[rmwop]
      7 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[inst][rd_reg][rnid]
     39 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[addr]
     64 u_core_tile/u_lsu_top/u_stq/stq_loop[0].u_entry/r_entry_reg[rs2_data]