Skip to content

Commit 23e5567

Browse files
author
Georg Rutishauser
committed
Regs: Fix arbitration of stream_idx
- with `NumRegs>1`, if a new ID is read on multiple register interfaces simultaneously, `stream_idx_o` was set to the stream index that the highest regfile index is reading from. This is incorrect as it ignores the result of the arbitration between the different regfiles - this commit changes this behavior to correctly arbitrate `stream_idx` along with the ID so that `stream_idx_o` is set to the index of the stream the granted ID read belongs to
1 parent 29356c5 commit 23e5567

1 file changed

Lines changed: 48 additions & 44 deletions

File tree

src/frontend/reg/tpl/idma_reg.sv.tpl

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,22 @@ module idma_${identifier} #(
6161
idma_${identifier}_reg_pkg::idma_reg__in_t dma_hw2reg [NumRegs-1:0];
6262

6363
// arbitration output
64-
dma_req_t [NumRegs-1:0] arb_dma_req;
65-
logic [NumRegs-1:0] arb_valid;
66-
logic [NumRegs-1:0] arb_ready;
64+
typedef struct packed {
65+
dma_req_t req;
66+
stream_t stream_idx;
67+
} arb_payload_t;
68+
69+
arb_payload_t [NumRegs-1:0] arb_payload;
70+
arb_payload_t arb_payload_out;
71+
stream_t [NumRegs-1:0] arb_stream_idx;
72+
logic [NumRegs-1:0] arb_valid;
73+
logic [NumRegs-1:0] arb_ready;
6774

6875
// register signals
6976
reg_rsp_t [NumRegs-1:0] dma_ctrl_rsp;
7077

71-
always_comb begin
72-
stream_idx_o = '0;
73-
for (int r = 0; r < NumRegs; r++) begin
74-
for (int c = 0; c < NumStreams; c++) begin
75-
if (dma_reg2hw[r].next_id[c].req && !dma_reg2hw[r].next_id[c].req_is_wr) begin
76-
stream_idx_o = c;
77-
end
78-
end
79-
end
80-
end
78+
assign dma_req_o = arb_payload_out.req;
79+
assign stream_idx_o = arb_payload_out.stream_idx;
8180

8281
// generate the registers
8382
for (genvar i = 0; i < NumRegs; i++) begin : gen_core_regs
@@ -128,74 +127,79 @@ module idma_${identifier} #(
128127

129128
always_comb begin : proc_launch
130129
read_happens = 1'b0;
130+
arb_stream_idx[i] = '0;
131131
for (int c = 0; c < NumStreams; c++) begin
132-
read_happens |= dma_reg2hw[i].next_id[c].req & ~dma_reg2hw[i].next_id[c].req_is_wr;
132+
if (dma_reg2hw[i].next_id[c].req & ~dma_reg2hw[i].next_id[c].req_is_wr) begin
133+
read_happens = 1'b1;
134+
arb_stream_idx[i] = stream_t'(c);
135+
end
133136
end
134137
arb_valid[i] = read_happens;
135138
end
136139

137140
// assign request struct
138141
always_comb begin : proc_hw_req_conv
139142
// all fields are zero per default
140-
arb_dma_req[i] = '0;
143+
arb_payload[i] = '0;
144+
arb_payload[i].stream_idx = arb_stream_idx[i];
141145

142146
// address and length
143147
% if bit_width == '32':
144-
arb_dma_req[i]${sep}length = dma_reg2hw[i].length[0].length.value;
145-
arb_dma_req[i]${sep}src_addr = dma_reg2hw[i].src_addr[0].src_addr.value;
146-
arb_dma_req[i]${sep}dst_addr = dma_reg2hw[i].dst_addr[0].dst_addr.value;
148+
arb_payload[i].req${sep}length = dma_reg2hw[i].length[0].length.value;
149+
arb_payload[i].req${sep}src_addr = dma_reg2hw[i].src_addr[0].src_addr.value;
150+
arb_payload[i].req${sep}dst_addr = dma_reg2hw[i].dst_addr[0].dst_addr.value;
147151
% else:
148-
arb_dma_req[i]${sep}length = {dma_reg2hw[i].length[1].length.value, dma_reg2hw[i].length[0].length.value};
149-
arb_dma_req[i]${sep}src_addr = {dma_reg2hw[i].src_addr[1].src_addr.value, dma_reg2hw[i].src_addr[0].src_addr.value};
150-
arb_dma_req[i]${sep}dst_addr = {dma_reg2hw[i].dst_addr[1].dst_addr.value, dma_reg2hw[i].dst_addr[0].dst_addr.value};
152+
arb_payload[i].req${sep}length = {dma_reg2hw[i].length[1].length.value, dma_reg2hw[i].length[0].length.value};
153+
arb_payload[i].req${sep}src_addr = {dma_reg2hw[i].src_addr[1].src_addr.value, dma_reg2hw[i].src_addr[0].src_addr.value};
154+
arb_payload[i].req${sep}dst_addr = {dma_reg2hw[i].dst_addr[1].dst_addr.value, dma_reg2hw[i].dst_addr[0].dst_addr.value};
151155
% endif
152156

153157
// Protocols
154-
arb_dma_req[i]${sep}opt.src_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.src_protocol.value);
155-
arb_dma_req[i]${sep}opt.dst_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.dst_protocol.value);
158+
arb_payload[i].req${sep}opt.src_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.src_protocol.value);
159+
arb_payload[i].req${sep}opt.dst_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.dst_protocol.value);
156160

157161
// Current backend only supports incremental burst
158-
arb_dma_req[i]${sep}opt.src.burst = axi_pkg::BURST_INCR;
159-
arb_dma_req[i]${sep}opt.dst.burst = axi_pkg::BURST_INCR;
162+
arb_payload[i].req${sep}opt.src.burst = axi_pkg::BURST_INCR;
163+
arb_payload[i].req${sep}opt.dst.burst = axi_pkg::BURST_INCR;
160164
// this frontend currently does not support cache variations
161-
arb_dma_req[i]${sep}opt.src.cache = axi_pkg::CACHE_MODIFIABLE;
162-
arb_dma_req[i]${sep}opt.dst.cache = axi_pkg::CACHE_MODIFIABLE;
165+
arb_payload[i].req${sep}opt.src.cache = axi_pkg::CACHE_MODIFIABLE;
166+
arb_payload[i].req${sep}opt.dst.cache = axi_pkg::CACHE_MODIFIABLE;
163167

164168
// Backend options
165-
arb_dma_req[i]${sep}opt.beo.decouple_aw = dma_reg2hw[i].conf.decouple_aw.value;
166-
arb_dma_req[i]${sep}opt.beo.decouple_rw = dma_reg2hw[i].conf.decouple_rw.value;
167-
arb_dma_req[i]${sep}opt.beo.src_max_llen = dma_reg2hw[i].conf.src_max_llen.value;
168-
arb_dma_req[i]${sep}opt.beo.dst_max_llen = dma_reg2hw[i].conf.dst_max_llen.value;
169-
arb_dma_req[i]${sep}opt.beo.src_reduce_len = dma_reg2hw[i].conf.src_reduce_len.value;
170-
arb_dma_req[i]${sep}opt.beo.dst_reduce_len = dma_reg2hw[i].conf.dst_reduce_len.value;
169+
arb_payload[i].req${sep}opt.beo.decouple_aw = dma_reg2hw[i].conf.decouple_aw.value;
170+
arb_payload[i].req${sep}opt.beo.decouple_rw = dma_reg2hw[i].conf.decouple_rw.value;
171+
arb_payload[i].req${sep}opt.beo.src_max_llen = dma_reg2hw[i].conf.src_max_llen.value;
172+
arb_payload[i].req${sep}opt.beo.dst_max_llen = dma_reg2hw[i].conf.dst_max_llen.value;
173+
arb_payload[i].req${sep}opt.beo.src_reduce_len = dma_reg2hw[i].conf.src_reduce_len.value;
174+
arb_payload[i].req${sep}opt.beo.dst_reduce_len = dma_reg2hw[i].conf.dst_reduce_len.value;
171175

172176
% if num_dim != 1:
173177
// ND connections
174178
% for nd in range(0, num_dim-1):
175179
% if bit_width == '32':
176-
arb_dma_req[i].d_req[${nd}].reps = dma_reg2hw[i].dim[${nd}].reps[0].reps.value;
177-
arb_dma_req[i].d_req[${nd}].src_strides = dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value;
178-
arb_dma_req[i].d_req[${nd}].dst_strides = dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value;
180+
arb_payload[i].req.d_req[${nd}].reps = dma_reg2hw[i].dim[${nd}].reps[0].reps.value;
181+
arb_payload[i].req.d_req[${nd}].src_strides = dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value;
182+
arb_payload[i].req.d_req[${nd}].dst_strides = dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value;
179183
% else:
180-
arb_dma_req[i].d_req[${nd}].reps = {dma_reg2hw[i].dim[${nd}].reps[1].reps.value,
184+
arb_payload[i].req.d_req[${nd}].reps = {dma_reg2hw[i].dim[${nd}].reps[1].reps.value,
181185
dma_reg2hw[i].dim[${nd}].reps[0].reps.value };
182-
arb_dma_req[i].d_req[${nd}].src_strides = {dma_reg2hw[i].dim[${nd}].src_stride[1].src_stride.value,
186+
arb_payload[i].req.d_req[${nd}].src_strides = {dma_reg2hw[i].dim[${nd}].src_stride[1].src_stride.value,
183187
dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value};
184-
arb_dma_req[i].d_req[${nd}].dst_strides = {dma_reg2hw[i].dim[${nd}].dst_stride[1].dst_stride.value,
188+
arb_payload[i].req.d_req[${nd}].dst_strides = {dma_reg2hw[i].dim[${nd}].dst_stride[1].dst_stride.value,
185189
dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value};
186190
% endif
187191
% endfor
188192

189193
// Disable higher dimensions
190194
if ( dma_reg2hw[i].conf.enable_nd.value == 0) begin
191195
% for nd in range(0, num_dim-1):
192-
arb_dma_req[i].d_req[${nd}].reps = ${"'0" if nd != num_dim-2 else "'d1"};
196+
arb_payload[i].req.d_req[${nd}].reps = ${"'0" if nd != num_dim-2 else "'d1"};
193197
% endfor
194198
end
195199
% for nd in range(1, num_dim-1):
196200
else if ( dma_reg2hw[i].conf.enable_nd.value == ${nd}) begin
197201
% for snd in range(nd, num_dim-1):
198-
arb_dma_req[i].d_req[${snd}].reps = 'd1;
202+
arb_payload[i].req.d_req[${snd}].reps = 'd1;
199203
% endfor
200204
end
201205
% endfor
@@ -231,7 +235,7 @@ module idma_${identifier} #(
231235
// arbitration
232236
rr_arb_tree #(
233237
.NumIn ( NumRegs ),
234-
.DataType ( dma_req_t ),
238+
.DataType ( arb_payload_t ),
235239
.ExtPrio ( 0 ),
236240
.AxiVldRdy ( 1 ),
237241
.LockIn ( 1 )
@@ -242,10 +246,10 @@ module idma_${identifier} #(
242246
.rr_i ( '0 ),
243247
.req_i ( arb_valid ),
244248
.gnt_o ( arb_ready ),
245-
.data_i ( arb_dma_req ),
249+
.data_i ( arb_payload ),
246250
.gnt_i ( req_ready_i ),
247251
.req_o ( req_valid_o ),
248-
.data_o ( dma_req_o ),
252+
.data_o ( arb_payload_out ),
249253
.idx_o ( /* NC */ )
250254
);
251255

0 commit comments

Comments
 (0)