FPGA開発日記

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

Vivado Simulatorを使ってUVMに入門する (18. Round Robin Arbiter向けのUVMを作る)

前回はこちら:msyksphinz.hatenablog.com

次はラウンドロビン型の4入力Arbiterを作って、UVMで検証してみようと思う。

  • arbiter4_rr.sv
module arbiter4_rr
  (
   input logic          i_clk,
   input logic          i_reset_n,

   input logic          i_valid0,
   input logic [15: 0]  i_data0,
   input logic          i_valid1,
   input logic [15: 0]  i_data1,
   input logic          i_valid2,
   input logic [15: 0]  i_data2,
   input logic          i_valid3,
   input logic [15: 0]  i_data3,

   output logic         o_valid,
   output logic [15: 0] o_data
   );

優先度を勝ち取ったポートの情報がr_current_ptrに格納されているものとし、これに基づいて、優先度順にポートを並び替える。

always_comb begin
  case (r_current_ptr)
    'h0 : begin
      w_valids = {i_valid1, i_valid2, i_valid3, i_valid0};
      w_idx    = {1, 2, 3, 0};
      w_data[3] = i_data1;
      w_data[2] = i_data2;
      w_data[1] = i_data3;
      w_data[0] = i_data0;
    end
    'h1 : begin
      w_valids = {i_valid2, i_valid3, i_valid0, i_valid1};
      w_idx    = {2, 3, 0, 1};
      w_data[3] = i_data2;
      w_data[2] = i_data3;
      w_data[1] = i_data0;
      w_data[0] = i_data1;
    end
    'h2 : begin
      w_valids = {i_valid3, i_valid0, i_valid1, i_valid2};
      w_idx    = {3, 0, 1, 2};
      w_data[3] = i_data3;
      w_data[2] = i_data0;
      w_data[1] = i_data1;
      w_data[0] = i_data2;
    end
    default begin // 'h3 : begin
      w_valids = {i_valid0, i_valid1, i_valid2, i_valid3};
      w_idx    = {0, 1, 2, 3};
      w_data[3] = i_data0;
      w_data[2] = i_data1;
      w_data[1] = i_data2;
      w_data[0] = i_data3;
    end
  endcase // case (r_current_ptr)

これをもとに、通常の優先度付きArbitrationを行う。

  casex (w_valids)
    4'b1xxx : begin o_data = w_data[3]; w_current_ptr_next = w_idx[3]; end
    4'b01xx : begin o_data = w_data[2]; w_current_ptr_next = w_idx[2]; end
    4'b001x : begin o_data = w_data[1]; w_current_ptr_next = w_idx[1]; end
    4'b0001 : begin o_data = w_data[0]; w_current_ptr_next = w_idx[0]; end
    default : begin o_data = 'h0;       w_current_ptr_next = 'h0;      end
  endcase