Skip to content

Commit bc6fa6f

Browse files
committed
Add grouped request
1 parent e903c49 commit bc6fa6f

File tree

4 files changed

+161
-80
lines changed

4 files changed

+161
-80
lines changed

rtl/variable_latency_interconnect/burst_manager.sv

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ module burst_manager
2222
// determines the width of the byte offset in a memory word. normally this can be left at the default vaule,
2323
// but sometimes it needs to be overridden (e.g. when meta-data is supplied to the memory via the wdata signal).
2424
parameter int unsigned ByteOffWidth = $clog2(DataWidth-1)-3,
25+
// Group Request Extension Grouping Factor for TCDM
26+
parameter int unsigned ReqGF = 1,
2527
// Group Response Extension Grouping Factor for TCDM
2628
parameter int unsigned RspGF = 1,
2729
// Dependant parameters. DO NOT CHANGE!
28-
parameter int unsigned NumInLog2 = (NumIn == 1) ? 1 : $clog2(NumIn),
30+
parameter int unsigned NumInLog2 = (NumIn > 32'd1) ? unsigned'($clog2(NumIn)) : 32'd1,
31+
parameter int unsigned NumOutLog2 = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1,
2932
// Burst response type can be overwritten for DataWidth > 32b
3033
// This can happen when the DataWidth includes transaction metadata
3134
parameter type burst_resp_t = burst_pkg::burst_gresp_t
@@ -70,11 +73,50 @@ module burst_manager
7073
// Include FF module
7174
`include "common_cells/registers.svh"
7275

73-
localparam int unsigned NumOutLog2 = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1;
76+
/***************
77+
* Burst WRITE *
78+
***************/
79+
80+
localparam int unsigned NumGroupReq = ReqGF > 0 ? NumOut >> $clog2(ReqGF) : NumOut;
81+
logic [NumOut-1:0][NumInLog2-1:0] req_ini_addr;
82+
logic [NumOut-1:0][AddrWidth-1:0] req_tgt_addr;
83+
logic [NumOut-1:0][DataWidth-1:0] req_wdata;
84+
logic [NumOut-1:0] req_wen;
85+
logic [NumOut-1:0][BeWidth-1:0] req_be;
86+
burst_t [NumOut-1:0] req_burst;
87+
logic [NumOut-1:0] req_valid;
88+
logic [NumOut-1:0] req_ready;
89+
90+
// Write request ungrouper
91+
always_comb begin
92+
req_ini_addr = req_ini_addr_i;
93+
req_tgt_addr = req_tgt_addr_i;
94+
req_wdata = req_wdata_i;
95+
req_wen = req_wen_i;
96+
req_be = req_be_i;
97+
req_burst = req_burst_i;
98+
req_valid = req_valid_i;
99+
// Redistribute grouped write requests
100+
for (int i = 0; i < NumGroupReq; i++) begin
101+
for (int j = 0; j < ReqGF; j++) begin
102+
if (req_burst[i*ReqGF].isburst && req_wen_i[i*ReqGF] && ReqGF > 1) begin
103+
req_ini_addr[i*ReqGF+j] = req_ini_addr_i[i*ReqGF] + j;
104+
req_tgt_addr[i*ReqGF+j] = req_tgt_addr_i[i*ReqGF] + j;
105+
req_wen[i*ReqGF+j] = req_wen_i[i*ReqGF];
106+
req_be[i*ReqGF+j] = req_be_i[i*ReqGF];
107+
req_burst[i*ReqGF+j] = '0;
108+
req_valid[i*ReqGF+j] = req_valid_i[i*ReqGF];
109+
if (j > 0) begin
110+
req_wdata[i*ReqGF+j] = req_burst_i[i*ReqGF].gdata[j];
111+
end
112+
end
113+
end
114+
end
115+
end
74116

75-
/******************
76-
* Burst Identify *
77-
******************/
117+
/**************
118+
* Burst READ *
119+
**************/
78120

79121
typedef struct packed {
80122
logic [NumInLog2-1:0] ini_addr;
@@ -93,21 +135,20 @@ module burst_manager
93135
logic [NumOut-1:0] ready_mask;
94136
logic [NumOut-1:0] valid_mask;
95137

96-
97138
always_comb begin
98139
prearb_data = '0;
99140
prearb_valid = '0;
100-
valid_mask = req_valid_i;
141+
valid_mask = req_valid;
101142
for (int unsigned i = 0; i < NumOut; i++) begin
102-
if (req_valid_i[i] && req_burst_i[i].isburst) begin
103-
prearb_data[i].ini_addr = req_ini_addr_i[i];
104-
prearb_data[i].tgt_addr = req_tgt_addr_i[i];
105-
prearb_data[i].wdata = req_wdata_i[i];
106-
prearb_data[i].wen = req_wen_i[i];
107-
prearb_data[i].ben = req_be_i[i];
108-
prearb_data[i].burst = req_burst_i[i];
109-
prearb_valid[i] = 1'b1;
110-
valid_mask[i] = 1'b0;
143+
if (req_valid[i] && req_burst[i].isburst) begin
144+
prearb_data[i].ini_addr = req_ini_addr[i];
145+
prearb_data[i].tgt_addr = req_tgt_addr[i];
146+
prearb_data[i].wdata = req_wdata[i];
147+
prearb_data[i].wen = req_wen[i];
148+
prearb_data[i].ben = req_be[i];
149+
prearb_data[i].burst = req_burst[i];
150+
prearb_valid[i] = 1'b1;
151+
valid_mask[i] = 1'b0;
111152
end
112153
end
113154
end
@@ -116,11 +157,11 @@ module burst_manager
116157
assign ready_mask = prearb_valid & prearb_ready;
117158

118159
rr_arb_tree #(
119-
.NumIn ( NumOut ),
120-
.DataType ( arb_data_t ),
121-
.ExtPrio ( 1'b0),
122-
.AxiVldRdy ( 1'b1),
123-
.LockIn ( 1'b1)
160+
.NumIn ( NumOut ),
161+
.DataType ( arb_data_t ),
162+
.ExtPrio ( 1'b0 ),
163+
.AxiVldRdy ( 1'b1 ),
164+
.LockIn ( 1'b1 )
124165
) i_rr_arb_tree (
125166
.clk_i ( clk_i ),
126167
.rst_ni ( rst_ni ),
@@ -217,11 +258,11 @@ module burst_manager
217258
fifo_pop = 1'b0;
218259

219260
// Bypass all requests by default
220-
req_wdata_o = req_wdata_i;
221-
req_tgt_addr_o = req_tgt_addr_i;
222-
req_ini_addr_o = req_ini_addr_i;
223-
req_wen_o = req_wen_i;
224-
req_be_o = req_be_i;
261+
req_wdata_o = req_wdata;
262+
req_ini_addr_o = req_ini_addr;
263+
req_tgt_addr_o = req_tgt_addr;
264+
req_wen_o = req_wen;
265+
req_be_o = req_be;
225266

226267
case (state_q)
227268

@@ -273,9 +314,9 @@ module burst_manager
273314
endcase
274315
end
275316

276-
/******************
277-
* Rsp Handling *
278-
******************/
317+
/***********************
318+
* Response Handling *
319+
***********************/
279320

280321
if (RspGF == 1) begin : gen_grouper_bypass
281322
// Bypass all responses if no grouping
@@ -288,7 +329,7 @@ module burst_manager
288329
end else begin : gen_grouper
289330

290331
// Number of groups we will check for grouping rsp
291-
localparam int unsigned NumGroup = RspGF > 0 ? NumOut >> $clog2(RspGF) : NumOut;
332+
localparam int unsigned NumGroupRsp = RspGF > 0 ? NumOut >> $clog2(RspGF) : NumOut;
292333

293334
logic [NumOut-1:0][NumInLog2-1:0] grouped_resp_ini_addr;
294335
logic [NumOut-1:0][DataWidth-1:0] grouped_resp_rdata;
@@ -298,7 +339,7 @@ module burst_manager
298339

299340
always_comb begin
300341
// Latch the new ports requested in burst
301-
for (int i = 0; i < NumGroup; i ++) begin
342+
for (int i = 0; i < NumGroupRsp; i ++) begin
302343
// If ready cancel the reservation
303344
if (resp_valid_o[i*RspGF] && resp_ready_i[i*RspGF]) begin
304345
group_mask_d[i*RspGF+:RspGF] = '0;
@@ -314,7 +355,7 @@ module burst_manager
314355

315356
// Assign input data to grouped response
316357
always_comb begin
317-
for (int i = 0; i < NumGroup; i++) begin
358+
for (int i = 0; i < NumGroupRsp; i++) begin
318359
grouped_resp_ini_addr[i*RspGF] = resp_ini_addr_i[i*RspGF];
319360
grouped_resp_rdata[i*RspGF] = resp_rdata_i[i*RspGF];
320361
grouped_resp_burst[i*RspGF].isburst = &resp_valid_i[i*RspGF+:RspGF];

rtl/variable_latency_interconnect/burst_pkg.sv

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@ package burst_pkg;
2020
localparam integer unsigned BurstLen = `ifdef BURSTLEN `BURSTLEN `else 1 `endif;
2121
parameter int unsigned BurstLenWidth = BurstLen == 1 ? 1 : $clog2(BurstLen);
2222

23+
// Grouped request in bursted writes
24+
localparam integer unsigned ReqGF = `ifdef GROUP_REQ `GROUP_REQ `else 1 `endif;
25+
localparam int ReqBurstMSB = (ReqGF > 1) ? (ReqGF - 2) : 0;
26+
2327
// Number of cuts if a burst crosses the target memory boundary
2428
localparam integer unsigned NumCuts = 1;
2529

2630
typedef struct packed {
2731
logic isburst;
2832
logic [BurstLenWidth-1:0] blen;
33+
logic [ReqBurstMSB:0][31:0] gdata;
2934
} burst_t;
3035

3136
/********************************
@@ -34,9 +39,9 @@ package burst_pkg;
3439

3540
// Grouping Factor of response data
3641
localparam integer unsigned RspGF = `ifdef GROUP_RSP `GROUP_RSP `else 1 `endif;
37-
38-
// replace rdata payload with this when the response is grouped
3942
localparam int RspBurstMSB = (RspGF > 1) ? (RspGF - 2) : 0;
43+
44+
// Add this to rdata payload when the response is grouped
4045
typedef struct packed {
4146
logic isburst;
4247
logic [RspBurstMSB:0][31:0] gdata;

rtl/variable_latency_interconnect/burst_req_grouper.sv

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ module burst_req_grouper
2323
// Determines the width of the byte offset in a memory word. Normally this can be left at the default value,
2424
// but sometimes it needs to be overridden (e.g., when metadata is supplied to the memory via the wdata signal).
2525
parameter int unsigned ByteOffWidth = $clog2(DataWidth-1)-3,
26+
// Group Request Extension Grouping Factor for TCDM
27+
parameter int unsigned ReqGF = 1,
2628
// Group Response Extension Grouping Factor for TCDM
2729
parameter int unsigned RspGF = 1,
2830
// Dependant parameters. DO NOT CHANGE!
@@ -64,6 +66,8 @@ module burst_req_grouper
6466
);
6567

6668
`include "common_cells/registers.svh"
69+
localparam int unsigned NumGroupReq = ReqGF > 1 ? NumIn >> $clog2(ReqGF) : NumIn;
70+
localparam int unsigned NumGroupRsp = RspGF > 1 ? NumIn >> $clog2(RspGF) : NumIn;
6771

6872
/*************/
6973
/* Request */
@@ -86,58 +90,93 @@ module burst_req_grouper
8690
logic req_bursted_valid;
8791

8892
// To verify that the request goes to consecutive addresses
89-
logic consecutive;
93+
logic [NumIn-2:0] consecutive;
94+
logic consecutive_read, consecutive_write;
9095

9196
always_comb begin
9297

93-
// Assign input requests to cutter inputs
94-
req_cutter_tgt_addr = req_tgt_addr_i[0];
95-
req_cutter_wdata = req_wdata_i;
96-
req_cutter_wen = req_wen_i[0];
97-
req_cutter_be = req_be_i[0];
98-
req_cutter_burst.isburst = 1'b0;
99-
req_cutter_burst.blen = NumIn;
98+
// Bypass input
99+
req_ini_addr_o = req_ini_addr_i;
100+
req_tgt_addr_o = req_tgt_addr_i;
101+
req_wdata_o = req_wdata_i;
102+
req_wen_o = req_wen_i;
103+
req_be_o = req_be_i;
104+
req_burst_o = '0;
105+
req_valid_o = req_valid_i;
106+
req_ready_o = req_ready_i;
100107

101108
// Check if request goes to consecutive addresses
102-
for (int i = 1; i < NumIn; i++) begin
103-
if (req_valid_i[i] && req_valid_i[i-1]) begin
104-
consecutive = (req_tgt_addr_i[i][AddrWidth-1:ByteOffWidth] == req_tgt_addr_i[i-1][AddrWidth-1:ByteOffWidth] + 1);
105-
end else begin
106-
consecutive = 1'b0;
109+
for (int i = 0; i < NumIn-1; i++) begin
110+
consecutive[i] = (req_tgt_addr_i[i+1][AddrWidth-1:ByteOffWidth]
111+
- req_tgt_addr_i[i][AddrWidth-1:ByteOffWidth]) == AddrWidth'(1);
112+
end
113+
114+
/* WRITE */
115+
116+
// Assign grouped requests
117+
if (ReqGF > 1) begin
118+
for (int i = 0; i < NumGroupReq; i++) begin
119+
consecutive_write = &consecutive[i*ReqGF+:(ReqGF-1)] && &req_wen_i[i*ReqGF+:ReqGF];
120+
if (&req_valid_i[i*ReqGF+:ReqGF] && consecutive_write) begin
121+
req_ini_addr_o[i*ReqGF] = req_ini_addr_i[i*ReqGF];
122+
req_tgt_addr_o[i*ReqGF] = req_tgt_addr_i[i*ReqGF];
123+
req_wdata_o[i*ReqGF] = req_wdata_i[i*ReqGF];
124+
req_wen_o[i*ReqGF] = req_wen_i[i*ReqGF];
125+
req_be_o[i*ReqGF] = req_be_i[i*ReqGF];
126+
req_burst_o[i*ReqGF].isburst = 1'b1;
127+
req_burst_o[i*ReqGF].blen = '0;
128+
req_valid_o[i*ReqGF] = req_valid_i[i*ReqGF];
129+
req_ready_o[i*ReqGF] = req_valid_o[i*ReqGF] && req_ready_i[i*ReqGF];
130+
for (int j = 1; j < ReqGF; j++) begin
131+
req_ini_addr_o[i*ReqGF+j] = '0;
132+
req_tgt_addr_o[i*ReqGF+j] = '0;
133+
req_wdata_o[i*ReqGF+j] = '0;
134+
req_wen_o[i*ReqGF+j] = 1'b0;
135+
req_be_o[i*ReqGF+j] = '0;
136+
req_burst_o[i*ReqGF+j] = '0;
137+
req_valid_o[i*ReqGF+j] = 1'b0;
138+
req_ready_o[i*ReqGF+j] = req_valid_o[i*ReqGF] && req_ready_i[i*ReqGF];
139+
// Redistribute the outputs from the i*RspGF'th input
140+
req_burst_o[i*ReqGF].gdata = req_wdata_i[i*ReqGF+j];
141+
end
142+
end
107143
end
108144
end
109145

110-
// Burst the request
111-
if (&req_valid_i && !req_wen_i[0] && consecutive) begin
112-
// Send a burst request on the first port
146+
/* READ */
147+
148+
// Assign input requests to cutter inputs
149+
req_cutter_tgt_addr = req_tgt_addr_i[0];
150+
req_cutter_wdata = req_wdata_i;
151+
req_cutter_wen = req_wen_i[0];
152+
req_cutter_be = req_be_i[0];
153+
req_cutter_burst.isburst = 1'b0;
154+
req_cutter_burst.blen = NumIn;
155+
156+
consecutive_read = &consecutive && (~|req_wen_i);
157+
158+
// Burst the read request
159+
if (&req_valid_i && consecutive_read) begin
113160
req_cutter_burst.isburst = 1'b1;
114-
req_tgt_addr_o[0] = req_bursted_tgt_addr;
115-
req_wdata_o[0] = req_bursted_wdata;
116-
req_wen_o[0] = req_bursted_wen;
117-
req_be_o[0] = req_bursted_be;
118-
req_burst_o[0] = req_bursted_burst;
119-
req_valid_o[0] = req_bursted_valid;
120-
req_ready_o[0] = cutter_ready;
161+
req_ini_addr_o[0] = req_bursted_ini_addr;
162+
req_tgt_addr_o[0] = req_bursted_tgt_addr;
163+
req_wdata_o[0] = req_bursted_wdata;
164+
req_wen_o[0] = req_bursted_wen;
165+
req_be_o[0] = req_bursted_be;
166+
req_burst_o[0] = req_bursted_burst;
167+
req_valid_o[0] = req_bursted_valid;
168+
req_ready_o[0] = cutter_ready;
121169
// Silence other ports
122170
for (int i = 1; i < NumIn; i++) begin
123-
req_tgt_addr_o[i] = '0;
124-
req_wdata_o[i] = '0;
125-
req_wen_o[i] = 1'b0;
126-
req_be_o[i] = '0;
127-
req_burst_o[i] = '0;
128-
req_valid_o[i] = 1'b0;
129-
req_ready_o[i] = cutter_ready;
171+
req_ini_addr_o[i] = '0;
172+
req_tgt_addr_o[i] = '0;
173+
req_wdata_o[i] = '0;
174+
req_wen_o[i] = 1'b0;
175+
req_be_o[i] = '0;
176+
req_burst_o[i] = '0;
177+
req_valid_o[i] = 1'b0;
178+
req_ready_o[i] = cutter_ready;
130179
end
131-
end else begin
132-
// Bypass input
133-
req_ini_addr_o = req_ini_addr_i;
134-
req_tgt_addr_o = req_tgt_addr_i;
135-
req_wdata_o = req_wdata_i;
136-
req_wen_o = req_wen_i;
137-
req_be_o = req_be_i;
138-
req_burst_o = '0;
139-
req_valid_o = req_valid_i;
140-
req_ready_o = req_ready_i;
141180
end
142181

143182
end
@@ -177,9 +216,6 @@ module burst_req_grouper
177216
/* Response */
178217
/*************/
179218

180-
181-
localparam int unsigned NumGroup = RspGF > 1 ? NumIn >> $clog2(RspGF) : NumIn;
182-
183219
if (RspGF == 1) begin: gen_default_assignment
184220

185221
// Default assignment
@@ -197,7 +233,7 @@ module burst_req_grouper
197233
resp_valid_o = resp_valid_i;
198234
resp_ready_o = resp_ready_i;
199235

200-
for (int ii = 0; ii < NumGroup; ii++) begin
236+
for (int ii = 0; ii < NumGroupRsp; ii++) begin
201237
if (resp_valid_i[ii*RspGF] && resp_burst_i[ii*RspGF].isburst) begin
202238
// If the response is grouped only one every RspGF input will be
203239
// valid. If any of the other inputs is valid give them priority.

rtl/variable_latency_interconnect/burst_variable_latency_interconnect.sv

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ module burst_variable_latency_interconnect import tcdm_interconnect_pkg::topo_e;
2727
parameter int unsigned DataWidth = 32, // Data Word Width
2828
parameter int unsigned BeWidth = DataWidth/8, // Byte Strobe Width
2929
parameter int unsigned AddrMemWidth = 12, // Number of Address bits per Target
30-
parameter int unsigned RspGF = 1, // Grouping Factor for the Burst Response
3130
parameter int unsigned BurstWidth = 1, // Burst Signal Width
32-
parameter int unsigned BurstRspWidth = (RspGF-1)*DataWidth, // Burst Response Widening
31+
parameter int unsigned BurstRspWidth = 1, // Burst Response Widening
3332
parameter bit AxiVldRdy = 1'b1, // Valid/ready signaling
3433
// Spill registers
3534
// A bit set at position i indicates a spill register at the i-th crossbar layer.

0 commit comments

Comments
 (0)