1212// AXI Reservation Table
1313module axi_res_tbl # (
1414 parameter int unsigned AXI_ADDR_WIDTH = 0 ,
15- parameter int unsigned AXI_ID_WIDTH = 0
15+ parameter int unsigned AXI_ID_WIDTH = 0 ,
16+ parameter int unsigned NUM_RESERVATIONS = 2 ** AXI_ID_WIDTH
1617) (
1718 input logic clk_i,
1819 input logic rst_ni,
@@ -30,49 +31,157 @@ module axi_res_tbl #(
3031
3132 localparam integer N_IDS = 2 ** AXI_ID_WIDTH ;
3233
33- // Declarations of Signals and Types
34- logic [N_IDS - 1 : 0 ][AXI_ADDR_WIDTH - 1 : 0 ] tbl_d, tbl_q;
35- logic clr,
36- set,
37- match;
34+ if (N_IDS <= NUM_RESERVATIONS ) begin : gen_standard_table
35+ // Declarations of Signals and Types
36+ logic [N_IDS - 1 : 0 ][AXI_ADDR_WIDTH - 1 : 0 ] tbl_d, tbl_q;
37+ logic clr,
38+ set,
39+ match;
3840
39- assign match = (tbl_q[check_id_i] == check_clr_addr_i);
41+ assign match = (tbl_q[check_id_i] == check_clr_addr_i);
4042
41- generate for (genvar i = 0 ; i < N_IDS ; ++ i) begin : gen_tbl
43+ for (genvar i = 0 ; i < N_IDS ; ++ i) begin : gen_tbl
44+ always_comb begin
45+ tbl_d[i] = tbl_q[i];
46+ if (set && i == set_id_i) begin
47+ tbl_d[i] = set_addr_i;
48+ end else if (clr && tbl_q[i] == check_clr_addr_i) begin
49+ tbl_d[i] = '0 ;
50+ end
51+ end
52+ end
53+
54+ // Table-Managing Logic
4255 always_comb begin
43- tbl_d[i] = tbl_q[i];
44- if (set && i == set_id_i) begin
45- tbl_d[i] = set_addr_i;
46- end else if (clr && tbl_q[i] == check_clr_addr_i) begin
47- tbl_d[i] = '0 ;
56+ clr = 1'b0 ;
57+ set = 1'b0 ;
58+ set_gnt_o = 1'b0 ;
59+ check_res_o = 1'b0 ;
60+ check_clr_gnt_o = 1'b0 ;
61+
62+ if (check_clr_req_i) begin
63+ check_clr_gnt_o = 1'b1 ;
64+ check_res_o = match;
65+ clr = ! (check_clr_excl_i && ! match);
66+ end else if (set_req_i) begin
67+ set = 1'b1 ;
68+ set_gnt_o = 1'b1 ;
4869 end
4970 end
50- end endgenerate
51-
52- // Table-Managing Logic
53- always_comb begin
54- clr = 1'b0 ;
55- set = 1'b0 ;
56- set_gnt_o = 1'b0 ;
57- check_res_o = 1'b0 ;
58- check_clr_gnt_o = 1'b0 ;
59-
60- if (check_clr_req_i) begin
61- check_clr_gnt_o = 1'b1 ;
62- check_res_o = match;
63- clr = ! (check_clr_excl_i && ! match);
64- end else if (set_req_i) begin
65- set = 1'b1 ;
66- set_gnt_o = 1'b1 ;
71+
72+ // Registers
73+ always_ff @ (posedge clk_i, negedge rst_ni) begin
74+ if (~ rst_ni) begin
75+ tbl_q <= '0 ;
76+ end else begin
77+ tbl_q <= tbl_d;
78+ end
6779 end
68- end
80+ end else begin : gen_prlu_table
81+ // Declarations of Signals and Types
82+ logic [NUM_RESERVATIONS - 1 : 0 ][AXI_ADDR_WIDTH - 1 : 0 ] tbl_d, tbl_q;
83+ logic clr, set, match, matching_set;
84+ logic [NUM_RESERVATIONS - 1 : 0 ] plru_used, plru_evict_oh;
85+ logic [cf_math_pkg :: idx_width (NUM_RESERVATIONS )- 1 : 0 ] plru_evict;
86+ logic [NUM_RESERVATIONS - 1 : 0 ][AXI_ID_WIDTH - 1 : 0 ] tbl_id_d, tbl_id_q;
87+ logic [NUM_RESERVATIONS - 1 : 0 ] field_in_use_d, field_in_use_q;
88+
89+ plru_tree # (
90+ .ENTRIES (NUM_RESERVATIONS )
91+ ) i_reservation_plru (
92+ .clk_i (clk_i),
93+ .rst_ni (rst_ni),
94+ .used_i (plru_used),
95+ .plru_o (plru_evict_oh)
96+ );
6997
70- // Registers
71- always_ff @ (posedge clk_i, negedge rst_ni) begin
72- if (~ rst_ni) begin
73- tbl_q <= '0 ;
74- end else begin
75- tbl_q <= tbl_d;
98+ onehot_to_bin # (
99+ .ONEHOT_WIDTH (NUM_RESERVATIONS )
100+ ) i_reservation_plru_bin (
101+ .onehot (plru_evict_oh),
102+ .bin (plru_evict)
103+ );
104+
105+ always_comb begin
106+ tbl_d = tbl_q;
107+ tbl_id_d = tbl_id_q;
108+ matching_set = 1'b0 ;
109+ field_in_use_d = field_in_use_q;
110+ if (set) begin
111+ // First reuse existing entry for ID
112+ for (int i = 0 ; i < NUM_RESERVATIONS ; ++ i) begin
113+ if (set_id_i == tbl_id_q[i]) begin
114+ tbl_d[i] = set_addr_i;
115+ plru_used[i] = 1'b1 ;
116+ matching_set = 1'b1 ;
117+ field_in_use_d[i] = 1'b1 ;
118+ break ;
119+ end
120+ end
121+ // Then check for unused entries
122+ for (int i = 0 ; i < NUM_RESERVATIONS ; ++ i) begin
123+ if (! field_in_use_q[i] && ! matching_set) begin
124+ tbl_d[i] = set_addr_i;
125+ plru_used[i] = 1'b1 ;
126+ matching_set = 1'b1 ;
127+ field_in_use_d[i] = 1'b1 ;
128+ break ;
129+ end
130+ end
131+ // Finally evict the least recently used entry
132+ for (int i = 0 ; i < NUM_RESERVATIONS ; ++ i) begin
133+ if (i == plru_evict && ! matching_set) begin
134+ tbl_d[i] = set_addr_i;
135+ tbl_id_d[i] = set_id_i;
136+ plru_used[i] = 1'b1 ;
137+ field_in_use_d[i] = 1'b1 ;
138+ end
139+ end
140+ end else if (clr) begin
141+ for (int i = 0 ; i < NUM_RESERVATIONS ; ++ i) begin
142+ if (tbl_q[i] == check_clr_addr_i) begin
143+ tbl_d[i] = '0 ;
144+ field_in_use_d[i] = 1'b0 ;
145+ end
146+ end
147+ end
148+ end
149+
150+ // Table-Managing Logic
151+ always_comb begin
152+ clr = 1'b0 ;
153+ set = 1'b0 ;
154+ set_gnt_o = 1'b0 ;
155+ check_res_o = 1'b0 ;
156+ check_clr_gnt_o = 1'b0 ;
157+ match = 1'b0 ;
158+
159+ if (check_clr_req_i) begin
160+ for (int i = 0 ; i < NUM_RESERVATIONS ; i++ ) begin
161+ match | = (tbl_q[i] == check_clr_addr_i) &&
162+ (tbl_id_q[i] == check_id_i) &&
163+ field_in_use_q[i];
164+ end
165+ check_clr_gnt_o = 1'b1 ;
166+ check_res_o = match;
167+ clr = ! (check_clr_excl_i && ! match);
168+ end else if (set_req_i) begin
169+ set = 1'b1 ;
170+ set_gnt_o = 1'b1 ;
171+ end
172+ end
173+
174+ // Registers
175+ always_ff @ (posedge clk_i, negedge rst_ni) begin
176+ if (~ rst_ni) begin
177+ tbl_q <= '0 ;
178+ tbl_id_q <= '0 ;
179+ field_in_use_q <= '0 ;
180+ end else begin
181+ tbl_q <= tbl_d;
182+ tbl_id_q <= tbl_id_d;
183+ field_in_use_q <= field_in_use_d;
184+ end
76185 end
77186 end
78187
0 commit comments