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

143 lines
4.4 KiB
Systemverilog
Executable File

`ifndef __AGE_ORDER_SELECTOR_SV__
`define __AGE_ORDER_SELECTOR_SV__
/*
* Age Matrix
* | Dependency bit |
* |E| | 0 | 1 | 2 | 3 |
* |N| 0 | 1 | 1 | 1 | 1 |
* |T| 1 | 0 | 1 | 1 | 1 |
* |R| 2 | 0 | 0 | 1 | 1 |
* |Y| 3 | 0 | 0 | 0 | 1 |
*
* age_matrix_r[i][i] : valid signal for entry(i)
* age_matrix_r[i][j] : if entry(j) deponds on entry(i)
*
* */
module age_order_selector #(
parameter int unsigned ENTRY_COUNT = 4,
parameter int unsigned ENQ_WIDTH = 1,
parameter int unsigned DEQ_WIDTH = 1,
parameter int unsigned SEL_WIDTH = 1,
localparam int unsigned ENTRY_TAG = $clog2(ENTRY_COUNT)
) (
// Enqueue
input logic [ENQ_WIDTH-1:0] enq_vld_i,
input logic [ENQ_WIDTH-1:0][ENTRY_TAG-1:0] enq_tag_i,
// Dequeue
input logic [DEQ_WIDTH-1:0] deq_vld_i,
input logic [DEQ_WIDTH-1:0][ENTRY_TAG-1:0] deq_tag_i,
// Status
output logic [ENTRY_COUNT-1:0] vld_mask_o,
// Select Oldest
input logic [SEL_WIDTH-1:0][ENTRY_COUNT-1:0] sel_mask_i,
output logic [SEL_WIDTH-1:0][ENTRY_COUNT-1:0] sel_oldest_mask_o,
// Flush
input logic flush_i,
input clk,
input rst
);
logic [ENTRY_COUNT-1:0][ENTRY_COUNT-1:0] age_matrix_r, age_matrix_n;
logic [ENTRY_COUNT-1:0] vld_mask;
logic [SEL_WIDTH-1:0][ENTRY_COUNT-1:0][ENTRY_COUNT-1:0] sel_age_matrix;
logic [SEL_WIDTH-1:0][ENTRY_COUNT-1:0] sel_oldest_mask;
logic clk_en;
assign clk_en = (|enq_vld_i) | (|deq_vld_i) | flush_i;
always_comb begin : get_vld_mask
for (int row = 0; row < ENTRY_COUNT; row++) begin
vld_mask[row] = age_matrix_r[row][row];
end
end
// Sel Oldest Logic
always_comb begin : gen_sel_matrix
for (int i = 0; i < SEL_WIDTH; i++) begin
for (int row = 0; row < ENTRY_COUNT; row++) begin
for (int col = 0; col < ENTRY_COUNT; col++) begin
if (row == col) begin
sel_age_matrix[i][row][col] = sel_mask_i[i][col];
end else begin
sel_age_matrix[i][row][col] = sel_mask_i[i][col] ? age_matrix_r[row][col] :
1'b1;
end
end
end
end
end
always_comb begin : gen_sel_oldest_mask
for (int i = 0; i < SEL_WIDTH; i++) begin
for (int row = 0; row < ENTRY_COUNT; row++) begin
sel_oldest_mask[i][row] = &sel_age_matrix[i][row];
end
end
end
// Update Logic
always_comb begin : update_logic
age_matrix_n = age_matrix_r;
for (int i = 0; i < ENQ_WIDTH; i++) begin
if (enq_vld_i[i]) begin
for (int col = 0; col < ENTRY_COUNT; col++) begin
age_matrix_n[enq_tag_i[i]][col] = ~age_matrix_r[col][col]; // Set Dependency
for(int j = 0; j < i; j++) begin
if(enq_vld_i[j]) begin
age_matrix_n[enq_tag_i[i]][enq_tag_i[j]] = 1'b0;
end
end
end
end
end
for (int i = 0; i < DEQ_WIDTH; i++) begin
if (deq_vld_i[i]) begin
for (int row = 0; row < ENTRY_COUNT; row++) begin
age_matrix_n[row][deq_tag_i[i]] = deq_tag_i[i] !=
row[ENTRY_TAG-1:0]; // Clear Dependency
end
end
end
if (flush_i) begin
for (int row = 0; row < ENTRY_COUNT; row++) begin
for (int col = 0; col < ENTRY_COUNT; col++) begin
age_matrix_n[row][col] = 1'b0;
end
end
end
end
always_ff @(posedge clk) begin : age_matrix_dff
if (rst) begin
for (int row = 0; row < ENTRY_COUNT; row++) begin
for (int col = 0; col < ENTRY_COUNT; col++) begin
age_matrix_r[row][col] <= 1'b0;
end
end
end else begin
if (clk_en) begin
age_matrix_r <= age_matrix_n;
end
end
end
// Output
assign vld_mask_o = vld_mask;
assign sel_oldest_mask_o = sel_oldest_mask;
endmodule : age_order_selector
`endif