Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Bender.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ packages:
Git: https://github.com/pulp-platform/common_verification.git
dependencies: []
fpnew:
revision: bf2100ff68cf736c50b095169d87231a1fa3cc66
revision: 0f6caf1dc76eb4f96c388364e35e8bf03ca19625
version: null
source:
Git: https://github.com/Jayanth2209/cvfpu.git
Git: https://github.com/arpansur/cvfpu.git
dependencies:
- common_cells
- fpu_div_sqrt_mvp
Expand Down
6 changes: 4 additions & 2 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# SPDX-License-Identifier: Apache-2.0

package:
name: spatz_core
name: spatz_vpu
authors:
- "Matheus Cavalcante <matheusd@iis.ee.ethz.ch>"
- "Mattia Sinigaglia <mattia.sinigaglia5@unibo.it>"
Expand All @@ -12,7 +12,7 @@ package:
dependencies:
riscv-dbg: { git: "https://github.com/pulp-platform/riscv-dbg.git", version: 0.7.0 }
common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.28.0 }
FPnew: { git: "https://github.com/Jayanth2209/cvfpu.git", rev: bf2100ff68cf736c50b095169d87231a1fa3cc66 }
FPnew: { git: "https://github.com/arpansur/cvfpu.git", rev: 0f6caf1dc76eb4f96c388364e35e8bf03ca19625 } # branch: pace-pipe-rebase
tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.13 }
snitch: { path: "hw/ip/snitch" }
reqrsp_interface: { path: "hw/ip/reqrsp_interface" }
Expand All @@ -34,6 +34,7 @@ sources:
# Level 2
- hw/src/spatz_decoder.sv
- hw/src/spatz_simd_lane.sv
- hw/src/pace_mem.sv
- target: fpga
files:
- hw/src/vregfile_fpga.sv
Expand All @@ -45,6 +46,7 @@ sources:
- hw/src/spatz_ipu.sv
- hw/src/spatz_vfu.sv
- hw/src/spatz_vlsu.sv
- hw/src/spatz_doublebw_vlsu.sv
- hw/src/spatz_vrf.sv
- hw/src/spatz_vsldu.sv
# Level 4
Expand Down
1 change: 1 addition & 0 deletions hw/ip/snitch/src/riscv_instr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,7 @@ package riscv_instr;
localparam logic [11:0] CSR_MHPMCOUNTER29H = 12'hb9d;
localparam logic [11:0] CSR_MHPMCOUNTER30H = 12'hb9e;
localparam logic [11:0] CSR_MHPMCOUNTER31H = 12'hb9f;
localparam logic [11:0] CSR_PACE = 12'hba0;

// MXCore custom instructions (opcode custom-3: 1110111)
localparam logic [31:0] MXDOTP_B0 = 32'b?????????????????000?????1110111;
Expand Down
37 changes: 24 additions & 13 deletions hw/src/generated/spatz_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// Number of IPUs in each VFU (between 1 and 8)
localparam int unsigned N_IPU = 1;
// Number of FPUs in each VFU (between 1 and 8)
localparam int unsigned N_FPU = 8;
localparam int unsigned N_FPU = 4;

Check warning on line 21 in hw/src/generated/spatz_pkg.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/generated/spatz_pkg.sv#L21

Localparam name does not match the naming convention defined by regex pattern: (([A-Z0-9]+[a-z0-9]*)+(_[0-9]+)?) [Style: constants] [parameter-name-style]
Raw output
message:"Localparam name does not match the naming convention defined by regex pattern: (([A-Z0-9]+[a-z0-9]*)+(_[0-9]+)?) [Style: constants] [parameter-name-style]" location:{path:"hw/src/generated/spatz_pkg.sv" range:{start:{line:21 column:27}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
// Number of FUs in each VFU
localparam int unsigned N_FU = N_IPU > N_FPU ? N_IPU : N_FPU;
// FPU support
Expand Down Expand Up @@ -62,7 +62,7 @@
localparam int unsigned NrWordsPerBank = NrVRFWords / NrVRFBanks;

// Number of VLSU interfaces
localparam int unsigned NumVLSUInterfaces = 1;
localparam int unsigned NumVLSUInterfaces = 2;

// Width of scalar register file adresses
// Depends on whether we have a FP regfile or not
Expand All @@ -76,6 +76,11 @@

// Encodes both the scalar RD and the VD address in the VRF
localparam int VFURespAddrWidth = GPRWidth > $clog2(NrVRFWords) ? GPRWidth : $clog2(NrVRFWords);
localparam int PaceDegree = 2;
localparam int PaceParts = 16;
localparam int PaceEps = 1;
localparam int PaceDataWidth = 32;
localparam int PaceParamWidth = ((PaceDegree + 1)*PaceParts + PaceParts - 1 + 2*PaceEps) * PaceDataWidth;

//////////////////////
// Type Definitions //
Expand Down Expand Up @@ -311,30 +316,34 @@
// VRF/SB Ports //
//////////////////

typedef enum logic [idx_width(4 + 2 * 1):0] {
typedef enum logic [idx_width(4 + 2 * 2):0] {
VFU_VS2_RD,
VFU_VS1_RD,
VFU_VD_RD,
VLSU_VS2_RD,
VLSU_VD_RD,
VLSU_VD_RD0,
VLSU_VS2_RD0,
VLSU_VD_RD1,
VLSU_VS2_RD1,
VSLDU_VS2_RD
} vreg_port_rd_e;

typedef enum logic [idx_width(2 + 1):0] {
typedef enum logic [idx_width(2 + 2):0] {
VFU_VD_WD,
VLSU_VD_WD,
VLSU_VD_WD[2],
VSLDU_VD_WD
} vreg_port_wd_e;

typedef enum logic [idx_width(6 + 3 * 1):0] {
typedef enum logic [idx_width(6 + 3 * 2):0] {
SB_VFU_VS2_RD,
SB_VFU_VS1_RD,
SB_VFU_VD_RD,
SB_VLSU_VS2_RD,
SB_VLSU_VD_RD,
SB_VLSU_VD_RD0,
SB_VLSU_VS2_RD0,
SB_VLSU_VD_RD1,
SB_VLSU_VS2_RD1,
SB_VSLDU_VS2_RD,
SB_VFU_VD_WD,
SB_VLSU_VD_WD,
SB_VLSU_VD_WD[2],
SB_VSLDU_VD_WD
} sb_port_e;

Expand All @@ -358,7 +367,8 @@
// INT8 INT16 INT32 INT64
IntFmtMask : {1'b1, 1'b1, 1'b1, 1'b1},
MxFpFmtMask : 9'b0,
MxIntFmtMask : 4'b0
MxIntFmtMask : 4'b0,
PaceFeatures : '{PaceDegree: PaceDegree, PaceParts: PaceParts, PaceEps: 1'b1, PaceDataWidth: PaceDataWidth, PaceParamWidth: PaceParamWidth, PaceBstPipeRegs: 4'b0100, FmtConfig: 9'b101010000}
} :
// Single Precision FPU
'{
Expand All @@ -370,7 +380,8 @@
// INT8 INT16 INT32 INT64
IntFmtMask : {1'b1, 1'b1, 1'b1, 1'b0},
MxFpFmtMask : 9'b0,
MxIntFmtMask : 4'b0
MxIntFmtMask : 4'b0,
PaceFeatures : '{PaceDegree: PaceDegree, PaceParts: PaceParts, PaceEps: 1'b1, PaceDataWidth: PaceDataWidth, PaceParamWidth: PaceParamWidth, PaceBstPipeRegs: 4'b0100, FmtConfig: 9'b101010000}
};

// FP format conversion
Expand Down
63 changes: 63 additions & 0 deletions hw/src/pace_mem.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2026 ETH Zurich and University of Bologna.
//

Check failure on line 2 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / lint-license

FAILED: Licence did not match

Check failure on line 2 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / lint-license

FAILED: Licence did not match
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// SPDX-License-Identifier: SHL-0.51

// Author: Arpan Suravi Prasad <prasadar@iis.ee.ethz.ch>
module pace_mem #(
parameter int unsigned BufDepth = 2,
parameter int unsigned BufWidth = 256,
parameter int unsigned ParamWidth = 256,
localparam int unsigned AddrWidth = $clog2(BufDepth)
)(
input logic clk_i,
input logic rst_ni,
input logic we_i,
output logic done_o,
input logic init_i,
input logic [BufWidth-1:0] data_i,
output logic [ParamWidth-1:0] data_o
);
logic [BufDepth-1:0][BufWidth-1:0] mem_d, mem_q;
logic [AddrWidth-1:0] cnt_d, cnt_q;

always_comb begin
mem_d = mem_q;
cnt_d = cnt_q;
mem_d[cnt_q] = we_i ? data_i : mem_q[cnt_q];
cnt_d = (init_i == 1'b0) ? '0 : we_i ? cnt_q + 1 : cnt_q;
end

assign done_o = (cnt_q == BufDepth);

always_ff @(posedge clk_i, negedge rst_ni) begin
if(~rst_ni) begin
cnt_q <= '0;
mem_q <= '0;
end else begin
cnt_q <= cnt_d;
mem_q <= mem_d;
end
end

localparam NumParamWords = ParamWidth / BufWidth;

Check warning on line 51 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/pace_mem.sv#L51

Explicitly define a storage type for every parameter and localparam, (NumParamWords). [Style: constants] [explicit-parameter-storage-type]
Raw output
message:"Explicitly define a storage type for every parameter and localparam, (NumParamWords). [Style: constants] [explicit-parameter-storage-type]" location:{path:"hw/src/pace_mem.sv" range:{start:{line:51 column:14}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
localparam RemParamWords = ParamWidth % BufWidth;

Check warning on line 52 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/pace_mem.sv#L52

Explicitly define a storage type for every parameter and localparam, (RemParamWords). [Style: constants] [explicit-parameter-storage-type]
Raw output
message:"Explicitly define a storage type for every parameter and localparam, (RemParamWords). [Style: constants] [explicit-parameter-storage-type]" location:{path:"hw/src/pace_mem.sv" range:{start:{line:52 column:14}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}

if(NumParamWords > 0) begin

Check warning on line 54 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/pace_mem.sv#L54

All generate block statements must have a label [Style: generate-statements] [generate-label]
Raw output
message:"All generate block statements must have a label [Style: generate-statements] [generate-label]" location:{path:"hw/src/pace_mem.sv" range:{start:{line:54 column:25}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
for(genvar ii=0; ii<NumParamWords; ii++) begin

Check warning on line 55 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/pace_mem.sv#L55

All generate block statements must have a label [Style: generate-statements] [generate-label]
Raw output
message:"All generate block statements must have a label [Style: generate-statements] [generate-label]" location:{path:"hw/src/pace_mem.sv" range:{start:{line:55 column:46}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
assign data_o[ii*BufWidth+:BufWidth] = mem_q[ii];
end
end
if(RemParamWords > 0) begin

Check warning on line 59 in hw/src/pace_mem.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/src/pace_mem.sv#L59

All generate block statements must have a label [Style: generate-statements] [generate-label]
Raw output
message:"All generate block statements must have a label [Style: generate-statements] [generate-label]" location:{path:"hw/src/pace_mem.sv" range:{start:{line:59 column:25}}} severity:WARNING source:{name:"verible-verilog-lint" url:"https://github.com/chipsalliance/verible"}
localparam int unsigned RemWidth = ParamWidth - NumParamWords*BufWidth;
assign data_o[NumParamWords*BufWidth+:RemWidth] = mem_q[NumParamWords][0+:RemWidth];
end
endmodule
63 changes: 60 additions & 3 deletions hw/src/spatz.sv
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
// FPU side channel
input roundmode_e fpu_rnd_mode_i,
input fmt_mode_t fpu_fmt_mode_i,
input pace_mode_t fpu_pace_mode_i,
output status_t fpu_status_o
);

Expand Down Expand Up @@ -403,14 +404,49 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
vrf_addr_t [NrWritePorts-1:0] vrf_waddr, vrf_waddr_buf;
vrf_data_t [NrWritePorts-1:0] vrf_wdata, vrf_wdata_buf;
logic [NrWritePorts-1:0] vrf_we;
logic [NrWritePorts-1:0] vrf_we_mask;
vrf_be_t [NrWritePorts-1:0] vrf_wbe, vrf_wbe_buf;
logic [NrWritePorts-1:0] vrf_wvalid;
logic [NrWritePorts-1:0] vrf_wvalid_mask;
// Read ports
vrf_addr_t [NrReadPorts-1:0] vrf_raddr;
logic [NrReadPorts-1:0] vrf_re;
vrf_data_t [NrReadPorts-1:0] vrf_rdata;
logic [NrReadPorts-1:0] vrf_rvalid;

// PACE parameter memory
// With DOUBLE_BW both VLSU write ports carry consecutive 256-bit chunks each cycle,
// so we must capture both to reconstruct the contiguous parameter stream.
`ifdef DOUBLE_BW
// Use WD0-only for pace_mem: each beat captures 256 bits from WD0 (lower addresses).
// This avoids requiring simultaneous WD0+WD1 grants, which is unreliable in DOUBLE_BW.
localparam int unsigned PaceBufWidth = N_FU * ELEN;
`else
localparam int unsigned PaceBufWidth = N_FU * ELEN;
`endif
localparam int unsigned PaceLdIdx = VLSU_VD_WD0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess PaceLdIdx could be initialized within the above ifdef? and so only PaceLdIdx need to be used in later code.

localparam int unsigned PaceBufDepth = (PaceParamWidth + PaceBufWidth - 1) / PaceBufWidth;
logic pace_mem_we;
logic [PaceParamWidth-1:0] pace_params;
logic pace_mem_init_done;

`ifdef DOUBLE_BW
assign pace_mem_we = fpu_pace_mode_i.enable & vrf_we[VLSU_VD_WD0] & (~pace_mem_init_done);
`else
assign pace_mem_we = fpu_pace_mode_i.enable & vrf_we[PaceLdIdx] & (~pace_mem_init_done);
`endif

always_comb begin
vrf_we_mask = vrf_we;
vrf_wvalid = vrf_wvalid_mask;
vrf_we_mask[VLSU_VD_WD0] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? 1'b0 : vrf_we[VLSU_VD_WD0];
vrf_wvalid[VLSU_VD_WD0] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? vrf_we[VLSU_VD_WD0] : vrf_wvalid_mask[VLSU_VD_WD0];
`ifdef DOUBLE_BW
vrf_we_mask[VLSU_VD_WD1] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? 1'b0 : vrf_we[VLSU_VD_WD1];
vrf_wvalid[VLSU_VD_WD1] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? vrf_we[VLSU_VD_WD1] : vrf_wvalid_mask[VLSU_VD_WD1];
`endif
end

spatz_vrf #(
.NrReadPorts (NrReadPorts ),
.NrWritePorts(NrWritePorts),
Expand All @@ -422,9 +458,9 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
// Write Ports
.waddr_i (vrf_waddr_buf ),
.wdata_i (vrf_wdata_buf ),
.we_i (vrf_we ),
.wbe_i (vrf_wbe_buf ),
.wvalid_o (vrf_wvalid ),
.we_i (vrf_we_mask ),
.wbe_i (vrf_wbe_buf ),
.wvalid_o (vrf_wvalid_mask),
`ifdef BUF_FPU
.fpu_buf_usage_i (vfu_buf_usage ),
`endif
Expand All @@ -435,6 +471,24 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
.rvalid_o (vrf_rvalid )
);

pace_mem #(
.BufDepth (PaceBufDepth ),
.BufWidth (PaceBufWidth ),
.ParamWidth(PaceParamWidth)
) i_pace_mem (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.we_i (pace_mem_we ),
.done_o (pace_mem_init_done ),
.init_i (fpu_pace_mode_i.enable ),
`ifdef DOUBLE_BW
.data_i (vrf_wdata_buf[VLSU_VD_WD0]),
`else
.data_i (vrf_wdata_buf[PaceLdIdx]),
`endif
.data_o (pace_params )
);

////////////////
// Controller //
////////////////
Expand Down Expand Up @@ -654,6 +708,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
.vrf_rvalid_i (vrf_rvalid[VFU_VD_RD:VFU_VS2_RD] ),
.vrf_id_o ({sb_id[SB_VFU_VD_WD], sb_id[SB_VFU_VD_RD:SB_VFU_VS2_RD]}),
// FPU side-channel
.pace_mode_i (fpu_pace_mode_i ),
.pace_param_i (pace_params ),
.fpu_status_o (fpu_status_o )
);

Expand All @@ -676,6 +732,7 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #(
// Response
.vlsu_rsp_valid_o (vlsu_rsp_valid ),
.vlsu_rsp_o (vlsu_rsp ),
.vlsu_buf_full_i (vlsu_buf_full ),
.vlsu_buf_empty_i (vlsu_buf_empty ),
// VRF
.vrf_wvalid_i ({vrf_vlsu_wvalid, vrf_wvalid[VLSU_VD_WD0]} ),
Expand Down
Loading
Loading