98 lines
3.0 KiB
Systemverilog
98 lines
3.0 KiB
Systemverilog
// vc credit counter per out port port
|
|
module output_port_vc_credit_counter
|
|
import rvh_noc_pkg::*;
|
|
#(
|
|
parameter VC_NUM = 4,
|
|
parameter VC_NUM_IDX_W = VC_NUM > 1 ? $clog2(VC_NUM) : 1,
|
|
parameter VC_DEPTH = 1,
|
|
parameter VC_DEPTH_COUNTER_W = $clog2(VC_DEPTH+1)
|
|
)
|
|
(
|
|
// input new free vc credit
|
|
input logic free_vc_credit_vld_i,
|
|
input logic [VC_NUM_IDX_W-1:0] free_vc_credit_vc_id_i,
|
|
|
|
// input new consume vc credit
|
|
input logic consume_vc_credit_vld_i,
|
|
input logic [VC_NUM_IDX_W-1:0] consume_vc_credit_vc_id_i,
|
|
|
|
// output to vc selection
|
|
output logic [VC_NUM-1:0][VC_DEPTH_COUNTER_W-1:0] vc_credit_counter_o,
|
|
|
|
input logic clk,
|
|
input logic rstn
|
|
|
|
);
|
|
genvar i;
|
|
|
|
// credit counter
|
|
logic [VC_NUM-1:0][VC_DEPTH_COUNTER_W-1:0] vc_credit_counter_d, vc_credit_counter_q;
|
|
logic [VC_NUM-1:0][VC_DEPTH_COUNTER_W-1:0] vc_credit_counter_q_plus1, vc_credit_counter_q_minus1;
|
|
logic [VC_NUM-1:0] vc_credit_counter_ena;
|
|
|
|
// credit counter nxt
|
|
logic [VC_NUM-1:0] free_vc_credit_vc_id_hit;
|
|
logic [VC_NUM-1:0] consume_vc_credit_vc_id_hit;
|
|
generate
|
|
for(i = 0; i < VC_NUM; i++) begin: gen_vc_credit_vc_id_hit
|
|
assign free_vc_credit_vc_id_hit [i] = free_vc_credit_vld_i & (free_vc_credit_vc_id_i == i[VC_NUM_IDX_W-1:0]);
|
|
assign consume_vc_credit_vc_id_hit[i] = consume_vc_credit_vld_i & (consume_vc_credit_vc_id_i == i[VC_NUM_IDX_W-1:0]);
|
|
end
|
|
endgenerate
|
|
|
|
generate
|
|
for(i = 0; i < VC_NUM; i++) begin: gen_vc_credit_counter_q_plus1
|
|
assign vc_credit_counter_q_plus1[i] = vc_credit_counter_q[i] + 1;
|
|
end
|
|
endgenerate
|
|
|
|
generate
|
|
for(i = 0; i < VC_NUM; i++) begin: gen_vc_credit_counter_q_minus1
|
|
assign vc_credit_counter_q_minus1[i] = vc_credit_counter_q[i] - 1;
|
|
end
|
|
endgenerate
|
|
|
|
generate
|
|
for(i = 0; i < VC_NUM; i++) begin: gen_vc_credit_counter_d
|
|
always_comb begin
|
|
vc_credit_counter_d [i] = vc_credit_counter_q[i];
|
|
vc_credit_counter_ena [i] = 1'b0;
|
|
if(free_vc_credit_vc_id_hit[i] & ~consume_vc_credit_vc_id_hit[i]) begin
|
|
vc_credit_counter_d [i] = vc_credit_counter_q_plus1[i];
|
|
vc_credit_counter_ena [i] = 1'b1;
|
|
end else if(~free_vc_credit_vc_id_hit[i] & consume_vc_credit_vc_id_hit[i]) begin
|
|
vc_credit_counter_d [i] = vc_credit_counter_q_minus1[i];
|
|
vc_credit_counter_ena [i] = 1'b1;
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
// dff vc_credit_counter_q
|
|
generate
|
|
for(i = 0; i < VC_NUM; i++) begin: gen_vc_credit_counter_q
|
|
std_dffrve
|
|
#(.WIDTH(VC_DEPTH_COUNTER_W))
|
|
U_DAT_VC_CREDIT_CONTER_REG
|
|
(
|
|
.clk(clk),
|
|
.rstn(rstn),
|
|
.rst_val(VC_DEPTH[VC_DEPTH_COUNTER_W-1:0]),
|
|
.en(vc_credit_counter_ena[i]),
|
|
.d(vc_credit_counter_d[i]),
|
|
.q(vc_credit_counter_q[i])
|
|
);
|
|
|
|
`ifndef SYNTHESIS
|
|
assert property(@(posedge clk)disable iff(~rstn) ((vc_credit_counter_q[i]) <= VC_DEPTH))
|
|
else $fatal("output_port_vc_credit_counter: vc credit counter overflow");
|
|
`endif
|
|
end
|
|
endgenerate
|
|
|
|
// output to vc selection
|
|
assign vc_credit_counter_o = vc_credit_counter_q;
|
|
|
|
|
|
endmodule
|