前回はこちら: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