Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
67 changes: 64 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,53 @@ 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
`ifdef DOUBLE_BW
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.

`else
localparam int unsigned PaceLdIdx = VLSU_VD_WD;
`endif
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[PaceLdIdx] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? 1'b0 : vrf_we[PaceLdIdx];
vrf_wvalid[PaceLdIdx] = fpu_pace_mode_i.enable & (~pace_mem_init_done) ? vrf_we[PaceLdIdx] : vrf_wvalid_mask[PaceLdIdx];
`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 +462,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 +475,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 +712,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 +736,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