Skip to content

Commit

Permalink
This commit adds support for the following extension:
Browse files Browse the repository at this point in the history
Zcb (code reduction):
since no gcc support is in the mainline assembler yet these instructions are
injected as raw data. Coverage class has been extended with these
instructions and the illegal instruction class should not be able to
generate legal Zcb instruction if the extension is enabled.

Zfh (half-precision floats):
Similarly to single and double precission, RISC-V now support
half-precission is now supported. Most things are identical to the F & D
extension which is why the pre-existing floating_point class was
extended rather than a separate class. Inital coverage support has also been
added. If testing with OVPsim the Jan 2023 version has a bug for FMV_X_H.

Zbkb (crypto):
The complementary instruction not defined in Zbb has been added to the
instruction generator. This required a few instructions which were
previously defined in the non-ratified bitmanip instruction class to be
moved to Zbkb. I believe this makes more sense since Zbkb is ratified.
Inital coverage has also been added for these instructions.

Zfa:
Instructions has been defined for Zfa, more work will follow once OVPsim
supports this extension.

The illegal instruction class has seen the following bug fixes:
1) Not all legal op-codes were considered for compressed floating
instructions leading to leagal instructions being injected in undesired
locations (sometimes overwriting stack-pointer since no reserved gpr check was
performed).
2) ldsp and lqsp are only reserved at some XLENs.

ovpsim_log_to_trace:
Fixed a bug where some CSRs were not considered CSRs but GPRs

run.py:
Fixed bug in the regex replace, not all C's in the march string should
be replaced since that breaks all zc... extension substrings.

load_store_instr_lib:
Added the Zcb load and store instructions to this class.

riscv_instr_pkg:
Added new extensions and instructions.
Fixed bug introduced in aee6c4d where
"Push USP from gpr.SP onto the kernel stack" should be XLEN dependent and not
hardcoded to +-4.
  • Loading branch information
JJ-Gaisler committed Feb 1, 2023
1 parent b09bb67 commit 5e72708
Show file tree
Hide file tree
Showing 28 changed files with 1,439 additions and 67 deletions.
2 changes: 1 addition & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts, debug_cmd):
if 'gen_opts' in test:
# Disable compressed instruction
if re.search('disable_compressed_instr', test['gen_opts']):
test_isa = re.sub("c", "", test_isa)
test_isa = re.sub("c", "", test_isa, 1)
# If march/mabi is not defined in the test gcc_opts, use the default
# setting from the command line.
if not re.search('march', cmd):
Expand Down
4 changes: 2 additions & 2 deletions scripts/ovpsim_log_to_trace_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ def is_csr(r):
""" see if r is a csr """
if len(r) > 4:
return True
elif r[0] in ["m", "u", "d"]:
elif r[0] in ["m", "u", "d", "h"]:
return True
elif r in ["frm", "fcsr", "vl", "satp"]:
elif r in ["frm", "fcsr", "vl", "satp", "time", "sie", "sepc", "sip", "vsie", "vsip"]:
return True
else:
return False
Expand Down
18 changes: 10 additions & 8 deletions src/isa/riscv_b_instr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,16 @@ class riscv_b_instr extends riscv_instr;
GORCI, SLOI, SROI, GREVI, CMIX, CMOV, FSL: get_opcode = 7'b0010011;
FSR, FSRI, BMATFLIP, CRC32_B, CRC32_H, CRC32_W, CRC32C_B, CRC32C_H: get_opcode = 7'b0010011;
CRC32C_W, CRC32_D, CRC32C_D: get_opcode = 7'b0010011;
SHFL, UNSHFL, BCOMPRESS, BDECOMPRESS, PACK, PACKU, BMATOR, BMATXOR, PACKH, BFP: get_opcode
// PACK, PACKH (now in zbkb)
SHFL, UNSHFL, BCOMPRESS, BDECOMPRESS, PACKU, BMATOR, BMATXOR, BFP: get_opcode
= 7'b0110011;
SHFLI, UNSHFLI: get_opcode = 7'b0010011;
SLOW, SROW, GORCW, GREVW: get_opcode = 7'b0111011;
SLOIW, SROIW, GORCIW, GREVIW: get_opcode = 7'b0011011;
FSLW, FSRW: get_opcode = 7'b0111011;
FSRIW: get_opcode = 7'b0011011;
SHFLW, UNSHFLW, BCOMPRESSW, BDECOMPRESSW, PACKW, PACKUW, BFPW: get_opcode = 7'b0111011;
// PACKW,
SHFLW, UNSHFLW, BCOMPRESSW, BDECOMPRESSW, PACKUW, BFPW: get_opcode = 7'b0111011;
default: get_opcode = super.get_opcode();
endcase
endfunction
Expand Down Expand Up @@ -152,11 +154,11 @@ class riscv_b_instr extends riscv_instr;
UNSHFL: get_func3 = 3'b101;
BCOMPRESS: get_func3 = 3'b110;
BDECOMPRESS: get_func3 = 3'b110;
PACK: get_func3 = 3'b100;
//PACK: get_func3 = 3'b100;
PACKU: get_func3 = 3'b100;
BMATOR: get_func3 = 3'b011;
BMATXOR: get_func3 = 3'b011;
PACKH: get_func3 = 3'b111;
//PACKH: get_func3 = 3'b111;
BFP: get_func3 = 3'b111;
SHFLI: get_func3 = 3'b001;
UNSHFLI: get_func3 = 3'b101;
Expand All @@ -177,7 +179,7 @@ class riscv_b_instr extends riscv_instr;
UNSHFLW: get_func3 = 3'b101;
BCOMPRESSW: get_func3 = 3'b110;
BDECOMPRESSW: get_func3 = 3'b110;
PACKW: get_func3 = 3'b100;
//PACKW: get_func3 = 3'b100;
PACKUW: get_func3 = 3'b100;
BFPW: get_func3 = 3'b111;
XPERM_N: get_func3 = 3'b010;
Expand Down Expand Up @@ -213,11 +215,11 @@ class riscv_b_instr extends riscv_instr;
UNSHFL: get_func7 = 7'b0000100;
BCOMPRESS: get_func7 = 7'b0000100;
BDECOMPRESS: get_func7 = 7'b0100100;
PACK: get_func7 = 7'b0000100;
//PACK: get_func7 = 7'b0000100;
PACKU: get_func7 = 7'b0100100;
BMATOR: get_func7 = 7'b0000100;
BMATXOR: get_func7 = 7'b0100100;
PACKH: get_func7 = 7'b0000100;
//PACKH: get_func7 = 7'b0000100;
BFP: get_func7 = 7'b0100100;
SLOW: get_func7 = 7'b0010000;
SROW: get_func7 = 7'b0010000;
Expand All @@ -231,7 +233,7 @@ class riscv_b_instr extends riscv_instr;
UNSHFLW: get_func7 = 7'b0000100;
BCOMPRESSW: get_func7 = 7'b0000100;
BDECOMPRESSW: get_func7 = 7'b0100100;
PACKW: get_func7 = 7'b0000100;
//PACKW: get_func7 = 7'b0000100;
PACKUW: get_func7 = 7'b0100100;
BFPW: get_func7 = 7'b0100100;
XPERM_N: get_func7 = 7'b0010100;
Expand Down
50 changes: 39 additions & 11 deletions src/isa/riscv_floating_point_instr.sv
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2020 Google LLC
* Copyright 2023 Frontgrade Gaisler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -53,11 +54,14 @@ class riscv_floating_point_instr extends riscv_instr;
asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name());
end else if (instr_name inside {FMV_X_W, FMV_X_D, FCVT_W_S, FCVT_WU_S,
FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D,
FCVT_W_D, FCVT_WU_D}) begin
FCVT_W_D, FCVT_WU_D, FMV_X_H, FCVT_W_H,
FCVT_WU_H, FCVT_L_H, FCVT_LU_H}) begin

asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
end else if (instr_name inside {FMV_W_X, FMV_D_X, FCVT_S_W, FCVT_S_WU,
FCVT_S_L, FCVT_D_L, FCVT_S_LU, FCVT_D_W,
FCVT_D_LU, FCVT_D_WU}) begin
FCVT_D_LU, FCVT_D_WU, FCVT_H_WU, FCVT_H_W,
FMV_H_X, FCVT_H_L, FCVT_H_LU}) begin
asm_str = $sformatf("%0s%0s, %0s", asm_str, fd.name(), rs1.name());
end else begin
asm_str = $sformatf("%0s%0s, %0s", asm_str, fd.name(), fs1.name());
Expand All @@ -67,7 +71,7 @@ class riscv_floating_point_instr extends riscv_instr;
R_FORMAT:
if (category == COMPARE) begin
asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), fs1.name(), fs2.name());
end else if (instr_name inside {FCLASS_S, FCLASS_D}) begin
end else if (instr_name inside {FCLASS_H, FCLASS_S, FCLASS_D}) begin
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
end else begin
asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, fd.name(), fs1.name(), fs2.name());
Expand All @@ -88,9 +92,11 @@ class riscv_floating_point_instr extends riscv_instr;
endcase
if ((category == ARITHMETIC) && use_rounding_mode_from_instr &&
!(instr_name inside {FMIN_S, FMAX_S, FMIN_D, FMAX_D, FMV_W_X, FMV_X_W,
FMV_D_X, FMV_X_D, FCLASS_S, FCLASS_D,
FCVT_D_S, FCVT_D_W, FCVT_D_WU,
FSGNJ_S, FSGNJN_S, FSGNJX_S, FSGNJ_D, FSGNJN_D, FSGNJX_D})) begin
FMV_D_X, FMV_X_D, FCLASS_H, FCLASS_S, FCLASS_D,
FCVT_D_S, FCVT_D_W, FCVT_D_WU, FSGNJ_S, FSGNJN_S,
FCVT_S_H, FCVT_D_H, FCVT_Q_H, FMV_X_H, FSGNJX_S,
FSGNJ_D, FSGNJN_D, FSGNJX_D, FSGNJ_H, FSGNJN_H,
FSGNJX_H, FMIN_H, FMAX_H, FCLASS_H, FMV_H_X })) begin
asm_str = {asm_str, ", ", rm.name()};
end
if(comment != "")
Expand Down Expand Up @@ -131,12 +137,14 @@ class riscv_floating_point_instr extends riscv_instr;
has_imm = 1'b1;
end else if (instr_name inside {FMV_X_W, FMV_X_D, FCVT_W_S, FCVT_WU_S,
FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D, FCVT_LU_S,
FCVT_W_D, FCVT_WU_D}) begin
FCVT_W_D, FCVT_WU_D, FCVT_W_H, FCVT_WU_H, FMV_X_H,
FCVT_L_H, FCVT_LU_H, FCVT_H_L, FCVT_H_LU }) begin
has_fd = 1'b0;
has_rd = 1'b1;
end else if (instr_name inside {FMV_W_X, FMV_D_X, FCVT_S_W, FCVT_S_WU,
FCVT_S_L, FCVT_D_L, FCVT_S_LU, FCVT_D_W,
FCVT_D_LU, FCVT_D_WU}) begin
FCVT_D_LU, FCVT_D_WU, FCVT_H_W,
FCVT_H_WU, FMV_H_X }) begin
has_rs1 = 1'b1;
has_fs1 = 1'b0;
end
Expand All @@ -151,7 +159,7 @@ class riscv_floating_point_instr extends riscv_instr;
if (category == COMPARE) begin
has_rd = 1'b1;
has_fd = 1'b0;
end else if (instr_name inside {FCLASS_S, FCLASS_D}) begin
end else if (instr_name inside {FCLASS_H, FCLASS_S, FCLASS_D}) begin
has_rd = 1'b1;
has_fd = 1'b0;
has_fs2 = 1'b0;
Expand Down Expand Up @@ -222,8 +230,9 @@ class riscv_floating_point_instr extends riscv_instr;
R_FORMAT: begin
// convert Pseudoinstructions for ovpsim
// fmv.s rd, rs -> fsgnj.s rd, rs, rs
if (operands.size() == 2 && instr_name inside {FSGNJ_S, FSGNJX_S, FSGNJN_S, FSGNJ_D,
FSGNJX_D, FSGNJN_D}) begin
if (operands.size() == 2 && instr_name inside {FSGNJ_H, FSGNJX_H, FSGNJN_H,
FSGNJ_S, FSGNJX_S, FSGNJN_S,
FSGNJ_D, FSGNJX_D, FSGNJN_D}) begin
operands.push_back(operands[$]);
end

Expand Down Expand Up @@ -282,6 +291,25 @@ class riscv_floating_point_instr extends riscv_instr;
fs2_sign = get_fp_operand_sign(fs2_value, 31);
fs3_sign = get_fp_operand_sign(fs3_value, 31);
fd_sign = get_fp_operand_sign(fd_value, 31);
// zfh introduces many new convert functions
end else if (instr_name == FCVT_S_H) begin
fs1_sign = get_fp_operand_sign(fs1_value, 15);
fd_sign = get_fp_operand_sign(fd_value, 31);
end else if (instr_name == FCVT_H_S) begin
fs1_sign = get_fp_operand_sign(fs1_value, 31);
fd_sign = get_fp_operand_sign(fd_value, 15);
end else if (instr_name == FCVT_D_H) begin
fs1_sign = get_fp_operand_sign(fs1_value, 15);
fd_sign = get_fp_operand_sign(fd_value, 63);
end else if (instr_name == FCVT_H_D) begin
fs1_sign = get_fp_operand_sign(fs1_value, 63);
fd_sign = get_fp_operand_sign(fd_value, 15);
end else if (instr_name == FCVT_Q_H) begin
fs1_sign = get_fp_operand_sign(fs1_value, 15);
fd_sign = get_fp_operand_sign(fd_value, 127);
end else if (instr_name == FCVT_H_Q) begin
fs1_sign = get_fp_operand_sign(fs1_value, 127);
fd_sign = get_fp_operand_sign(fd_value, 15);
end else if (instr_name == FCVT_S_D) begin
fs1_sign = get_fp_operand_sign(fs1_value, 63);
fd_sign = get_fp_operand_sign(fd_value, 31);
Expand Down
6 changes: 4 additions & 2 deletions src/isa/riscv_instr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ class riscv_instr extends uvm_object;
end
if (!cfg.enable_sfence && instr_name == SFENCE_VMA) continue;
if (cfg.no_fence && (instr_name inside {FENCE, FENCE_I, SFENCE_VMA})) continue;
if (!(RV32Q inside {supported_isa}) && instr_name inside {FCVT_H_Q, FCVT_Q_H}) continue;
if (!cfg.enable_zfh_extension && instr_inst.group inside {RV32ZFH, RV64ZFH}) continue;
if ((instr_inst.group inside {supported_isa}) &&
!(cfg.disable_compressed_instr &&
(instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
(instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C, RV32ZCB, RV64ZCB})) &&
!(!cfg.enable_floating_point &&
(instr_inst.group inside {RV32F, RV64F, RV32D, RV64D})) &&
(instr_inst.group inside {RV32ZFH, RV64ZFH, RV32F, RV64F, RV32D, RV64D})) &&
!(!cfg.enable_vector_extension &&
(instr_inst.group inside {RVV})) &&
!(cfg.vector_instr_only &&
Expand Down
20 changes: 20 additions & 0 deletions src/isa/riscv_instr_cov.svh
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,26 @@
// c.j imm
get_val(operands[0], imm);
end
CSZN_FORMAT: begin
rs1 = get_gpr(operands[0]);
rs1_value = get_gpr_state(operands[0]);
end
CLB_FORMAT, CLH_FORMAT: begin
get_val(operands[2], imm);
rs1 = get_gpr(operands[1]);
rs1_value = get_gpr_state(operands[1]);
end
CSB_FORMAT, CSH_FORMAT: begin
rs2 = get_gpr(operands[0]);
rs2_value = get_gpr_state(operands[0]);
get_val(operands[2], imm);
rs1 = get_gpr(operands[1]);
rs1_value = get_gpr_state(operands[1]);
end
CSZN_FORMAT: begin
rs1 = get_gpr(operands[0]);
rs1_value = get_gpr_state(operands[0]);
end
default: `uvm_fatal(`gfn, $sformatf("Unsupported format %0s", format))
endcase
endfunction : update_src_regs
Expand Down
145 changes: 145 additions & 0 deletions src/isa/riscv_zbkb_instr.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright 2018 Google LLC
* Copyright 2021 Silicon Labs, Inc.
* Copyright 2023 Frontgrade Gaisler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the 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.
*/
class riscv_zbkb_instr extends riscv_instr;
`uvm_object_utils(riscv_zbkb_instr)

function new(string name = "");
super.new(name);
endfunction : new

virtual function void set_rand_mode();
super.set_rand_mode();
case (format) inside
I_FORMAT: begin
has_imm = 1'b0;
end
endcase
endfunction : set_rand_mode

function void pre_randomize();
super.pre_randomize();
endfunction

virtual function string convert2asm(string prefix = "");
string asm_str_final;
string asm_str;

asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);

case (format)
I_FORMAT : begin // instr rd rs1
if (!has_imm) begin
asm_str_final = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs1.name());
end
end

R_FORMAT : begin // instr rd rs1
if (!has_rs2) begin
asm_str_final = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs1.name());
end
end

default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
endcase

if (asm_str_final == "") begin
return super.convert2asm(prefix);
end

if (comment != "") begin
asm_str_final = { asm_str_final, " #", comment };
end

return asm_str_final.tolower();

endfunction : convert2asm

function bit[6:0] get_opcode();
case (instr_name) inside
default : get_opcode = super.get_opcode();
PACK : get_opcode = 7'b0110011;
PACKH : get_opcode = 7'b0110111;
PACKW : get_opcode = 7'b0111011;
BREV8 : get_opcode = 7'b0010011;
ZIP : get_opcode = 7'b0010011;
UNZIP : get_opcode = 7'b0010011;
endcase
endfunction : get_opcode

virtual function bit [2:0] get_func3();
case (instr_name) inside
PACK : get_func3 = 3'b100;
PACKH : get_func3 = 3'b111;
PACKW : get_func3 = 3'b100;
BREV8 : get_func3 = 3'b101;
ZIP : get_func3 = 3'b001;
UNZIP : get_func3 = 3'b101;
default : get_func3 = super.get_func3();
endcase
endfunction : get_func3

virtual function bit [4:0] get_func5();
case (instr_name) inside
BREV8 : get_func5 = 5'b00111;
ZIP : get_func5 = 5'b01111;
UNZIP : get_func5 = 5'b01111;
endcase
endfunction : get_func5

virtual function bit [6:0] get_func7();
case (instr_name) inside
PACK : get_func7 = 7'b0000100;
PACKH : get_func7 = 7'b0000100;
PACKW : get_func7 = 7'b0000100;
BREV8 : get_func7 = 7'b0110100;
ZIP : get_func7 = 7'b0000100;
UNZIP : get_func7 = 7'b0000100;
default : get_func7 = super.get_func7();
endcase
endfunction : get_func7

virtual function string convert2bin(string prefix = "");
string binary = "";

case (format)
R_FORMAT: begin
binary = $sformatf("%8h", {get_func7(), rs2, rs1, get_func3(), rd, get_opcode()});
end

I_FORMAT: begin
binary = $sformatf("%8h", {get_func7(), get_func5(), rs1, get_func3(), rd, get_opcode()});
end

default: begin
if (binary == "") begin
binary = super.convert2bin(prefix);
end
end

endcase // case (format)
endfunction : convert2bin

virtual function bit is_supported(riscv_instr_gen_config cfg);
return (cfg.enable_zbkb_extension &&
(RV32ZBKB inside { supported_isa } || RV64ZBKB inside { supported_isa }) &&
instr_name inside {
PACK, PACKH, PACKW, BREV8, ZIP, UNZIP
});
endfunction : is_supported

endclass : riscv_zbkb_instr
Loading

0 comments on commit 5e72708

Please sign in to comment.