@@ -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,94 @@ 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+ req_cutter_burst.gdata = '0 ;
156+
157+ consecutive_read = & consecutive && (~| req_wen_i);
158+
159+ // Burst the read request
160+ if (& req_valid_i && consecutive_read) begin
113161 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;
162+ req_ini_addr_o[0 ] = req_bursted_ini_addr;
163+ req_tgt_addr_o[0 ] = req_bursted_tgt_addr;
164+ req_wdata_o[0 ] = req_bursted_wdata;
165+ req_wen_o[0 ] = req_bursted_wen;
166+ req_be_o[0 ] = req_bursted_be;
167+ req_burst_o[0 ] = req_bursted_burst;
168+ req_valid_o[0 ] = req_bursted_valid;
169+ req_ready_o[0 ] = cutter_ready;
121170 // Silence other ports
122171 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;
172+ req_ini_addr_o[i] = '0 ;
173+ req_tgt_addr_o[i] = '0 ;
174+ req_wdata_o[i] = '0 ;
175+ req_wen_o[i] = 1'b0 ;
176+ req_be_o[i] = '0 ;
177+ req_burst_o[i] = '0 ;
178+ req_valid_o[i] = 1'b0 ;
179+ req_ready_o[i] = cutter_ready;
130180 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;
141181 end
142182
143183 end
@@ -177,9 +217,6 @@ module burst_req_grouper
177217 /* Response */
178218 /* ************/
179219
180-
181- localparam int unsigned NumGroup = RspGF > 1 ? NumIn >> $clog2 (RspGF) : NumIn;
182-
183220 if (RspGF == 1 ) begin : gen_default_assignment
184221
185222 // Default assignment
@@ -197,7 +234,7 @@ module burst_req_grouper
197234 resp_valid_o = resp_valid_i;
198235 resp_ready_o = resp_ready_i;
199236
200- for (int ii = 0 ; ii < NumGroup ; ii++ ) begin
237+ for (int ii = 0 ; ii < NumGroupRsp ; ii++ ) begin
201238 if (resp_valid_i[ii* RspGF] && resp_burst_i[ii* RspGF].isburst) begin
202239 // If the response is grouped only one every RspGF input will be
203240 // valid. If any of the other inputs is valid give them priority.
0 commit comments