FPGA開発日記

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

オープンソース形式検証ツールSymbiYosysを用いて形式検証に入門する (12. BMCモードにおけるFIFOの検証)

カテゴリインデックス:https://msyksphinz.hatenablog.com/entry/2024/12/14/040000

形式検証ツールSymbiYosysを用いたFIFOの検証

検証対象のFIFO

検証対象としたFIFOは、以下の特徴を持つシンプルな実装である:

  • データ幅:8ビット(パラメータ化可能)
  • エントリ数:4
  • 制御信号:プッシュ(書き込み)、ポップ(読み出し)
  • 状態信号:フル、エンプティ

実装コード

module fifo4
  #(
    parameter WIDTH = 8
    )
(
 input logic              i_clk,
 input logic              i_rst_n,
 input logic              i_push,
 input logic              i_pop,
 input logic [WIDTH-1:0]  i_din,
 output logic [WIDTH-1:0] o_dout,

 output logic             o_full,
 output logic             o_empty
);
logic [WIDTH-1:0]             r_mem [3:0];
logic [ 2: 0]                 rd_ptr, wr_ptr, r_count;

assign o_full  = (r_count == 'h4);
assign o_empty = (r_count == 'h0);

always_ff @(posedge i_clk or negedge i_rst_n) begin
  if (!i_rst_n) begin
    rd_ptr  <= 'h0;
    wr_ptr  <= 'h0;
    r_count <= 'h0;
  end else begin
    if (i_push && !o_full) begin
      r_mem[wr_ptr] <= i_din;
      wr_ptr        <= wr_ptr + 1;
    end
    if (i_pop & !o_empty) begin
      o_dout <= r_mem[rd_ptr];
      rd_ptr <= rd_ptr + 1;
    end
    case ({i_push && !o_full, i_pop && !o_empty})
      2'b10: r_count <= r_count + 'h1;
      2'b01: r_count <= r_count - 'h1;
      default: ;
    endcase // case ({i_push && !o_full, i_pop && !o_empty})
  end // else: !if(!i_rst_n)
end // always @ (posedge i_clk or negedge i_rst_n)

`ifdef FORMAL
wire push = i_push & !o_full;
wire pop  = i_pop  & !o_empty;
always_comb begin
  // Doesn't happen full & push
  assert ((o_full & push) == 0);
  // Doesn't happen empty & pop
  assert ((o_empty & pop) == 0);
end
`endif // FORMAL

endmodule // fifo4

形式検証の設定

形式検証には、以下の設定ファイルを使用した:

[options]
mode bmc
depth 40

[engines]
smtbmc z3

[script]
read -sv -formal fifo4.sv
prep -top fifo4

[files]
fifo4.sv

主な設定項目: - 検証モード:BMC(Bounded Model Checking) - 検証深度:40ステップ - 使用エンジン:Z3

検証結果

形式検証の結果、以下のことが確認できた:

  1. フル状態でのプッシュ操作が発生しないこと
  2. エンプティ状態でのポップ操作が発生しないこと

検証ログ:

SBY 16:36:59 [fifo4_bmc] engine_0: Status: passed
SBY 16:36:59 [fifo4_bmc] engine_0: finished (returncode=0)
SBY 16:36:59 [fifo4_bmc] engine_0: Status returned by engine: pass