Skip to content

Commit c60a7b2

Browse files
hw: add 2x VLSU bandwidth support for Spatz
1 parent 70bc183 commit c60a7b2

20 files changed

+1709
-32
lines changed

Bender.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ sources:
139139
- hw/ip/spatz/src/spatz_ipu.sv
140140
- hw/ip/spatz/src/spatz_vfu.sv
141141
- hw/ip/spatz/src/spatz_vlsu.sv
142+
- hw/ip/spatz/src/spatz_doublebw_vlsu.sv
142143
- hw/ip/spatz/src/spatz_vrf.sv
143144
- hw/ip/spatz/src/spatz_vsldu.sv
144145
# Level 4

docs/schema/spatz_cluster.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@
165165
"description": "Activate floating point support in Spatz",
166166
"default": false
167167
},
168+
"spatz_nports": {
169+
"type": "number",
170+
"description": "Number of TCDM ports per Spatz instance",
171+
"default": 4
172+
},
168173
"timing": {
169174
"type": "object",
170175
"title": "Timing and Latency Tuning Parameter",

hw/ip/spatz/src/generated/spatz_pkg.sv

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package spatz_pkg;
88

99
import rvv_pkg::*;
10+
import cf_math_pkg::idx_width;
1011

1112
//////////////////
1213
// Parameters //
@@ -58,6 +59,9 @@ package spatz_pkg;
5859
// Number of elements per VRF Bank
5960
localparam int unsigned NrWordsPerBank = NrVRFWords / NrVRFBanks;
6061

62+
// Number of VLSU interfaces
63+
localparam int unsigned NumVLSUInterfaces = 1;
64+
6165
// Width of scalar register file adresses
6266
// Depends on whether we have a FP regfile or not
6367
localparam int GPRWidth = FPU ? 6 : 5;
@@ -286,8 +290,12 @@ package spatz_pkg;
286290

287291
// Did the memory request trigger an exception
288292
logic exc;
293+
294+
// Interface that is committing
295+
logic intf_id;
289296
} vlsu_rsp_t;
290297

298+
291299
////////////////////
292300
// VSLDU Response //
293301
////////////////////
@@ -301,7 +309,7 @@ package spatz_pkg;
301309
// VRF/SB Ports //
302310
//////////////////
303311

304-
typedef enum logic [2:0] {
312+
typedef enum logic [idx_width(4 + 2 * 1):0] {
305313
VFU_VS2_RD,
306314
VFU_VS1_RD,
307315
VFU_VD_RD,
@@ -310,13 +318,13 @@ package spatz_pkg;
310318
VSLDU_VS2_RD
311319
} vreg_port_rd_e;
312320

313-
typedef enum logic [1:0] {
321+
typedef enum logic [idx_width(2 + 1):0] {
314322
VFU_VD_WD,
315323
VLSU_VD_WD,
316324
VSLDU_VD_WD
317325
} vreg_port_wd_e;
318326

319-
typedef enum logic [3:0] {
327+
typedef enum logic [idx_width(6 + 3 * 1):0] {
320328
SB_VFU_VS2_RD,
321329
SB_VFU_VS1_RD,
322330
SB_VFU_VD_RD,

hw/ip/spatz/src/spatz.sv

Lines changed: 120 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
7272
////////////////
7373

7474
// Number of ports of the vector register file
75-
localparam int unsigned NrWritePorts = 3;
76-
localparam int unsigned NrReadPorts = 6;
75+
localparam int unsigned NrWritePorts = 2 + NumVLSUInterfaces; // 1 for VFU and SLDU each and 1 for each VLSU
76+
localparam int unsigned NrReadPorts = 4 + 2*NumVLSUInterfaces; // 3 for VFU, 1 for SLDU and 2 for each VLSU interface
7777

7878
// FPU buffer size (need atleast depth of 2 to hide conflicts)
7979
localparam int unsigned FpuBufDepth = 4;
80+
localparam int unsigned VlsuBufDepth = 2;
8081

8182
/////////////
8283
// Signals //
@@ -92,8 +93,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
9293
vfu_rsp_t vfu_rsp, vfu_rsp_buf;
9394

9495
logic vlsu_req_ready;
95-
logic vlsu_rsp_valid;
96-
vlsu_rsp_t vlsu_rsp;
96+
logic vlsu_rsp_valid, vlsu_rsp_buf_valid;
97+
vlsu_rsp_t vlsu_rsp, vlsu_rsp_buf;
9798

9899
logic vsldu_req_ready;
99100
logic vsldu_rsp_valid;
@@ -104,6 +105,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
104105
// buffers store the metadata to commit to the VRF in later cycles
105106

106107
logic [$clog2(FpuBufDepth)-1:0] vfu_buf_usage;
108+
logic [$clog2(VlsuBufDepth)-1:0] vlsu_buf_usage;
107109

108110
typedef struct packed {
109111
vrf_data_t wdata;
@@ -116,6 +118,17 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
116118

117119
vfu_buf_t vfu_buf_data;
118120

121+
typedef struct packed {
122+
vrf_data_t wdata;
123+
vrf_addr_t waddr;
124+
vrf_be_t wbe;
125+
spatz_id_t wid;
126+
vlsu_rsp_t rsp;
127+
logic rsp_valid;
128+
} vlsu_buf_t;
129+
130+
vlsu_buf_t vlsu_buf_data;
131+
119132
/////////////////////
120133
// FPU sequencer //
121134
/////////////////////
@@ -218,7 +231,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
218231

219232
spatz_vrf #(
220233
.NrReadPorts (NrReadPorts ),
221-
.NrWritePorts(NrWritePorts)
234+
.NrWritePorts(NrWritePorts),
235+
.FpuBufDepth (FpuBufDepth )
222236
) i_vrf (
223237
.clk_i (clk_i ),
224238
.rst_ni (rst_ni ),
@@ -278,9 +292,9 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
278292
.vfu_rsp_ready_o (vfu_rsp_ready ),
279293
.vfu_rsp_i (vfu_rsp_buf ),
280294
// VLSU
281-
.vlsu_req_ready_i (vlsu_req_ready ),
282-
.vlsu_rsp_valid_i (vlsu_rsp_valid ),
283-
.vlsu_rsp_i (vlsu_rsp ),
295+
.vlsu_req_ready_i (vlsu_req_ready ),
296+
.vlsu_rsp_valid_i (vlsu_rsp_buf_valid ),
297+
.vlsu_rsp_i (vlsu_rsp_buf ),
284298
// VLSD
285299
.vsldu_req_ready_i(vsldu_req_ready ),
286300
.vsldu_rsp_valid_i(vsldu_rsp_valid ),
@@ -331,6 +345,40 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
331345
.data_o (vfu_buf_data ),
332346
.pop_i (vfu_buf_pop )
333347
);
348+
349+
`ifdef DOUBLE_BW
350+
// Buffering of VLSU1 when conflicting with VLSU0
351+
logic vlsu_buf_en, vlsu_buf_push, vlsu_buf_pop, vrf_vlsu_wvalid, vlsu_buf_full, vlsu_buf_empty;
352+
353+
assign vlsu_buf_en = sb_we[VLSU_VD_WD1] && (!vrf_wvalid[VLSU_VD_WD1] || (vrf_wvalid[VLSU_VD_WD1] && !vlsu_buf_empty));
354+
assign vlsu_buf_push = vlsu_buf_en && !vlsu_buf_full;
355+
assign vlsu_buf_pop = vrf_wvalid[VLSU_VD_WD1] && !vlsu_buf_empty;
356+
assign vrf_vlsu_wvalid = sb_we[VLSU_VD_WD1] && !vlsu_buf_full;
357+
358+
fifo_v3 #(
359+
.FALL_THROUGH (1'b0 ),
360+
.dtype (vlsu_buf_t ),
361+
.DEPTH (VlsuBufDepth )
362+
) i_vlsu_buf (
363+
.clk_i (clk_i ),
364+
.rst_ni (rst_ni ),
365+
.flush_i (1'b0 ),
366+
.testmode_i (1'b0 ),
367+
.full_o (vlsu_buf_full ),
368+
.empty_o (vlsu_buf_empty ),
369+
.usage_o (vlsu_buf_usage ),
370+
.data_i ({vrf_wdata[VLSU_VD_WD1],
371+
vrf_waddr[VLSU_VD_WD1],
372+
vrf_wbe [VLSU_VD_WD1],
373+
sb_id [SB_VLSU_VD_WD1],
374+
vlsu_rsp,
375+
vlsu_rsp_valid} ),
376+
.push_i (vlsu_buf_push ),
377+
.data_o (vlsu_buf_data ),
378+
.pop_i (vlsu_buf_pop )
379+
);
380+
381+
`endif
334382
`endif
335383

336384
always_comb begin
@@ -343,6 +391,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
343391
// Responses
344392
vfu_rsp_buf = vfu_rsp;
345393
vfu_rsp_buf_valid = vfu_rsp_valid;
394+
vlsu_rsp_buf = vlsu_rsp;
395+
vlsu_rsp_buf_valid = vlsu_rsp_valid;
346396

347397
// If the buffering feature is used for the FPU or VLSU,
348398
// Use the metadata to commit the data to the VRF
@@ -361,6 +411,30 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
361411
vfu_rsp_buf_valid = 1'b0;
362412
end
363413
end
414+
415+
`ifdef DOUBLE_BW
416+
// VLSU1 buffering
417+
// Check if interface 1 response is being buffered, if so do not send response now
418+
if (vlsu_rsp_valid && (vlsu_rsp.intf_id == 1'b1) && vlsu_buf_push)
419+
vlsu_rsp_buf_valid = 1'b0;
420+
421+
if (!vlsu_buf_empty) begin
422+
sb_we_buf [VLSU_VD_WD1] = 1'b1;
423+
vrf_wdata_buf[VLSU_VD_WD1] = vlsu_buf_data.wdata;
424+
vrf_waddr_buf[VLSU_VD_WD1] = vlsu_buf_data.waddr;
425+
vrf_wbe_buf [VLSU_VD_WD1] = vlsu_buf_data.wbe;
426+
sb_buf_id [SB_VLSU_VD_WD1] = vlsu_buf_data.wid;
427+
if (vlsu_buf_data.rsp_valid) begin
428+
vlsu_rsp_buf = vlsu_buf_data.rsp;
429+
vlsu_rsp_buf_valid = vrf_wvalid[VLSU_VD_WD1];
430+
end
431+
end else begin
432+
// If the buffer is being enabled in this cycle, don't send the response now
433+
if (vlsu_buf_en) begin
434+
vlsu_rsp_buf_valid = 1'b0;
435+
end
436+
end
437+
`endif
364438
`endif
365439
end // always_comb
366440

@@ -405,6 +479,43 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
405479
// VLSU //
406480
//////////
407481

482+
`ifdef DOUBLE_BW
483+
spatz_doublebw_vlsu #(
484+
.NrMemPorts (NrMemPorts ),
485+
.spatz_mem_req_t (spatz_mem_req_t ),
486+
.spatz_mem_rsp_t (spatz_mem_rsp_t )
487+
) i_vlsu (
488+
.clk_i (clk_i ),
489+
.rst_ni (rst_ni ),
490+
// Request
491+
.spatz_req_i (spatz_req ),
492+
.spatz_req_valid_i (spatz_req_valid ),
493+
.spatz_req_ready_o (vlsu_req_ready ),
494+
// Response
495+
.vlsu_rsp_valid_o (vlsu_rsp_valid ),
496+
.vlsu_rsp_o (vlsu_rsp ),
497+
// VRF
498+
.vrf_wvalid_i ({vrf_vlsu_wvalid, vrf_wvalid[VLSU_VD_WD0]} ),
499+
.vrf_waddr_o (vrf_waddr[VLSU_VD_WD1:VLSU_VD_WD0] ),
500+
.vrf_wdata_o (vrf_wdata[VLSU_VD_WD1:VLSU_VD_WD0] ),
501+
.vrf_we_o (sb_we[VLSU_VD_WD1:VLSU_VD_WD0] ),
502+
.vrf_wbe_o (vrf_wbe[VLSU_VD_WD1:VLSU_VD_WD0] ),
503+
.vrf_raddr_o (vrf_raddr[VLSU_VD_RD1:VLSU_VS2_RD0] ),
504+
.vrf_re_o (sb_re[VLSU_VD_RD1:VLSU_VS2_RD0] ),
505+
.vrf_rdata_i (vrf_rdata[VLSU_VD_RD1:VLSU_VS2_RD0] ),
506+
.vrf_rvalid_i (vrf_rvalid[VLSU_VD_RD1:VLSU_VS2_RD0] ),
507+
.vrf_id_o ({sb_id[SB_VLSU_VD_WD1], sb_id[VLSU_VD_RD1], sb_id[VLSU_VS2_RD1], // VLSU Interface-1
508+
sb_id[SB_VLSU_VD_WD0], sb_id[VLSU_VD_RD0], sb_id[VLSU_VS2_RD0]}), // VLSU Interface-0
509+
// Interface Memory
510+
.spatz_mem_req_o (spatz_mem_req_o ),
511+
.spatz_mem_req_valid_o (spatz_mem_req_valid_o ),
512+
.spatz_mem_req_ready_i (spatz_mem_req_ready_i ),
513+
.spatz_mem_rsp_i (spatz_mem_rsp_i ),
514+
.spatz_mem_rsp_valid_i (spatz_mem_rsp_valid_i ),
515+
.spatz_mem_finished_o (spatz_mem_finished ),
516+
.spatz_mem_str_finished_o(spatz_mem_str_finished )
517+
);
518+
`else
408519
spatz_vlsu #(
409520
.NrMemPorts (NrMemPorts ),
410521
.spatz_mem_req_t (spatz_mem_req_t ),
@@ -439,6 +550,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
439550
.spatz_mem_finished_o (spatz_mem_finished ),
440551
.spatz_mem_str_finished_o(spatz_mem_str_finished )
441552
);
553+
`endif
442554

443555
///////////
444556
// VSLDU //

0 commit comments

Comments
 (0)