Files
OpenExSys_NoC/rtl/output_port_vc_credit_counter.sv
2023-11-26 14:59:34 +01:00

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