143 lines
4.4 KiB
Systemverilog
Executable File
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 |