Skip to content

Commit 6f24184

Browse files
authored
Merge pull request #39 from pulp-platform/num_reservations
Add support for limited number of reservations
2 parents 4b534f2 + cb350a6 commit 6f24184

7 files changed

Lines changed: 179 additions & 43 deletions

src/axi_res_tbl.sv

Lines changed: 146 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
// AXI Reservation Table
1313
module 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

src/axi_riscv_atomics.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ module axi_riscv_atomics
4646
parameter bit FULL_BANDWIDTH = 1'b1,
4747
/// Cut combinational path between input and output in LRSC ID queues with full bandwidth
4848
parameter bit CUT_OUP_POP_INP_GNT = 1'b0,
49+
/// Number of simultaineous LRSC reservations (power of 2, <= 2^AXI_ID_WIDTH or <= 2^(AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1))
50+
parameter int unsigned NUM_RESERVATIONS = 2**(AXI_USER_AS_ID ?
51+
AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1
52+
: AXI_ID_WIDTH),
4953
/// Derived Parameters (do NOT change manually!)
5054
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8
5155
) (
@@ -494,7 +498,8 @@ module axi_riscv_atomics
494498
.AXI_USER_ID_LSB (AXI_USER_ID_LSB),
495499
.AXI_ADDR_LSB (AXI_ADDR_LSB),
496500
.FULL_BANDWIDTH (FULL_BANDWIDTH),
497-
.CUT_OUP_POP_INP_GNT (CUT_OUP_POP_INP_GNT)
501+
.CUT_OUP_POP_INP_GNT (CUT_OUP_POP_INP_GNT),
502+
.NUM_RESERVATIONS (NUM_RESERVATIONS)
498503
) i_lrsc (
499504
.clk_i ( clk_i ),
500505
.rst_ni ( rst_ni ),

src/axi_riscv_atomics_structs.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ module axi_riscv_atomics_structs #(
3333
parameter int unsigned AxiAddrLSB = $clog2(AxiDataWidth/8),
3434
parameter bit FullBandwidth = 1,
3535
parameter bit CutOupPopInpGnt = 0,
36+
parameter int unsigned NumReservations = 2**(AxiUserAsId ?
37+
AxiUserIdMsb - AxiUserIdLsb + 1
38+
: AxiIdWidth),
39+
3640
parameter type axi_req_t = logic,
3741
parameter type axi_rsp_t = logic
3842
) (
@@ -78,7 +82,8 @@ module axi_riscv_atomics_structs #(
7882
.RISCV_WORD_WIDTH ( RiscvWordWidth ),
7983
.N_AXI_CUT ( NAxiCuts ),
8084
.FULL_BANDWIDTH ( FullBandwidth ),
81-
.CUT_OUP_POP_INP_GNT ( CutOupPopInpGnt )
85+
.CUT_OUP_POP_INP_GNT ( CutOupPopInpGnt ),
86+
.NUM_RESERVATIONS ( NumReservations )
8287
) i_axi_riscv_atomics_wrap (
8388
.clk_i,
8489
.rst_ni,

src/axi_riscv_atomics_wrap.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ module axi_riscv_atomics_wrap #(
4343
parameter bit FULL_BANDWIDTH = 1'b1,
4444
/// Cut combinational path between input and output in LRSC ID queues with full bandwidth
4545
parameter bit CUT_OUP_POP_INP_GNT = 1'b0,
46+
/// Number of simultaineous LRSC reservations (power of 2, <= 2^AXI_ID_WIDTH or <= 2^(AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1))
47+
parameter int unsigned NUM_RESERVATIONS = 2**(AXI_USER_AS_ID ?
48+
AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1
49+
: AXI_ID_WIDTH),
4650
/// Derived Parameters (do NOT change manually!)
4751
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8
4852
) (
@@ -66,7 +70,8 @@ module axi_riscv_atomics_wrap #(
6670
.RISCV_WORD_WIDTH (RISCV_WORD_WIDTH),
6771
.N_AXI_CUT (N_AXI_CUT),
6872
.FULL_BANDWIDTH (FULL_BANDWIDTH),
69-
.CUT_OUP_POP_INP_GNT (CUT_OUP_POP_INP_GNT)
73+
.CUT_OUP_POP_INP_GNT (CUT_OUP_POP_INP_GNT),
74+
.NUM_RESERVATIONS (NUM_RESERVATIONS)
7075
) i_atomics (
7176
.clk_i ( clk_i ),
7277
.rst_ni ( rst_ni ),

src/axi_riscv_lrsc.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ module axi_riscv_lrsc #(
4848
parameter bit FULL_BANDWIDTH = 1'b1,
4949
/// Cut combinational path between input and output in ID queues with full bandwidth
5050
parameter bit CUT_OUP_POP_INP_GNT = 1'b0,
51+
/// Number of simultaineous reservations (power of 2, <= 2^AXI_ID_WIDTH or <= 2^(AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1))
52+
parameter int unsigned NUM_RESERVATIONS = 2**(AXI_USER_AS_ID ?
53+
AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1
54+
: AXI_ID_WIDTH),
5155
/// Derived Parameters (do NOT change manually!)
5256
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8
5357
) (
@@ -1030,7 +1034,8 @@ module axi_riscv_lrsc #(
10301034
: slv_ar_id_i;
10311035
axi_res_tbl #(
10321036
.AXI_ADDR_WIDTH (AXI_ADDR_WIDTH-AXI_ADDR_LSB), // Track reservations with given granularity.
1033-
.AXI_ID_WIDTH (RES_ID_WIDTH)
1037+
.AXI_ID_WIDTH (RES_ID_WIDTH),
1038+
.NUM_RESERVATIONS (NUM_RESERVATIONS)
10341039
) i_art (
10351040
.clk_i (clk_i),
10361041
.rst_ni (rst_ni),

src/axi_riscv_lrsc_wrap.sv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ module axi_riscv_lrsc_wrap #(
3434
parameter bit FULL_BANDWIDTH = 1'b1,
3535
/// Cut combinational path between input and output in LRSC ID queues with full bandwidth
3636
parameter bit CUT_OUP_POP_INP_GNT = 1'b0,
37+
/// Number of simultaineous reservations (power of 2, <= 2^AXI_ID_WIDTH or <= 2^(AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1))
38+
parameter int unsigned NUM_RESERVATIONS = 2**(AXI_USER_AS_ID ?
39+
AXI_USER_ID_MSB - AXI_USER_ID_LSB + 1
40+
: AXI_ID_WIDTH),
3741
/// Enable debug prints (not synthesizable).
3842
parameter bit DEBUG = 1'b0,
3943
/// Derived Parameters (do NOT change manually!)
@@ -60,7 +64,8 @@ module axi_riscv_lrsc_wrap #(
6064
.AXI_ADDR_LSB (AXI_ADDR_LSB),
6165
.FULL_BANDWIDTH (FULL_BANDWIDTH),
6266
.CUT_OUP_POP_INP_GNT (CUT_OUP_POP_INP_GNT),
63-
.DEBUG (DEBUG)
67+
.DEBUG (DEBUG),
68+
.NUM_RESERVATIONS (NUM_RESERVATIONS)
6469
) i_lrsc (
6570
.clk_i ( clk_i ),
6671
.rst_ni ( rst_ni ),

test/axi_riscv_lrsc_tb.sv

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module axi_riscv_lrsc_tb #(
2222
parameter int unsigned AXI_MAX_READ_TXNS = 16,
2323
parameter int unsigned AXI_MAX_WRITE_TXNS = 16,
2424
parameter int unsigned AXI_ADDR_LSB = 3,
25+
parameter int unsigned NUM_RESERVATIONS = 16,
2526
parameter bit DEBUG = 1'b0,
2627
// TB Parameters
2728
parameter int unsigned REQ_MIN_WAIT_CYCLES = 0,
@@ -100,7 +101,8 @@ module axi_riscv_lrsc_tb #(
100101
.AXI_MAX_READ_TXNS (AXI_MAX_READ_TXNS),
101102
.AXI_MAX_WRITE_TXNS (AXI_MAX_WRITE_TXNS),
102103
.AXI_ADDR_LSB (AXI_ADDR_LSB),
103-
.DEBUG (DEBUG)
104+
.DEBUG (DEBUG),
105+
.NUM_RESERVATIONS (NUM_RESERVATIONS)
104106
) dut (
105107
.clk_i (clk),
106108
.rst_ni (rst_n),

0 commit comments

Comments
 (0)