@@ -96,8 +96,8 @@ module burst_manager
9696 always_comb begin
9797 prearb_data = '0 ;
9898 prearb_valid = '0 ;
99- ready_mask = '0 ;
10099 valid_mask = req_valid_i;
100+ ready_mask = '0 ;
101101
102102 for (int unsigned i = 0 ; i < NumOut; i++ ) begin
103103 if (req_valid_i[i] && req_burst_i[i].isburst) begin
@@ -108,7 +108,7 @@ module burst_manager
108108 prearb_data[i].ben = req_ben_i[i];
109109 prearb_data[i].burst = req_burst_i[i];
110110 prearb_valid[i] = 1'b1 ;
111- valid_mask = 1'b0 ;
111+ valid_mask[i] = 1'b0 ;
112112 // Mark retired burst requests
113113 if (prearb_ready[i]) begin
114114 ready_mask[i] = 1'b1 ;
@@ -190,31 +190,30 @@ module burst_manager
190190 DoBurst // generate parallel requests when ready
191191 } req_gen_fsm_e ;
192192
193- // FSM state
193+ // FSM state & signals
194194 req_gen_fsm_e state_d, state_q;
195- // FSM stored signals
196- fifo_data_t breq_d, breq_q;
197-
195+ fifo_data_t req_d, req_q;
196+ // Indicates which req inputs are involved in a burst
198197 logic [NumOut- 1 : 0 ] burst_mask_d, burst_mask_q;
199- // group mask used for response grouping
198+ // Indicates which resp inputs are involved in a burst
200199 logic [NumOut- 1 : 0 ] group_mask_d, group_mask_q;
201-
202- // indicate if there is pending response to be picked
200+ // indicates if there is pending response to be picked
203201 logic pending_rsp;
204202
203+ // Store FSM state and signals
205204 `FF (state_q, state_d, Idle, clk_i, rst_ni);
206- `FF (breq_q, breq_d , '0 , clk_i, rst_ni);
205+ `FF (req_q, req_d , '0 , clk_i, rst_ni);
207206 `FF (burst_mask_q, burst_mask_d, '0 , clk_i, rst_ni);
208207 `FF (group_mask_q, group_mask_d, '0 , clk_i, rst_ni);
209208
210- // Each element of a burst request must be retired to start request
209+ // Block burstlen ports after the port receiving a burst
211210 assign req_ready_o = ready_mask | (req_ready_i & ~ burst_mask_q);
212211
213212 always_comb begin : request_generator
214213
215214 // FSM defaults
216215 state_d = state_q;
217- breq_d = breq_q ;
216+ req_d = req_q ;
218217 burst_mask_d = burst_mask_q;
219218
220219 // comb logic defaults
@@ -228,7 +227,6 @@ module burst_manager
228227 req_ini_addr_o = req_ini_addr_i;
229228 req_wen_o = req_wen_i;
230229 req_ben_o = req_ben_i;
231-
232230 // Let valid requests not in burst pass
233231 req_valid_o = valid_mask;
234232
@@ -245,30 +243,30 @@ module burst_manager
245243 // pop next element
246244 fifo_pop = 1'b1 ;
247245 // store request
248- breq_d = fifo_data;
246+ req_d = fifo_data;
249247 // a mask with burst length ones
250- burst_mask_d = (1'b1 << breq_d .burst.blen) - 1'b1 ;
248+ burst_mask_d = (1'b1 << req_d .burst.blen) - 1'b1 ;
251249 // shift the mask to the first bank index addressed by the burst
252- burst_mask_d = burst_mask_d << breq_d .idx;
250+ burst_mask_d = burst_mask_d << req_d .idx;
253251 state_d = DoBurst;
254252 end
255253
256254 end
257255
258256 DoBurst: begin
259257
260- // If there is pending responses among the affected banks we wait
258+ // Check if there is pending responses among the affected banks
261259 pending_rsp = | ((resp_valid_o & ~ resp_ready_i) & burst_mask_q);
262- // Send out requests when 1. required banks are all ready 2. no pending responses
263- if (& (req_ready_i | (~ burst_mask_q)) & ! pending_rsp) begin
260+ // If no pending response and all the affected banks are ready send a new request
261+ if (& (req_ready_i | (~ burst_mask_q)) && ! pending_rsp) begin
264262 for (int unsigned i = 0 ; i < NumOut; i++ ) begin
263+ // Overwrite the request on affected banks
265264 if (burst_mask_q[i]) begin
266- req_wdata_o[i] = breq_q.wdata;
267- req_wen_o[i] = breq_q.wen;
268- req_ben_o[i] = breq_q.ben;
269- // overwrite tgt_addr
270- req_tgt_addr_o[i] = i + breq_q.tgt_addr - breq_q.idx;
271- req_ini_addr_o[i] = i + breq_q.ini_addr - breq_q.idx;
265+ req_wdata_o[i] = req_q.wdata;
266+ req_tgt_addr_o[i] = i + req_q.tgt_addr - req_q.idx;
267+ req_ini_addr_o[i] = i + req_q.ini_addr - req_q.idx;
268+ req_wen_o[i] = req_q.wen;
269+ req_ben_o[i] = req_q.ben;
272270 // Set the valid for burst requests
273271 req_valid_o[i] = 1'b1 ;
274272 end
@@ -306,49 +304,46 @@ module burst_manager
306304 logic [NumOut- 1 : 0 ] grouped_resp_valid;
307305 logic [NumOut- 1 : 0 ] grouped_resp_ready;
308306
309- for (genvar i = 0 ; i < NumGroup; i ++ ) begin : gen_data_grouper
310- burst_rsp_grouper # (
311- .NumIn ( NumIn ),
312- .NumOut ( NumOut ),
313- .DataWidth ( DataWidth ),
314- .RspGF ( RspGF ),
315- .burst_resp_t ( burst_resp_t )
316- ) i_burst_rsp_grouper (
317- .clk_i (clk_i ),
318- .rst_ni (rst_ni ),
319- // / Bank side
320- .resp_ini_addr_i (resp_ini_addr_i[i* RspGF+ : RspGF] ),
321- .resp_rdata_i (resp_rdata_i[i* RspGF+ : RspGF] ),
322- .resp_valid_i (resp_valid_i[i* RspGF+ : RspGF] ),
323- .resp_ready_o (grouped_resp_ready[i* RspGF+ : RspGF] ),
324- // / Xbar side
325- .resp_ini_addr_o (grouped_resp_ini_addr[i* RspGF+ : RspGF] ),
326- .resp_rdata_o (grouped_resp_rdata[i* RspGF+ : RspGF] ),
327- .resp_burst_o (grouped_resp_burst[i* RspGF+ : RspGF] ),
328- .resp_valid_o (grouped_resp_valid[i* RspGF+ : RspGF] ),
329- .resp_ready_i (resp_ready_i[i* RspGF+ : RspGF] )
330- );
331- end
332-
333307 always_comb begin
308+ // Latch the new ports requested in burst
309+ group_mask_d = group_mask_q;
334310 for (int i = 0 ; i < NumGroup; i ++ ) begin
335- if (state_q == DoBurst) begin
336- group_mask_d[i* RspGF+ : RspGF] = { RspGF{& burst_mask_q[i* RspGF+ : RspGF]}} ;
337- end else if (resp_ready_i[i* RspGF]) begin
311+ if (( state_q == DoBurst) && ! pending_rsp ) begin
312+ group_mask_d[i* RspGF+ : RspGF] = group_mask_q[i * RspGF+ : RspGF] | burst_mask_q[i* RspGF+ : RspGF];
313+ end else if (resp_valid_o[i * RspGF] && resp_ready_i[i* RspGF]) begin
338314 group_mask_d[i* RspGF+ : RspGF] = '0 ;
339- end else begin
340- group_mask_d[i* RspGF+ : RspGF] = group_mask_q[i* RspGF+ : RspGF];
341315 end
342316 end
343317 end
344318
319+ // Assign data to grouped response field
320+ always_comb begin
321+ for (int i = 0 ; i < NumGroup; i++ ) begin
322+ grouped_resp_burst[i* RspGF].isburst = & resp_valid_i[i* RspGF+ : RspGF];
323+ grouped_resp_valid[i* RspGF] = & resp_valid_i[i* RspGF+ : RspGF];
324+ for (int j = 1 ; j < RspGF; j++ ) begin
325+ grouped_resp_burst[i* RspGF].gdata[j- 1 ] = resp_rdata_i[i* RspGF+ j];
326+ grouped_resp_burst[i* RspGF+ j].isburst = '0 ;
327+ grouped_resp_valid[i* RspGF+ j] = 1'b0 ;
328+ end
329+ end
330+ end
331+
332+ // Assign grouped outputs
333+ // TODO: the code runs through, but there is a violation because the valid_o is sent before all the grouped factors are collected
334+ // This gives an assertion error on the local_response_interconnect, because the response_data changes (we add the gdata), before
335+ // the handshake happens.
345336 for (genvar i = 0 ; i < NumOut; i++ ) begin
346- assign resp_ini_addr_o[i] = group_mask_q[i] ? (i % RspGF == 0 ? grouped_resp_ini_addr[i] : '0 ) : resp_ini_addr_i[i];
347- assign resp_rdata_o[i] = group_mask_q[i] ? (i % RspGF == 0 ? grouped_resp_rdata[i] : '0 ) : resp_rdata_i[i];
348- assign resp_burst_o[i].gdata = group_mask_q[i] ? (i % RspGF == 0 ? grouped_resp_burst[i].gdata : '0 ) : '0 ;
349- assign resp_burst_o[i].isburst = group_mask_q[i] ? (i % RspGF == 0 ? grouped_resp_burst[i].isburst : 1'b0 ) : 1'b0 ;
350- assign resp_valid_o[i] = group_mask_q[i] ? (i % RspGF == 0 ? grouped_resp_valid[i] : '0 ) : resp_valid_i[i];
351- assign resp_ready_o[i] = group_mask_q[i] ? grouped_resp_ready[RspGF* (i/ RspGF)] : resp_ready_i[i];
337+ assign grouped_resp_ini_addr[i] = (i % RspGF == 0 ) ? resp_ini_addr_i[i] : '0 ;
338+ assign grouped_resp_rdata[i] = (i % RspGF == 0 ) ? resp_rdata_i[i] : '0 ;
339+
340+ assign grouped_resp_ready[i] = (resp_valid_o[RspGF* (i/ RspGF)] && resp_ready_i[RspGF* (i/ RspGF)]);
341+ assign resp_ini_addr_o[i] = group_mask_q[i] ? grouped_resp_ini_addr[i] : resp_ini_addr_i[i];
342+ assign resp_rdata_o[i] = group_mask_q[i] ? grouped_resp_rdata[i] : resp_rdata_i[i];
343+ assign resp_burst_o[i].gdata = group_mask_q[i] ? grouped_resp_burst[i].gdata : '0 ;
344+ assign resp_burst_o[i].isburst = group_mask_q[i] ? grouped_resp_burst[i].isburst : 1'b0 ;
345+ assign resp_valid_o[i] = group_mask_q[i] ? grouped_resp_valid[i] : resp_valid_i[i];
346+ assign resp_ready_o[i] = group_mask_q[i] ? grouped_resp_ready[i] : (resp_valid_o[i] && resp_ready_i[i]);
352347 end
353348 end
354349
0 commit comments