Skip to content

Commit 96f9335

Browse files
Merge branch 'master' into svnapot-feature
2 parents 3548f87 + bb5e4f3 commit 96f9335

8 files changed

Lines changed: 61 additions & 49 deletions

File tree

Bender.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependencies:
1010
axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.31.0 }
1111
common_cells:
1212
{ git: "https://github.com/pulp-platform/common_cells", version: 1.23.0 }
13-
fpnew: { git: "https://github.com/openhwgroup/cvfpu.git", rev: 2c79477 } # branch: develop
13+
fpnew: { git: "https://github.com/openhwgroup/cvfpu.git", rev: 58ca3c3 } # branch: develop
1414
tech_cells_generic:
1515
{ git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.13 }
1616

core/cva6.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ module cva6
474474
logic [CVA6Cfg.XLEN-1:0] fpu_result_ex_id;
475475
logic fpu_valid_ex_id;
476476
exception_t fpu_exception_ex_id;
477+
logic fpu_early_valid_ex_id;
477478
// ALU2
478479
logic [CVA6Cfg.NrIssuePorts-1:0] alu2_valid_id_ex;
479480
// Accelerator
@@ -890,6 +891,7 @@ module cva6
890891
.fpu_valid_o (fpu_valid_id_ex),
891892
.fpu_fmt_o (fpu_fmt_id_ex),
892893
.fpu_rm_o (fpu_rm_id_ex),
894+
.fpu_early_valid_i (fpu_early_valid_ex_id),
893895
// ALU2
894896
.alu2_valid_o (alu2_valid_id_ex),
895897
// CSR
@@ -1022,6 +1024,7 @@ module cva6
10221024
.fpu_result_o (fpu_result_ex_id),
10231025
.fpu_valid_o (fpu_valid_ex_id),
10241026
.fpu_exception_o (fpu_exception_ex_id),
1027+
.fpu_early_valid_o (fpu_early_valid_ex_id),
10251028
// ALU2
10261029
.alu2_valid_i (alu2_valid_id_ex),
10271030
.amo_valid_commit_i (amo_valid_commit),

core/ex_stage.sv

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ module ex_stage
139139
output logic fpu_valid_o,
140140
// FPU exception - ISSUE_STAGE
141141
output exception_t fpu_exception_o,
142+
// FPU early valid - ISSUE_STAGE
143+
output logic fpu_early_valid_o,
142144
// ALU2 instruction is valid - ISSUE_STAGE
143145
input logic [CVA6Cfg.NrIssuePorts-1:0] alu2_valid_i,
144146
// CVXIF instruction is valid - ISSUE_STAGE
@@ -465,14 +467,16 @@ module ex_stage
465467
.fpu_trans_id_o(fpu_trans_id),
466468
.result_o(fpu_result),
467469
.fpu_valid_o(fpu_valid),
468-
.fpu_exception_o
470+
.fpu_exception_o,
471+
.fpu_early_valid_o
469472
);
470473
end else begin : no_fpu_gen
471-
assign fpu_ready_o = '0;
472-
assign fpu_trans_id = '0;
473-
assign fpu_result = '0;
474-
assign fpu_valid = '0;
475-
assign fpu_exception_o = '0;
474+
assign fpu_ready_o = '0;
475+
assign fpu_trans_id = '0;
476+
assign fpu_result = '0;
477+
assign fpu_valid = '0;
478+
assign fpu_exception_o = '0;
479+
assign fpu_early_valid_o = '0;
476480
end
477481
endgenerate
478482

core/fpu_wrap.sv

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ module fpu_wrap
3434
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] fpu_trans_id_o,
3535
output logic [ CVA6Cfg.FLen-1:0] result_o,
3636
output logic fpu_valid_o,
37-
output exception_t fpu_exception_o
37+
output exception_t fpu_exception_o,
38+
output logic fpu_early_valid_o
3839
);
3940

4041
// this is a workaround
@@ -553,7 +554,8 @@ module fpu_wrap
553554
.tag_o (fpu_trans_id_o),
554555
.out_valid_o (fpu_out_valid),
555556
.out_ready_i (fpu_out_ready),
556-
.busy_o ( /* unused */)
557+
.busy_o ( /* unused */),
558+
.early_valid_o (fpu_early_valid_o)
557559
);
558560

559561
// Pack status flag into exception cause, tval ignored in wb, exception is always invalid

core/include/config_pkg.sv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ package config_pkg;
431431
assert (Cfg.NrExecuteRegionRules <= NrMaxRules);
432432
assert (Cfg.NrCachedRegionRules <= NrMaxRules);
433433
assert (Cfg.NrPMPEntries <= 64);
434-
assert (!(Cfg.SuperscalarEn && Cfg.RVF));
435434
assert (Cfg.FETCH_WIDTH == 32 || Cfg.FETCH_WIDTH == 64)
436435
else $fatal(1, "[frontend] fetch width != not supported");
437436
// Support for disabling MIP.MSIP and MIE.MSIE in Hypervisor and Supervisor mode is not supported

core/issue_read_operands.sv

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ module issue_read_operands
8282
output logic [CVA6Cfg.NrIssuePorts-1:0] mult_valid_o,
8383
// FPU FU is ready - EX_STAGE
8484
input logic fpu_ready_i,
85+
// FPU FU will perform a writeback in the next cycle - EX_STAGE
86+
input logic fpu_early_valid_i,
8587
// FPU FU is valid - EX_STAGE
8688
output logic [CVA6Cfg.NrIssuePorts-1:0] fpu_valid_o,
8789
// FPU fmt field - EX_STAGE
@@ -152,10 +154,10 @@ module issue_read_operands
152154
rs3_len_t operand_c_fpr;
153155
// output flipflop (ID <-> EX)
154156
fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_n, fu_data_q;
155-
logic [CVA6Cfg.VLEN-1:0] pc_n;
156-
logic is_compressed_instr_n;
157-
branchpredict_sbe_t branch_predict_n;
158-
logic [CVA6Cfg.XLEN-1:0] imm_forward_rs3;
157+
logic [ CVA6Cfg.VLEN-1:0] pc_n;
158+
logic is_compressed_instr_n;
159+
branchpredict_sbe_t branch_predict_n;
160+
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] imm_forward_rs3;
159161

160162
logic [CVA6Cfg.NrIssuePorts-1:0] alu_valid_n, alu_valid_q;
161163
logic [CVA6Cfg.NrIssuePorts-1:0] aes_valid_n, aes_valid_q;
@@ -215,8 +217,10 @@ module issue_read_operands
215217
logic [CVA6Cfg.NrIssuePorts-1:0] forward_rs1, forward_rs2, forward_rs3;
216218

217219
// original instruction
218-
riscv::instruction_t orig_instr;
219-
assign orig_instr = riscv::instruction_t'(orig_instr_i[0]);
220+
riscv::instruction_t [CVA6Cfg.NrIssuePorts-1:0] orig_instr;
221+
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
222+
assign orig_instr[i] = riscv::instruction_t'(orig_instr_i[i]);
223+
end
220224

221225
// ALU-ALU bypass signals
222226
alu_bypass_t alu_bypass, alu_bypass_n, alu_bypass_q;
@@ -309,10 +313,11 @@ module issue_read_operands
309313
end
310314

311315
if (CVA6Cfg.SuperscalarEn) begin
312-
// When a bypass is possible, an instruction uses `alu2` only when `alu` is already busy,
313-
// in all other scenarios `alu2` is preferred over `alu`, unless it is busy
316+
// When a bypass is possible or an FPU instruction is present on the second issue port,
317+
// an instruction uses `alu2` only when `alu` is already busy
318+
// In all other scenarios `alu2` is preferred over `alu`, unless it is busy
314319
for (genvar i = 0; i < 2; i++) begin
315-
assign use_alu2[i] = is_alu_bypass ? fus_busy[i].alu : !fus_busy[i].alu2;
320+
assign use_alu2[i] = is_alu_bypass || (issue_instr_i[1].fu inside {FPU, FPU_VEC}) ? fus_busy[i].alu : !fus_busy[i].alu2;
316321
end
317322
end else begin
318323
assign use_alu2 = '0;
@@ -347,7 +352,6 @@ module issue_read_operands
347352
if (CVA6Cfg.FpPresent && !fpu_ready_i) begin
348353
fus_busy[0].fpu = 1'b1;
349354
fus_busy[0].fpu_vec = 1'b1;
350-
if (CVA6Cfg.SuperscalarEn) fus_busy[0].alu2 = 1'b1;
351355
end
352356

353357
if (!lsu_ready_i) begin
@@ -356,6 +360,11 @@ module issue_read_operands
356360
end
357361

358362
if (CVA6Cfg.SuperscalarEn) begin
363+
364+
if (fpu_early_valid_i) begin
365+
fus_busy[0].alu2 = 1'b1;
366+
end
367+
359368
fus_busy[1] = fus_busy[0];
360369

361370
// Never issue CSR instruction on second issue port.
@@ -390,10 +399,6 @@ module issue_read_operands
390399
ALU: begin
391400
if (use_alu2[0]) begin
392401
fus_busy[1].alu2 = 1'b1;
393-
// TODO is there a minimum float execution time?
394-
// If so we could issue FPU & ALU2 the same cycle
395-
fus_busy[1].fpu = 1'b1;
396-
fus_busy[1].fpu_vec = 1'b1;
397402
end else begin
398403
fus_busy[1].alu = 1'b1;
399404
fus_busy[1].ctrl_flow = 1'b1;
@@ -408,10 +413,18 @@ module issue_read_operands
408413
FPU, FPU_VEC: begin
409414
fus_busy[1].fpu = 1'b1;
410415
fus_busy[1].fpu_vec = 1'b1;
416+
if (issue_instr_i[1].op inside {[FLD : FSB]}) begin
417+
fus_busy[1].load = 1'b1;
418+
fus_busy[1].store = 1'b1;
419+
end
411420
end
412421
LOAD, STORE: begin
413422
fus_busy[1].load = 1'b1;
414423
fus_busy[1].store = 1'b1;
424+
if (issue_instr_i[0].op inside {[FLD : FSB]}) begin
425+
fus_busy[1].fpu = 1'b1;
426+
fus_busy[1].fpu_vec = 1'b1;
427+
end
415428
end
416429
CVXIF: ;
417430
default: ;
@@ -658,10 +671,12 @@ module issue_read_operands
658671
end
659672

660673
// third operand from fp regfile or gp regfile if NR_RGPR_PORTS == 3
661-
if (OPERANDS_PER_INSTR == 3) begin : gen_gp_rs3
662-
assign imm_forward_rs3 = rs3_res[0];
663-
end else begin : gen_fp_rs3
664-
assign imm_forward_rs3 = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, rs3_res[0]};
674+
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
675+
if (OPERANDS_PER_INSTR == 3) begin : gen_gp_rs3
676+
assign imm_forward_rs3[i] = rs3_res[i];
677+
end else begin : gen_fp_rs3
678+
assign imm_forward_rs3[i] = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, rs3_res[i]};
679+
end
665680
end
666681

667682
// Forwarding/Output MUX
@@ -696,7 +711,7 @@ module issue_read_operands
696711
fu_data_n[i].operand_b = rs2_res[i];
697712
end
698713
if ((CVA6Cfg.FpPresent || (CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3)) && forward_rs3[i]) begin
699-
fu_data_n[i].imm = imm_forward_rs3;
714+
fu_data_n[i].imm = imm_forward_rs3[i];
700715
end
701716

702717
// use the PC as operand a
@@ -760,12 +775,12 @@ module issue_read_operands
760775
default: begin
761776
if (issue_instr_i[i].fu == FPU && CVA6Cfg.FpPresent) begin
762777
fpu_valid_n[i] = 1'b1;
763-
fpu_fmt_n = orig_instr.rftype.fmt; // fmt bits from instruction
764-
fpu_rm_n = orig_instr.rftype.rm; // rm bits from instruction
778+
fpu_fmt_n = orig_instr[i].rftype.fmt; // fmt bits from instruction
779+
fpu_rm_n = orig_instr[i].rftype.rm; // rm bits from instruction
765780
end else if (issue_instr_i[i].fu == FPU_VEC && CVA6Cfg.FpPresent) begin
766781
fpu_valid_n[i] = 1'b1;
767-
fpu_fmt_n = orig_instr.rvftype.vfmt; // vfmt bits from instruction
768-
fpu_rm_n = {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction
782+
fpu_fmt_n = orig_instr[i].rvftype.vfmt; // vfmt bits from instruction
783+
fpu_rm_n = {2'b0, orig_instr[i].rvftype.repl}; // repl bit from instruction
769784
end
770785
end
771786
endcase
@@ -948,7 +963,7 @@ module issue_read_operands
948963
};
949964

950965
if (CVA6Cfg.SuperscalarEn) begin
951-
if (!(issue_instr_i[0].fu inside {FPU, FPU_VEC})) begin
966+
if (!(issue_instr_i[0].fu inside {FPU, FPU_VEC} || issue_instr_i[0].op inside {[FLD:FSB]})) begin
952967
fp_raddr_pack = {
953968
issue_instr_i[1].result[4:0], issue_instr_i[1].rs2[4:0], issue_instr_i[1].rs1[4:0]
954969
};
@@ -1101,20 +1116,6 @@ module issue_read_operands
11011116
);
11021117
end
11031118

1104-
// FPU does not declare that it will return a result the subsequent cycle so
1105-
// it is not possible for issue stage to know when ALU2 can be used if there
1106-
// is an FPU. As there are discussions to change the FPU, I did not explore
1107-
// its architecture to create this "FPU returns next cycle" signal. Also, a
1108-
// "lookahead" optimization should be added to be performant with FPU: when
1109-
// issue port 2 is issuing to FPU, issue port 1 should issue to ALU1 instead
1110-
// of ALU2 so that FPU is not busy. However, if FPU has a minimum execution
1111-
// time of 2 cycles, it is possible to simply not raise fus_busy[1].alu2.
1112-
initial begin
1113-
assert (!(CVA6Cfg.SuperscalarEn && CVA6Cfg.FpPresent))
1114-
else
1115-
$fatal(1, "FPU is not yet supported in superscalar CVA6, see comments above this assertion.");
1116-
end
1117-
11181119
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
11191120
assert property (@(posedge clk_i) (branch_valid_q) |-> (!$isunknown(
11201121
fu_data_q[i].operand_a

core/issue_stage.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ module issue_stage
9494
output logic [1:0] fpu_fmt_o,
9595
// FPU rm field - EX_STAGE
9696
output logic [2:0] fpu_rm_o,
97+
// FPU early valid - EX_STAGE
98+
input logic fpu_early_valid_i,
9799
// ALU2 FU is valid - EX_STAGE
98100
output logic [CVA6Cfg.NrIssuePorts-1:0] alu2_valid_o,
99101
// CSR is valid - EX_STAGE
@@ -283,6 +285,7 @@ module issue_stage
283285
.fpu_valid_o,
284286
.fpu_fmt_o,
285287
.fpu_rm_o,
288+
.fpu_early_valid_i,
286289
.alu2_valid_o,
287290
.csr_valid_o,
288291
.cvxif_valid_o (xfu_valid_o),

0 commit comments

Comments
 (0)