Skip to content

Commit 8031aeb

Browse files
rtl/compute_unit: fix superscalar opc handshake
1 parent 3fa4b15 commit 8031aeb

File tree

4 files changed

+70
-54
lines changed

4 files changed

+70
-54
lines changed

rtl/compute_unit/compute_unit.sv

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,11 +1114,13 @@ module compute_unit import bgpu_pkg::*; #(
11141114
@(posedge clk_i);
11151115
for (int wb = 0; wb < DispatchWidth; wb++) begin : loop_writeback_ports
11161116
if (eu_to_opc_valid_q[wb] && opc_to_eu_ready_d[wb]) begin
1117-
data = $sformatf("%t: WB: %0d Tag: %0d, Warp: %0d, ActMask: %b,",
1117+
data = $sformatf("%t: WB: %0d TagWid: %0d, Warp: %0d, Tag: %0d, ActMask: %b,",
11181118
$time(), wb, eu_to_opc_data_q[wb].tag,
1119-
eu_to_opc_data_q[wb].tag[WidWidth-1:0], eu_to_opc_data_q[wb].act_mask);
1119+
eu_to_opc_data_q[wb].tag[WidWidth-1:0],
1120+
eu_to_opc_data_q[wb].tag[WidWidth+:TagWidth],
1121+
eu_to_opc_data_q[wb].act_mask);
11201122

1121-
data = {data, $sformatf(" Dst: r%od, Data:", eu_to_opc_data_q[wb].dst)};
1123+
data = {data, $sformatf(" Dst: r%0d, Data:", eu_to_opc_data_q[wb].dst)};
11221124

11231125
for (int thread = 0; thread < WarpWidth; thread++) begin
11241126
data = {data, $sformatf(" (t%0d: 0x%h)", thread,

rtl/compute_unit/dispatcher/dispatcher.sv

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
module dispatcher import bgpu_pkg::*; #(
1919
/// Number of instructions to fetch for the warp
2020
parameter int unsigned FetchWidth = 1,
21+
/// Number of instructions to dispatch simultaneously
22+
parameter int unsigned DispatchWidth = 1,
2123
/// Number of instructions that can write back simultaneously
2224
parameter int unsigned WritebackWidth = 1,
2325
/// Number of inflight instructions per warp
@@ -86,8 +88,8 @@ module dispatcher import bgpu_pkg::*; #(
8688
output op_reg_idx_t disp_operands_o,
8789

8890
/// From Operand Collector -> instruction has read its operands
89-
input logic opc_eu_handshake_i,
90-
input tag_t opc_eu_tag_i,
91+
input logic [DispatchWidth-1:0] opc_eu_handshake_i,
92+
input tag_t [DispatchWidth-1:0] opc_eu_tag_i,
9193

9294
/// From Execution Units
9395
input logic [WritebackWidth-1:0] eu_valid_i,
@@ -187,13 +189,14 @@ module dispatcher import bgpu_pkg::*; #(
187189
// #######################################################################################
188190

189191
wait_buffer #(
190-
.FetchWidth ( FetchWidth ),
191-
.WritebackWidth ( WritebackWidth ),
192-
.NumTags ( NumTags ),
193-
.PcWidth ( PcWidth ),
194-
.WarpWidth ( WarpWidth ),
195-
.RegIdxWidth ( RegIdxWidth ),
196-
.OperandsPerInst ( OperandsPerInst )
192+
.FetchWidth ( FetchWidth ),
193+
.DispatchWidth ( DispatchWidth ),
194+
.WritebackWidth ( WritebackWidth ),
195+
.NumTags ( NumTags ),
196+
.PcWidth ( PcWidth ),
197+
.WarpWidth ( WarpWidth ),
198+
.RegIdxWidth ( RegIdxWidth ),
199+
.OperandsPerInst( OperandsPerInst )
197200
) i_wait_buffer (
198201
.clk_i ( clk_i ),
199202
.rst_ni( rst_ni ),

rtl/compute_unit/dispatcher/multi_warp_dispatcher.sv

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
112112
} disp_data_t;
113113

114114
typedef logic [WritebackWidth-1:0] eu_valid_vec_t;
115+
typedef logic [ DispatchWidth-1:0] opc_valid_vec_t;
115116

116117
// #######################################################################################
117118
// # Signals #
@@ -136,8 +137,8 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
136137
fetch_mask_t [NumWarps-1:0] dec_decoded_unused_ibe;
137138

138139
// OPC EU Handshake Demultiplexer
139-
warp_mask_t opc_eu_handshake_warp;
140-
tag_t [NumWarps-1:0] opc_eu_tag;
140+
opc_valid_vec_t [ NumWarps-1:0] opc_eu_handshake_warp;
141+
tag_t [DispatchWidth-1:0] opc_eu_tag;
141142

142143
// #######################################################################################
143144
// # Dispatcher per warp #
@@ -181,16 +182,20 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
181182
// OPC EU Handshake Demultiplexer
182183
always_comb begin
183184
opc_eu_handshake_warp = '0;
184-
opc_eu_tag = '0;
185-
for (int didx = 0; didx < DispatchWidth; didx++) begin
186-
if (opc_eu_handshake_i[didx]) begin
187-
opc_eu_handshake_warp[opc_eu_tag_i[didx][WidWidth-1:0]] = 1'b1;
188-
opc_eu_tag[opc_eu_tag_i[didx][WidWidth-1:0]] =
189-
opc_eu_tag_i[didx][WidWidth+:TagWidth];
185+
for (int warp = 0; warp < NumWarps; warp++) begin
186+
for (int didx = 0; didx < DispatchWidth; didx++) begin
187+
opc_eu_handshake_warp[warp][didx] =
188+
opc_eu_handshake_i[didx]
189+
&& (opc_eu_tag_i[didx][WidWidth-1:0] == warp[WidWidth-1:0]);
190190
end
191191
end
192192
end
193193

194+
// Extract OPC EU Tags
195+
for (genvar didx = 0; didx < DispatchWidth; didx++) begin : gen_opc_eu_tags
196+
assign opc_eu_tag[didx] = opc_eu_tag_i[didx][WidWidth+:TagWidth];
197+
end : gen_opc_eu_tags
198+
194199
// Extract EU Tags
195200
for (genvar wb = 0; wb < WritebackWidth; wb++) begin : gen_eu_tags
196201
assign eu_tag[wb] = eu_tag_i[wb][WidWidth+:TagWidth];
@@ -207,13 +212,14 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
207212
// Dispatcher per Warp
208213
for (genvar warp = 0; warp < NumWarps; warp++) begin : gen_dispatcher
209214
dispatcher #(
210-
.FetchWidth ( FetchWidth ),
211-
.WritebackWidth ( WritebackWidth ),
212-
.NumTags ( NumTags ),
213-
.PcWidth ( PcWidth ),
214-
.WarpWidth ( WarpWidth ),
215-
.RegIdxWidth ( RegIdxWidth ),
216-
.OperandsPerInst ( OperandsPerInst )
215+
.FetchWidth ( FetchWidth ),
216+
.DispatchWidth ( DispatchWidth ),
217+
.WritebackWidth ( WritebackWidth ),
218+
.NumTags ( NumTags ),
219+
.PcWidth ( PcWidth ),
220+
.WarpWidth ( WarpWidth ),
221+
.RegIdxWidth ( RegIdxWidth ),
222+
.OperandsPerInst( OperandsPerInst )
217223
) i_dispatcher (
218224
.clk_i ( clk_i ),
219225
.rst_ni( rst_ni ),
@@ -248,7 +254,7 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
248254
.disp_operands_o ( arb_in_data [warp].operands ),
249255

250256
.opc_eu_handshake_i( opc_eu_handshake_warp[warp] ),
251-
.opc_eu_tag_i ( opc_eu_tag [warp] ),
257+
.opc_eu_tag_i ( opc_eu_tag ),
252258

253259
.eu_valid_i( eu_valid[warp] ),
254260
.eu_tag_i ( eu_tag )
@@ -267,10 +273,10 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
267273
rr_arb_tree #(
268274
.DataType ( disp_data_t ),
269275
.NumIn ( NumWarps ),
270-
.ExtPrio ( 1'b0 ),
271-
.AxiVldRdy( 1'b0 ),
272-
.LockIn ( 1'b0 ),
273-
.FairArb ( 1'b1 )
276+
.ExtPrio ( 1'b0 ),
277+
.AxiVldRdy( 1'b0 ),
278+
.LockIn ( 1'b0 ),
279+
.FairArb ( 1'b1 )
274280
) i_rr_arb (
275281
.clk_i ( clk_i ),
276282
.rst_ni( rst_ni ),
@@ -308,13 +314,6 @@ module multi_warp_dispatcher import bgpu_pkg::*; #(
308314
for (genvar other_didx = 0; other_didx < DispatchWidth; other_didx++)
309315
begin : gen_out_asserts_inner
310316
if (didx != other_didx) begin : gen_diff_didx
311-
// Check for OPC EU Handshake for the same warp received on multiple dispatch outputs
312-
assert property (@(posedge clk_i) disable iff (!rst_ni)
313-
(opc_eu_handshake_i[didx] && opc_eu_handshake_i[other_didx]
314-
-> opc_eu_tag_i[didx][WidWidth-1:0]
315-
!= opc_eu_tag_i[other_didx][WidWidth-1:0]))
316-
else $error("OPC EU Handshake for the same warp received!");
317-
318317
// Check that no two dispatch outputs dispatch to the same warp in the same cycle
319318
assert property (@(posedge clk_i) disable iff (!rst_ni)
320319
(disp_valid_o[didx] && opc_ready_i[didx] && disp_valid_o[other_didx]

rtl/compute_unit/dispatcher/wait_buffer.sv

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
module wait_buffer import bgpu_pkg::*; #(
99
/// Number of instructions to fetch for the warp
1010
parameter int unsigned FetchWidth = 1,
11+
/// Number of instructions to dispatch simultaneously
12+
parameter int unsigned DispatchWidth = 1,
1113
/// Number of instructions that can write back simultaneously
1214
parameter int unsigned WritebackWidth = 1,
1315
/// Number of inflight instructions
@@ -71,8 +73,8 @@ module wait_buffer import bgpu_pkg::*; #(
7173
output op_reg_idx_t disp_operands_o,
7274

7375
/// From Operand Collector -> instruction has read its operands
74-
input logic opc_eu_handshake_i,
75-
input tag_t opc_eu_tag_i,
76+
input logic [DispatchWidth-1:0] opc_eu_handshake_i,
77+
input tag_t [DispatchWidth-1:0] opc_eu_tag_i,
7678

7779
/// From Execution Units
7880
input logic [WritebackWidth-1:0] eu_valid_i,
@@ -291,15 +293,17 @@ module wait_buffer import bgpu_pkg::*; #(
291293
always_comb begin : build_remove_mask
292294
remove_mask = '0;
293295

294-
if (opc_eu_handshake_i) begin
295-
for (int i = 0; i < NumTags; i++) begin : gen_remove_mask
296-
if (wait_buffer_valid_q[i]
297-
&& wait_buffer_dispatched_q[i]
298-
&& wait_buffer_q[i].tag == opc_eu_tag_i) begin
299-
remove_mask[i] = 1'b1;
300-
end
301-
end : gen_remove_mask
302-
end
296+
for (int didx = 0; didx < DispatchWidth; didx++) begin : loop_remove_mask
297+
if (opc_eu_handshake_i[didx]) begin
298+
for (int i = 0; i < NumTags; i++) begin : gen_remove_mask
299+
if (wait_buffer_valid_q[i]
300+
&& wait_buffer_dispatched_q[i]
301+
&& wait_buffer_q[i].tag == opc_eu_tag_i[didx]) begin
302+
remove_mask[i] = 1'b1;
303+
end
304+
end : gen_remove_mask
305+
end
306+
end : loop_remove_mask
303307
end : build_remove_mask
304308

305309
// Wait Buffer Entry Logic
@@ -434,10 +438,18 @@ module wait_buffer import bgpu_pkg::*; #(
434438
|-> |arb_gnt)
435439
else $error("No instruction selected for dispatch");
436440

437-
// Remove mask can only have one or no bits set
438-
assert property (@(posedge clk_i) disable iff(!rst_ni)
439-
(remove_mask == '0 || $onehot(remove_mask)))
440-
else $error("Remove mask has more than one bit set");
441+
// OPC handshake must only have unique tags
442+
for (genvar didx = 0; didx < DispatchWidth; didx++) begin : gen_assert_unique_opc_tags
443+
for (genvar didx2 = 0; didx2 < DispatchWidth; didx2++) begin : gen_check_unique_opc_tags
444+
if (didx != didx2) begin : gen_check_different_dispatch_indices
445+
assert property (@(posedge clk_i) disable iff(!rst_ni)
446+
!(opc_eu_handshake_i[didx] && opc_eu_handshake_i[didx2]
447+
&& opc_eu_tag_i[didx] == opc_eu_tag_i[didx2]))
448+
else $error("OPC EU handshake has non-unique tags: %0d and %0d have tag %0d",
449+
didx, didx2, opc_eu_tag_i[didx]);
450+
end : gen_check_different_dispatch_indices
451+
end : gen_check_unique_opc_tags
452+
end : gen_assert_unique_opc_tags
441453

442454
// Dispatch mask can only have one or no bits set
443455
assert property (@(posedge clk_i) disable iff(!rst_ni)

0 commit comments

Comments
 (0)