Skip to content

Commit

Permalink
Move from PULP_ZFINX to ratified v1.0 ZFINX.
Browse files Browse the repository at this point in the history
Issue openhwgroup#725 correction: Illegal exception for FMV/FLW/FSW when ZFINX.
Updated MISA value and make MSTATUS.FS/SD ZFINX dependent.

Signed-off-by: Pascal Gouedo <[email protected]>
  • Loading branch information
Pascal Gouedo committed Apr 19, 2023
1 parent 60b87ee commit cbe7ef5
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 58 deletions.
23 changes: 14 additions & 9 deletions rtl/cv32e40p_compressed_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
////////////////////////////////////////////////////////////////////////////////

module cv32e40p_compressed_decoder #(
parameter FPU = 0
parameter FPU = 0,
parameter PULP_ZFINX = 0
) (
input logic [31:0] instr_i,
output logic [31:0] instr_o,
Expand Down Expand Up @@ -72,7 +73,8 @@ module cv32e40p_compressed_decoder #(

3'b001: begin
// c.fld -> fld rd', imm(rs1')
if (FPU == 1) // instr_i[12:10]-> offset[5:3], instr_i[6:5]-> offset[7:6]
if (FPU == 1 && PULP_ZFINX == 0)
// instr_i[12:10]-> offset[5:3], instr_i[6:5]-> offset[7:6]
instr_o = {
4'b0,
instr_i[6:5],
Expand Down Expand Up @@ -107,7 +109,7 @@ module cv32e40p_compressed_decoder #(

3'b011: begin
// c.flw -> flw rd', imm(rs1')
if (FPU == 1)
if (FPU == 1 && PULP_ZFINX == 0)
instr_o = {
5'b0,
instr_i[5],
Expand All @@ -126,7 +128,8 @@ module cv32e40p_compressed_decoder #(

3'b101: begin
// c.fsd -> fsd rs2', imm(rs1')
if (FPU == 1) // instr_i[12:10] -> offset[5:3], instr_i[6:5] -> offset[7:6]
if (FPU == 1 && PULP_ZFINX == 0)
// instr_i[12:10] -> offset[5:3], instr_i[6:5] -> offset[7:6]
instr_o = {
4'b0,
instr_i[6:5],
Expand Down Expand Up @@ -163,7 +166,7 @@ module cv32e40p_compressed_decoder #(

3'b111: begin
// c.fsw -> fsw rs2', imm(rs1')
if (FPU == 1)
if (FPU == 1 && PULP_ZFINX == 0)
instr_o = {
5'b0,
instr_i[5],
Expand Down Expand Up @@ -449,7 +452,8 @@ module cv32e40p_compressed_decoder #(

3'b001: begin
// c.fldsp -> fld rd, imm(x2)
if (FPU==1) // instr_i[6:5] -> offset[4:3], instr_i[4:2] -> offset[8:6], instr_i[12] -> offset[5]
if (FPU == 1 && PULP_ZFINX == 0)
// instr_i[6:5] -> offset[4:3], instr_i[4:2] -> offset[8:6], instr_i[12] -> offset[5]
instr_o = {
3'b0,
instr_i[4:2],
Expand Down Expand Up @@ -482,7 +486,7 @@ module cv32e40p_compressed_decoder #(

3'b011: begin
// c.flwsp -> flw rd, imm(x2)
if (FPU == 1)
if (FPU == 1 && PULP_ZFINX == 0)
instr_o = {
4'b0,
instr_i[3:2],
Expand Down Expand Up @@ -536,7 +540,8 @@ module cv32e40p_compressed_decoder #(

3'b101: begin
// c.fsdsp -> fsd rs2, imm(x2)
if (FPU == 1) // instr_i[12:10] -> offset[5:3], instr_i[9:7] -> offset[8:6]
if (FPU == 1 && PULP_ZFINX == 0)
// instr_i[12:10] -> offset[5:3], instr_i[9:7] -> offset[8:6]
instr_o = {
3'b0,
instr_i[9:7],
Expand Down Expand Up @@ -567,7 +572,7 @@ module cv32e40p_compressed_decoder #(

3'b111: begin
// c.fswsp -> fsw rs2, imm(x2)
if (FPU == 1)
if (FPU == 1 && PULP_ZFINX == 0)
instr_o = {
4'b0,
instr_i[8:7],
Expand Down
4 changes: 3 additions & 1 deletion rtl/cv32e40p_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ module cv32e40p_core
.PULP_XPULP (PULP_XPULP),
.PULP_OBI (PULP_OBI),
.PULP_SECURE(PULP_SECURE),
.FPU (FPU)
.FPU (FPU),
.PULP_ZFINX (PULP_ZFINX)
) if_stage_i (
.clk (clk),
.rst_n(rst_ni),
Expand Down Expand Up @@ -928,6 +929,7 @@ module cv32e40p_core
.N_HWLP (N_HWLP),
.A_EXTENSION (A_EXTENSION),
.FPU (FPU),
.PULP_ZFINX (PULP_ZFINX),
.APU (APU),
.PULP_SECURE (PULP_SECURE),
.USE_PMP (USE_PMP),
Expand Down
53 changes: 34 additions & 19 deletions rtl/cv32e40p_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module cv32e40p_cs_registers
parameter APU = 0,
parameter A_EXTENSION = 0,
parameter FPU = 0,
parameter PULP_ZFINX = 0,
parameter PULP_SECURE = 0,
parameter USE_PMP = 0,
parameter N_PMP_ENTRIES = 16,
Expand Down Expand Up @@ -165,7 +166,7 @@ module cv32e40p_cs_registers
| (1 << 2) // C - Compressed extension
| (0 << 3) // D - Double precision floating-point extension
| (0 << 4) // E - RV32E base ISA
| (32'(FPU) << 5) // F - Single precision floating-point extension
| (32'(FPU == 1 && PULP_ZFINX == 0) << 5) // F - Single precision floating-point extension
| (1 << 8) // I - RV32I/64I/128I base ISA
| (1 << 12) // M - Integer Multiply/Divide extension
| (0 << 13) // N - User level interrupts supported
Expand Down Expand Up @@ -255,7 +256,6 @@ module cv32e40p_cs_registers
FS_t mstatus_fs_q, mstatus_fs_n;
logic [5:0] mcause_q, mcause_n;
logic [5:0] ucause_q, ucause_n;
//not implemented yet
logic [23:0] mtvec_n, mtvec_q;
logic [23:0] utvec_n, utvec_q;
logic [1:0] mtvec_mode_n, mtvec_mode_q;
Expand Down Expand Up @@ -504,11 +504,11 @@ module cv32e40p_cs_registers
// mstatus: always M-mode, contains IE bit
CSR_MSTATUS:
csr_rdata_int = {
(FPU == 1) ? (mstatus_fs_q == FS_DIRTY ? 1'b1 : 1'b0) : 1'b0,
(FPU == 1 && PULP_ZFINX == 0) ? (mstatus_fs_q == FS_DIRTY ? 1'b1 : 1'b0) : 1'b0,
13'b0,
mstatus_q.mprv,
2'b0,
(FPU == 1) ? mstatus_fs_q : FS_OFF,
(FPU == 1 && PULP_ZFINX == 0) ? mstatus_fs_q : FS_OFF,
mstatus_q.mpp,
3'b0,
mstatus_q.mpie,
Expand Down Expand Up @@ -918,8 +918,10 @@ module cv32e40p_cs_registers
if (FPU == 1) begin
fflags_n = fflags_q;
frm_n = frm_q;
mstatus_fs_n = mstatus_fs_q;
fcsr_update = 1'b0;
if (PULP_ZFINX == 0) begin
mstatus_fs_n = mstatus_fs_q;
fcsr_update = 1'b0;
end
end
mscratch_n = mscratch_q;
mepc_n = mepc_q;
Expand Down Expand Up @@ -951,23 +953,29 @@ module cv32e40p_cs_registers
CSR_FFLAGS:
if (FPU == 1) begin
if (csr_we_int) begin
fcsr_update = 1'b1;
fflags_n = csr_wdata_int[C_FFLAG-1:0];
fflags_n = csr_wdata_int[C_FFLAG-1:0];
if (PULP_ZFINX == 0) begin
fcsr_update = 1'b1;
end
end
end
CSR_FRM:
if (FPU == 1) begin
if (csr_we_int) begin
fcsr_update = 1'b1;
frm_n = csr_wdata_int[C_RM-1:0];
frm_n = csr_wdata_int[C_RM-1:0];
if (PULP_ZFINX == 0) begin
fcsr_update = 1'b1;
end
end
end
CSR_FCSR:
if (FPU == 1) begin
if (csr_we_int) begin
fcsr_update = 1'b1;
fflags_n = csr_wdata_int[C_FFLAG-1:0];
frm_n = csr_wdata_int[C_RM+C_FFLAG-1:C_FFLAG];
fflags_n = csr_wdata_int[C_FFLAG-1:0];
frm_n = csr_wdata_int[C_RM+C_FFLAG-1:C_FFLAG];
if (PULP_ZFINX == 0) begin
fcsr_update = 1'b1;
end
end
end

Expand All @@ -982,7 +990,7 @@ module cv32e40p_cs_registers
mpp: PrivLvl_t'(csr_wdata_int[MSTATUS_MPP_BIT_HIGH:MSTATUS_MPP_BIT_LOW]),
mprv: csr_wdata_int[MSTATUS_MPRV_BIT]
};
if (FPU) begin
if (FPU == 1 && PULP_ZFINX == 0) begin
mstatus_fs_n = FS_t'(csr_wdata_int[MSTATUS_FS_BIT_HIGH:MSTATUS_FS_BIT_LOW]);
end
end
Expand Down Expand Up @@ -1051,8 +1059,11 @@ module cv32e40p_cs_registers
fflags_n = fflags_i | fflags_q;
end

if (fflags_we_i || fcsr_update) begin // FPU Register File/Flags implicit update or modified by CSR instructions
mstatus_fs_n = FS_DIRTY;
if (PULP_ZFINX == 0) begin
// FPU Register File/Flags implicit update or modified by CSR instructions
if (fflags_we_i || fcsr_update) begin
mstatus_fs_n = FS_DIRTY;
end
end
end

Expand Down Expand Up @@ -1128,7 +1139,7 @@ module cv32e40p_cs_registers
assign sec_lvl_o = priv_lvl_q[0];

// mstatus_fs_q = FS_OFF, FPU not enabled
assign fs_off_o = (FPU == 1) ? (mstatus_fs_q == FS_OFF ? 1'b1 : 1'b0) : 1'b0;
assign fs_off_o = (FPU == 1 && PULP_ZFINX == 0) ? (mstatus_fs_q == FS_OFF ? 1'b1 : 1'b0) : 1'b0;
assign frm_o = (FPU == 1) ? frm_q : '0;

assign mtvec_o = mtvec_q;
Expand Down Expand Up @@ -1201,7 +1212,9 @@ module cv32e40p_cs_registers
if (FPU == 1) begin
frm_q <= '0;
fflags_q <= '0;
mstatus_fs_q <= FS_OFF;
if (PULP_ZFINX == 0) begin
mstatus_fs_q <= FS_OFF;
end
end
mstatus_q <= '{
uie: 1'b0,
Expand Down Expand Up @@ -1232,7 +1245,9 @@ module cv32e40p_cs_registers
if (FPU == 1) begin
frm_q <= frm_n;
fflags_q <= fflags_n;
mstatus_fs_q <= mstatus_fs_n;
if (PULP_ZFINX == 0) begin
mstatus_fs_q <= mstatus_fs_n;
end
end
if (PULP_SECURE == 1) begin
mstatus_q <= mstatus_n;
Expand Down
40 changes: 16 additions & 24 deletions rtl/cv32e40p_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ module cv32e40p_decoder

// Floating Point arithmetic
OPCODE_OP_FP: begin
if (FPU == 1 && fs_off_i == 1'b0) begin
if (FPU == 1 && (PULP_ZFINX == 1 || fs_off_i == 1'b0)) begin

// using APU instead of ALU
alu_en = 1'b0;
Expand Down Expand Up @@ -1260,7 +1260,7 @@ module cv32e40p_decoder
fp_op_group = NONCOMP;
check_fprm = 1'b0; // instruction encoded in rm, do the check here
// fmv.x.fmt - FPR to GPR Move
if (instr_rdata_i[14:12] == 3'b000 || (C_XF16ALT && instr_rdata_i[14:12] == 3'b100)) begin
if ((PULP_ZFINX == 0 && instr_rdata_i[14:12] == 3'b000) || (C_XF16ALT && instr_rdata_i[14:12] == 3'b100)) begin
alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD; // set rs2 = rs1 so we can map FMV to SGNJ in the unit
fpu_op = cv32e40p_fpu_pkg::SGNJ; // mapped to SGNJ-passthrough since no recoding
fpu_op_mod = 1'b1; // sign-extend result
Expand Down Expand Up @@ -1295,7 +1295,7 @@ module cv32e40p_decoder
fp_op_group = NONCOMP;
fp_rnd_mode_o = 3'b011; // passthrough without checking nan-box
check_fprm = 1'b0; // instruction encoded in rm, do the check here
if (instr_rdata_i[14:12] == 3'b000 || (C_XF16ALT && instr_rdata_i[14:12] == 3'b100)) begin
if ((PULP_ZFINX == 0 && instr_rdata_i[14:12] == 3'b000) || (C_XF16ALT && instr_rdata_i[14:12] == 3'b100)) begin
// FP16ALT uses special encoding here
if (instr_rdata_i[14]) begin
fpu_dst_fmt_o = cv32e40p_fpu_pkg::FP16ALT;
Expand Down Expand Up @@ -1371,7 +1371,7 @@ module cv32e40p_decoder
// Set FPnew OP and OPMOD as the APU op
apu_op_o = {fpu_vec_op, fpu_op_mod, fpu_op};

// No FPU or MSTATUS.FS == FS_OFF
// No FPU or (PULP_ZFINX == 0 && MSTATUS.FS == FS_OFF)
end else begin
illegal_insn_o = 1'b1;
end
Expand All @@ -1382,7 +1382,7 @@ module cv32e40p_decoder
OPCODE_OP_FMSUB,
OPCODE_OP_FNMSUB,
OPCODE_OP_FNMADD : begin
if (FPU == 1 && fs_off_i == 1'b0) begin
if (FPU == 1 && (PULP_ZFINX == 1 || fs_off_i == 1'b0)) begin
// using APU instead of ALU
alu_en = 1'b0;
apu_en = 1'b1;
Expand Down Expand Up @@ -1494,24 +1494,20 @@ module cv32e40p_decoder

// Set FPnew OP and OPMOD as the APU op
apu_op_o = {fpu_vec_op, fpu_op_mod, fpu_op};
// No FPU or MSTATUS.FS == FS_OFF
// No FPU or (PULP_ZFINX == 0 && MSTATUS.FS == FS_OFF)
end else begin
illegal_insn_o = 1'b1;
end
end

OPCODE_STORE_FP: begin
if (FPU == 1 && fs_off_i == 1'b0) begin
if (FPU == 1 && PULP_ZFINX == 0 && fs_off_i == 1'b0) begin
data_req = 1'b1;
data_we_o = 1'b1;
rega_used_o = 1'b1;
regb_used_o = 1'b1;
alu_operator_o = ALU_ADD;
if (PULP_ZFINX == 0) begin
reg_fp_b_o = 1'b1;
end else begin
reg_fp_b_o = 1'b0;
end
reg_fp_b_o = 1'b1;

// offset from immediate
imm_b_mux_sel_o = IMMB_S;
Expand Down Expand Up @@ -1542,21 +1538,17 @@ module cv32e40p_decoder
data_req = 1'b0;
data_we_o = 1'b0;
end
// No FPU or MSTATUS.FS == FS_OFF
// No FPU or PULP_ZFINX or MSTATUS.FS == FS_OFF
end else begin
illegal_insn_o = 1'b1;
end
end

OPCODE_LOAD_FP: begin
if (FPU == 1 && fs_off_i == 1'b0) begin
if (FPU == 1 && PULP_ZFINX == 0 && fs_off_i == 1'b0) begin
data_req = 1'b1;
regfile_mem_we = 1'b1;
if (PULP_ZFINX == 0) begin
reg_fp_d_o = 1'b1;
end else begin
reg_fp_d_o = 1'b0;
end
reg_fp_d_o = 1'b1;
rega_used_o = 1'b1;
alu_operator_o = ALU_ADD;

Expand All @@ -1583,7 +1575,7 @@ module cv32e40p_decoder
else illegal_insn_o = 1'b1;
default: illegal_insn_o = 1'b1;
endcase
// No FPU or MSTATUS.FS == FS_OFF
// No FPU or PULP_ZFINX or MSTATUS.FS == FS_OFF
end else begin
illegal_insn_o = 1'b1;
end
Expand Down Expand Up @@ -2773,9 +2765,9 @@ module cv32e40p_decoder
// if set or clear with rs == x0 or imm == 0,
// then do not perform a write action
unique case (instr_rdata_i[13:12])
2'b01: csr_op = CSR_OP_WRITE;
2'b10: csr_op = instr_rdata_i[19:15] == 5'b0 ? CSR_OP_READ : CSR_OP_SET;
2'b11: csr_op = instr_rdata_i[19:15] == 5'b0 ? CSR_OP_READ : CSR_OP_CLEAR;
2'b01: csr_op = CSR_OP_WRITE;
2'b10: csr_op = instr_rdata_i[19:15] == 5'b0 ? CSR_OP_READ : CSR_OP_SET;
2'b11: csr_op = instr_rdata_i[19:15] == 5'b0 ? CSR_OP_READ : CSR_OP_CLEAR;
default: csr_illegal = 1'b1;
endcase

Expand All @@ -2790,7 +2782,7 @@ module cv32e40p_decoder
CSR_FFLAGS,
CSR_FRM,
CSR_FCSR :
if (FPU == 0 || fs_off_i == 1'b1) csr_illegal = 1'b1;
if (FPU == 0 || (PULP_ZFINX == 0 && fs_off_i == 1'b1)) csr_illegal = 1'b1;

// Writes to read only CSRs results in illegal instruction
CSR_MVENDORID,
Expand Down
Loading

0 comments on commit cbe7ef5

Please sign in to comment.