Merge branch 'dev' into installation

This commit is contained in:
Jordan Carlin 2024-06-28 13:39:27 -07:00
commit 6b6ff23c72
No known key found for this signature in database
278 changed files with 69119 additions and 93 deletions

View file

@ -96,7 +96,7 @@ foreach my $key (@derivnames) {
my @ent = @{$entry};
my $param = $ent[0];
my $value = $ent[1];
if ($line =~ s/$param\s*=\s*.*;/$param = $value;/) {
if ($line =~ s/\b$param\s*=\s*.*;/$param = $value;/) {
$hit{$param} = 1;
# print("Hit: new line in $config for $param is $line");
}
@ -130,4 +130,4 @@ sub printref {
print join('_', @{$entry}), ', ';
}
print("\n");
}
}

View file

@ -93,7 +93,7 @@ derivconfigtests = [
["nodcache_rv64gc", ["ahb64"]],
["nocache_rv64gc", ["ahb64"]],
# Atomic variatnts
# Atomic variants
["zaamo_rv64gc", ["arch64i", "arch64a_amo"]],
["zalrsc_rv64gc", ["arch64i", "wally64a_lrsc"]],
["zaamo_rv32gc", ["arch32i", "arch32a_amo"]],
@ -122,6 +122,16 @@ derivconfigtests = [
["zknd_rv64gc", ["arch64i", "arch64zknd"]],
["zknh_rv64gc", ["arch64i", "arch64zknh"]],
# No privilege modes variants
["noS_rv32gc", ["arch32i", "arch32f", "arch32priv", "arch32c", "arch32m", "arch32a_amo", "arch32zifencei", "arch32zicond",
"arch32zba", "arch32zfaf", "arch32zfad", "wally32a_lrsc", "arch32zcb", "arch32zbkx", "arch32zknd"]],
["noS_rv64gc", ["arch64i", "arch64f", "arch64priv", "arch64c", "arch64m", "arch64a_amo", "arch64zifencei", "arch64zicond",
"arch64zba", "arch64zfaf", "arch64zfad", "wally64a_lrsc", "arch64zcb", "arch64zbkx", "arch64zknd"]],
["noU_rv32gc", ["arch32i", "arch32f", "arch32priv", "arch32c", "arch32m", "arch32a_amo", "arch32zifencei", "arch32zicond",
"arch32zba", "arch32zfaf", "arch32zfad", "wally32a_lrsc", "arch32zcb", "arch32zbkx", "arch32zknd"]],
["noU_rv64gc", ["arch64i", "arch64f", "arch64priv", "arch64c", "arch64m", "arch64a_amo", "arch64zifencei", "arch64zicond",
"arch64zba", "arch64zfaf", "arch64zfad", "wally64a_lrsc", "arch64zcb", "arch64zbkx", "arch64zknd"]],
### add misaligned tests
# fp/int divider permutations

View file

@ -123,7 +123,7 @@ if [ "$FAMILY" = rhel ]; then
# Packages are grouped by which tool requires them, split by line.
# If mutltipole tools need a package, it is included in the first tool only
# General/Wally specific, riscv-gnu-toolchain, qemu, spike, verilator
sudo dnf install -y git make cmake python3.12 python3-pip curl wget ftp tar pkgconfig dialog mutt ssmtp \
sudo dnf install -y git make cmake python3.12 python3-pip curl wget ftp tar pkgconfig dialog mutt ssmtp gcc-gfortran boost-devel\
autoconf automake libmpc-devel mpfr-devel gmp-devel gawk bison flex texinfo gperf libtool patchutils bc gcc gcc-c++ zlib-devel expat-devel libslirp-devel \
glib2-devel libfdt-devel pixman-devel bzip2 ninja-build \
dtc boost-regex boost-system \

View file

@ -124,7 +124,7 @@ if [ "$FAMILY" = rhel ]; then
# Packages are grouped by which tool requires them, split by line.
# If mutltipole tools need a package, it is included in the first tool only
# General/Wally specific, riscv-gnu-toolchain, qemu, spike, verilator
sudo dnf install -y git make cmake python3.12 python3-pip curl wget ftp tar pkgconfig dialog mutt ssmtp \
sudo dnf install -y git make cmake python3.12 python3-pip curl wget ftp tar pkgconfig dialog mutt ssmtp gcc-gfortran \
autoconf automake libmpc-devel mpfr-devel gmp-devel gawk bison flex texinfo gperf libtool patchutils bc gcc gcc-c++ zlib-devel expat-devel libslirp-devel \
glib2-devel libfdt-devel pixman-devel bzip2 ninja-build \
dtc boost-regex boost-system \
@ -145,7 +145,7 @@ elif [ "$FAMILY" = ubuntu ]; then
# Packages are grouped by which tool requires them, split by line.
# If mutltipole tools need a package, it is included in the first tool only
# General/Wally specific, riscv-gnu-toolchain, qemu, spike, verilator, sail
sudo apt install -y git make cmake python3 python3-pip python3-venv curl wget ftp tar pkg-config dialog mutt ssmtp \
sudo apt install -y git make cmake python3 python3-pip python3-venv curl wget ftp tar pkg-config dialog mutt ssmtp gfortran libboost-all-dev \
autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat1-dev ninja-build libglib2.0-dev libslirp-dev \
libfdt-dev libpixman-1-dev \
device-tree-compiler libboost-regex-dev libboost-system-dev \

View file

@ -64,7 +64,7 @@ sudo apt upgrade -y
# Packages are grouped by which tool requires them, split by line.
# If mutltipole tools need a package, it is included in the first tool only
# General/Wally specific, riscv-gnu-toolchain, qemu, spike, verilator, sail
sudo apt install -y git make cmake python3 python3-pip python3-venv curl wget ftp tar pkg-config dialog mutt ssmtp \
sudo apt install -y git make cmake python3 python3-pip python3-venv curl wget ftp tar pkg-config dialog mutt ssmtp gfortran libboost-all-dev \
autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat1-dev ninja-build libglib2.0-dev libslirp-dev \
libfdt-dev libpixman-1-dev \
device-tree-compiler libboost-regex-dev libboost-system-dev \

View file

@ -58,15 +58,17 @@ PLIC_SDC_ID 32'd20
BPRED_SIZE 32'd12
# The syn configurations are trimmed down for faster synthesis.
deriv syn_rv32e rv32e
DTIM_RANGE 64'h1FF
IROM_RANGE 64'h1FF
BOOTROM_RANGE 64'h1FF
UNCORE_RAM_RANGE 64'h1FF
WAYSIZEINBYTES 32'd512
NUMWAYS 32'd1
BPRED_SIZE 32'd5
BTB_SIZE 32'd5
deriv syn_rv32e rv32e
DTIM_RANGE 64'h1FF
IROM_RANGE 64'h1FF
BOOTROM_RANGE 64'h1FF
UNCORE_RAM_RANGE 64'h1FF
DCACHE_WAYSIZEINBYTES 32'd512
ICACHE_WAYSIZEINBYTES 32'd512
DCACHE_NUMWAYS 32'd1
ICACHE_NUMWAYS 32'd1
BPRED_SIZE 32'd5
BTB_SIZE 32'd5
# The other syn configurations have the same trimming
deriv syn_rv32i rv32i syn_rv32e
@ -101,10 +103,15 @@ ZICSR_SUPPORTED 0
deriv syn_rv64gc_noFPU syn_rv64gc_noPriv
F_SUPPORTED 0
ZCF_SUPPORTED 0
D_SUPPORTED 0
ZCD_SUPPORTED 0
deriv syn_sram_rv64gc_noFPU syn_sram_rv64gc_noPriv
F_SUPPORTED 0
ZCF_SUPPORTED 0
D_SUPPORTED 0
ZCD_SUPPORTED 0
deriv syn_rv64gc_noMulDiv syn_rv64gc_noFPU
M_SUPPORTED 0
@ -389,22 +396,24 @@ VIRTMEM_SUPPORTED 0
deriv nodcache_rv32gc rv32gc
DCACHE_SUPPORTED 0
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZALRSC_SUPPORTED 0
ZAAMO_SUPPORTED 0
ZICBOM_SUPPORTED 0
ZICBOZ_SUPPORTED 0
VIRTMEM_SUPPORTED 0
VIRTMEM_SUPPORTED 0
# nocache_rv32gc must also disable several features incompatible with no cache
deriv nocache_rv32gc rv32gc
ICACHE_SUPPORTED 0
DCACHE_SUPPORTED 0
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZALRSC_SUPPORTED 0
ZAAMO_SUPPORTED 0
ZICBOM_SUPPORTED 0
ZICBOZ_SUPPORTED 0
VIRTMEM_SUPPORTED 0
VIRTMEM_SUPPORTED 0
deriv noicache_rv64gc rv64gc
ICACHE_SUPPORTED 0
@ -777,14 +786,38 @@ ZKND_SUPPORTED 0
ZKNE_SUPPORTED 0
ZKNH_SUPPORTED 1
deriv noS_rv32gc rv32gc
S_SUPPORTED 0
SSTC_SUPPORTED 0
VIRTMEM_SUPPORTED 0
SVINVAL_SUPPORTED 0
SVADU_SUPPORTED 0
deriv noS_rv64gc rv64gc
S_SUPPORTED 0
SSTC_SUPPORTED 0
VIRTMEM_SUPPORTED 0
SVPBMT_SUPPORTED 0
SVNAPOT_SUPPORTED 0
SVINVAL_SUPPORTED 0
SVADU_SUPPORTED 0
deriv noU_rv32gc noS_rv32gc
U_SUPPORTED 0
deriv noU_rv64gc noS_rv64gc
U_SUPPORTED 0
# Floating-point modes supported
deriv f_rv32gc rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv fh_rv32gc rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fd_rv32gc rv32gc
@ -803,10 +836,12 @@ ZFH_SUPPORTED 1
deriv f_rv64gc rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv fh_rv64gc rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fd_rv64gc rv64gc
@ -866,100 +901,124 @@ IEEE754 1
#### F_only, RK variable
deriv f_div_2_1_rv32gc div_2_1_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_2_2_rv32gc div_2_2_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_2_4_rv32gc div_2_4_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_1_rv32gc div_4_1_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_2_rv32gc div_4_2_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_4_rv32gc div_4_4_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_2_1_rv64gc div_2_1_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_2_2_rv64gc div_2_2_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_2_4_rv64gc div_2_4_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_1_rv64gc div_4_1_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_2_rv64gc div_4_2_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
deriv f_div_4_4_rv64gc div_4_4_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 0
#### FH_only, RK variable
deriv fh_div_2_1_rv32gc div_2_1_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_2_2_rv32gc div_2_2_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_2_4_rv32gc div_2_4_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_1_rv32gc div_4_1_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_2_rv32gc div_4_2_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_4_rv32gc div_4_4_rv32gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_2_1_rv64gc div_2_1_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_2_2_rv64gc div_2_2_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_2_4_rv64gc div_2_4_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_1_rv64gc div_4_1_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_2_rv64gc div_4_2_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
deriv fh_div_4_4_rv64gc div_4_4_rv64gc
D_SUPPORTED 0
ZCD_SUPPORTED 0
ZFH_SUPPORTED 1
# FD only , rk variable

View file

@ -90,7 +90,7 @@ RTL_FILES="$INCLUDE_DIRS $(find ${SRC} -name "*.sv" ! -path "${SRC}/generic/mem/
# Simulation and Coverage Commands
OUTPUT="sim_out"
VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF +vcs+vcdpluson -suppress +warn -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -ntb_opts sensitive_dyn +define+SIM_VCS ${INCLUDE_PATH} $RTL_FILES"
VCS_CMD="vcs +lint=all,noGCWM,noUI,noSVA-UA,noIDTS,noNS,noULCO,noCAWM-L,noWMIA-L,noSV-PIU,noSTASKW_CO,noSTASKW_CO1,noSTASKW_RMCOF +vcs+vcdpluson -suppress +warn -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -ntb_opts sensitive_dyn ${INCLUDE_PATH} $RTL_FILES"
SIMV_CMD="./${WKDIR}/$OUTPUT +TEST=${TESTSUITE} ${PLUSARGS}"
COV_FILES="${TB}/coverage/test_pmp_coverage.sv"
COV_OPTIONS="-cm line+cond+branch+fsm+tgl -cm_log ${WKDIR}/coverage.log -cm_dir ${WKDIR}/COVERAGE"

View file

@ -259,10 +259,12 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign SCOUNTEREN_REGW = '0;
assign SATP_REGW = '0;
assign IllegalCSRSAccessM = 1'b1;
assign STimerInt = '0;
assign SENVCFG_REGW = '0;
end
// Floating Point CSRs in User Mode only needed if Floating Point is supported
if (P.F_SUPPORTED | P.D_SUPPORTED) begin:csru
if (P.F_SUPPORTED) begin:csru
csru #(P) csru(.clk, .reset, .InstrValidNotFlushedM,
.CSRUWriteM, .CSRAdrM, .CSRWriteValM, .STATUS_FS, .CSRUReadValM,
.SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM,

View file

@ -73,6 +73,7 @@ module csri import cvw::*; #(parameter cvw_t P) (
assign MIP_WRITE_MASK = 12'h000;
assign SIP_WRITE_MASK = 12'h000;
assign MIE_WRITE_MASK = 12'h888;
assign STIP = '0;
end
always_ff @(posedge clk)
if (reset) MIP_REGW_writeable <= 12'b0;

View file

@ -195,6 +195,9 @@ module csrm import cvw::*; #(parameter cvw_t P) (
flopenr #(P.XLEN) MENVCFGHreg(clk, reset, WriteMENVCFGHM, MENVCFG_WriteValM[63:32], MENVCFG_REGW[63:32]);
assign MENVCFGH_REGW = MENVCFG_REGW[63:32];
end
end else begin
assign MENVCFG_REGW = '0;
assign MENVCFGH_REGW = '0;
end
// Read machine mode CSRs

View file

@ -99,7 +99,7 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP
assign STATUS_FS = P.F_SUPPORTED ? STATUS_FS_INT : 2'b00; // off if no FP
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty

View file

@ -54,7 +54,7 @@ module testbench;
`ifdef VERILATOR
import "DPI-C" function string getenvval(input string env_name);
string RISCV_DIR = getenvval("RISCV"); // "/opt/riscv";
`elsif SIM_VCS
`elsif VCS
import "DPI-C" function string getenv(input string env_name);
string RISCV_DIR = getenv("RISCV"); // "/opt/riscv";
`else
@ -419,12 +419,10 @@ module testbench;
$display("Coverage tests don't get checked");
end else if (ElfFile != "none") begin
$display("Single Elf file tests are not signatured verified.");
`ifdef VERILATOR // this macro is defined when verilator is used
$finish; // Simulator Verilator needs $finish to terminate simulation.
`elsif SIM_VCS // this macro is defined when vcs is used
$finish; // Simulator VCS needs $finish to terminate simulation.
`ifdef QUESTA
$stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug
`else
$stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug
$finish;
`endif
end else begin
// for tests with no self checking mechanism, read .signature.output file and compare to check for errors
@ -440,12 +438,10 @@ module testbench;
if (test == tests.size()) begin
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
else $display("FAIL: %d test programs had errors", totalerrors);
`ifdef VERILATOR // this macro is defined when verilator is used
$finish; // Simulator Verilator needs $finish to terminate simulation.
`elsif SIM_VCS // this macro is defined when vcs is used
$finish; // Simulator VCS needs $finish to terminate simulation.
`ifdef QUESTA
$stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug
`else
$stop; // if this is changed to $finish for Questa, wally-batch.do does not go to the next step to run coverage, and wally.do terminates without allowing GUI debug
$finish;
`endif
end
end

View file

@ -1083,7 +1083,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
end
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
if (OpCtrl === `FMA_OPCTRL) begin
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+4*(P.S_LEN)-1:8+3*(P.S_LEN)]};
Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+3*(P.S_LEN)-1:8+2*(P.S_LEN)]};
@ -1125,7 +1125,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]};
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]};
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
end
@ -1146,7 +1146,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]};
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+3*(P.S_LEN)-1:8+2*(P.S_LEN)]};
Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]};
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
@ -1169,7 +1169,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[12+(P.D_LEN)-1:12]};
Ans = {{P.FLEN-1{1'b0}}, TestVector[8]};
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+2*(P.S_LEN)-1:12+(P.S_LEN)]};
Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+(P.S_LEN)-1:12]};
Ans = {{P.FLEN-1{1'b0}}, TestVector[8]};
@ -1222,7 +1222,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
end
endcase
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
case (OpCtrl[1:0])
2'b11: begin // quad
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+P.S_LEN+P.Q_LEN-1:8+(P.Q_LEN)]};
@ -1252,7 +1252,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.D_LEN-1:8+(P.D_LEN)]};
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.S_LEN-1:8+(P.S_LEN)]};
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
end
@ -1317,7 +1317,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
end
endcase
end
2'b00: if (P.S_SUPPORTED) begin // single
2'b00: if (P.F_SUPPORTED) begin // single
// {is the integer a long, is the opperation to an integer}
casez ({OpCtrl[2:1]})
2'b11: begin // long -> single

View file

@ -17,7 +17,7 @@ all: $(OBJECTS)
# Change many things if bit width isn't 64
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 -mcmodel=medany \
-nostartfiles -T../../examples/link/link.ld $<
riscv64-unknown-elf-objdump -S -D $@ > $@.objdump
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile

View file

@ -43,7 +43,10 @@ wally64:
riscof run --work-dir=$(work_dir) --config=config64.ini --suite=$(wally_dir)/riscv-test-suite/ --env=$(wally_dir)/riscv-test-suite/env --no-browser --no-dut-run
rsync -a $(work_dir)/rv64i_m/ $(wally_workdir)/rv64i_m/ || echo "error suppressed"
# Also copy F and D tests to RV64
rsync -a $(work_dir)/rv32i_m/ $(wally_workdir)/rv64i_m/ || echo "error suppressed"
rsync -a $(work_dir)/rv32i_m/ $(wally_workdir)/rv64i_m/ || echo "error suppressed"
quad64:
riscof run --work-dir=$(work_dir) --config=config64.ini --suite=$(wally_dir)/riscv-test-suite/rv64i_m/Q/riscv-ctg/tests/ --env=$(wally_dir)/riscv-test-suite/env
#wally32e:
# riscof run --work-dir=$(work_dir) --config=config32e.ini --suite=$(wally_dir)/riscv-test-suite/ --env=$(wally_dir)/riscv-test-suite/env --no-browser --no-dut-run

View file

@ -70,6 +70,8 @@ class sail_cSim(pluginTemplate):
self.isa += 'd'
if "Zcb" in ispec["ISA"]: # for some strange reason, Sail requires a command line argument to enable Zcb
self.sailargs += "--enable-zcb"
if "Q" in ispec["ISA"]:
self.isa += 'q'
objdump = "riscv64-unknown-elf-objdump".format(self.xlen)
if shutil.which(objdump) is None:
logger.error(objdump+": executable not found. Please check environment setup.")

View file

@ -107,6 +107,8 @@ class spike(pluginTemplate):
self.isa += 'f'
if "D" in ispec["ISA"]:
self.isa += 'd'
if "Q" in ispec["ISA"]:
self.isa += 'q'
if "C" in ispec["ISA"]:
self.isa += 'c'
if "Zicsr" in ispec["ISA"]:

View file

@ -1,5 +1,6 @@
hart_ids: [0]
hart0:
# ISA: RV32IMAFDCZicboz_Zicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
physical_addr_sz: 32
User_Spec_Version: '2.3'

View file

@ -1,11 +1,14 @@
hart_ids: [0]
hart0:
ISA: RV64IMAFDQCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
# ISA: RV64IMAFDQCSUZicboz_Zicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
ISA: RV64IMAFDCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
# ISA: RV64IMAFDQCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zca_Zcb_Zba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh
physical_addr_sz: 56
User_Spec_Version: '2.3'
supported_xlen: [64]
misa:
reset-val: 0x800000000015112D
reset-val: 0x800000000014112D
# reset-val: 0x800000000015112D
rv32:
accessible: false
rv64:

View file

@ -0,0 +1,68 @@
# Quad Precision Floating Point Tests for Wally
## Shreesh Kulkarni
## Email : kshreesh5@gmail.com
## Date : 26th June, 2024
This folder consists of all the required files and tools to generate Q tests for Wally via riscv-ctg, riscv-isac and riscof.
NOTE : Only some of the IBM tests are currently supporting Quad testing.
Tests which are working : ibm1, ibm9,ibm21,ibm23,ibm24,ibm25,ibm26,ibm27,ibm28,ibm29
These ibm tests can be included in the riscv-ctg tests generation command, along with riscof.
The tests which are currently breaking due to overflow errors are : ibm2,ibm3,ibm4,ibm5,ibm6,ibm7,ibm8,ibm10,ibm11,ibm12,ibm13,ibm14,ibm15,ibm16,ibm17,ibm18,ibm19,ibm20,ibm22
These tests cannnot generate Quad tests yet due to underlying errors.
Changes Made : fp_dataset.py in riscv-isac -> This dataset consists of 10 IBM floating point tests generators for Quads
riscv-ctg-> This folder consists of the CTG tool which is responsible for generating the assembly files for Quads by using the fp_dataset.py in riscv-isac. CGF files were added for each of the IBM floating point tests.
riscof -> The riscof directory in Wally was changed to include some Quad precision template files for compilation. Along with modification of scripts and yaml files to support FLEN=128
Start by installing riscv-ctg via the following commands :
cd $WALLY/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/riscv-ctg
pip3 install --editable .
Once installed, generate the assembly files in the tests directory{cvw/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/riscv-ctg/tests} for the specific opcode by running this command :
riscv_ctg --base-isa rv64i --flen 128 --cgf ./sample_cgfs/dataset.cgf --cgf ./sample_cgfs/sample_cgfs_fext/RV32D/fadd.q.cgf -d ./tests/ --randomize -v debug -p2
NOTE : The following warning might be generated :
WARNING | Neither mnemonics nor csr_comb node not found in covergroup: datasets
This can be ignored as this warning tells us that not all IBM tests have been included as only a limited number of them support Quads currently.
You can choose the corresponding cgf file for the opcode you wish to generate tests.
This command was referenced in the following Issue generated in the riscv-ctg repository.
(CTG Issue 111){https://github.com/riscv-software-src/riscv-ctg/issues/111}
You should now see some assembly tests pertaining to your selected opcode in the tests directory(cvw/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/riscv-ctg/tests).
To finally generate the SAIL signatures and dut/ref log/assembly files, RISCOF will be used to compile our generated tests from CTG.
The following command will invoke riscof and generate a riscof-work directory with all the selected tests and log files, SAIL signatures and dis-assembly files.
PATH=/home/jcarlin/REPOS/sail-riscv/c_emulator/current:$PATH
cd $WALLY/tests/riscof
make quad64
NOTE : The above command will generate the following error.
ERROR | /home/skulkarni/cvw/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/Q/riscv-ctg/tests/fadd.q_b1-01.S : - : Failed
This is because and SAIL and SPIKE's signatures do not match. This needs further debugging.
The log-files, disassembly files and reference SAIL signatures can be viewed in the riscof-work directory(cvw/tests/riscof/riscof_work/)

View file

@ -0,0 +1,204 @@
# CHANGELOG
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Please note the header `WIP-DEV` is to always remain indicating the changes done on the dev branch.
Only when a release to the main branch is done, the contents of the WIP-DEV are put under a
versioned header while the `WIP-DEV` is left empty
## [0.12.2] - 2024-03-06
- Add Zfa support.
## [0.12.1] - 2024-02-27
- Fix test.yml
## [0.12.0] - 2024-02-22
- Update generator.py to take care of hard coded register testcases only if a hard coded register is assigned in the op_comb node of a coverpoint of an instruction.
- Add hardcoded register testcases to dataset.cgf and rv32im.cgf
- Define rs1_val_data for c.ldsp in imc.yaml
- Update "opcode" to "mnemonics" in the cgf files
- Delete main.yml
- Update test.yml for CI
- Define rs1_val_data for instructions from zicfiss.cgf in template.yaml
- Add "warning" in the verbose definition
- Add unratified Zicfiss extension
- Add unratified Zicfilp extension
- Add corner case of division for division operations for RV64
- Fix csr_comb to write test information
- Add unratified Zaamo subcomponent of A extension
- Add unratified B extension
- Fix issues with csr_comb
- Minor fix in kslraw.u in rv32ip
- Fix incorrect 'sig:' entry in aes32dsi in template.yaml
- Add sig and sz for instructions in template.yaml
- Minor change of rd definition in c.lui in rv32ec
- Minor fix in rv32i_k
- Add rs1_val_data, rs2_val_data, imm_val_data for instructions in template.yaml
- Comment xlenlim out of val_comb in rv32i_b, rv64i_b
- Fix the formats of leading_ones, leading_zeros, trailing_ones, trailing_zeros for instructions in rv32i_b, rv32e_b
- Add op_comb for instructions in rv32i_zcb
- Add rs1_val_data for instructions in imc.yaml
- Add op_comb and val_comb for instructions in rv32ic, rv64ic, rv32ec
- Add corner case of division for division operations for RV32
- Comment print statements out from generator.py
- Fix whitespaces on empty lines in yaml template files.
- Add unratified Zabha extension
- Add support for unratified Zcmop extension
- Add support for unratified Zimop extension
- Add missing coverage for hard coded register testcases
- Updated CONTRIBUTING.rst to capture the new git strategy adopted to follow a monthly release cadence.
- Add Zifencei, Bit Manipulation and Privilege tests cgf files for RV32E
- Add unratified Zacas extension
- Add support for standard Atomic(A) extension
## [0.11.1] - 2023-08-15
- Fixed hex values handling for K extensions
- Fixed set indexing error during opcomb gen
- Fixed whitespaces on empty lines in yaml template files.
## [0.11.0] - 2022-12-11
- Added support for csr_comb test generation
## [0.10.4] - 2023-03-28
- Adding Zicond support
## [0.10.3] - 2022-11-22
- Fixed canary definition
## [0.10.2] - 2022-10-20
- Fixed use of lowercase LI.
- Fixed correctval to ?? in comments.
- Fixed sw to SREG for K tests.
- Added canaries and signature boundary labels.
## [0.10.1] - 2022-09-30
- Added support for evaluating derived fields for evaluating coverpoints using the instruction object class
## [0.10.0] - 2022-09-05
- Added support for bitmanip and crypto scalar coverpoint test generation
## [0.9.0] - 2022-08-25
- Added support for cross_comb coverpoint test generation
## [0.8.0] - 2022-08-08
- Added support for a distributed template database.
- Added generic mechanisms to generate data sections based on test instances.
- Update templates for floating point tests.
- Fix test generation and macros for floating point tests.
## [0.7.2]
- Fix errors related to global variables across processes.
## [0.7.1] - 2022-02-07
- Fixed mistune version for doc build.
## [0.7.0] - 2022-02-05
- Included support for pseudoinstructions
## [0.6.3] - 2022-03-14
- Read the vxsat.OV flag before updating signatures in TEST_PKRR_OP() macro
- Use RDOV() macro to read the vxsat.OV flag.
## [0.6.2] - 2022-03-15
- Added method to generate data patterns for bitmanip instructions.
## [0.6.1] - 2022-03-04
- Check the vxsat.OV flag for P-extension instructions that saturate their results.
- Correct test generation of P-extension instructions affected by the template.yaml ISA node change in 0.6.0.
- update SIGUPD macros to automatically adjust base and offset if offset gets too big
## [0.6.0] - 2022-01-27
- Add CGFs for B extensions.
- Modify ISA node in template.yaml to support multiple ISAs per instruction.
## [0.5.9] - 2021-12-20
- Add CGFs for P extensions
- Add support for P extension test generation
## [0.5.8] - 2021-10-21
- Updated and added bitmanip_real_world.py script to generate test with real world patterns.
## [0.5.7] - 2021-09-20
- Fix the generation of rv32ec/cswsp test
## [0.5.6] - 2021-09-19
- rvtest\_data section now includes 16 bytes of rotated versions of `0xbabecafe`
## [0.5.5] - 2021-09-10
- Add CGFs for F&D extensions
- Add support for F & D extension test generation
- Add support for test splitting based on number of macro instances
- Add macro based signature entry sizes
## [0.5.4] - 2021-09-02
- Updated logger to enable logging for API calls.
## [0.5.3] - 2021-08-12
- Update instruction format of aes32 and sm4 instructions for K extensions.
- Improve the coverage of S-boxes for sm4 instructions by setting overlap = "Y" in byte_count.
## [0.5.2] - 2021-08-09
- Fix sign of immediate value for branching instructions while filtering.
- Fix instruction generation while result shadowing.
## [0.5.1] - 2021-07-16
- Update the sample cgf for RV32E
- fix the generation of RV32E Tests
## [0.5.0] - 2021-05-27
- support for K extension and subextension instructions
- support for comments in coverpoints
- added std_op field in template.yaml to indicate is standard-instruction the pseudo op belongs to.
- added support for parsing #nosat in coverpoint which disables the solvers for the current resolution.
- added sample cgf files for rv64ik and rv32ik
## [0.4.5] - 2021-05-15
- Minor code restructure to support API calls.
- Fixes to include env files in pip package.
## [0.4.4] - 2021-02-23
- Added missing coverpoints for JALR
- fixed CI to run main.yml on pushes to master.
- added version check for PRs in test.yml
## [0.4.3] - 2021-02-23
- Updated CI to actions
## [0.4.2] - 2021-01-15
- Fixed header base_isa argument
- Change header configuration argument list
- Remove first empty line in assembler output
- Add header randomization argument
## [0.4.1] - 2020-12-13
- Fixed correctval generation for existing ops.
- Fixed signedness of operand values for m ext instructions.
- Added operation strings for m and c extensions.
## [0.4.0] - 2020-11-19
- Added base_isa as option in cli
- Added support for register set based on base isa.
- Reformatted output values in tests to be hex strings.
- change compliance_model to model_test
## [0.3.0] - 2020-11-18
- minor doc updates
- renamed compliance_test.h to arch_test.h
- added aliasing macros for v0.1 compliance framework
- split datasets and coverpoints into multiple cgfs
- support for multiple cgf as inputs
- added support for special datasets to relevant instructions
- adding explicit entry point label to all tests
- remove x2 as coverpoint in cswsp and csdsp
## [0.2.0] - 2020-11-10
- initial draft of CTG
- parallelization support added
- random solvers can be used
- support rv32/64imc instructions
- docs updated
## [0.1.0] - 2020-07025
- initial draft

View file

@ -0,0 +1,119 @@
.. See LICENSE.incore for details
.. highlight:: shell
======================
Developer Contribution
======================
Contributions are welcome, and they are greatly appreciated and credit will always be given.
You can contribute in many ways:
Types of Contributions
----------------------
Report Bugs
~~~~~~~~~~~
Report bugs at https://github.com/riscv-software-src/riscv-ctg/issues/.
Submit Feedback
~~~~~~~~~~~~~~~
The best way to send feedback is to file an issue at https://github.com/riscv-software-src/riscv-ctg/issues/.
If you are proposing a feature:
* Explain in detail how it would work.
* Keep the scope as narrow as possible, to make it easier to implement.
* Remember that this is a volunteer-driven project, and that contributions
are welcome :)
Git Strategy
------------
The repo adopts a simple git strategy where all contributions to the repo are made to the ``dev``
branch (i.e. all Pull-Requests must use ``dev`` as the target branch). On a monthly cadence (decided
and controlled by the SIG-ARCH-TEST members) the ``dev`` branch will be merged to the ``main`` to by
the official maintainers of the repo. This will create an official release capturing all the
development over the month into a single release.
To implement the above strategy successfully the following needs be followed:
* Developers: All pull-requests from developers must target the ``dev`` branch and the PR must
contain an entry in the CHANGELOG.md file under `[WIP-DEV]` section.
* Maintainers: When a making a release the maintainers shall assign semantic version number by
updating the CHANGELOG and the respective python files before raising a PR from the `dev` to `main`.
Get Started!
------------
Ready to contribute? Here's how to set up `riscv_ctg` for local development.
1. Fork the `riscv_ctg` repo on GitHub.
2. Clone your fork locally and checkout the ``dev`` branch::
$ git clone https://github.com/riscv-software-src/riscv-ctg.git -b dev
3. Create an issue and WIP merge request that creates a working branch for you::
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
4. When you're done making changes, check that your changes pass pytest
tests, including testing other Python versions with tox::
$ cd tests
$ pytest test_riscv_ctg.py -v
5. Commit your changes and push your branch to GitLab::
$ git add .
$ git commit -m "Your detailed description of your changes."
$ git push origin name-of-your-bugfix-or-feature
6. Submit a pull-request through the GitHub website. Make sure the pull-request is on the `dev`
branch of the origin repo.
7. Do not forget to make an entry in the CHANGELOG.md file under the `[WIP-DEV]` section
highlighting the changes you have done.
Merge Request Guidelines
------------------------
Before you submit a merge request, check that it meets these guidelines:
1. The merge request should include tests (if any).
2. If the merge request adds functionality, the docs should be updated.
3. The target branch must always be the `dev` branch.
Versioning (only for maintainers)
---------------------------------
When issuing pull requests to the main branch (from dev), a version entry in the CHANGELOG.md is mandatory. The tool adheres to
the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. Following guidelines must
be followed while assigning a new version number :
- Patch-updates: all doc updates (like typos, more clarification,etc).
- Minor-updates: Fixing bugs in current features, adding new features which do not break current
features or working. Adding new extensions.
- Major-updates: Backward incompatible changes.
Note: You can have either a patch or minor or major update.
Note: In case of a conflict, the maintainers will decide the final version to be assigned.
To update the version of the python package for deployment you can use `bumpversion` (installed
using ``pip install bumpversion``)::
$ bumpversion --no-tag --config-file setup.cfg patch # last arg can be: major or minor or patch
If you don't have bumpversion installed you can manually update the version in the following files:
- change the value of variable ``current_version`` in `./setup.cfg`
- change the value of variable ``__version__`` in `./riscv_ctg/__init__.py`

View file

@ -0,0 +1,30 @@
BSD 3-Clause License
Copyright (c) 2020, InCore Semiconductors Pvt. Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,9 @@
include LICENSE.incore
include README.rst
include riscv_ctg/requirements.txt
recursive-include riscv_ctg/data/ *
recursive-include riscv_ctg/env/ *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
recursive-exclude tests/ *

View file

@ -0,0 +1,7 @@
#################################################
**RISC-V Compliance Test Generator** : RISC-V CTG
#################################################
Latest documentation of riscv_ctg : `click here <https://riscv-ctg.readthedocs.io/en/latest>`_

View file

@ -0,0 +1,26 @@
# See LICENSE.incore for details
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = riscv_ctg
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
clean:
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View file

@ -0,0 +1,15 @@
# Build the docs
## For PDF
```
pip install -r requirements.txt
make latexpdf
evince build/latex/*.pdf
```
## HTML
```
pip install -r requirements.txt
make html
firefox build/html/index.html
```

View file

@ -0,0 +1,38 @@
alabaster==0.7.12
Babel==2.7.0
Cerberus==1.3.1
certifi==2019.6.16
chardet==3.0.4
doc8==0.8.0
docutils==0.14
gitdb2==2.0.5
idna==2.8
imagesize==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
oyaml==0.9
packaging==19.0
pbr==5.3.1
Pygments==2.4.2
pyparsing==2.4.0
python-dateutil==2.8.0
pytz==2019.1
PyYAML==5.1.1
requests==2.22.0
restructuredtext-lint==1.3.0
ruamel.yaml==0.15.97
six==1.12.0
smmap2==2.0.5
snowballstemmer==1.2.1
Sphinx==3.0.4
sphinx-rtd-theme==0.4.3
sphinxcontrib-autoyaml==0.5.0
sphinxcontrib-mermaid
sphinxcontrib-websupport==1.1.2
sphinxcontrib-bibtex==1.0.0
stevedore==1.30.1
urllib3==1.25.3
twine==1.13.0
sphinx_tabs
m2r2==0.2.7
mistune==0.8.4

View file

@ -0,0 +1,305 @@
/* -- Extra CSS styles for Zephyr content (RTD theme) ----------------------- */
/* make the page width fill the window */
.wy-nav-content {
max-width: none;
}
/* pygments tweak for white-on-black console */
/* hold off on this change for now
.highlight-console .highlight {
background-color: black;
}
.highlight-console .highlight .go, .highlight-console .highlight .gp {
color: white;
}
.highlight-console .highlight .hll {
background-color: white;
}
.highlight-console .highlight .hll .go, .highlight-console .highlight .hll .gp {
color: black;
font-weight: bold;
}
*/
/* tweak doc version selection */
.rst-versions {
position: static !important;
}
.rst-versions .rst-current-version {
padding: 5px;
background-color: #2980B9;
color: #80FF80;
}
.rst-versions .rst-other-versions {
padding: 5px;
}
div.rst-other-versions dl {
margin-bottom: 0;
}
/* tweak spacing after a toctree, fixing issue from sphinx-tabs */
.toctree-wrapper ul, ul.simple ol.simple {
margin-bottom: 24px !important;
}
/* code block highlight color in rtd changed to lime green, no no no */
.rst-content tt.literal, .rst-content code.literal, .highlight {
background: #f0f0f0;
}
.rst-content tt.literal, .rst-content code.literal {
color: #000000;
}
/* code literal links should be blue, and purple after visiting */
a.internal code.literal {
color: #2980B9;
}
a.internal:visited code.literal {
color: #9B59B9;
}
/* Make the version number more visible */
.wy-side-nav-search>div.version {
color: rgba(255,255,255,1);
}
/* squish the space between a paragraph before a list */
div > p + ul, div > p + ol {
margin-top: -20px;
}
/* squish space before an hlist in a list */
li table.hlist {
margin-top: -10px;
margin-bottom: 5px;
}
/* add some space before the figure caption */
p.caption {
# border-top: 1px solid;
margin-top: 1em;
}
/* decrease line leading a bit, 24px is too wide */
p {
line-height: 22px;
}
/* add a colon after the figure/table number (before the caption) */
span.caption-number::after {
content: ": ";
}
p.extrafooter {
text-align: right;
margin-top: -36px;
}
table.align-center {
display: table !important;
}
/* put the table caption at the bottom, as done for figures */
table {
caption-side: bottom;
}
.code-block-caption {
color: #000;
font: italic 85%/1 arial,sans-serif;
padding: 1em 0;
text-align: center;
}
/* make .. hlist:: tables fill the page */
table.hlist {
width: 95% !important;
table-layout: fixed;
}
/* override rtd theme white-space no-wrap in table heading and content */
th,td {
white-space: normal !important;
}
/* dbk tweak for doxygen-generated API headings (for RTD theme) */
.rst-content dl.group>dt, .rst-content dl.group>dd>p {
display:none !important;
}
.rst-content dl.group {
margin: 0 0 12px 0px;
}
.rst-content dl.group>dd {
margin-left: 0 !important;
}
.rst-content p.breathe-sectiondef-title {
text-decoration: underline; /* dbk for API sub-headings */
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 12px;
}
.rst-content div.breathe-sectiondef {
padding-left: 0 !important;
}
/* doxygenXX item color tweaks, light blue background with dark blue top border */
.rst-content dl:not(.docutils) dl dt, dl:not(.docutils,.rst-other-versions) dt {
background: #e7f2fa !important;
border-top: none !important;
border-left: none !important; */
}
/* tweak display of option tables to make first column wider */
col.option {
width: 25%;
}
/* tweak format for <kbd> (:kbd:`F10`) */
kbd
{
-moz-border-radius:3px;
-moz-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
-webkit-border-radius:3px;
-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
background-color:#f7f7f7;
border:1px solid #ccc;
border-radius:3px;
box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
color:#333;
display:inline-block;
font-family:Arial,Helvetica,sans-serif;
font-size:11px;
line-height:1.4;
margin:0 .1em;
padding:.1em .6em;
text-shadow:0 1px 0 #fff;
}
/* home page grid display */
.grid {
list-style-type: none !important;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
margin: 1rem auto;
max-width: calc((250px + 2rem) * 4);
}
.grid-item {
list-style-type: none !important;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
width: 200px;
text-align: center;
margin: 1rem;
}
.grid-item a {
display: block;
width: 200px;
height: 200px;
padding: 20px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid #c6cbce;
background-color: #1ab4e7;
color: white;
}
.grid-item h2 {
font-size: 1.1rem;
}
.grid-item img {
margin-bottom: 1.1rem;
max-width: 75%;
}
.grid-item a:hover {
background-color: #1892BA;
color: white;
}
.grid-item p {
margin-top: 0.5rem;
color: #333e48;
}
.grid-icon {
line-height: 1.8;
font-size: 4rem;
color: white;
}
/* add a class for multi-column support
* in docs to replace use of .hlist with
* a .. rst-class:: rst-columns
*/
.rst-columns {
column-width: 18em;
}
/* numbered "h2" steps */
body {
counter-reset: step-count;
}
div.numbered-step h2::before {
counter-increment: step-count;
content: counter(step-count);
background: #cccccc;
border-radius: 0.8em;
-moz-border-radius: 0.8em;
-webkit-border-radius: 0.8em;
color: #ffffff;
display: inline-block;
font-weight: bold;
line-height: 1.6em;
margin-right: 5px;
text-align: center;
width: 1.6em;
}
/* tweak bottom margin of a code block in a list */
.tab div[class^='highlight']:last-child {
margin-bottom: 1em;
}
/* force table content font-size in responsive tables to be 100%
* fixing larger font size for paragraphs in the kconfig tables */
.wy-table-responsive td p {
font-size:100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -0,0 +1,13 @@
/* override table width restrictions */
@media screen and (min-width: 767px) {
.wy-table-responsive table td {
/* !important prevents the common CSS stylesheets from overriding
this as on RTD they are loaded after this stylesheet */
white-space: normal !important;
}
.wy-table-responsive {
overflow: visible !important;
}
}

View file

@ -0,0 +1,14 @@
{% extends "!breadcrumbs.html" %}
{% block breadcrumbs %}
<!-- {{ docs_title }} -->
{# parameterize default name "Docs" in breadcrumb via docs_title in conf.py #}
{% if not docs_title %}
{% set docs_title = "Docs" %}
{% endif %}
<li><a href="{{ pathto(master_doc) }}">{{ docs_title }}</a> &raquo;</li>
{% for doc in parents %}
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
{% endfor %}
<li>{{ title }}</li>
{% endblock %}

View file

@ -0,0 +1,14 @@
{% extends "!layout.html" %}
{% block document %}
{% if is_release %}
<div class="wy-alert wy-alert-danger">
The <a href="/latest/{{ pagename }}.html">latest development version</a>
of this page may be more current than this released {{ version }} version.
</div>
{% endif %}
{{ super() }}
{% endblock %}
{% block menu %}
{% include "versions.html" %}
{{ super() }}
{% endblock %}

View file

@ -0,0 +1,25 @@
{# Add rst-badge after rst-versions for small badge style. #}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> RISC-V Compatibility Test Generator </span>
v: {{ current_version }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<dl>
<dt>{{ _('Release Versions') }}</dt>
{% for slug, url in versions %}
<dd><a href="{{ url }}">{{ slug }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('Quick Links') }}</dt>
<dd>
<a href="https://github.com/riscv/riscv-ctg">Project Home</a>
</dd>
<dd>
<a href="https://github.com/riscv/riscv-ctg/tags">Releases</a>
</dd>
</dl>
</div>
</div>

View file

@ -0,0 +1,48 @@
.. _add_instr:
###################################
Adding Support for New instructions
###################################
This section discusses the tasks required to add support of a new instruction generation in CTG.
Update the Attributes YAML
--------------------------
The first step would be to update the attributes YAML to define a node for the new instruction. The
new node must follow the same :ref:`template <attributes>` as defined earlier.
One must try to use the existing datasets and fields as much as possible and avoid creation of new
redundant datasets unless absolutely required. One can also define abstract functions to generate
the datasets on the go instead of having to elaborate them completely in the YAML itself.
Some of the abstract functions are available in :meth:`~riscv_ctg.constants` for reference.
Create a new format
-------------------
If the instruction uses a new instruction format type, which is not already present in the CTG
currently, then the behavior of that will have to be defined in the :meth:`~riscv_ctg.generator`
class.
This would involve updating the dictionaries :meth:`~riscv_ctg.generator.OPS` and
:meth:`~riscv_ctg.generator.VALS` with the new type. Next create a function ``__XX_instr__`` in
:meth:`~riscv_ctg.generator` similar to the existing ones which defines how the
:ref:`op_comb and val_comb <opval_comb>` solutions are merged to create the corresponding instruction.
Additional Register Allocations
-------------------------------
Currently the signature register allocation assumes a max of 3 registers being used by an
instruction. However, if your instruction uses more registers then the
:meth:`~riscv_ctg.generator.Generator.swreg` function will also need an update.
Similarly the test register allocation function :meth:`~riscv_ctg.generator.Generator.testreg` function will
also have to be updated.
Adding Instruction Macros
-------------------------
CTG does not generate direct instruction. It rather uses the template field in the attributes YAML
as a template to generate tests. This template is usually an assembly macro. The definition of these
macros must be defined in ``env/arch_test.h`` header file.

View file

@ -0,0 +1,91 @@
.. See LICENSE.incore for details
=====
Usage
=====
Once you have RISCV-CTG installed, executing ``riscv_ctg --help`` should print the following on the terminal. ::
Usage: riscv_ctg [OPTIONS]
Options:
--version Show the version and exit.
-v, --verbose [info|error|debug]
Set verbose level
-d, --out-dir PATH Output directory path
-r, --randomize Randomize Outputs.
-cf, --cgf PATH Path to the cgf file(s). Multiple allowed.
-p, --procs INTEGER Max number of processes to spawn
-bi, --base-isa [rv32e|rv32i|rv64i]
Base ISA string for the tests.
--help Show this message and exit.
To use RISC-V Compatibility Test Generator in a project::
import riscv_ctg
Running the Test generator
==========================
In order to generate the tests for **RV32I** the following command is used. ::
$ mkdir tests/
$ riscv_ctg -v debug -d ./tests/ -r -cf ./sample_cgfs/dataset.cgf -cf ./sample_cgfs/rv32i.cgf -bi rv32i -p2
Suite Characteristics
=====================
Directory structure
-------------------
The various `.S` files are the tests themselves.
.. code-block:: console
.
├── Addi.S
├── Add.S
├── Andi.S
├── And.S
├── Auipc.S
├── Beq.S
├── Bge.S
├── Bgeu.S
├── Blt.S
├── Bltu.S
├── Bne.S
├── env # Contains the necessary environment files
│   ├── arch_test.h # Header file containing the macros used in tests
│   └── encoding.h # Header file containing varios encodings required
├── Jalr.S
├── Jal.S
├── Lb-align.S
├── Lbu-align.S
├── Lh-align.S
├── Lhu-align.S
├── Lui.S
├── Lw-align.S
├── Ori.S
├── Or.S
├── Sb-align.S
├── Sh-align.S
├── Slli.S
├── Sll.S
├── Slti.S
├── Sltiu.S
├── Slt.S
├── Sltu.S
├── Srai.S
├── Sra.S
├── Srli.S
├── Srl.S
├── Sub.S
├── Sw-align.S
├── Xori.S
└── Xor.S
Test Structure
--------------
All tests follow the test-spec format available here: `Test Spec Format`_
.. _Test Spec Format: https://riscof.readthedocs.io/en/latest/testformat.html#test-format-spec

View file

@ -0,0 +1,21 @@
.. _code:
Code Docs
#########
Generator-Module
=================
.. automodule:: riscv_ctg.generator
:members:
:special-members:
:private-members:
Constants-Module
================
.. automodule:: riscv_ctg.constants
:members:
:special-members:
:private-members:

View file

@ -0,0 +1,450 @@
# See LICENSE.incore for details
# riscv_ctg documentation build configuration file, created by
# sphinx-quickstart on Fri Jun 9 13:47:02 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import shlex
import re
def get_version():
changelog = open('../../CHANGELOG.md','r').read()
x = re.findall(r'## \[(.*?)\] -',changelog)[0]
return str(x)
sys.path.insert(0, os.path.abspath('../..'))
sys.setrecursionlimit(1500)
# General information about the project.
project = 'RISC-V Compatibility Test Generator'
copyright = u'2020 InCore Semiconductors Pvt. Ltd'
author = ''
version = str(get_version())
# The full version, including alpha/beta/rc tags
release = version
def setup(app):
app.add_stylesheet("custom.css")
app.add_css_file("_static/custom.css")
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
needs_sphinx = '1.7.5'
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinxcontrib.autoyaml',
'sphinxcontrib.bibtex',
'sphinx_tabs.tabs',
'm2r2'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
source_suffix = ['.rst', '.md']
#source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for HTML output -------------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
github_url = 'https://github.com/riscv/riscv-ctg'
html_show_sourcelink = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
#html_theme = 'bootstrap'
#html_theme = 'alabaster'
import sphinx_rtd_theme
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_theme = 'sphinx_rtd_theme'
html_theme_options = {
'prev_next_buttons_location': 'both',
'display_version': True,
'includehidden': False,
'collapse_navigation':True,
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False
}
#html_sidebars = {
# "**": ["about.html", "navigation.html", "searchbox.html", "donate.html"]
#}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_logo='_static/incore_logo.png'
html_show_license = True
docs_title = 'Docs / %s' %(version)
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = '_static/onlyC.png'
html_context = {
'show_license': html_show_license,
'docs_title': docs_title,
'is_release': False,
'theme_logo_only': False,
'current_version': version,
}
html_last_updated_fmt = '%b %d, %Y'
# If false, no module index is generated.
html_domain_indices = False
# If false, no index is generated.
html_use_index = True
# If true, the index is split into individual pages for each letter.
html_split_index = True
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
html_show_sphinx = False
# If true, license is shown in the HTML footer. Default is True.
html_show_license = True
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# Output file base name for HTML help builder.
htmlhelp_basename = 'RISC-V Compatibility Test Generator'
# -- Options for LaTeX output ---------------------------------------------
# -- Options for LaTeX output ------------------------------------------------
latex_engine='xelatex'
numfig = True
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
'papersize': 'letterpaper',
'releasename':version,
'extraclassoptions': 'openany, twoside',
# Sonny, Lenny, Glenn, Conny, Rejne, Bjarne and Bjornstrup
#'fncychap': '\\usepackage[Bjornstrup]{fncychap}',
'fncychap': '\\usepackage{fancyhdr}',
'fontpkg': '\\usepackage{amsmath,amsfonts,amssymb,amsthm}',
'figure_align':'htbp',
# The font size ('10pt', '11pt' or '12pt').
#
'pointsize': '12pt',
# Additional stuff for the LaTeX preamble.
#
'preamble': r'''
% change the fon to san-serif
%\renewcommand{\familydefault}{\sfdefault}
%%%%%%%%%%%%%%%%%%%% Meher %%%%%%%%%%%%%%%%%%
%%%add number to subsubsection 2=subsection, 3=subsubsection
%%% below subsubsection is not good idea.
\setcounter{secnumdepth}{3}
%
%%%% Table of content upto 2=subsection, 3=subsubsection
\setcounter{tocdepth}{2}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{graphicx}
\usepackage{array, caption, tabularx, ragged2e, booktabs, longtable}
\usepackage{stfloats}
\usepackage{multirow}
\usepackage{gensymb}
\usepackage{fontspec}
\setmainfont{Ubuntu Light}
\definecolor{light-gray}{gray}{0.85}
\usepackage{color,xesearch}
\usepackage{soul}
\sethlcolor{light-gray}
\makeatletter
%%% reduce spaces for Table of contents, figures and tables
%%% it is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document
\usepackage[notlot,nottoc,notlof]{}
\usepackage{color}
\usepackage{transparent}
\usepackage{eso-pic}
\usepackage{lipsum}
\usepackage{footnotebackref} %%link at the footnote to go to the place of footnote in the text
%% spacing between line
\usepackage{setspace}
%%%%\onehalfspacing
%%%%\doublespacing
\singlespacing
%%%%%%%%%%% datetime
\usepackage{datetime}
\newdateformat{MonthYearFormat}{%
\monthname[\THEMONTH], \THEYEAR}
%% RO, LE will not work for 'oneside' layout.
%% Change oneside to twoside in document class
\pagestyle{fancy}
\makeatletter
\fancypagestyle{normal}{
\fancyhf{}
%%% Alternating Header for oneside
%\fancyhead[L]{\ifthenelse{\isodd{\value{page}}}{ \small \nouppercase{\leftmark} }{}}
%\fancyhead[R]{\ifthenelse{\isodd{\value{page}}}{}{ \small \nouppercase{\rightmark} }}
%%% Alternating Header for two side
\fancyhead[RO]{\small \nouppercase{\leftmark}}
\fancyhead[RE]{\small \nouppercase{\leftmark}}
\fancyhead[LE,LO]{\py@HeaderFamily \@title\sphinxheadercomma\releasename}
%\fancyhead[RE,RO]{\py@HeaderFamily \c@chapter}
%% for oneside: change footer at right side. If you want to use Left and right then use same as header defined above.
%\fancyfoot[R]{\ifthenelse{\isodd{\value{page}}}{{\tiny Meher Krishna Patel} }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{\tiny PythonDSP}}}
%%% Alternating Footer for two side
\fancyfoot[LO, LE]{\small \bf{Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.}}
%\fancyfoot[LO, LE]{\scriptsize \bf{RISC-V Compatibility Test Generator}}
%%% page number
\fancyfoot[RO, RE]{\thepage}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
}
\makeatother
\RequirePackage{tocbibind} %%% comment this to remove page number for following
\addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}}
\addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}}
\addto\captionsenglish{\renewcommand{\listtablename}{List of tables}}
% \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}}
%%reduce spacing for itemize
\usepackage{enumitem}
\setlist{nosep}
%%%%%%%%%%% Quote Styles at the top of chapter
\usepackage{epigraph}
\setlength{\epigraphwidth}{0.8\columnwidth}
\newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}}
%%%%%%%%%%% Quote for all places except Chapter
\newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}}
\linespread{1}
''',
'maketitle': r'''
\pagenumbering{Roman} %%% to avoid page 1 conflict with actual page 1
\begin{titlepage}
\centering
\begin{figure}[!h]
\centering
\includegraphics[scale=0.2]{incore_logo.png}
\end{figure}
\vspace*{40mm} %%% * is used to give space from top
\textbf{\Huge {RISC-V Compatibility Test Generator}}
\vspace*{40mm} %%% * is used to give space from top
\vspace{10mm}
\Large \textbf{{Release: \releasename}}
\vspace{10mm}
Last update on : \today
\vspace*{0mm}
%\small Last updated : \MonthYearFormat\today
%% \vfill adds at the bottom
\vfill
Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.
\end{titlepage}
\sloppy
\clearpage
% \pagenumbering{roman}
\tableofcontents
\clearpage
\listoffigures
\clearpage
\listoftables
\clearpage
\pagenumbering{arabic}
''',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
'sphinxsetup': \
'hmargin={0.7in,0.7in}, vmargin={1in,1in}, \
verbatimwithframe=true, \
TitleColor={rgb}{0,0,0}, \
HeaderFamily=\\rmfamily\\bfseries, \
InnerLinkColor={rgb}{0,0,1}, \
OuterLinkColor={rgb}{0,0,1}',
'tableofcontents':' ',
}
#latex_elements = {
# # The paper size ('letterpaper' or 'a4paper').
# #
# 'papersize': 'letterpaper',
#
# # The font size ('10pt', '11pt' or '12pt').
# #
# 'pointsize': '10pt',
#
# # Additional stuff for the LaTeX preamble.
# #
# 'preamble': '',
#
# # Latex figure (float) alignment
# #
# 'figure_align': 'htbp',
#
# 'atendofbody' : ' InCore Semiconductors Pvt. Ltd.'
#}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'riscv_ctg.tex', 'RISC-V CTG Documentation',
'InCore Semiconductors Pvt. Ltd.', 'manual'),
]
latex_logo = '_static/incore_logo.png'
latex_show_pagerefs = True
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'riscv_ctg', 'RISC-V CTG Documentation',
'InCore Semiconductors Pvt. Ltd.', 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'riscv_ctg', 'RISC-V CTG Documentation',
'InCore Semiconductors Pvt. Ltd.', 'One line description of project.',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# -- Options for intersphinx extension ---------------------------------------
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

View file

@ -0,0 +1 @@
.. include:: ../../CONTRIBUTING.rst

View file

@ -0,0 +1,35 @@
************************************************
Test Generation using Cross Coverage Coverpoints
************************************************
Coverpoints constituting multiple instructions can help identify interesting instruction
sequences which have architectural significance such as structural hazards and data hazards.
The coverpoint node associated with the test generation is ``cross_comb`` defined `here <https://riscv-isac.readthedocs.io/en/stable/cgf.html>`_.
The test generator employs a constraint solver to generate relevant instruction sequence for a
``cross_comb`` coverpoint.
Example
-------
**Coverpoint Definition**
An example cross combination coverpoint is given below: ::
add:
cross_comb:
"[add : ? : rv32i_arith : ? : sub] :: [a=rd : ? : ? : ? : ?] :: [? : rs1==a or rs2==a : rs1==a or rs2==a : rs1==a or rs2==a : rd==a]"
**Possible assembly sequence**
A possible sequence of instructions CTG would generate is: ::
add x3, x3, x4
addi x5, x3, 1
sub x6, x4, x3
addi x4, x3, -3
sub x3, x5, x6
The test generator also embeds appropriate macros for initialization of registers and signature region pointing registers.
Note: The cross-combination test generator as of now, does not support load, store and branch instructions

View file

@ -0,0 +1,26 @@
*************************************************
Test Generation using CSR Combination Coverpoints
*************************************************
CSR Combination Coverpoints can help checking for some basic compliance with the privileged
part of the RISC-V spec by specifying conditions on the CSR values.
The coverpoint node associated with the test generation is ``csr_comb`` defined `here <https://riscv-isac.readthedocs.io/en/stable/cgf.html>`_.
Currently, the test generation is only possible for the coverpoints that test for the values of subfields in CSRs.
Thus, the only supported coverpoints are the form ``csr_reg & mask == val``, where:
* ``mask`` and ``val`` are allowed to be any valid python expressions.
* ``csr_reg`` is allowed to be operated by a bit shift operator, i.e., ``(csr_reg >> shift) & mask == val`` is allowed where ``shift`` is a valid python expression.
* functions ``old("csr_name")`` and ``write("csr_name")`` are allowed to be used in the place of ``csr_reg`` to access the old value and write value of a CSR respectively.
* combination of multiple conditions with ``and`` and ``or`` is allowed.
Example
-------
**Coverpoint Definition**
An example CSR combination coverpoint is given below: ::
misa:
csr_comb:
'old("misa") & 0x4 == 0 and (write("misa") >> 12) & 1 == 0 and misa & 0x1000 == 0x1000': 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,25 @@
.. See LICENSE.incore for details
.. _home:
RISC-V Compatibility Test Generator Documentation
#################################################
Welcome to RISC-V Compatibility Test Generator documentation.
For information about the changes and additions for releases,
please refer to the :ref:`Revisions <revisions>` documentation.
.. toctree::
:glob:
:maxdepth: 1
:numbered:
overview
installation
cli
add_instr
code
contributing
revisions
licensing

View file

@ -0,0 +1,103 @@
.. See LICENSE.incore for details
.. _home:
RISC-V Compliance Test Generator Documentation
###############################################
Welcome to RISC-V Compliance Test Generator documentation version: |version|
For information about the changes and additions for releases,
please refer to the :ref:`Revisions <revisions>` documentation.
.. raw:: html
<ul class="grid">
<li class="grid-item">
<a href="overview.html">
<span class="grid-icon fa fa-info" aria-hidden="true"></span>
<h2>Overview</h2>
</a>
<p>Introduction</p>
</li>
<li class="grid-item">
<a href="getting_started.html">
<span class="grid-icon fa fa-angle-double-right" aria-hidden="true"></span>
<h2>Getting Started Guide</h2>
</a>
<p>Guide</p>
</li>
<li class="grid-item">
<a href="features.html">
<span class="grid-icon fa fa-puzzle-piece"></span>
<h2>Features</h2>
</a>
<p>Features</p>
</li>
<li class="grid-item">
<a href="tests.html">
<span class="grid-icon fa fa-line-chart"></span>
<h2>Tests</h2>
</a>
<p>Tests</p>
</li>
<li class="grid-item">
<a href="cli.html">
<span class="grid-icon fa fa-cogs"></span>
<h2>Options</h2>
</a>
<p>User Options</p>
</li>
<li class="grid-item">
<a href="https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg">
<span class="grid-icon fa fa-gitlab"></span>
<h2>Code Access</h2>
</a>
<p>The entire RISC-V Compliance Test Generator code is available on GitLab</p>
</li>
</ul>
.. include:: <isonum.txt>
.. only:: latex
.. note::
This document provides detailed information of the IPs generated and maintained by InCore
Semiconductors Pvt. Ltd.
**Proprietary Notice**
Copyright (c) 2020, InCore Semiconductors Pvt. Ltd.
Information in this document is provided "as is" with faults, if any.
InCore expressly disclaims all warranties, representations, and conditions of any kind, whether
express or implied, including, but not limited to, the implied warranties or conditions of
merchantability, fitness for a particular purpose and non-infringement.
InCore does not assume any liability rising out of the application or use of any product or circuit,
and specifically disclaims any and all liability, including without limitation indirect, incidental,
special, exemplary, or consequential damages.
InCore reserves the right to make changes without further notice to any products herein.
.. only:: html
Sections
********
.. toctree::
:glob:
:maxdepth: 1
:numbered:
overview
getting_started
features
installation
cli
tests
contriburing
revisions
licensing

View file

@ -0,0 +1,162 @@
.. See LICENSE.incore for details
.. highlight:: shell
============
Installation
============
Install Python
==============
.. tabs::
.. tab:: Ubuntu
Ubuntu 17.10 and 18.04 by default come with python-3.6.9 which is sufficient for using riscv-ctg.
If you are are Ubuntu 16.10 and 17.04 you can directly install python3.6 using the Universe
repository
.. code-block:: shell-session
$ sudo apt-get install python3.6
$ pip3 install --upgrade pip
If you are using Ubuntu 14.04 or 16.04 you need to get python3.6 from a Personal Package Archive
(PPA)
.. code-block:: shell-session
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt-get update
$ sudo apt-get install python3.6 -y
$ pip3 install --upgrade pip
You should now have 2 binaries: ``python3`` and ``pip3`` available in your $PATH.
You can check the versions as below
.. code-block:: shell-session
$ python3 --version
Python 3.6.9
$ pip3 --version
pip 20.1 from <user-path>.local/lib/python3.6/site-packages/pip (python 3.6)
.. tab:: CentOS7
The CentOS 7 Linux distribution includes Python 2 by default. However, as of CentOS 7.7, Python 3
is available in the base package repository which can be installed using the following commands
.. code-block:: shell-session
$ sudo yum update -y
$ sudo yum install -y python3
$ pip3 install --upgrade pip
For versions prior to 7.7 you can install python3.6 using third-party repositories, such as the
IUS repository
.. code-block:: shell-session
$ sudo yum update -y
$ sudo yum install yum-utils
$ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install python36u
$ pip3 install --upgrade pip
You can check the versions
.. code-block:: shell-session
$ python3 --version
Python 3.6.8
$ pip --version
pip 20.1 from <user-path>.local/lib/python3.6/site-packages/pip (python 3.6)
Using Virtualenv for Python
---------------------------
Many a times users face issues in installing and managing multiple python versions. This is actually
a major issue as many gui elements in Linux use the default python versions, in which case installing
python3.6 using the above methods might break other software. We thus advise the use of **pyenv** to
install python3.6.
For Ubuntu and CentosOS, please follow the steps here: https://github.com/pyenv/pyenv#basic-github-checkout
RHEL users can find more detailed guides for virtual-env here: https://developers.redhat.com/blog/2018/08/13/install-python3-rhel/#create-env
Once you have pyenv installed do the following to install python 3.6.0::
$ pyenv install 3.6.0
$ pip3 install --upgrade pip
$ pyenv shell 3.6.0
You can check the version in the **same shell**::
$ python --version
Python 3.6.0
$ pip --version
pip 20.1 from <user-path>.local/lib/python3.6/site-packages/pip (python 3.6)
Install RISC-V CTG (From Git)
=============================================================
To install RISC-V Compatibility Test Generator, run this command in your terminal:
.. code-block:: console
$ python3 -m pip3 install git+https://github.com/riscv/riscv-ctg.git
This is the preferred method to install RISC-V Compatibility Test Generator, as it will always install the most recent stable release.
If you don't have `pip`_ installed, this `Python installation guide`_ can guide
you through the process.
.. _pip: https://pip.pypa.io
.. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/
Install RISC-V CTG (via pip)
=====================================================
.. note:: If you are using `pyenv` as mentioned above, make sure to enable that environment before
performing the following steps.
.. code-block:: bash
$ pip3 install riscv_ctg
To update an already installed version of RISCV-CTG to the latest version:
.. code-block:: bash
$ pip3 install -U riscv_ctg
To checkout a specific version of riscv_ctg:
.. code-block:: bash
$ pip3 install riscv_ctg==1.x.x
Install CTG for Dev
===================
The sources for RISC-V Compatibility Test Generator can be downloaded from the `Github repo`_.
You can clone the repository:
.. code-block:: console
$ git clone https://github.com/riscv/riscv-ctg
Once you have a copy of the source, you can install it with:
.. code-block:: console
$ cd riscv_ctg
$ pip3 install --editable .
.. _Github repo: https://github.com/riscv/riscv-ctg

View file

@ -0,0 +1,10 @@
.. See LICENSE.incore for details
#####################
Licensing and Support
#####################
Please review the LICENSE.* files in the `repository <https://github.com/riscv/riscv-ctg>`_ for licensing details.
For more information about support, customization and other IP developments
please write to info@incoresemi.com.

View file

@ -0,0 +1,166 @@
.. See LICENSE.incore for details
########
Overview
########
RISCV-CTG is the RISC-V based Compatibility Test Generator. This tool is used to generate tests used in
the official `RISC-V Architectural Test Suite <https://github.com/riscv/riscv-compliance>`_ and
the RISC-V architectural test framework `RISCOF <https://riscof.readthedocs.io>`_. All tests generated by
the CTG are compliant with the official `Test Format Spec <https://riscof.readthedocs.io/en/latest/testformat.html>`_.
The CTG is similar to a constrained test generator capable of generating tests targeting a specific
set of constraints. These constraints are supplied to the CTG using the `Coverage Group Format
<https://riscv-isac.readthedocs.io/en/latest/cgf.html>`_ (CGF) File. The CGF file contains various
cover-points for different instructions. The CTG treats each cover-point as a constraint and employs a
solver to identify potential solutions. CTG uses the constraint satisfaction problem (CSPs) solvers
offered by the `python-constraint <https://pypi.org/project/python-constraint/>`_ package.
Target Audience
===============
The target users/audience of the CTG would be verification and design engineers who would like to
create a suite of tests focusing on covering specific corner cases. These tests could then be used
as way of demonstrating the capabilities of the instruction itself.
Note, that the capabilities of the CTG is completely limited by the limitations of the cover-points
in the CGF. A more elaborate CGF covering all corner cases of an instruction can be supplied to CTG
to create a near verification test for that instruction.
CTG Components and Flow
=======================
The following diagram shows the internal flow of data of the CTG. The following sections will
discuss briefly about the working of the CTG.
.. figure:: _static/riscv-ctg.png
:align: center
:alt: riscv-isac
.. _attributes:
Instr Attributes
----------------
In order to generate tests for a given instructions attributes of the instruction need to be known
before hand. This information is stored within the CTG in a YAML format known as the `attributes file
<https://github.com/riscv/riscv-ctg/riscv_ctg/data/template.yaml>`_.
Each node in the attributes files has the following structure:
.. code-block:: yaml
name: # name of the instruction
xlen: # list of XLEN values under which this instruction is applicable
isa: # RISC-V ISA extension this instruction attribute belongs to
operation: # a python evaluated string which defines the function of the instruction
formattype: # a string indicating the format type of the instruction
rs1_op_data: # a list of legal registers that can be used as operand 1
rs2_op_data: # a list of legal registers that can be used as operand 2
rd_op_data: # a list of legal registers that can be used as destination
rs1_val_data: # a list of integers that can be used as values for operand 1
rs2_val_data: # a list of integers that can be used as values for operand 2
template: # a string indicating the assembly macro to be used to creating tests.
Following is an example of the "add" instruction attribute
.. code-block:: yaml
add:
xlen: [32,64]
isa: I
operation: 'hex((rs1_val + rs2_val) & (2**(xlen)-1))'
formattype: 'rformat'
rs1_op_data: *all_regs
rs2_op_data: *all_regs
rd_op_data: *all_regs
rs1_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)'
rs2_val_data: 'gen_sign_dataset(xlen) + gen_sp_dataset(xlen,True)'
template: |
// $comment
// opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val
TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg)
Note in the above example `gen_sign_dataset(**)` and `gen_sp_dataset(**)` are custom functions
defined within the CTG to generate the relevant data points required for those fields.
.. note:: \*all_reg is an alias to a node defined in the attributes yaml prior to the add node.
.. _opval_comb:
Op and Val Combinations
-----------------------
The first two stages of the CTG receive the input CGF file and identify solutions for the
operands and value combinations. These solutions are carried out independent of each other. During
these phases solvers are employed to find solutions which satisfy the corresponding cover-points.
Immediate values are also assigned here.
If randomization is enabled, then random solvers are employed.
Instruction Creation
--------------------
In this stage, the operand and value combination solutions derived in the previous phases are combined with
each other in this phase to complete all the fields of the instruction under test.
Signature and Test Register Allocation
---------------------------------------
Each instance of the instruction should also be provided a signature register to save the result of
the operation and an additional test register to perform alternate target-specific checks or debug.
The registers are allocated in a greedy fashion, such that maximum number of instructions use the
same signature and test registers. This thus leads to minimal transfer of pointers across registers.
CorrectVal Generation
---------------------
.. warning:: This feature is a WIP and is not completely supported yet.
For a few arithmetic instructions like add, sll, sub, etc the corresponding operation field in the
:ref:`attributes <attributes>` YAML can be easily defined to capture the behavior of those
instructions. In this, phase CTG uses those fields to define the expected values/result of those
operations. These correctval fields in the tests can be used to perform inline checking of results
and debug failures.
Generate Tests
--------------
Finally, with all the fields defined, specific templates of the tests which conform to the Test
Format Spec are used to generate the assembly files for each instruction.
Parallel Runs
-------------
Since CTG employs CSP solvers the runtime of certain constraints involving large data sets can soon
shoot up. Also typically CTG is used to generate a suite of test across instructions instead of a
single test. Thus to reduce runtime in suite generations, CTG internally allocates a cover-group in
the CGF to an individual host-process thereby parallelizing the runs.
Why Random Solvers?
===================
The random solvers are essential in boosting speed. With loosely defined constraints in the CGF,
(like ``rs1_val >0 and rs2_val>0``) the solvers may spend quite some time to find all the solutions
when the datasets are large. Random solvers on the other hand provide the first solution that
satisfies the problem and quit after that, thereby saving time.
A second benefit of using random values for loosely defined constraints, is that it increases the
chances of covering multiple cover-points (that may be presented later) in the same instruction. This
thereby reduces the number of instructions required to cover all the cover-points mentioned in the
cover-group of the CGF.
One must note that at no point is the coverage of the test compromised due to the use of random
solvers.
A obvious down-side of using random solvers is the fact that the same test cannot be reproduced
again. However, the typical intent of users of CTG would be to generates tests satisfying the
cover-points defined in the CGF. Since that is guaranteed by CTG, the reproducibility issue can be
set aside.

View file

@ -0,0 +1,45 @@
********************************
Pseudo-Ops Support for RISCV-CTG
********************************
Coverpoints are defined in a CGF file under the ``opcode`` node in the CGF. This is a misnomer as ISAC and CTG
deals with mnemonics of the instruction rather than the actual encoding. In order to deal with mnemonics of pseudo-Ops,
and its congruent base instruction definition, changes are brought to the CGF format.
Format
######
The ``opcode`` field is renamed to ``mnemonics``. To support pseudo-instructions two new fields ``base_op`` and ``p_op_cond``
are added to the covergroups. The ``base_op`` and ``p_op_cond`` are optional fields which specify the base operation and the
condition over the different fields of the instruction which when satisfied results in the instruction being recognized as the
pseudo-op mentioned in ``mnemonics``. As an example, ``zext.h`` is a pseudo-op of ``pack`` in RV32 and ``packw`` in RV64 with ``rs2``
equal to ``x0``. Covergroup for ``zext.h`` pseudo-op can be expressed as follows: ::
zext.h_32:
config:
- check ISA:=regex(.*RV32.*B.*)
- check ISA:=regex(.*RV32.*Zbb.*)
mnemonics:
zext.h: 0
base_op: packw
p_op_cond: rs2 == x0
...
zext.h_64:
config:
- check ISA:=regex(.*RV64.*B.*)
- check ISA:=regex(.*RV64.*Zbb.*)
mnemonics:
zext.h: 0
base_op: pack
p_op_cond: rs2 == x0
...
During CTG runtime, the ``base_op`` field is checked for in every covergroup. The template corresponding to the instruction found
in ``base_op`` node is extracted to generate the test. If ``base_op`` node does not exist, the instruction found in ``mnemonics``
is used to extract the required template. ``p_op_cond`` fields are not used as additional constraints for the corresponding pseudo-op.
This is due to the assumption that test generation for a base-op encompasses all pseudo-ops associated with the base-op.
Note
####
- The ``p_op_cond`` node is relevant only if the ``base_op`` node has been defined.
- The ``mnemonics`` node is allowed to have multiple entries only if the ``base_op`` node is empty.

View file

@ -0,0 +1,19 @@
@article{riscvpriv,
author = {RISC-V ISA Privileged Specification},
year = {2020},
title = {},
journal = {https://riscv.org/specifications/privileged-isa/},
}
@article{riscv,
author = {RISC-V ISA Unprivileged Specification},
year = {2020},
title = {},
journal = {https://riscv.org/specifications/isa-spec-pdf/},
}
@article{riscvdebug,
author = {RISC-V ISA Debug Specification},
year = {2020},
title = {},
journal = {https://riscv.org/specifications/debug-specification/}
}

View file

@ -0,0 +1,7 @@
.. raw:: latex
\pagebreak
.. _revisions:
.. mdinclude:: ../../CHANGELOG.md

View file

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""
"""
from sphinx.errors import ExtensionError
from sphinx.locale import _
from sphinx.transforms.post_transforms.images import ImageConverter
from sphinx.util import logging
from sphinx.util.osutil import ENOENT, EPIPE, EINVAL
from cairosvg import svg2pdf
logger = logging.getLogger(__name__)
class CairoSvgConverter(ImageConverter):
conversion_rules = [
('image/svg+xml', 'application/pdf'),
]
def is_available(self):
# type: () -> bool
return True
def convert(self, _from, _to):
# type: (unicode, unicode) -> bool
"""Converts the image to expected one."""
svg2pdf(url=_from, write_to=_to)
return True
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_post_transform(CairoSvgConverter)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View file

@ -0,0 +1,27 @@
Metadata-Version: 2.1
Name: riscv-ctg
Version: 0.12.2
Summary: RISC-V CTG
Home-page: https://github.com/riscv/riscv-ctg
Author: InCore Semiconductors Pvt. Ltd.
Author-email: info@incoresemi.com
License: BSD-3-Clause
Keywords: riscv_ctg
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3.6
Classifier: License :: OSI Approved :: BSD License
Classifier: Development Status :: 4 - Beta
Requires-Python: >=3.6.0
License-File: LICENSE.incore
#################################################
**RISC-V Compliance Test Generator** : RISC-V CTG
#################################################
Latest documentation of riscv_ctg : `click here <https://riscv-ctg.readthedocs.io/en/latest>`_

View file

@ -0,0 +1,31 @@
LICENSE.incore
MANIFEST.in
README.rst
setup.cfg
setup.py
riscv_ctg/__init__.py
riscv_ctg/constants.py
riscv_ctg/cross_comb.py
riscv_ctg/csr_comb.py
riscv_ctg/ctg.py
riscv_ctg/dsp_function.py
riscv_ctg/function_generators.py
riscv_ctg/generator.py
riscv_ctg/helpers.py
riscv_ctg/log.py
riscv_ctg/main.py
riscv_ctg/requirements.txt
riscv_ctg/utils.py
riscv_ctg.egg-info/PKG-INFO
riscv_ctg.egg-info/SOURCES.txt
riscv_ctg.egg-info/dependency_links.txt
riscv_ctg.egg-info/entry_points.txt
riscv_ctg.egg-info/not-zip-safe
riscv_ctg.egg-info/requires.txt
riscv_ctg.egg-info/top_level.txt
riscv_ctg/data/fd.yaml
riscv_ctg/data/imc.yaml
riscv_ctg/data/template.yaml
riscv_ctg/env/arch_test.h
riscv_ctg/env/encoding.h
riscv_ctg/env/riscv-isac.code-workspace

View file

@ -0,0 +1,3 @@
[console_scripts]
riscv_ctg = riscv_ctg.main:cli

View file

@ -0,0 +1,5 @@
click
colorlog
python-constraint
riscv_isac>=0.14.0
ruamel.yaml>=0.16.0

View file

@ -0,0 +1,7 @@
# See LICENSE.incore for details
"""Top-level package for RISC-V Compliance Test Generator."""
__author__ = """InCore Semiconductors Pvt Ltd"""
__email__ = 'incorebot@gmail.com'
__version__ = '0.12.2'

View file

@ -0,0 +1,334 @@
# See LICENSE.incore for details
import os
from math import *
from string import Template
from riscv_isac.fp_dataset import *
root = os.path.abspath(os.path.dirname(__file__))
cwd = os.getcwd()
env = os.path.join(root,"env")
default_regset = ['x0' ,'x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9'
,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15' ,'x16' ,'x17' ,'x18' ,'x19'
,'x20' ,'x21' ,'x22' ,'x23' ,'x24' ,'x25' ,'x26' ,'x27' ,'x28' ,'x29'
,'x30' ,'x31']
default_fregset = ['f0' ,'f1' ,'f2' ,'f3' ,'f4' ,'f5' ,'f6' ,'f7' ,'f8' ,'f9'
,'f10' ,'f11' ,'f12' ,'f13' ,'f14' ,'f15' ,'f16' ,'f17' ,'f18' ,'f19'
,'f20' ,'f21' ,'f22' ,'f23' ,'f24' ,'f25' ,'f26' ,'f27' ,'f28' ,'f29'
,'f30' ,'f31']
e_regset = ['x0' ,'x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9'
,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15']
default_regset_mx0 = ['x1' ,'x2' ,'x3' ,'x4' ,'x5' ,'x6' ,'x7' ,'x8' ,'x9'
,'x10' ,'x11' ,'x12' ,'x13' ,'x14' ,'x15' ,'x16' ,'x17' ,'x18' ,'x19'
,'x20' ,'x21' ,'x22' ,'x23' ,'x24' ,'x25' ,'x26' ,'x27' ,'x28' ,'x29'
,'x30' ,'x31']
def sign_extend(value, bits):
sign_bit = 1 << (bits - 1)
return (value & (sign_bit - 1)) - (value & sign_bit)
def twos(val,bits):
'''
A function to generate the two's complement of a number which is of
arbitrary width
:param val: the input which can be either a hexadecimal string or integer
:param bits: size of the input in terms of bits.
:type val: Union[int, str]
:type bits: int
:return: integer value in 2's complement representation
'''
if isinstance(val,str):
if '0x' in val:
val = int(val,16)
else:
val = int(val,2)
if (val & (1 << (bits - 1))) != 0:
val = val - (1 << bits)
return val
def gen_imm_dataset(bit_width):
'''
Function to enumerate a dataset for immediate values:
- [0,2**bit_width]
:param bit_width: Integer defining the size of the input
:type bit_width: int
:return: a list of integers
'''
usign_val = (2**(bit_width))
dataset = []
for i in range(usign_val):
dataset.append(i)
return dataset
def gen_sp_dataset(bit_width,sign=True):
'''
Function generates a special dataset of interesting values:
- [3*1/3,3*2/3,5,5*1/5,5*2/5]
- sqrt (bit_width<<1)
- +/-1 variants of the above
:param bit_width: Integer defining the size of the input
:param sign: Boolen value specifying whether the dataset should be interpreted as signed numbers or not.
:type sign: bool
:type bit_width: int
:return: a list of integers
'''
if sign:
conv_func = lambda x: twos(x,bit_width)
sqrt_min = int(-sqrt(2**(bit_width-1)))
sqrt_max = int(sqrt((2**(bit_width-1)-1)))
else:
sqrt_min = 0
sqrt_max = int(sqrt((2**bit_width)-1))
conv_func = lambda x:(int(x,16) if '0x' in x else int(x,2)) if isinstance(x,str) else x
dataset = [3, "0x"+"".join(["5"]*int(bit_width/4)), "0x"+"".join(["a"]*int(bit_width/4)), 5, "0x"+"".join(["3"]*int(bit_width/4)), "0x"+"".join(["6"]*int(bit_width/4))]
dataset = list(map(conv_func,dataset)) + [int(sqrt(abs(conv_func("0x8"+"".join(["0"]*int((bit_width/4)-1)))))*(-1 if sign else 1))] + [sqrt_min,sqrt_max]
return dataset + [x - 1 if x > 0 else 0 for x in dataset] + [x+1 for x in dataset]
# def gen_fp_dataset(flen,instr,field):
# return (ibm_dataset(flen,instr,field)) # Dataset will be returned by isac
def gen_sign_dataset(bit_width):
'''
Function to generate the signed data set with datapoints from the following patterns.
- alternating ones
- alternating zeros
- walking ones
- walking zeros
- max val
- min val
- max val/2
- min val/2
- [-10,10]
:param bit_width: integer defining the size of the input
:type bit_width: int
:return: a list of integers
'''
rval_w0_base = ['1']*(bit_width-1)+['0']
rval_w1_base = ['0']*(bit_width-1)+['1']
data = [(-2**(bit_width-1)),int((-2**(bit_width-1))/2),0,(2**(bit_width-1)-1),int((2**(bit_width-1)-1)/2)] + list(range(-10,10))
data += [twos(''.join(rval_w1_base[n:] + rval_w1_base[:n]),bit_width) for n in range(bit_width)]
data += [twos(''.join(rval_w0_base[n:] + rval_w0_base[:n]),bit_width) for n in range(bit_width)]
t1 =( '' if bit_width%2 == 0 else '1') + ''.join(['01']*int(bit_width/2))
t2 =( '' if bit_width%2 == 0 else '0') + ''.join(['10']*int(bit_width/2))
data += [twos(t1,bit_width),twos(t2,bit_width)]
return list(set(data))
def gen_usign_dataset(bit_width):
'''
Function to generate the unsigned dataset
- alternating ones
- alternating zeros
- walking ones
- walking zeros
- max val
- min val
- max val/2
- min val/2
- [0,20]
:param bit_width: integer defining the size of the input
:type bit_width: int
:return: a list of integers
'''
rval_w0_base = ['1']*(bit_width-1)+['0']
rval_w1_base = ['0']*(bit_width-1)+['1']
data = [0,((2**bit_width)-1),int(((2**bit_width)-1)/2)] + list(range(0,20))
data += [int(''.join(rval_w1_base[n:] + rval_w1_base[:n]),2) for n in range(bit_width)]
data += [int(''.join(rval_w0_base[n:] + rval_w0_base[:n]),2) for n in range(bit_width)]
t1 =( '' if bit_width%2 == 0 else '1') + ''.join(['01']*int(bit_width/2))
t2 =( '' if bit_width%2 == 0 else '0') + ''.join(['10']*int(bit_width/2))
data += [int(t1,2),int(t2,2)]
return list(set(data))
def zerotoxlen(bit_width):
vals = []
for i in range(bit_width):
vals.append(i)
return vals
def gen_bitmanip_dataset(bit_width,sign=True):
'''
Function generates a special dataset of interesting values for bitmanip:
0x0, 0x3, 0xc, 0x5,0xa,0x6,0x9 each of the pattern exenteding for bit_width
for 32 bit
0x33333333,0xcccccccc,0x55555555, 0xaaaaaaaaa,0x66666666,0x99999999
for 64 bit
0x3333333333333333,0xcccccccccccccccc,0x5555555555555555, 0xaaaaaaaaaaaaaaaaa,
0x6666666666666666,0x9999999999999999
- +1 and -1 variants of the above pattern
:param bit_width: Integer defining the size of the input
:param sign: Boolen value specifying whether the dataset should be interpreted as signed numbers or not.
:type sign: bool
:type bit_width: int
:return: a list of integers
'''
if sign:
conv_func = lambda x: twos(x,bit_width)
else:
conv_func = lambda x:(int(x,16) if '0x' in x else int(x,2)) if isinstance(x,str) else x
# dataset for 0x5, 0xa, 0x3, 0xc, 0x6, 0x9 patterns
dataset = ["0x"+"".join(["5"]*int(bit_width/4)), "0x"+"".join(["a"]*int(bit_width/4)), "0x"+"".join(["3"]*int(bit_width/4)), "0x"+"".join(["6"]*int(bit_width/4)),"0x"+"".join(["9"]*int(bit_width/4)),"0x"+"".join(["c"]*int(bit_width/4))]
dataset = list(map(conv_func,dataset))
# dataset0 is for 0,1 and 0xf pattern. 0xf pattern is added instead of -1 so that code for checking coverpoints in coverage.py
# is kept simple.
dataset0 = [0,1,"0x"+"".join(["f"]*int(bit_width/4))]
dataset0 = list(map(conv_func,dataset0))
# increment each value in dataset, increment each value in dataset, add them to the dataset
return dataset + [x - 1 for x in dataset] + [x+1 for x in dataset] + dataset0
template_fnames = ["template.yaml","imc.yaml","fd.yaml"]
template_files = [os.path.join(root,"data/"+f) for f in template_fnames]
usage = Template('''
// -----------
// This file was generated by riscv_ctg (https://github.com/riscv-software-src/riscv-ctg)
// version : $version
// timestamp : $time
// usage : riscv_ctg \\
// -- cgf $cgf \\
// -- xlen $xlen $randomize \\
// -----------
//''')
copyright_string = '''
// -----------
// Copyright (c) 2020. RISC-V International. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
// -----------
//'''
comment_template = '''
// This assembly file tests the $opcode instruction of the RISC-V $extension extension for the $label covergroup.
// '''
cross_comment_template = '''
// This assembly file is used for the test of cross-combination coverpoint described in $label covergroup.
'''
csr_comb_comment_template = '''
// This assembly file is used for the test of CSR-combination coverpoint described in $label covergroup.
'''
test_template = Template(copyright_string + comment_template+'''
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("$isa")
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
$test
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
$data
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;
$sig
sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
''')
cross_test_template = Template(copyright_string + cross_comment_template+'''
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("$isa")
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
$test
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
$data
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
$sig
RVMODEL_DATA_END
''')
csr_comb_test_template = Template(copyright_string + csr_comb_comment_template + '''
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("$isa")
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
$test
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
$data
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
$sig
RVMODEL_DATA_END
''')
case_template = Template('''
RVTEST_CASE($num,"//$cond;def TEST_CASE_1=True;",$cov_label)
''')
part_template = Template('''
#ifdef TEST_CASE_1
$case_str
$code
#endif
''')
signode_template = Template('''
$label:
.fill $n*$sz,4,0xdeadbeef
''')
csr_reg_write_to_field_template = Template('''
WRITE_TO_CSR_FIELD_W_MASK($csr_reg, $restore_reg, $temp_reg1, $temp_reg2, $mask, $val)
''')
csr_reg_read_and_sig_upd_template = Template('''
READ_CSR_REG_AND_UPD_SIG($csr_reg, $dest_reg, $offset, $base_reg)
''')
csr_reg_restore_template = Template('''
RESTORE_CSR_REG($csr_reg, $restore_reg)
''')

View file

@ -0,0 +1,501 @@
# See LICENSE.incore for details
import random
from constraint import *
import riscv_isac.utils as isac_utils
from riscv_ctg import constants
import riscv_ctg.utils as utils
import riscv_ctg.constants as const
from riscv_ctg.constants import *
from riscv_ctg.log import logger
from riscv_ctg.__init__ import __version__
from riscv_ctg.generator import OPS
from riscv_ctg.dsp_function import *
INSTR_FORMAT = {
'rformat' : '$instr $rd, $rs1, $rs2',
'iformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)',
'sformat' : '$instr $rs2, $imm_val($rs1)',
'bsformat' : '$instr $rd, $rs2, $imm_val',
'bformat' : '$instr $rs1, $rs2, $label',
'uformat' : '$instr $rd, $imm_val',
'jformat' : '$instr $rd, $imm',
'crformat' : '$instr $rs1 $rs2',
'cmvformat' : '$instr $rd, $rs2',
'ciformat' : '$instr $rd, $imm_val',
'cssformat' : '$instr $rs2, $imm_val($rs1)',
'ciwformat' : '$instr $rd, x2, $imm_val',
'clformat' : '$instr $rd, $imm_val($rs1)',
'csformat' : '$instr $rs2, $imm_val($rs2)',
'caformat' : '$instr',
'cbformat' : '$instr',
'cjformat' : '$instr',
'kformat' : '$instr',
'frformat' : '$instr $rd, $rs1, $rs2',
'fsrformat' : '$instr $rd, $rs1',
'fr4format' : '$instr $rd, $rs1, $rs2, $rs3',
'pbrrformat' : '$instr $rd, $rs1, $rs2',
'phrrformat' : '$instr $rd, $rs1, $rs2',
'pbrformat' : '$instr $rd, $rs1',
'phrformat' : '$instr $rd, $rs1',
'pbriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)' ,
'phriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)',
'psbrrformat' : '$instr $rd, $rs1, $rs2',
'pshrrformat' : '$instr $rd, $rs1, $rs2',
'pwrrformat' : '$instr $rd, $rs1, $rs2',
'pwriformat' : '$instr $rd, $rs1, SEXT_IMM($imm_val)' ,
'pwrformat' : '$instr $rd, $rs1',
'pswrrformat' : '$instr $rd, $rs1, $rs2',
'pwhrrformat' : '$instr $rd, $rs1, $rs2',
'pphrrformat' : '$instr $rd, $rs1, $rs2',
'ppbrrformat' : '$instr $rd, $rs1, $rs2',
'prrformat' : '$instr ',
'prrrformat' : '$instr',
'dcasrformat' : '$instr '
}
'''Dictionary to store instruction formats'''
REG_INIT = {
'x1' : 'LI (x1, (0xFEEDBEADFEEDBEAD & MASK))',
'x2' : 'LI (x2, (0xFF76DF56FF76DF56 & MASK))',
'x3' : 'LI (x3, (0x7FBB6FAB7FBB6FAB & MASK))',
'x4' : 'LI (x4, (0xBFDDB7D5BFDDB7D5 & MASK))',
'x5' : 'LI (x5, (0xAB7FFB6FAB7FBB6F & MASK))',
'x6' : 'LI (x6, (0x6FAB71BB6F7B7FBB & MASK))',
'x7' : 'LI (x7, (0xB7FBB6FAB7FBB6FA & MASK))',
'x8' : 'LI (x8, (0x5BFDDB7D5BFDDB7D & MASK))',
'x9' : 'LI (x9, (0xADFEEDBEADFEEDBE & MASK))',
'x10' : 'LI (x10, (0x56FF76DF56FF76DF & MASK))',
'x11' : 'LI (x11, (0xAB7FBB6FAB7FBB6F & MASK))',
'x12' : 'LI (x12, (0xD5BFDDB7D5BFDDB7 & MASK))',
'x13' : 'LI (x13, (0xEADFEEDBEADFEEDB & MASK))',
'x14' : 'LI (x14, (0xF56FF76DF56FF76D & MASK))',
'x15' : 'LI (x15, (0xFAB7FBB6FAB7FBB6 & MASK))',
'x16' : 'LI (x16, (0x7D5BFDDB7D5BFDDB & MASK))',
'x17' : 'LI (x17, (0xBEADFEEDBEADFEED & MASK))',
'x18' : 'LI (x18, (0xDF56FF76DF56FF76 & MASK))',
'x19' : 'LI (x19, (0x6FAB7FBB6FAB7FBB & MASK))',
'x20' : 'LI (x20, (0xB7D5BFDDB7D5BFDD & MASK))',
'x21' : 'LI (x21, (0xDBEADFEEDBEADFEE & MASK))',
'x22' : 'LI (x22, (0x6DF56FF76DF56FF7 & MASK))',
'x23' : 'LI (x23, (0xB6FAB7FBB6FAB7FB & MASK))',
'x24' : 'LI (x24, (0xDB7D5BFDDB7D5BFD & MASK))',
'x25' : 'LI (x25, (0xEDBEADFEEDBEADFE & MASK))',
'x26' : 'LI (x26, (0x76DF56FF76DF56FF & MASK))',
'x27' : 'LI (x27, (0xBB6FAB7FBB6FAB7F & MASK))',
'x28' : 'LI (x28, (0xDDB7D5BFDDB7D5BF & MASK))',
'x29' : 'LI (x29, (0xEEDBEADFEEDBEADF & MASK))',
'x30' : 'LI (x30, (0xF76DF56FF76DF56F & MASK))',
'x31' : 'LI (x31, (0xFBB6FAB7FBB6FAB7 & MASK))',
}
''' Initial values for general purpose and floating point registers'''
class cross():
'''
A cross class to genereate RISC-V assembly tests for cross-combination coverpoints.
'''
def __init__(self, base_isa_str, xlen_in, randomize, label):
global xlen
global flen
global base_isa
# Template dictionary
self.OP_TEMPLATE = utils.load_yamls(const.template_files)
xlen = xlen_in
base_isa = base_isa_str
self.randomize = randomize
self.label = label
# Flag if floating point instructions are chosen
self.if_fp = False
def cross_comb(self, cgf_node):
'''
This function finds solution for various cross-combinations defined by the coverpoints
in the CGF under the `cross_comb` node of the covergroup.
'''
logger.debug('Generating CrossComb')
full_solution = []
if 'cross_comb' in cgf_node:
cross_comb = set(cgf_node['cross_comb'])
else:
return
isa_set = []
# Generate register file and variables
reg_file = const.default_regset
for each in reg_file:
exec(f"{each} = '{each}'")
dntcare_instrs = isac_utils.import_instr_alias(base_isa + '_arith') + isac_utils.import_instr_alias(base_isa + '_shift')
# This function retrieves available operands in a string
def get_oprs(opr_str):
opr_lst = []
if opr_str.find('rd') != -1:
opr_lst.append('rd')
if opr_str.find('rs1') != -1:
opr_lst.append('rs1')
if opr_str.find('rs2') != -1:
opr_lst.append('rs2')
if opr_str.find('rs3') != -1:
opr_lst.append('rs3')
return opr_lst
# Add conditions mentioned in the condition list in the cross-comb coverpoint
def add_cond(local_var):
def eval_conds(*oprs_lst):
i = 0
for opr in oprs:
exec(opr + "='" + oprs_lst[i] + "'", local_var)
i = i + 1
return eval(cond, locals(), local_var)
return eval_conds
solution = []
for each in cross_comb:
solution = []
# Parse cross-comb coverpoint
parts = each.split('::')
data = parts[0].replace(' ', '')[1:-1].split(':')
assgn_lst = parts[1].replace(' ', '')[1:-1].split(':')
cond_lst = parts[2].lstrip().rstrip()[1:-1].split(':')
# Initialize CSP
problem = Problem()
for i in range(len(data)):
if data[i] == '?':
# When instruction is not specified,
# - Gather conditions and assigngments if any and list requisite operands
# - Choose instruction from base instruction set based on operands
# - Based on conditions, choose operand values. Choose immediate value if required
# - Evaluate assignments
# Get corresponding conditions and accordingly chose instruction
cond = cond_lst[i]
assgn = assgn_lst[i]
if cond.find('?') != -1: # Don't care condition
# Check variables in assignment list and generate required operand list
opr_lst = get_oprs(assgn)
# Get possible instructions based on the operand list
problem.reset()
problem.addVariable('i', dntcare_instrs)
problem.addConstraint(lambda i: all(item in OPS[self.OP_TEMPLATE[i]['formattype']] for item in opr_lst))
instrs_sol = problem.getSolutions()
instrs_sol = [list(each.items())[0][1] for each in instrs_sol]
else: # If condition is specified
opr_lst = []
# Extract required operands from condition list
opr_lst += get_oprs(cond)
# Extract required operands from assignment list
opr_lst += get_oprs(assgn)
# Remove redundant operands
opr_lst = list(set(opr_lst))
# Get possible instructions
problem.reset()
problem.addVariable('i', dntcare_instrs)
problem.addConstraint(lambda i: all(item in OPS[self.OP_TEMPLATE[i]['formattype']] for item in opr_lst))
instrs_sol = problem.getSolutions()
instrs_sol = [list(each.items())[0][1] for each in instrs_sol]
# Randomly choose an instruction
instr = random.choice(instrs_sol)
isa_set += (self.OP_TEMPLATE[instr]['isa'])
# Choose operand values
formattype = self.OP_TEMPLATE[instr]['formattype']
oprs = OPS[formattype]
instr_template = self.OP_TEMPLATE[instr]
# Choose register values
problem.reset()
for opr in oprs:
opr_dom = instr_template[opr + '_op_data']
problem.addVariable(opr, eval(opr_dom))
# Since rd = x0 is a trivial operation, it has to be excluded
if 'rd' in oprs:
# exclude zeros
def exc_rd_zero(*oprs_lst):
pos = oprs.index('rd')
if oprs_lst[pos] == 'x0':
return False
return True
problem.addConstraint(exc_rd_zero, oprs)
# Add additional contraints if any
if cond.find('?') != -1:
opr_sols = problem.getSolutions()
else:
local_vars = locals()
problem.addConstraint(add_cond(local_vars), oprs)
opr_sols = problem.getSolutions()
opr_vals = random.choice(opr_sols)
# Assign operand values to operands
for opr, val in opr_vals.items():
exec(opr + "='" + val + "'")
# Generate immediate value if required
if 'imm_val_data' in instr_template:
imm_val = eval(instr_template['imm_val_data'])
opr_vals['imm_val'] = random.choice(imm_val)
# Get assignments if any and execute them
if assgn_lst[i] != '?':
assgns = assgn_lst[i].split(';')
for each in assgns:
exec(each)
# Set floating point flag if instruction belongs to F or D extension
if instr[0] == 'f' and instr != 'fence':
self.if_fp = True
opr_vals['instr'] = instr
solution += [opr_vals]
else:
# When instruction(s)/alias is specified,
# - If an instruction is specified, operands are directly extracted and assigned values according to conditions
# - If a tuple of instructions is specified, one of the instruction is chosen at random
# - If an alias is specified, the alias is already substituted by its equivalent tuple of instructions at this point
# through expand_cgf method.
# - Immediate values are generated if required
# - Assignments are evaluated
cond = cond_lst[i]
assgn = assgn_lst[i]
# Gather required operands
opr_lst = get_oprs(cond)
opr_lst += get_oprs(assgn)
opr_lst = list(set(opr_lst))
if data[i] in self.OP_TEMPLATE: # If single instruction
instr = data[i]
else:
if data[i].find('(') != -1: # If data is a tuple of instructions
instrs_sol = data[i][1:-1].split(',')
instr = random.choice(instrs_sol)
else:
logger.error('Invalid instruction/alias in cross_comb: ' + data[i])
# Gather operands
formattype = self.OP_TEMPLATE[instr]['formattype']
oprs = OPS[formattype]
instr_template = self.OP_TEMPLATE[instr]
problem.reset()
for opr in oprs:
opr_dom = instr_template[opr + '_op_data']
problem.addVariable(opr, eval(opr_dom))
# Since rd = x0 is a trivial operation, it has to be excluded
if 'rd' in oprs:
# exclude zeros
def exc_rd_zero(*oprs_lst):
pos = oprs.index('rd')
if oprs_lst[pos] == 'x0':
return False
return True
problem.addConstraint(exc_rd_zero, oprs)
# Assign values to operands
if cond.find('?') != -1:
opr_sols = problem.getSolutions()
else:
local_vars = locals()
problem.addConstraint(add_cond(local_vars), oprs)
opr_sols = problem.getSolutions()
# Get operand values
opr_vals = random.choice(opr_sols)
# Assign operand values to operands
for opr, val in opr_vals.items():
exec(opr + "='" + val + "'")
# Generate immediate value if required
if 'imm_val_data' in instr_template:
imm_val = eval(instr_template['imm_val_data'])
opr_vals['imm_val'] = random.choice(imm_val)
# Execute assignments
# Get assignments if any and execute them
if assgn_lst[i] != '?':
assgns = assgn_lst[i].split(';')
for each in assgns:
exec(each)
isa_set += (self.OP_TEMPLATE[instr]['isa'])
# Set floating point flag if instruction belongs to F or D extension
if instr[0] == 'f' and instr != 'fence':
self.if_fp = True
opr_vals['instr'] = instr
solution += [opr_vals]
full_solution += [solution]
self.isa = list(set(isa_set))
return full_solution
def swreg(cross_comb_instrs):
'''
This function generates the register which can be used as a signature pointer for each instruction.
It also generates the register which stores the value used by floating point registers
'''
global base_isa
op_vals = {'x0'}
for instr_dict in cross_comb_instrs:
for key, val in instr_dict.items():
if key != 'instr' and key != 'imm_val':
op_vals.add(val)
swreg_sol = set(['x'+str(x) for x in range(0,32 if 'e' not in base_isa else 16)]) - op_vals
sreg = random.choice(list(swreg_sol))
freg_Sol = swreg_sol - set(sreg)
freg = random.choice(list(freg_Sol))
return (sreg, freg)
def get_reginit_str(cross_comb_instrs, freg):
'''
This function fetches the register initlialization macro to initialize
used destination instructions after the cross-coverpoint instruction sequence
generation
Input argument:
- cross_comb_instrs type: list(dict()) Holds info of various instructions in the sequence
Return:
- List of initialization strings
'''
reg_init_lst = set()
for instr_dict in cross_comb_instrs:
if 'rd' in instr_dict:
rd_val = instr_dict['rd']
if rd_val[0] == 'f':
freg_init = REG_INIT[freg].replace('& MASK', '>> FREGWIDTH')
reg_init_lst.add(freg_init + '\n' + 'FLREG ' + rd_val + ', 0(' + freg + ')')
else:
reg_init_lst.add(REG_INIT[instr_dict['rd']])
return list(reg_init_lst)
def write_test(self, fprefix, cgf_node, usage_str, cov_label, full_solution):
'''
Generate instruction sequence and write them into an assembly file
#TODO Initialization of floating point registers
#TODO Handling loads/stores and branches in the sequence
'''
global base_isa
code = '\n'
data = [".align 4","rvtest_data:",".word 0xbabecafe", \
".word 0xabecafeb", ".word 0xbecafeba", ".word 0xecafebab"]
sig = ['']
sreg_dict = dict()
# If floating point instructions are available
if self.if_fp:
code += "RVTEST_FP_ENABLE()"
# Generate ISA and extension string
extension = ""
rvxlen = "RV"+str(xlen)
op_node_isa = ",".join([rvxlen + isa for isa in self.isa])
op_node_isa = op_node_isa.replace("I","E") if 'e' in base_isa else op_node_isa
extension = op_node_isa.replace('I',"").replace('E',"")
# Handle solutions related to each cross combination coverpoint
for cross_sol in full_solution:
# Designate signature update register
(sreg, freg) = cross.swreg(cross_sol)
# Designate count of sreg for signature label generation
if sreg not in sreg_dict:
sreg_dict[sreg] = 0
else:
count = sreg_dict[sreg] + 1
sreg_dict[sreg] = count
sig_label = "signature_" + sreg + "_" + str(sreg_dict[sreg])
code = code + "\nRVTEST_SIGBASE(" + sreg + ", "+ sig_label + ")\n\n"
rd_lst = set()
# Generate instruction corresponding to each instruction dictionary
# Append signature update statements to store rd value after each instruction
code += '// Cross-combination test sequence\n'
for each in cross_sol:
if 'rd' in each:
rd_lst.add(each['rd'])
instr_str_format = Template(INSTR_FORMAT[self.OP_TEMPLATE[each['instr']]['formattype']])
instr_str = instr_str_format.substitute(each)
code = code + instr_str + '\n'
# Append .fill assembly directives to initialize signature regions
sig.append(signode_template.safe_substitute(label = sig_label, n = len(rd_lst)))
offset = 0
code += '\n// Store destination register values in the test signature region\n'
# Add signature update statement(s) for unique number of rds
for rd in rd_lst:
if rd[0] == 'f':
sig_upd = f'RVTEST_SIGUPD_F({sreg}, {rd}, {offset})'
else:
sig_upd = f'RVTEST_SIGUPD({sreg}, {rd}, {offset})'
offset = offset + int(xlen/8)
code = code + sig_upd + '\n'
# Initialize registers for next cross-comb coverpoint
code = code + '\n// Initialize used registers\n' + '\n'.join(cross.get_reginit_str(cross_sol, freg)) + '\n'
case_str = ''.join([case_template.safe_substitute(xlen = xlen,num = i, cond = cond, cov_label = cov_label) for i, cond in enumerate(cgf_node['config'])])
test = part_template.safe_substitute(case_str = case_str, code = code)
# Write test to file
with open(fprefix + '_cross-comb.S', 'w') as fp:
fp.write(usage_str + const.cross_test_template.safe_substitute(opcode = cov_label,
isa = op_node_isa,
test = test,
data = '\n'.join(data),
sig = '\n'.join(sig),
label = cov_label,
extension = extension
)
)

View file

@ -0,0 +1,425 @@
# See LICENSE.incore for details
import re
import functools
from riscv_ctg.log import logger
from riscv_ctg.constants import *
import tokenize as tkn
from io import BytesIO
OPS = ['not', 'and', 'or']
OP_PRIORITY = {
'not': -1,
'and': -2,
'or' : -3,
}
CSR_REGS = ['mvendorid', 'marchid', 'mimpid', 'mhartid', 'mstatus', 'misa', 'medeleg', 'mideleg', 'mie', 'mtvec', 'mcounteren', 'mscratch', 'mepc', 'mcause', 'mtval', 'mip', 'pmpcfg0', 'pmpcfg1', 'pmpcfg2', 'pmpcfg3', 'mcycle', 'minstret', 'mcycleh', 'minstreth', 'mcountinhibit', 'tselect', 'tdata1', 'tdata2', 'tdata3', 'dcsr', 'dpc', 'dscratch0', 'dscratch1', 'sstatus', 'sedeleg', 'sideleg', 'sie', 'stvec', 'scounteren', 'sscratch', 'sepc', 'scause', 'stval', 'sip', 'satp', 'vxsat', 'fflags', 'frm', 'fcsr', 'CSR_SRMCFG']
csr_regs_capture_group = f'({"|".join(CSR_REGS)})'
csr_regs_with_modifiers_capture_group = r'(write|old) *\( *"' + csr_regs_capture_group + r'" *\)'
csr_comb_covpt_regex_strings = [
csr_regs_capture_group + r' *& *([^ ].*)== *([^ ].*)', # regular
r'\( *' + csr_regs_capture_group + r' *(>>|<<) *([^ ].*)\) *& *([^ ].*)== *([^ ].*)', # with bitshifts only
csr_regs_with_modifiers_capture_group + r' *& *([^ ].*)== *([^ ].*)', # with modifiers only
r'\( *' + csr_regs_with_modifiers_capture_group + r' *(>>|<<) *([^ ].*)\) *& *([^ ].*)== *([^ ].*)', # with bitshifts and modifiers
]
csr_comb_covpt_regexes = [re.compile(regex_string) for regex_string in csr_comb_covpt_regex_strings]
def tokenize(s):
result = []
g = tkn.tokenize(BytesIO(s.encode('utf-8')).readline)
for tok_num, tok_val, _, _, _ in g:
if tok_num in [tkn.ENCODING, tkn.NEWLINE, tkn.ENDMARKER]:
continue
result.append((tok_num, tok_val))
return result
def untokenize(tokens):
return tkn.untokenize(tokens)
# a dummy class acting as an interface for boolean expressions
class BooleanExpression:
def SAT(self):
# returns the complete list of solutions for this expression's satisfiability
# a single solution is a tuple of two lists:
# - the literals in the first list must evaluate to true
# - the literals in the second list must evaluate to false
raise Exception("not implemented")
def __str__(self):
raise Exception("not implemented")
class NotExpression(BooleanExpression):
def __init__(self, operand):
self.operand = operand
def SAT(self):
return [(operand_f, operand_t) for operand_t, operand_f in self.operand.SAT()]
def __str__(self):
return f'not ({str(self.operand)})'
class AndExpression(BooleanExpression):
def __init__(self, lhs, rhs):
self.lhs = lhs
self.rhs = rhs
def SAT(self):
return [(lhs_t + rhs_t, lhs_f + rhs_f) for lhs_t, lhs_f in self.lhs.SAT() for rhs_t, rhs_f in self.rhs.SAT()]
def __str__(self):
return f'({str(self.lhs)}) and ({str(self.rhs)})'
class OrExpression(BooleanExpression):
def __init__(self, lhs, rhs):
self.lhs = lhs
self.rhs = rhs
def SAT(self):
lhs_SAT = self.lhs.SAT()
rhs_SAT = self.rhs.SAT()
sols = []
for lhs_t, lhs_f in lhs_SAT:
for rhs_t, rhs_f in rhs_SAT:
sols.extend([
(lhs_t + rhs_f, lhs_f + rhs_t),
(lhs_f + rhs_t, lhs_t + rhs_f),
(lhs_t + rhs_t, lhs_f + rhs_f),
])
return sols
def __str__(self):
return f'({str(self.lhs)}) or ({str(self.rhs)})'
class LiteralExpression(BooleanExpression):
def __init__(self, val):
self.val = val
def SAT(self):
return [([self.val], [])]
def __str__(self):
return str(self.val)
# This function parses coverpoints for the CSR-combination node
# The coverpoints are assumed of the form: multiple condition clauses combined with and's and or's
# A coverpoint condition clause is assumed of the form: 'csr_reg & mask == val' or '(csr_reg >> shift) & mask == val'
def parse_csr_covpt(covpt):
toks = tokenize(covpt)
bracket_depth = 0
clause_depths = []
for tok_num, tok_val in toks:
if tok_val == '(':
bracket_depth += 1
elif tok_val == ')':
bracket_depth -= 1
elif tok_val == '==':
clause_depths.append(bracket_depth)
bracket_depth = 0
operator_stack = []
clause_stack = []
clause_index = 0
current_clause = []
current_clause_depth = clause_depths[clause_index]
for tok_num, tok_val in toks:
if tok_val == '(':
bracket_depth += 1
if bracket_depth > current_clause_depth:
current_clause.append((tok_num, tok_val))
else:
operator_stack.append('(')
elif tok_val == ')':
bracket_depth -= 1
if current_clause:
if bracket_depth < current_clause_depth:
clause_stack.append(LiteralExpression(untokenize(current_clause)))
while operator_stack[-1] != '(':
op = operator_stack.pop()
if op == 'not':
operand = clause_stack.pop()
clause_stack.append(NotExpression(operand))
else:
rhs = clause_stack.pop()
lhs = clause_stack.pop()
clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs))
operator_stack.pop()
current_clause = []
clause_index += 1
if (clause_index >= len(clause_depths)):
break
current_clause_depth = clause_depths[clause_index]
else:
current_clause.append((tok_num, tok_val))
else:
while operator_stack[-1] != '(':
op = operator_stack.pop()
if op == 'not':
operand = clause_stack.pop()
clause_stack.append(NotExpression(operand))
else:
rhs = clause_stack.pop()
lhs = clause_stack.pop()
clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs))
operator_stack.pop()
elif tok_val in OPS:
if current_clause:
clause_stack.append(LiteralExpression(untokenize(current_clause)))
current_clause = []
clause_index += 1
current_clause_depth = clause_depths[clause_index]
# prioritize not over and over or
while len(operator_stack) > 0 and operator_stack[-1] in OPS and OP_PRIORITY[operator_stack[-1]] > OP_PRIORITY[tok_val]:
op = operator_stack.pop()
if op == 'not':
operand = clause_stack.pop()
clause_stack.append(NotExpression(operand))
else:
rhs = clause_stack.pop()
lhs = clause_stack.pop()
clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs))
operator_stack.append(tok_val)
else:
current_clause.append((tok_num, tok_val))
if current_clause:
clause_stack.append(LiteralExpression(untokenize(current_clause)))
while len(operator_stack) > 0:
op = operator_stack.pop()
if op == 'not':
operand = clause_stack.pop()
clause_stack.append(NotExpression(operand))
else:
rhs = clause_stack.pop()
lhs = clause_stack.pop()
clause_stack.append(AndExpression(lhs, rhs) if op == 'and' else OrExpression(lhs, rhs))
bool_expr = clause_stack.pop()
return bool_expr
# This function extracts the csr register, the field mask, the field value and the csr register modifier (if present) from the coverpoint clause
# The coverpoint clause is assumed of the format: 'csr_reg & mask == val' or '(csr_reg >> shift) & mask == val'
# Modifiers `old()` and `write()` are also allowed on the `csr_reg`s. Example: `old("csr_reg") & mask == val`
# csr_reg must be a valid csr register; mask and val are allowed to be valid python expressions
def get_csr_mask_val_modifier(clause, instr_dict={}):
clause = clause.strip()
for i, regex in enumerate(csr_comb_covpt_regexes):
regex_match = regex.match(clause)
if regex_match is not None:
if i == 0: # regular covpt
csr_reg, mask_expr, val_expr = regex_match.groups()
mask = eval(mask_expr, {}, instr_dict)
val = eval(val_expr, {}, instr_dict)
return csr_reg, mask, val, None
elif i == 1: # with bitshifts only
csr_reg, shift_op, shift_expr, mask_expr, val_expr = regex_match.groups()
shift = eval(shift_expr, {}, instr_dict)
mask = eval(mask_expr, {}, instr_dict)
val = eval(val_expr, {}, instr_dict)
if shift_op == '>>':
mask = mask << shift
val = val << shift
else:
mask = mask >> shift
val = val >> shift
return csr_reg, mask, val, None
elif i == 2: # with modifiers only
mod, csr_reg, mask_expr, val_expr = regex_match.groups()
mask = eval(mask_expr, {}, instr_dict)
val = eval(val_expr, {}, instr_dict)
return csr_reg, mask, val, mod
elif i == 3: # with both modifiers and bitshifts
mod, csr_reg, shift_op, shift_expr, mask_expr, val_expr = regex_match.groups()
shift = eval(shift_expr, {}, instr_dict)
mask = eval(mask_expr, {}, instr_dict)
val = eval(val_expr, {}, instr_dict)
if shift_op == '>>':
mask = mask << shift
val = val << shift
else:
mask = mask >> shift
val = val >> shift
return csr_reg, mask, val, mod
return None, None, None, None
class GeneratorCSRComb():
'''
A class to generate RISC-V assembly tests for CSR-combination coverpoints.
'''
def __init__(self, base_isa, xlen, randomize):
self.base_isa = base_isa + "_Zicsr"
self.xlen = xlen
self.randomize = randomize
def csr_comb(self, cgf_node):
logger.debug('Generating tests for csr_comb')
if 'csr_comb' in cgf_node:
csr_comb = set(cgf_node['csr_comb'])
else:
return
temp_regs = ['x30', 'x31']
dest_reg = 'x29'
instr_dict = []
offset = 0
for covpt in csr_comb:
try:
bool_expr = parse_csr_covpt(covpt)
sols = bool_expr.SAT()
except:
logger.error(f'Invalid csr_comb coverpoint: {covpt}')
continue
for sol, _ in sols:
reg_mask_val_mod_dict = {} # maps a csr_reg to the 6-tuple [mask, val, write_mask, write_val, old_mask, old_val]
reg_with_mod = None
for clause in sol:
csr_reg, mask, val, mod = get_csr_mask_val_modifier(clause, {'xlen': self.xlen})
if csr_reg is None:
logger.error(f'Skipping invalid csr_comb coverpoint condition clause: {clause}')
continue
if mod is not None:
if reg_with_mod is None: reg_with_mod = csr_reg
elif reg_with_mod != csr_reg:
logger.error(f'Skipping invalid csr_comb solution with modifiers on more than one registers for the coverpoint: {covpt}')
continue
if not csr_reg in reg_mask_val_mod_dict:
if mod == 'old':
reg_mask_val_mod_dict[csr_reg] = [0, 0, 0, 0, mask, val]
elif mod == 'write':
reg_mask_val_mod_dict[csr_reg] = [0, 0, mask, val, 0, 0]
else:
reg_mask_val_mod_dict[csr_reg] = [mask, val, 0, 0, 0, 0]
else:
if mod == 'old':
reg_mask_val_mod_dict[csr_reg][4] |= mask
reg_mask_val_mod_dict[csr_reg][5] |= val
elif mod == 'write':
reg_mask_val_mod_dict[csr_reg][2] |= mask
reg_mask_val_mod_dict[csr_reg][3] |= val
else:
reg_mask_val_mod_dict[csr_reg][0] |= mask
reg_mask_val_mod_dict[csr_reg][1] |= val
reg_mask_val_arr = list(reg_mask_val_mod_dict.items())
reg_mask_val_arr.sort(key=functools.cmp_to_key(lambda x, y: 1 if x[0] == reg_with_mod else -1)) # put the register with modifier at the end
instr_dict_csr_writes = []
instr_dict_csr_restores = []
uniq_csr_regs = []
restore_reg = 1
for csr_reg, mask_val in reg_mask_val_arr:
mask, val, write_mask, write_val, old_mask, old_val = mask_val
if old_mask != 0:
instr_dict_csr_writes.append({
'csr_reg': csr_reg, 'mask': hex(old_mask), 'val': hex(old_val), 'restore_reg': f'x{restore_reg}',
'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1]
})
instr_dict_csr_restores.append({
'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}'
})
restore_reg += 1
if write_mask != 0:
instr_dict_csr_writes.append({
'csr_reg': csr_reg, 'mask': hex(write_mask), 'val': hex(write_val), 'restore_reg': f'x{restore_reg}',
'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1]
})
instr_dict_csr_restores.append({
'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}'
})
restore_reg += 1
elif mask != 0:
instr_dict_csr_writes.append({
'csr_reg': csr_reg, 'mask': hex(mask), 'val': hex(val), 'restore_reg': f'x{restore_reg}',
'temp_reg1': temp_regs[0], 'temp_reg2': temp_regs[1]
})
instr_dict_csr_restores.append({
'csr_reg': csr_reg, 'restore_reg': f'x{restore_reg}'
})
restore_reg += 1
if csr_reg not in uniq_csr_regs:
uniq_csr_regs.append(csr_reg)
instr_dict_csr_restores.reverse()
instr_dict_csr_read_and_sig_upds = []
for csr_reg in uniq_csr_regs:
instr_dict_csr_read_and_sig_upds.append({
'csr_reg': csr_reg, 'dest_reg': dest_reg, 'offset': offset
})
offset += (self.xlen >> 3)
instr_dict.append((instr_dict_csr_writes, instr_dict_csr_read_and_sig_upds, instr_dict_csr_restores))
return instr_dict
def write_test(self, fprefix, cgf_node, usage_str, cov_label, instr_dict):
base_reg = 'x28'
code = [""]
data = [".align 4","rvtest_data:",".word 0xbabecafe", \
".word 0xabecafeb", ".word 0xbecafeba", ".word 0xecafebab"]
sig = [""]
sig_label = f"signature_{base_reg}_0"
sig.append(signode_template.safe_substitute(label = sig_label, n = len(instr_dict), sz = '(XLEN/32)'))
code.append(f"RVTEST_SIGBASE({base_reg}, {sig_label})\n")
for i, instr in enumerate(instr_dict):
csr_writes, csr_read_sig_upds, csr_restores = instr
for j, csr_write in enumerate(csr_writes):
code.extend([
f"\ninst_{i}_csr_write_{j}:",
csr_reg_write_to_field_template.safe_substitute({
'base_reg': base_reg, **csr_write
})
])
for j, csr_read_sig_upd in enumerate(csr_read_sig_upds):
code.extend([
f"\ninst_{i}_csr_read_sig_upd_{j}:",
csr_reg_read_and_sig_upd_template.safe_substitute({
'base_reg': base_reg, **csr_read_sig_upd
})
])
for j, csr_restore in enumerate(csr_restores):
code.extend([
f"\ninst_{i}_csr_restore_{j}:",
csr_reg_restore_template.safe_substitute({
'base_reg': base_reg, **csr_restore
})
])
case_str = ''.join([case_template.safe_substitute(xlen = self.xlen, num = i, cov_label = cov_label) for i, cond in enumerate(cgf_node.get('config', []))])
test_str = part_template.safe_substitute(case_str = case_str, code = '\n'.join(code))
fname = fprefix + '_csr-comb.S'
logger.debug("Writing Test to %s", str(fname))
with open(fname, 'w') as fp:
fp.write(usage_str + csr_comb_test_template.safe_substitute(
isa = self.base_isa.upper(), # how to get the extensions?
test = test_str,
data = '\n'.join(data),
sig = '\n'.join(sig),
label = cov_label
))

View file

@ -0,0 +1,131 @@
# See LICENSE.incore file for details
import copy
import os,re
import multiprocessing as mp
import time
import shutil
from riscv_ctg.log import logger
import riscv_ctg.utils as utils
import riscv_ctg.constants as const
from riscv_isac.cgf_normalize import expand_cgf
from riscv_ctg.generator import Generator
from riscv_ctg.cross_comb import cross
from riscv_ctg.csr_comb import GeneratorCSRComb
from math import *
from riscv_ctg.__init__ import __version__
def create_test(usage_str, node,label,base_isa,max_inst, op_template, randomize, out_dir, xlen, flen):
iflen = 0
if 'mnemonics' not in node and 'csr_comb' not in node:
logger.warning("Neither mnemonics nor csr_comb node not found in covergroup: " + str(label))
return
if 'ignore' in node:
logger.info("Ignoring :" + str(label))
if node['ignore']:
return
if 'mnemonics' in node:
# Function to encompass checks and test generation
def gen_test(op_node, opcode):
iflen = 0
if xlen not in op_node['xlen']:
logger.warning("Skipping {0} since its not supported in current XLEN:".format(opcode))
return
if 'flen' in op_node:
if flen not in op_node['flen']:
logger.warning("Skipping {0} since its not supported in current FLEN({1}):".format(\
opcode, flen))
return
iflen = min(op_node['flen'])
fprefix = os.path.join(out_dir,str(label))
logger.info('Generating Test for :' + str(label) +"-" + opcode)
formattype = op_node['formattype']
gen = Generator(formattype,op_node,opcode,randomize,xlen,flen,iflen,base_isa)
op_comb = gen.opcomb(node)
val_comb = gen.valcomb(node)
instr_dict = gen.correct_val(
gen.valreg(
gen.testreg(
gen.swreg(
gen.gen_inst(op_comb, val_comb, node)))))
logger.info("Writing tests for :"+str(label))
my_dict = gen.reformat_instr(instr_dict)
gen.write_test(fprefix,node,label,my_dict, op_node, usage_str, max_inst)
# If base_op defined in covergroup, extract corresponding template
# else go through the instructions defined in mnemonics label
op_node = None
if 'base_op' in node:
# Extract pseudo and base instructions
base_op = node['base_op']
pseudop = list(node['mnemonics'].keys())[0]
if base_op in op_template and pseudop in op_template:
op_node = copy.deepcopy(op_template[base_op])
pseudo_template = op_template[pseudop]
# Ovewrite/add nodes from pseudoinstruction template in base instruction template
for key, val in pseudo_template.items():
op_node[key] = val
# Generate tests
gen_test(op_node, pseudop)
else:
for opcode in node['mnemonics']:
if opcode in op_template:
op_node = op_template[opcode]
# Generate tests
gen_test(op_node, opcode)
else:
logger.warning(str(opcode) + " not found in template file. Skipping")
return
if 'cross_comb' in node:
fprefix = os.path.join(out_dir,str(label))
cross_obj = cross(base_isa, xlen, randomize, label)
cross_instr_dict = cross_obj.cross_comb(node)
logger.info('Writing cross-comb test')
cross_obj.write_test(fprefix, node, usage_str, label, cross_instr_dict)
if op_node is None:
# Return if there is no corresponding template
logger.warning("Skipping :" + str(opcode))
return
if 'csr_comb' in node:
fprefix = os.path.join(out_dir,str(label))
csr_comb_gen = GeneratorCSRComb(base_isa, xlen, randomize)
csr_comb_instr_dict = csr_comb_gen.csr_comb(node)
logger.info('Writing tests for csr_comb')
csr_comb_gen.write_test(fprefix, node, usage_str, label, csr_comb_instr_dict)
def ctg(verbose, out, random ,xlen_arg,flen_arg, cgf_file,num_procs,base_isa, max_inst):
logger.level(verbose)
logger.info('****** RISC-V Compliance Test Generator {0} *******'.format(__version__ ))
logger.info('Copyright (c) 2020, InCore Semiconductors Pvt. Ltd.')
logger.info('All Rights Reserved.')
logger.info("Copying env folder to Output directory.")
env_dir = os.path.join(out,"env")
if not os.path.exists(env_dir):
shutil.copytree(const.env,env_dir)
xlen = int(xlen_arg)
flen = int(flen_arg)
out_dir = out
randomize = random
mytime = time.asctime(time.gmtime(time.time()) ) + ' GMT'
cgf_argument = ''
for cf in cgf_file:
cgf_argument += '// --cgf {} \\\n'.format(cf)
randomize_argument = ''
if random is True:
randomize_argument = ' \\\n// --randomize'
usage_str = const.usage.safe_substitute(base_isa=base_isa, \
cgf=cgf_argument, version = __version__, time=mytime, \
randomize=randomize_argument,xlen=str(xlen_arg))
op_template = utils.load_yamls(const.template_files)
cgf = expand_cgf(cgf_file,xlen,flen)
pool = mp.Pool(num_procs)
results = pool.starmap(create_test, [(usage_str, node,label,base_isa,max_inst, op_template,
randomize, out_dir, xlen, flen) for label,node in cgf.items()])
pool.close()

View file

@ -0,0 +1,253 @@
def simd_val_vars(operand, xlen, bit_width):
'''
This function generates the operand value variables for SIMD elements of the given operand.
:param operand: a string indicating the name of the desired operand.
:param xlen: an integer indicating the XLEN value to be used.
:param bit_width: an integer indicating the element bit width for the current SIMD format.
:type operand: str
:type xlen: int
:type bit_width: int
:return: a list containing the element value variables for the given operand.
'''
val_list = []
nelms = xlen // bit_width
if bit_width == 8:
sz = "b"
elif bit_width == 16:
sz = "h"
elif bit_width == 32:
sz = "w"
elif bit_width == 64:
sz = "d"
else:
sz = "q"
for i in range(nelms):
val_list += [f"{operand}_{sz}{i}_val"]
return val_list
def get_fmt_sz(bit_width):
if bit_width == 8:
fmt = f"#02x"
elif bit_width == 16:
fmt = f"#04x"
elif bit_width == 32:
fmt = f"#08x"
elif bit_width == 64:
fmt = f"#016x"
else:
fmt = f"#032x"
if bit_width == 8:
sz = "b"
elif bit_width == 16:
sz = "h"
elif bit_width == 32:
sz = "w"
elif bit_width == 64:
sz = "d"
else:
sz = "q"
return fmt, sz
def gen_fmt(bit_width):
'''
This function generate fmt string by bit_width.
:param bit_width: an integer indicating the element bit width of the current RVP instruction.
:type bit_width: int
'''
if bit_width == 8:
fmt = f"#02x"
elif bit_width == 16:
fmt = f"#04x"
elif bit_width == 32:
fmt = f"#08x"
elif bit_width == 64:
fmt = f"#016x"
else:
fmt = f"032x"
return fmt
def gen_sz(bit_width):
'''
This function generate size string by bit_width.
:param bit_width: an integer indicating the element bit width of the current RVP instruction.
:type bit_width: int
'''
if bit_width == 8:
sz = "b"
elif bit_width == 16:
sz = "h"
elif bit_width == 32:
sz = "w"
elif bit_width == 64:
sz = "d"
else:
sz = "q"
return sz
def concat_simd_data(instr_dict, xlen, _bit_width):
'''
This function concatenates all element of a SIMD register into a single value in the hex format.
:param instr_dict: a dict holding metadata and operand data for the current instruction.
:param xlen: an integer indicating the XLEN value to be used.
:param bit_width: an integer or string of integer pair indicating the element bit width of rs1/rs2 of the current RVP instruction.
:type instr_dict: dict
:type xlen: int
:type bit_width: int
'''
if type(_bit_width)==str:
_bit_width = eval(_bit_width)
if type(_bit_width)==tuple:
bit_width1, bit_width2 = _bit_width
else:
bit_width1, bit_width2 = _bit_width, _bit_width
for instr in instr_dict:
if 'rs1' in instr:
twocompl_offset = 1<<bit_width1
fmt, sz= get_fmt_sz(bit_width1)
if 'rs1_val' in instr: # single element value
rs1_val = int(instr['rs1_val'])
if rs1_val < 0:
rs1_val = rs1_val + twocompl_offset
instr['rs1_val'] = format(rs1_val, f"#0x")
else: # concatenates all element of a SIMD register into a single value
rs1_val = 0
for i in range(xlen//bit_width1):
val_var = f"rs1_{sz}{i}_val"
val = int(instr[val_var])
if val < 0:
val = val + twocompl_offset
rs1_val += val << (i*bit_width1)
instr['rs1_val'] = format(rs1_val, f"#0{xlen//4}x")
if 'rs2' in instr:
# bit_width1 == bit_width2 except for instructions with pwhrrformat.
# but even for pwhrrformat, the values are aligned to bit_width1 instead of bit_width2.
twocompl_offset = 1<<bit_width2
fmt, sz= get_fmt_sz(bit_width2)
if 'rs2_val' in instr: # single element value
rs2_val = int(instr['rs2_val'])
if rs2_val < 0:
rs2_val = rs2_val + twocompl_offset
instr['rs2_val'] = format(rs2_val, f"#0x")
else: # concatenates all element of a SIMD register into a single value
rs2_val = 0
for i in range(xlen//bit_width2):
val_var = f"rs2_{sz}{i}_val"
val = int(instr[val_var])
if val < 0:
val = val + twocompl_offset
rs2_val += val << (i*bit_width2)
instr['rs2_val'] = format(rs2_val, f"#0{xlen//4}x")
if 'imm_val' in instr:
imm_val = int(instr['imm_val'])
instr['imm_val'] = format(imm_val, f"#0x")
def incr_reg_num(reg):
name = reg[0]
num = int(reg[1:])
num = num + 1
return name + str(num)
def gen_pair_reg_data(instr_dict, xlen, _bit_width, p64_profile):
'''
This function generate high registers for paired register operands, rs1_hi, rs2_hi and rd_hi depending on the specification of the p64_profile string.
It also generate the corresponding values rs1_val_hi, rs2_val_hi.
:param instr_dict: a dict holding metadata and operand data for the current instruction.
:param xlen: an integer indicating the XLEN value to be used.
:param bit_width: an integer or string of integer pair indicating the element bit width of rs1/rs2 of the current RVP instruction.
:param p64_profile: a string of 3 chars indicating the type of operands (pair/non-pair) of the current RVP instruction. (rd, rs1 and rs2)
:type instr_dict: dict
:type xlen: int
:type bit_width: int
:type p64_profile: string
'''
if type(_bit_width)==str:
_bit_width = eval(_bit_width)
if type(_bit_width)==tuple:
bit_width1, bit_width2 = _bit_width
else:
bit_width1, bit_width2 = _bit_width, _bit_width
if xlen == 32:
rs1_width = 64 if len(p64_profile) >= 3 and p64_profile[1]=='p' else xlen
rs2_width = 64 if len(p64_profile) >= 3 and p64_profile[2]=='p' else xlen
rd_width = 64 if len(p64_profile) >= 3 and p64_profile[0]=='p' else xlen
else:
rs1_width = 128 if len(p64_profile) >= 3 and p64_profile[1]=='p' else xlen
rs2_width = 128 if len(p64_profile) >= 3 and p64_profile[2]=='p' else xlen
rd_width = 128 if len(p64_profile) >= 3 and p64_profile[0]=='p' else xlen
for instr in instr_dict:
if 'rs1' in instr:
twocompl_offset = 1<<bit_width1
fmt, sz= get_fmt_sz(bit_width1)
if 'rs1_val' in instr:
rs1_val = int(instr['rs1_val'])
if rs1_val < 0:
rs1_val = rs1_val + twocompl_offset
else:
rs1_val = 0
for i in range(rs1_width//bit_width1):
val_var = f"rs1_{sz}{i}_val"
val = int(instr[val_var])
if val < 0:
val = val + twocompl_offset
rs1_val += val << (i*bit_width1)
if rs1_width > xlen:
instr['rs1_val'] = format(0xffffffff & rs1_val, f"#0{2+xlen//4}x")
instr['rs1_val_hi'] = format(0xffffffff & (rs1_val>>32), f"#0{2+xlen//4}x")
instr['rs1_hi'] = incr_reg_num(instr['rs1'])
else:
instr['rs1_val'] = format(rs1_val, f"#0{2+xlen//4}x")
if rs1_width == 64 and (len(p64_profile) >= 3):
instr['rs1_val64'] = format(rs1_val, f"#018x")
if 'rs2' in instr:
twocompl_offset = 1<<bit_width2
fmt, sz= get_fmt_sz(bit_width2)
if 'rs2_val' in instr: # single element value
rs2_val = int(instr['rs2_val'])
if rs2_val < 0:
rs2_val = rs2_val + twocompl_offset
else: # concatenates all element of a SIMD register into a single value
rs2_val = 0
for i in range(rs2_width//bit_width2):
val_var = f"rs2_{sz}{i}_val"
val = int(instr[val_var])
if val < 0:
val = val + twocompl_offset
rs2_val += val << (i*bit_width2)
if rs2_width > xlen:
instr['rs2_val'] = format(0xffffffff & rs2_val, f"#0{2+xlen//4}x")
instr['rs2_val_hi'] = format(0xffffffff & (rs2_val>>32), f"#0{2+xlen//4}x")
instr['rs2_hi'] = incr_reg_num(instr['rs2'])
else:
instr['rs2_val'] = format(rs2_val, f"#0{2+xlen//4}x")
if rs2_width == 64 and (len(p64_profile) >= 3):
instr['rs2_val64'] = format(rs2_val, f"#018x")
if 'rd' in instr and rd_width > xlen:
instr['rd_hi'] = incr_reg_num(instr['rd'])
if 'imm_val' in instr:
imm_val = int(instr['imm_val'])
instr['imm_val'] = format(imm_val, f"#0x")

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
{
"folders": [
{
"path": "../../../riscv-isac"
},
{
"path": "../../../cvw"
},
{
"path": "../.."
},
{
"path": "../../../riscv-arch-test"
},
{
"path": "../../../riscof"
}
],
"settings": {}
}

View file

@ -0,0 +1,368 @@
def get_cond_generator(opcode,fmt,val_vars,xlen,flen):
def fr128_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rm = argv[2]
bin_val = '{:0128b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:16],2)
fm1 = int(bin_val[16:],2)
bin_val = '{:064b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:16],2)
fm2 = int(bin_val[16:],2)
return eval(req_val_comb)
return condition
def fr64_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rm = argv[2]
bin_val = '{:064b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:12],2)
fm1 = int(bin_val[12:],2)
bin_val = '{:064b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:12],2)
fm2 = int(bin_val[12:],2)
return eval(req_val_comb)
return condition
def fr32_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rm = argv[2]
bin_val = '{:032b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:9],2)
fm1 = int(bin_val[9:],2)
bin_val = '{:032b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:9],2)
fm2 = int(bin_val[9:],2)
return eval(req_val_comb)
return condition
def fsr128_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rm = argv[1]
bin_val = '{:0128b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:16],2)
fm1 = int(bin_val[16:],2)
return eval(req_val_comb)
return condition
def fsr64_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rm = argv[1]
bin_val = '{:064b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:12],2)
fm1 = int(bin_val[12:],2)
return eval(req_val_comb)
return condition
def fsr32_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rm = argv[1]
bin_val = '{:032b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:9],2)
fm1 = int(bin_val[9:],2)
return eval(req_val_comb)
return condition
def fr4_128_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rs3_val = argv[2]
rm = argv[3]
bin_val = '{:0128b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:16],2)
fm1 = int(bin_val[16:],2)
bin_val = '{:0128b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:16],2)
fm2 = int(bin_val[16:],2)
bin_val = '{:0128b}'.format(rs3_val)
fs3 = int(bin_val[0],2)
fe3 = int(bin_val[1:16],2)
fm3 = int(bin_val[16:],2)
return eval(req_val_comb)
return condition
def fr4_64_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rs3_val = argv[2]
rm = argv[3]
bin_val = '{:064b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:12],2)
fm1 = int(bin_val[12:],2)
bin_val = '{:064b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:12],2)
fm2 = int(bin_val[12:],2)
bin_val = '{:064b}'.format(rs3_val)
fs3 = int(bin_val[0],2)
fe3 = int(bin_val[1:12],2)
fm3 = int(bin_val[12:],2)
return eval(req_val_comb)
return condition
def fr4_32_generator(req_val_comb):
def condition(*argv):
rs1_val = argv[0]
rs2_val = argv[1]
rs3_val = argv[2]
rm = argv[3]
bin_val = '{:032b}'.format(rs1_val)
fs1 = int(bin_val[0],2)
fe1 = int(bin_val[1:9],2)
fm1 = int(bin_val[9:],2)
bin_val = '{:032b}'.format(rs2_val)
fs2 = int(bin_val[0],2)
fe2 = int(bin_val[1:9],2)
fm2 = int(bin_val[9:],2)
bin_val = '{:032b}'.format(rs3_val)
fs3 = int(bin_val[0],2)
fe3 = int(bin_val[1:9],2)
fm3 = int(bin_val[9:],2)
return eval(req_val_comb)
return condition
def i_generator(req_val_comb):
def condition(*argv):
for var,val in zip(val_vars,argv):
locals()[var]=val
return eval(req_val_comb)
return condition
if opcode[0] == 'f' and 'fence' not in opcode:
if fmt == 'frformat':
if flen == 32:
return fr32_generator
elif flen == 64:
return fr64_generator
else:
return fr128_generator
elif fmt == 'fsrformat':
if flen == 32:
return fsr32_generator
elif flen == 64:
return fsr64_generator
else:
return fsr128_generator
elif fmt == 'fr4format':
if flen == 32:
return fr4_32_generator
elif flen == 64:
return fr4_64_generator
else:
return fr4_128_generator
else:
return i_generator
def get_filter_generator(opcode,fmt,val_vars,xlen,flen):
def fr128_generator(argv):
bin_val1 = '{:0128b}'.format(argv[0])
bin_val2 = '{:0128b}'.format(argv[1])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rm': argv[2]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:16],2)
,'fm1': int(bin_val1[16:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:16],2)
,'fm2': int(bin_val2[16:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fr64_generator(argv):
bin_val1 = '{:064b}'.format(argv[0])
bin_val2 = '{:064b}'.format(argv[1])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rm': argv[2]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:12],2)
,'fm1': int(bin_val1[12:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:12],2)
,'fm2': int(bin_val2[12:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fr32_generator(argv):
bin_val1 = '{:032b}'.format(argv[0])
bin_val2 = '{:032b}'.format(argv[1])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rm': argv[2]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:9],2)
,'fm1': int(bin_val1[9:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:9],2)
,'fm2': int(bin_val2[9:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fsr128_generator(argv):
bin_val1 = '{:0128b}'.format(argv[0])
local = {
'rs1_val': argv[0]
,'rm': argv[1]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:16],2)
,'fm1': int(bin_val1[16:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fsr64_generator(argv):
bin_val1 = '{:064b}'.format(argv[0])
local = {
'rs1_val': argv[0]
,'rm': argv[1]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:12],2)
,'fm1': int(bin_val1[12:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fsr32_generator(argv):
bin_val1 = '{:032b}'.format(argv[0])
local = {
'rs1_val': argv[0]
,'rm': argv[1]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:9],2)
,'fm1': int(bin_val1[9:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fr4_128_generator(argv):
bin_val1 = '{:0128b}'.format(argv[0])
bin_val2 = '{:0128b}'.format(argv[1])
bin_val3 = '{:0128b}'.format(argv[2])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rs3_val': argv[2]
,'rm': argv[3]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:16],2)
,'fm1': int(bin_val1[16:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:16],2)
,'fm2': int(bin_val2[16:],2)
,'fs3': int(bin_val3[0],2)
,'fe3': int(bin_val3[1:16],2)
,'fm3': int(bin_val3[16:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fr4_64_generator(argv):
bin_val1 = '{:064b}'.format(argv[0])
bin_val2 = '{:064b}'.format(argv[1])
bin_val3 = '{:064b}'.format(argv[2])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rs3_val': argv[2]
,'rm': argv[3]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:12],2)
,'fm1': int(bin_val1[12:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:12],2)
,'fm2': int(bin_val2[12:],2)
,'fs3': int(bin_val3[0],2)
,'fe3': int(bin_val3[1:12],2)
,'fm3': int(bin_val3[12:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def fr4_32_generator(argv):
bin_val1 = '{:032b}'.format(argv[0])
bin_val2 = '{:032b}'.format(argv[1])
bin_val3 = '{:032b}'.format(argv[2])
local = {
'rs1_val': argv[0]
,'rs2_val': argv[1]
,'rs3_val': argv[2]
,'rm': argv[3]
,'fs1': int(bin_val1[0],2)
,'fe1': int(bin_val1[1:9],2)
,'fm1': int(bin_val1[9:],2)
,'fs2': int(bin_val2[0],2)
,'fe2': int(bin_val2[1:9],2)
,'fm2': int(bin_val2[9:],2)
,'fs3': int(bin_val3[0],2)
,'fe3': int(bin_val3[1:9],2)
,'fm3': int(bin_val3[9:],2)
}
def filter_func(cond):
return eval(cond,{},local)
return filter_func
def i_generator(argv):
local = {}
for var,val in zip(val_vars,argv):
local[var]=val
def condition(req_val_comb):
return eval(req_val_comb,{},local)
return condition
if opcode[0] == 'f' and 'fence' not in opcode:
if fmt == 'frformat':
if flen == 32:
return fr32_generator
elif flen == 64:
return fr64_generator
else:
return fr128_generator
elif fmt == 'fsrformat':
if flen == 32:
return fsr32_generator
elif flen == 64:
return fsr64_generator
else:
return fsr128_generator
elif fmt == 'fr4format':
if flen == 32:
return fr4_32_generator
elif flen == 64:
return fr4_64_generator
else:
return fr4_128_generator
else:
return i_generator

View file

@ -0,0 +1,79 @@
import re
class ExtractException(Exception):
pass
num_dict = {
'rs1_val': '1',
'rs2_val': '2',
'rs3_val': '3',
}
fsub_vars = ['fe','fm','fs']
val_regex = "{0}\s*==\s*(?P<{1}>[0-9abcdefx+\-\*/\|\&]*)\s*"
def to_int(x):
if '0x' in x:
return int(x,16)
else:
return int(x)
def nan_box(prefix,rs,flen,iflen):
if int(prefix) == ((2**(flen-iflen))-1):
return (rs,iflen)
else:
return (str(to_int(rs)|(to_int(prefix)<<iflen)),flen)
def extract_frs_fields(reg,cvp,iflen):
if (iflen == 32):
e_sz = 8
m_sz = 23
elif (iflen == 64):
e_sz = 11
m_sz = 52
else:
e_sz = 15
m_sz = 112
s_sz_string = '{:01b}'
e_sz_string = '{:0'+str(e_sz)+'b}'
m_sz_string = '{:0'+str(m_sz)+'b}'
size_string = '{:0'+str(int(iflen/4))+'x}'
fvals = {}
for var in fsub_vars:
regex = val_regex.format(var+reg,var+reg)
match_obj = re.search(regex,cvp)
if match_obj is not None:
fvals[var+reg] = eval(match_obj.group(var+reg))
else:
raise ExtractException("{0} not defined in coverpoint:{1}".format(var+reg,cvp))
bin_val1 = s_sz_string.format(fvals['fs'+reg]) + e_sz_string.format(fvals['fe'+reg]) \
+ m_sz_string.format(fvals['fm'+reg])
hex_val1 = '0x' + size_string.format(int(bin_val1, 2))
return int(hex_val1,16)
def merge_fields_f(val_vars,cvp,flen,iflen,merge):
nan_box = False
if flen > iflen:
nan_box = True
fdict = {}
for var in val_vars:
if var in num_dict and merge:
fdict[var] = extract_frs_fields(num_dict[var],cvp,iflen)
if nan_box:
nan_var = 'rs{0}_nan_prefix'.format(num_dict[var])
regex = val_regex.format(nan_var.replace("_","\\_"),nan_var)
match_obj = re.search(regex,cvp)
if match_obj is not None:
fdict[nan_var] = eval(match_obj.group(nan_var))
else:
fdict[nan_var] = (2**(flen-iflen))-1
else:
regex = val_regex.format(var.replace("_","\\_"),var)
match_obj = re.search(regex,cvp)
if match_obj is not None:
fdict[var] = eval(match_obj.group(var))
elif 'nan_prefix' not in var:
raise ExtractException("{0} not defined in coverpoint:{1}".format(var,cvp))
return fdict

View file

@ -0,0 +1,92 @@
# See LICENSE.incore for details
import logging
import colorlog
class Log:
"""
this class holds all the logic; see the end of the script to
see how it's instantiated in order to have the line
"from zenlog import log" work
"""
aliases = {
logging.CRITICAL: ("critical", "crit", "fatal"),
logging.ERROR: ("error", "err"),
logging.WARNING: ("warning", "warn"),
logging.INFO: ("info", "inf"),
logging.DEBUG: ("debug", "dbg")
}
def __init__(self, format=None):
if not format:
format = "%(log_color)s%(levelname)8s%(reset)s | %(log_color)s%(message)s%(reset)s"
self.format = format
self.colors = {
'DEBUG': 'purple',
'INFO': 'green',
'WARNING': 'red',
'ERROR': 'bold_red',
'CRITICAL': 'bold_red',
}
self.logger = logging.getLogger()
# the magic happens here: we use the "extra" argument documented in
# https://docs.python.org/2/library/logging.html#logging.Logger.debug
# to inject new items into the logging.LogRecord objects
# we also create our convenience methods here
def critical(self, message, *args, **kwargs):
for line in str(message).splitlines():
self.logger.critical(line,
*args, **kwargs)
crit = c = fatal = critical
def error(self, message, *args, **kwargs):
for line in str(message).splitlines():
self.logger.error(line,
*args, **kwargs)
err = e = error
def warn(self, message, *args, **kwargs):
for line in str(message).splitlines():
self.logger.warning(line,
*args, **kwargs)
warning = w = warn
def info(self, message, *args, **kwargs):
for line in str(message).splitlines():
self.logger.info(line,
*args, **kwargs)
inf = nfo = i = info
def debug(self, message, *args, **kwargs):
for line in str(message).splitlines():
self.logger.debug(line,
*args, **kwargs)
dbg = d = debug
# other convenience functions to set the global logging level
def _parse_level(self, lvl):
for log_level in self.aliases:
if lvl == log_level or lvl in self.aliases[log_level]:
return log_level
print('Invalid log level passed. Please select from debug | info | warning | error')
raise ValueError("{}-Invalid log level.".format(lvl))
def level(self, lvl=logging.CRITICAL):
'''Setup the Logger.'''
self._lvl = self._parse_level(lvl)
self.stream = logging.StreamHandler()
self.stream.setLevel(self._lvl)
self.stream.setLevel(self._lvl)
self.stream.setFormatter(colorlog.ColoredFormatter(self.format,log_colors=self.colors))
self.logger.setLevel(self._lvl)
self.logger.addHandler(self.stream)
logging.root.setLevel(self._lvl)
logger = Log()

View file

@ -0,0 +1,29 @@
# See LICENSE.incore for details
"""Console script for riscv_ctg."""
import click,os
from riscv_ctg.log import logger
from riscv_ctg.ctg import ctg
from riscv_ctg.__init__ import __version__
from riscv_ctg.constants import env,gen_sign_dataset,gen_usign_dataset
from riscv_isac.cgf_normalize import expand_cgf
@click.command()
@click.version_option(prog_name="RISC-V Compliance Test Generator",version=__version__)
@click.option('--verbose', '-v', default='error', help='Set verbose level', type=click.Choice(['info','error','debug','warning'],case_sensitive=False))
@click.option('--out-dir', '-d', default='./', type=click.Path(resolve_path=True,writable=True), help='Output directory path')
@click.option('--randomize','-r', default=False , is_flag='True', help='Randomize Outputs.')
@click.option('--cgf','-cf',multiple=True,type=click.Path(exists=True,resolve_path=True,readable=True),help="Path to the cgf file(s). Multiple allowed.")
@click.option('--procs','-p',type=int,default=1,help='Max number of processes to spawn')
@click.option('--base-isa','-bi',type=click.Choice(['rv32e','rv32i','rv64i']),help="Base ISA string for the tests.")
@click.option('--flen','-fl',type=click.Choice(['32','64','128','0']),help="Value of FLEN in\
hardware.",default='0')
@click.option("--inst",type=int,help="Maximum number of Macro Instances per test.")
def cli(verbose, out_dir, randomize , cgf,procs,base_isa, flen,inst):
if not os.path.exists(out_dir):
os.mkdir(out_dir)
if '32' in base_isa:
xlen = 32
elif '64' in base_isa:
xlen = 64
ctg(verbose, out_dir, randomize ,xlen, int(flen), cgf,procs,base_isa,inst)

View file

@ -0,0 +1,442 @@
import random
import os
#---------------------------------------------------Start String--------------------------------------------------
start_str = '''
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV$xlenIK")
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
#ifdef TEST_CASE_1
RVTEST_CASE(0,"//check ISA:=regex(.*$xlen.*);check ISA:=regex(.*RV$xlen.*I.*K.*);def TEST_CASE_1=True;",$inst)
RVTEST_CASE(1,"//check ISA:=regex(.*$xlen.*);check ISA:=regex(.*RV$xlen.*I.*$config.*);def TEST_CASE_1=True;",$inst)
RVTEST_SIGBASE( $swreg1,signature_$swreg1_1)'''
#---------------------------------------------Assembly String: aes64*----------------------------------------------
string1 = '''// $comment
// opcode: $inst; op1:$rs1; op2:$rs2; dest1:$rd1; dest2:$rd2; dest3:$rd3; op1val:$r1_val; op2val:$r2_val
li $rs1, $r1_val;
li $rs2, $r2_val;
xor $rs1, $rs1, $rs2;
$inst $rd1, $rs1, $rs2;
$inst $rd2, $rs2, $rs1;
xor $rd3, $rd2, $rs2;
RVTEST_SIGUPD($swreg1,$rd1,$offset1);
RVTEST_SIGUPD($swreg1,$rd2,$offset2);
RVTEST_SIGUPD($swreg1,$rd3,$offset3);'''
#---------------------------------Assembly String: SHA2, SM3 & aes64im - Pattern 1---------------------------------
string2 = '''// $comment
// opcode: $inst2; op1:$rs3; dest1:$rs1; op1val:$r1_val; op2val:$r2_val
li $rs1, $r1_val;
li $rs2, $r2_val;
$inst1 $rs3, $rs1, $rs2;
$inst2 $rs1, $rs3;
$inst1 $rs4, $rs1, $rs2;
RVTEST_SIGUPD($swreg1,$rs3,$offset1);
RVTEST_SIGUPD($swreg1,$rs1,$offset2);
RVTEST_SIGUPD($swreg1,$rs4,$offset3);'''
string2_not = '''// $comment
// opcode: $inst2; op1:$rs3; dest1:$rs1; op1val:$r1_val; op2val:$r2_val
li $rs1, $r1_val;
li $rs2, $r2_val;
$inst1 $rs3, $rs2;
$inst2 $rs1, $rs3;
$inst1 $rs4, $rs1;
RVTEST_SIGUPD($swreg1,$rs3,$offset1);
RVTEST_SIGUPD($swreg1,$rs1,$offset2);
RVTEST_SIGUPD($swreg1,$rs4,$offset3);'''
#---------------------------------Assembly String: SHA2, SM3 & aes64im - Pattern 2---------------------------------
string3 = '''// $comment
// opcode: $inst; op1:$rs1; dest1:$rs2;
LREG $rs1, $offset1($rs0);
$inst $rs2, $rs1;
RVTEST_SIGUPD($swreg1,$rs1,$offset2);
RVTEST_SIGUPD($swreg1,$rs2,$offset3);'''
#---------------------------------------Assembly String: SHA2-512 - Pattern 1--------------------------------------
string5 = '''// $comment
// opcode: $inst2; op1:$rs3; op2:$rs2; dest1:$rs1; op1val:$r1_val; op2val:$r2_val
li $rs1, $r1_val;
li $rs2, $r2_val;
$inst1 $rs3, $rs1, $rs2;
$inst2 $rs1, $rs3, $rs2;
$inst1 $rs4, $rs1, $rs2;
RVTEST_SIGUPD($swreg1,$rs3,$offset1);
RVTEST_SIGUPD($swreg1,$rs1,$offset2);
RVTEST_SIGUPD($swreg1,$rs4,$offset3);'''
string5_not = '''// $comment
// opcode: $inst2; op1:$rs3; op2:$rs2; dest1:$rs1; op1val:$r1_val; op2val:$r2_val
li $rs1, $r1_val;
li $rs2, $r2_val;
$inst1 $rs3, $rs2;
$inst2 $rs1, $rs3, $rs2;
$inst1 $rs4, $rs1;
RVTEST_SIGUPD($swreg1,$rs3,$offset1);
RVTEST_SIGUPD($swreg1,$rs1,$offset2);
RVTEST_SIGUPD($swreg1,$rs4,$offset3);'''
#---------------------------------------Assembly String: SHA2-512 - Pattern 2--------------------------------------
string6 = '''// $comment
// opcode: $inst; op1:$rs1; op2:$rs2; dest1:$rs3;
LREG $rs1, $offset1($rs0);
LREG $rs2, $offset2($rs0);
$inst $rs3, $rs1, $rs2;
RVTEST_SIGUPD($swreg1,$rs1,$offset3);
RVTEST_SIGUPD($swreg1,$rs3,$offset4);'''
#----------------------------------------------Assembly String: aes32*---------------------------------------------
string4 = '''// $comment
// opcode: $inst; op1:$rs1; op1:$rs2; op1:$rs3; op1:$rs4; dest:$rs5;
li $rs1, $r1_val;
li $rs2, $r2_val;
li $rs3, $r3_val;
li $rs4, $r4_val;
li $rs5, $r5_val;
$inst $rs5, $rs1, 0;
$inst $rs5, $rs2, 1;
$inst $rs5, $rs3, 2;
$inst $rs5, $rs4, 3;
RVTEST_SIGUPD($swreg1,$rs5,$offset1);'''
#----------------------------------------------Assembly String: sm4ed, sm4ks ---------------------------------------------
string7 = '''// $comment
// opcode: $inst; $op1: $rs6; op2:$rs1; op2:$rs2; op2:$rs3; op2:$rs4; dest:$rs5;
li $rs1, $r1_val;
li $rs2, $r2_val;
li $rs3, $r3_val;
li $rs4, $r4_val;
li $rs5, $r5_val;
li $rs6, $r6_val;
$inst $rs5, $rs6, $rs1, 0;
$inst $rs5, $rs6, $rs2, 1;
$inst $rs5, $rs6, $rs3, 2;
$inst $rs5, $rs6, $rs4, 3;
RVTEST_SIGUPD($swreg1,$rs5,$offset1);'''
#----------------------------------------------------End String----------------------------------------------------
end_str = '''#endif
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
.align 4
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
signature_$swreg1_1:
.fill $fill_val*(XLEN/32),4,0xdeadbeef
#ifdef rvtest_mtrap_routine
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
RVMODEL_DATA_END'''
#-------------------------------------------------End String 1 & 2------------------------------------------------
end_str1 = '''#endif
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
.align 4
rvtest_data:'''
end_str2 = '''RVTEST_DATA_END
RVMODEL_DATA_BEGIN
signature_$swreg1_1:
.fill $fill_val*(XLEN/32),4,0xdeadbeef
#ifdef rvtest_mtrap_routine
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
RVMODEL_DATA_END'''
#----------------------------------------------------User Inputs---------------------------------------------------
instr_dict = {
1: ["aes64ds","aes64dsm","aes64es","aes64esm","sm4ed","sm4ks"],
2: ["sha256sig0","sha256sig1","sha256sum0","sha256sum1","sha512sig0",\
"sha512sig1","sha512sum0","sha512sum1","sm3p0","sm3p1","aes64im"],
3: ["aes32dsi","aes32dsmi","aes32esi","aes32esmi"],
4: ["sha256sig0","sha256sig1","sha256sum0","sha256sum1","sm3p0","sm3p1"],
5: ["sha512sig0h","sha512sig0l","sha512sig1h","sha512sig1l","sha512sum0r","sha512sum1r"],
6: ["sm4ed","sm4ks"],
7: ["sm4ed","sm4ks"]}
instr_f = {
1: ["xor"],
2: ["xor","not","add"],
3: ["none"],
4: ["xor","not","add"],
5: ["xor","not","add"],
6: ["none"],
7: ["none"]
}
xlen = {
1: 64,
2: 64,
3: 32,
4: 32,
5: 32,
6: 64,
7: 32}
comment_dict = {
1: ["1st Instruction => rs1 = $rs1; rs2 = $rs2 | 2nd Instruction => rs1 = $rs2; rs2 = $rs1\
| Result of xor goes into $inst & vice versa"],
2: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"],
3: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"],
4: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"],
5: ["Forwarded $inst1 into $inst2 & the result back into $inst1","Checking load-to-use hazard!"],
6: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"],
7: ["Expected use-case sequence -> Aims to test things like pipeline forwarding"]}
n_i = {
1: [27,3],
2: [28,30,3],
3: [27,1],
4: [28,30,3],
5: [28,29,3],
6: [27,1],
7: [27,1]
}
swreg1 = "x31"
seed = 10
#------------------------------------------------------------------------------------------------------------------
config_ZKn = ['aes64ds','aes64dsm','aes64es','aes64esm','sha256sig0','sha256sig1','sha256sum0','sha256sum1',\
'sha512sig0','sha512sig1','sha512sum0','sha512sum1','aes64im','aes32esi','aes32esmi','aes32dsi',\
'aes32dsmi','sha512sig0h','sha512sig0l','sha512sig1h','sha512sig1l','sha512sum0r','sha512sum1r']
config_ZKs = ['sm3p0','sm3p1','sm4ed','sm4ks']
if os.path.isdir(os.getcwd()+"/real_world_tests") == False:
os.mkdir(os.getcwd()+"/real_world_tests")
os.mkdir(os.getcwd()+"/real_world_tests/RV32IK")
os.mkdir(os.getcwd()+"/real_world_tests/RV64IK")
for key in instr_dict:
for z in instr_dict[key]:
with open(os.getcwd()+'/real_world_tests/RV'+str(xlen[key])+'IK/'+z+'-rwp1.S','w') as out:
offset_val = 0
if z in config_ZKn:
config = "ZKn"
elif z in config_ZKs:
config = "ZKs"
sp = start_str.replace("$inst",z).replace("$swreg1",swreg1).replace("$xlen",str(xlen[key])).replace("$config",config)
out.write(sp)
out.write('\n\n')
random.seed(seed)
for i in range(1,n_i[key][0]):
out.write("inst_"+str(i-1)+":\n")
r1 = random.randint(0,2**xlen[key]-1)
r2 = random.randint(0,2**xlen[key]-1)
r3 = random.randint(0,2**xlen[key]-1)
r4 = random.randint(0,2**xlen[key]-1)
r5 = random.randint(0,2**xlen[key]-1)
r6 = random.randint(0,2**xlen[key]-1)
r1_str = '{0:#0{1}x}'.format(r1,int(xlen[key]/4)+2)
r2_str = '{0:#0{1}x}'.format(r2,int(xlen[key]/4)+2)
r3_str = '{0:#0{1}x}'.format(r3,int(xlen[key]/4)+2)
r4_str = '{0:#0{1}x}'.format(r4,int(xlen[key]/4)+2)
r5_str = '{0:#0{1}x}'.format(r5,int(xlen[key]/4)+2)
r6_str = '{0:#0{1}x}'.format(r6,int(xlen[key]/4)+2)
if key == 1:
comment_str = comment_dict[key][0].replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1)).replace("$inst",z)
sp = string1.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rd1","x"+str(i+2)).replace("$rd2","x"+str(i+3)).replace("$rd3","x"+str(i+4))\
.replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$offset2",str(int(offset_val+xlen[key]/8)))\
.replace("$offset3",str(int(offset_val+xlen[key]/4)))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str)
offset_val = int(offset_val + (xlen[key]*6)/16)
out.write(sp)
out.write('\n\n')
elif key == 2 or key == 4 or key == 5:
for j in instr_f[key]:
comment_str = comment_dict[key][0].replace("$inst1",j).replace("$inst2",z)
if key == 2 or key == 4:
if j == 'not':
sp = string2_not.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\
.replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$offset2",str(int(offset_val+xlen[key]/8)))\
.replace("$offset3",str(int(offset_val+xlen[key]/4)))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str)
else:
sp = string2.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\
.replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$offset2",str(int(offset_val+xlen[key]/8)))\
.replace("$offset3",str(int(offset_val+xlen[key]/4)))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str)
elif key == 5:
if j == 'not':
sp = string5_not.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\
.replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$offset2",str(int(offset_val+xlen[key]/8)))\
.replace("$offset3",str(int(offset_val+xlen[key]/4)))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str)
else :
sp = string5.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$inst1",j)\
.replace("$inst2",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$offset2",str(int(offset_val+xlen[key]/8)))\
.replace("$offset3",str(int(offset_val+xlen[key]/4)))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$comment",comment_str)
offset_val = int(offset_val + (xlen[key]*6)/16)
out.write(sp)
out.write('\n\n')
elif key == 3:
comment_str = comment_dict[key][0]
sp = string4.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$rs5","x"+str(i+4))\
.replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$r3_val",r3_str)\
.replace("$r4_val",r4_str).replace("$r5_val",r5_str)\
.replace("$comment",comment_str)
offset_val = offset_val + int(xlen[key]/8)
out.write(sp)
out.write('\n\n')
elif key == 6 or key == 7:
comment_str = comment_dict[key][0]
sp = string7.replace("$rs1","x"+str(i)).replace("$rs2","x"+str(i+1))\
.replace("$rs3","x"+str(i+2)).replace("$rs4","x"+str(i+3)).replace("$rs5","x"+str(i+4))\
.replace("$rs6","x"+str(i+5))\
.replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val))\
.replace("$r1_val",r1_str).replace("$r2_val",r2_str).replace("$r3_val",r3_str)\
.replace("$r4_val",r4_str).replace("$r5_val",r5_str)\
.replace("$r6_val",r6_str)\
.replace("$comment",comment_str)
offset_val = offset_val + int(xlen[key]/8)
out.write(sp)
out.write('\n\n')
ed = end_str.replace("$swreg1",swreg1)\
.replace("$fill_val",str(((n_i[key][0])-1)*n_i[key][len(n_i[key])-1]*len(instr_f[key])))
out.write(ed)
out.write('\n')
out.close()
print("Test File Generated for "+str(xlen[key])+"-bit "+z+"-Test Pattern 1!")
if key == 2 or key == 4 or key == 5:
with open(os.getcwd()+'/real_world_tests/RV'+str(xlen[key])+'IK/'+z+'-rwp2.S','w') as out:
offset_val1 = 0
offset_val2 = 0
if z in config_ZKn:
config = "ZKn"
elif z in config_ZKs:
config = "ZKs"
sp = start_str.replace("$inst",z).replace("$swreg1",swreg1).replace("$xlen",str(xlen[key])).replace("$config",config)
out.write(sp)
out.write('\n\n')
out.write("la x1, rvtest_data")
out.write('\n\n')
random.seed(seed)
for i in range(2,n_i[key][1]):
out.write("inst_"+str(i-2)+":\n")
comment_str = comment_dict[key][1]
if key == 2 or key ==4:
sp = string3.replace("$rs0","x1").replace("$rs1","x"+str(i))\
.replace("$rs2","x"+str(i+1)).replace("$inst",z).replace("$swreg1",swreg1)\
.replace("$offset1",str(offset_val1)).replace("$offset2",str(offset_val2))\
.replace("$offset3",str(int(offset_val2+xlen[key]/8))).replace("$comment",comment_str)
elif key == 5:
sp = string6.replace("$rs0","x1").replace("$rs1","x"+str(i))\
.replace("$rs2","x"+str(i+1)).replace("$rs3","x"+str(i+2))\
.replace("$inst",z).replace("$swreg1",swreg1).replace("$offset1",str(offset_val1))\
.replace("$offset2",str(int(offset_val1+xlen[key]/8))).replace("$offset3",str(offset_val2))\
.replace("$offset4",str(int(offset_val2+xlen[key]/8))).replace("$comment",comment_str)
offset_val1 = int(offset_val1 + xlen[key]/8)
offset_val2 = int(offset_val2 + xlen[key]/4)
out.write(sp)
out.write('\n\n')
out.write(end_str1)
out.write('\n')
for j in range(2,30):
x = random.randint(0,2**xlen[key]-1)
x_str = '{0:#0{1}x}'.format(x,int(xlen[key]/4)+2)
if xlen[key] == 64:
out.write(".dword "+x_str+"\n")
else:
out.write(".word "+x_str+"\n")
ed = end_str2.replace("$swreg1",swreg1).replace("$fill_val",str((n_i[key][1]-2)*2))
out.write(ed)
out.write('\n')
out.close()
print("Test File Generated for "+str(xlen[key])+"-bit "+z+"-Test Pattern 2!")

View file

@ -0,0 +1,5 @@
click
ruamel.yaml>=0.16.0
colorlog
python-constraint
riscv_isac>=0.14.0

View file

@ -0,0 +1,359 @@
# See LICENSE.incore for details
"""Common Utils """
import sys
import os
import subprocess
import shlex
from riscv_ctg.log import logger
import ruamel
from ruamel.yaml import YAML
from collections import defaultdict
import riscv_ctg.constants as const
from riscv_isac.utils import combineReader
yaml = YAML(typ="rt")
yaml.default_flow_style = False
yaml.allow_unicode = True
def load_yaml(foo):
try:
with open(foo, "r") as file:
return dict(yaml.load(file))
except ruamel.yaml.constructor.DuplicateKeyError as msg:
logger = logging.getLogger(__name__)
error = "\n".join(str(msg).split("\n")[2:-7])
logger.error(error)
raise SystemExit
def gen_format_data():
'''
Generate dictionary from template.yaml file with the structure:
Format:
- ISA
- Mnemonics
'''
op_template = load_yaml(const.template_file)
# Initialize nested dictionary
nested_dict = lambda: defaultdict(nested_dict)
format_dict = nested_dict()
for mnemonic, data in op_template.items():
if mnemonic not in ['metadata']:
format_type = data['formattype']
isa = data['isa']
for each in isa:
format_dict[format_type][each][mnemonic] = None
return format_dict
def get_instr_list():
'''
Get list of all instructions defined in template file
'''
op_template = load_yaml(const.template_file)
instr_lst = list(op_template.keys())
instr_lst.remove('metadata')
return instr_lst
def load_yamls(foo):
with combineReader(foo) as fp:
return dict(yaml.load(fp))
class makeUtil():
"""
Utility for ease of use of make commands like `make` and `pmake`.
Supports automatic addition and execution of targets. Uses the class
:py:class:`shellCommand` to execute commands.
"""
def __init__(self,makeCommand='make',makefilePath="./Makefile"):
""" Constructor.
:param makeCommand: The variant of make to be used with optional arguments.
Ex - `pmake -j 8`
:type makeCommand: str
:param makefilePath: The path to the makefile to be used.
:type makefilePath: str
"""
self.makeCommand=makeCommand
self.makefilePath = makefilePath
self.targets = []
def add_target(self,command,tname=""):
"""
Function to add a target to the makefile.
:param command: The command to be executed when the target is run.
:type command: str
:param tname: The name of the target to be used. If not specified, TARGET<num> is used as the name.
:type tname: str
"""
if tname == "":
tname = "TARGET"+str(len(self.targets))
with open(self.makefilePath,"a") as makefile:
makefile.write("\n\n.PHONY : " + tname + "\n" + tname + " :\n\t"+command.replace("\n","\n\t"))
self.targets.append(tname)
def execute_target(self,tname,cwd="./"):
"""
Function to execute a particular target only.
:param tname: Name of the target to execute.
:type tname: str
:param cwd: The working directory to be set while executing the make command.
:type cwd: str
:raise AssertionError: If target name is not present in the list of defined targets.
"""
assert tname in self.targets, "Target does not exist."
shellCommand(self.makeCommand+" -f "+self.makefilePath+" "+tname).run(cwd=cwd)
def execute_all(self,cwd):
"""
Function to execute all the defined targets.
:param cwd: The working directory to be set while executing the make command.
:type cwd: str
"""
shellCommand(self.makeCommand+" -f "+self.makefilePath+" "+" ".join(self.targets)).run(cwd=cwd)
class Command():
"""
Class for command build which is supported
by :py:mod:`suprocess` module. Supports automatic
conversion of :py:class:`pathlib.Path` instances to
valid format for :py:mod:`subprocess` functions.
"""
def __init__(self, *args, pathstyle='auto', ensure_absolute_paths=False):
"""Constructor.
:param pathstyle: Determine the path style when adding instance of
:py:class:`pathlib.Path`. Path style determines the slash type
which separates the path components. If pathstyle is `auto`, then
on Windows backslashes are used and on Linux forward slashes are used.
When backslashes should be prevented on all systems, the pathstyle
should be `posix`. No other values are allowed.
:param ensure_absolute_paths: If true, then any passed path will be
converted to absolute path.
:param args: Initial command.
:type pathstyle: str
:type ensure_absolute_paths: bool
"""
self.ensure_absolute_paths = ensure_absolute_paths
self.pathstyle = pathstyle
self.args = []
for arg in args:
self.append(arg)
def append(self, arg):
"""Add new argument to command.
:param arg: Argument to be added. It may be list, tuple,
:py:class:`Command` instance or any instance which
supports :py:func:`str`.
"""
to_add = []
if type(arg) is list:
to_add = arg
elif type(arg) is tuple:
to_add = list(arg)
elif isinstance(arg, type(self)):
to_add = arg.args
elif isinstance(arg, str) and not self._is_shell_command():
to_add = shlex.split(arg)
else:
# any object which will be converted into str.
to_add.append(arg)
# Convert all arguments to its string representation.
# pathlib.Path instances
to_add = [
self._path2str(el) if isinstance(el, pathlib.Path) else str(el)
for el in to_add
]
self.args.extend(to_add)
def clear(self):
"""Clear arguments."""
self.args = []
def run(self, **kwargs):
"""Execute the current command.
Uses :py:class:`subprocess.Popen` to execute the command.
:return: The return code of the process .
:raise subprocess.CalledProcessError: If `check` is set
to true in `kwargs` and the process returns
non-zero value.
"""
kwargs.setdefault('shell', self._is_shell_command())
cwd = self._path2str(kwargs.get(
'cwd')) if not kwargs.get('cwd') is None else self._path2str(
os.getcwd())
kwargs.update({'cwd': cwd})
logger.debug(cwd)
# When running as shell command, subprocess expects
# The arguments to be string.
logger.debug(str(self))
cmd = str(self) if kwargs['shell'] else self
x = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
**kwargs)
out, err = x.communicate()
out = out.rstrip()
err = err.rstrip()
if x.returncode != 0:
if out:
logger.error(out.decode("ascii"))
if err:
logger.error(err.decode("ascii"))
else:
if out:
logger.warning(out.decode("ascii"))
if err:
logger.warning(err.decode("ascii"))
return x.returncode
def _is_shell_command(self):
"""
Return true if current command is supposed to be executed
as shell script otherwise false.
"""
return any('|' in arg for arg in self.args)
def _path2str(self, path):
"""Convert :py:class:`pathlib.Path` to string.
The final form of the string is determined by the
configuration of `Command` instance.
:param path: Path-like object which will be converted
into string.
:return: String representation of `path`
"""
path = pathlib.Path(path)
if self.ensure_absolute_paths and not path.is_absolute():
path = path.resolve()
if self.pathstyle == 'posix':
return path.as_posix()
elif self.pathstyle == 'auto':
return str(path)
else:
raise ValueError(f"Invalid pathstyle {self.pathstyle}")
def __add__(self, other):
cmd = Command(self,
pathstyle=self.pathstyle,
ensure_absolute_paths=self.ensure_absolute_paths)
cmd += other
return cmd
def __iadd__(self, other):
self.append(other)
return self
def __iter__(self):
"""
Support iteration so functions from :py:mod:`subprocess` module
support `Command` instance.
"""
return iter(self.args)
def __repr__(self):
return f'<{self.__class__.__name__} args={self.args}>'
def __str__(self):
return ' '.join(self.args)
class shellCommand(Command):
"""
Sub Class of the command class which always executes commands as shell commands.
"""
def __init__(self, *args, pathstyle='auto', ensure_absolute_paths=False):
"""
:param pathstyle: Determine the path style when adding instance of
:py:class:`pathlib.Path`. Path style determines the slash type
which separates the path components. If pathstyle is `auto`, then
on Windows backslashes are used and on Linux forward slashes are used.
When backslashes should be prevented on all systems, the pathstyle
should be `posix`. No other values are allowed.
:param ensure_absolute_paths: If true, then any passed path will be
converted to absolute path.
:param args: Initial command.
:type pathstyle: str
:type ensure_absolute_paths: bool
"""
return super().__init__(*args,
pathstyle=pathstyle,
ensure_absolute_paths=ensure_absolute_paths)
def _is_shell_command(self):
return True
def sys_command(command):
logger.warning('$ {0} '.format(' '.join(shlex.split(command))))
x = subprocess.Popen(shlex.split(command),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
try:
out, err = x.communicate(timeout=5)
except subprocess.TimeoutExpired:
x.kill()
out, err = x.communicate()
out = out.rstrip()
err = err.rstrip()
if x.returncode != 0:
if out:
logger.error(out.decode("ascii"))
if err:
logger.error(err.decode("ascii"))
else:
if out:
logger.debug(out.decode("ascii"))
if err:
logger.debug(err.decode("ascii"))
return out.decode("ascii")
def sys_command_file(command, filename):
cmd = command.split(' ')
cmd = [x.strip(' ') for x in cmd]
cmd = [i for i in cmd if i]
logger.debug('{0} > {1}'.format(' '.join(cmd), filename))
fp = open(filename, 'w')
out = subprocess.Popen(cmd, stdout=fp, stderr=fp)
stdout, stderr = out.communicate()
fp.close()

View file

@ -0,0 +1,13 @@
## CGF: Cover Group Format
- Uses a simple to use and a human readable YAML format to define cover groups and cover-points for the RISC-V ISA.
- Declares datasets separately which can be used across coverpoints:
- Operand Addresses for a single instruction
- Operand Value for a single instruction
- Abstract functions like walking1s and walking0s which get unrolled by the extraction tool
- Covergroups include multiple datasets
- Each coverpoint is defined as a boolean expression which can to be evaluated by the "eval"
tool of python.
- Coverpoints to use a standard set of keywords like: rs1, rs2, rd, rs1_val, rs2_val, etc
- Uses Anchors and Aliases to keep the size of the YAML file small

View file

@ -0,0 +1,563 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
datasets:
rv32e_regs_mx0: &rv32e_regs_mx0
x1: 0
x2: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
rv32e_regs_mx2: &rv32e_regs_mx2
x1: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
rv32e_regs: &rv32e_regs
x0: 0
x1: 0
x2: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
all_regs: &all_regs
x0: 0
x1: 0
x2: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
x16: 0
x17: 0
x18: 0
x19: 0
x20: 0
x21: 0
x22: 0
x23: 0
x24: 0
x25: 0
x26: 0
x27: 0
x28: 0
x29: 0
x30: 0
x31: 0
all_fregs: &all_fregs
f0: 0
f1: 0
f2: 0
f3: 0
f4: 0
f5: 0
f6: 0
f7: 0
f8: 0
f9: 0
f10: 0
f11: 0
f12: 0
f13: 0
f14: 0
f15: 0
f16: 0
f17: 0
f18: 0
f19: 0
f20: 0
f21: 0
f22: 0
f23: 0
f24: 0
f25: 0
f26: 0
f27: 0
f28: 0
f29: 0
f30: 0
f31: 0
pair_regs: &pair_regs
x2: 0
x4: 0
x6: 0
x8: 0
x10: 0
x12: 0
x14: 0
x16: 0
x18: 0
x20: 0
x22: 0
x24: 0
x26: 0
x28: 0
x30: 0
c_regs: &c_regs
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
all_regs_mx2: &all_regs_mx2
x1: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
x16: 0
x17: 0
x18: 0
x19: 0
x20: 0
x21: 0
x22: 0
x23: 0
x24: 0
x25: 0
x26: 0
x27: 0
x28: 0
x29: 0
x30: 0
x31: 0
all_regs_mx0: &all_regs_mx0
x1: 0
x2: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
x16: 0
x17: 0
x18: 0
x19: 0
x20: 0
x21: 0
x22: 0
x23: 0
x24: 0
x25: 0
x26: 0
x27: 0
x28: 0
x29: 0
x30: 0
x31: 0
cbfmt_immval_sgn: &cbfmt_immval_sgn
'imm_val == (-2**(6-1))': 0
'imm_val == 0': 0
'imm_val == (2**(6-1)-1)': 0
'imm_val == 1': 0
rfmt_op_comb: &rfmt_op_comb
'rs1 == rs2 != rd': 0
'rs1 == rd != rs2': 0
'rs2 == rd != rs1': 0
'rs1 == rs2 == rd': 0
'rs1 != rs2 and rs1 != rd and rs2 != rd': 0
div_hardcoded_opcomb: &div_hardcoded_opcomb
'rs1 == rd != rs2 and rd != "x0"': 0
'rs1 == rd != rs2 and rd == "x0"': 0
'rs1 == "x0" != rd': 0
'rd == "x0" != rs1': 0
ramofmt_op_comb: &ramofmt_op_comb
'rs1 == rd != rs2': 0
'rs2 == rd != rs1': 0
'rs1 != rs2 and rs1 != rd and rs2 != rd': 0
r4fmt_op_comb: &r4fmt_op_comb
'rs1 == rs2 == rs3 == rd': 0
'rs1 == rs2 == rs3 != rd': 0
'rs1 == rs2 == rd != rs3': 0
'rs1 == rd == rs3 != rs2': 0
'rd == rs2 == rs3 != rs1': 0
'rs2 == rd != rs1 and rs2 == rd != rs3 and rs3 != rs1': 0
'rs3 == rd != rs1 and rs3 == rd != rs2 and rs2 != rs1': 0
'rs2 == rs3 != rs1 and rs2 == rs3 != rd and rd != rs1': 0
'rs1 == rd != rs2 and rs1 == rd != rs3 and rs3 != rs2': 0
'rs1 == rs3 != rs2 and rs1 == rs3 != rd and rd != rs2': 0
'rs1 == rs2 != rs3 and rs1 == rs2 != rd and rd != rs3': 0
'rs1 != rs2 and rs1 != rd and rs1 != rs3 and rs2 != rs3 and rs2 != rd and rs3 != rd': 0
ifmt_op_comb: &ifmt_op_comb
'rs1 == rd': 0
'rs1 != rd': 0
sfmt_op_comb: &sfmt_op_comb
'rs1 == rs2': 0
'rs1 != rs2': 0
r0fmt_op_comb: &r0fmt_op_comb
'rs1 == 0': 0
'rs1 != 0': 0
base_rs1val_sgn: &base_rs1val_sgn
'rs1_val == (-2**(xlen-1))': 0
'rs1_val == 0': 0
'rs1_val == (2**(xlen-1)-1)': 0
'rs1_val == 1': 0
base_rs1val_sgn_rs2val_zero: &base_rs1val_sgn_rs2val_zero
'rs1_val == (-2**(xlen-1)) and rs2_val == 0': 0
'rs1_val == 0 and rs2_val == 0': 0
'rs1_val == (2**(xlen-1)-1) and rs2_val == 0': 0
'rs1_val == 1 and rs2_val == 0': 0
base_rs2val_sgn: &base_rs2val_sgn
'rs2_val == (-2**(xlen-1))': 0
'rs2_val == 0': 0
'rs2_val == (2**(xlen-1)-1)': 0
'rs2_val == 1': 0
base_rs3val_sgn: &base_rs3val_sgn
'rs3_val == (-2**(xlen-1))': 0
'rs3_val == 0': 0
'rs3_val == (2**(xlen-1)-1)': 0
'rs3_val == 1': 0
base_rs1val_unsgn: &base_rs1val_unsgn
'rs1_val == 0': 0
'rs1_val == (2**(xlen)-1)': 0
'rs1_val == 1': 0
base_rs2val_unsgn: &base_rs2val_unsgn
'rs2_val == 0': 0
'rs2_val == (2**(xlen)-1)': 0
'rs2_val == 1': 0
base_rs3val_unsgn: &base_rs3val_unsgn
'rs3_val == 0': 0
'rs3_val == (2**(xlen)-1)': 0
'rs3_val == 1': 0
rfmt_val_comb_sgn: &rfmt_val_comb_sgn
'rs1_val > 0 and rs2_val > 0': 0
'rs1_val > 0 and rs2_val < 0': 0
'rs1_val < 0 and rs2_val < 0': 0
'rs1_val < 0 and rs2_val > 0': 0
'rs1_val == rs2_val': 0
'rs1_val != rs2_val': 0
div_corner_case: &div_corner_case
'rs1_val == -(2**(xlen-1)) and rs2_val == -0x01': 0
rfmt_val_comb_unsgn: &rfmt_val_comb_unsgn
'rs1_val > 0 and rs2_val > 0': 0
'rs1_val == rs2_val and rs1_val > 0 and rs2_val > 0': 0
'rs1_val != rs2_val and rs1_val > 0 and rs2_val > 0': 0
ifmt_val_comb_sgn: &ifmt_val_comb_sgn
'rs1_val == imm_val': 0
'rs1_val != imm_val': 0
'rs1_val > 0 and imm_val > 0': 0
'rs1_val > 0 and imm_val < 0': 0
'rs1_val < 0 and imm_val > 0': 0
'rs1_val < 0 and imm_val < 0': 0
ifmt_val_comb_unsgn: &ifmt_val_comb_unsgn
'rs1_val == imm_val and rs1_val > 0 and imm_val > 0': 0
'rs1_val != imm_val and rs1_val > 0 and imm_val > 0': 0
ifmt_base_immval_sgn: &ifmt_base_immval_sgn
'imm_val == (-2**(12-1))': 0
'imm_val == 0': 0
'imm_val == (2**(12-1)-1)': 0
'imm_val == 1': 0
ifmt_base_immval_sgn_len: &ifmt_base_immval_sgn_len
'imm_val == (-2**(ceil(log(xlen,2))-1))': 0
'imm_val == 0': 0
'imm_val == (2**(ceil(log(xlen,2))-1)-1)': 0
'imm_val == 1': 0
ifmt_base_immval_unsgn_len_sub_3: &ifmt_base_immval_unsgn_len_sub_3
'imm_val == 0': 0
'imm_val == (2**(ceil(log(xlen,2))-3)-1)': 0
'imm_val == 1': 0
ifmt_base_immval_unsgn: &ifmt_base_immval_unsgn
'imm_val == 0': 0
'imm_val == (2**(12)-1)': 0
'imm_val == 1': 0
ifmt_base_shift: &ifmt_base_shift
'rs1_val < 0 and imm_val > 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val > 0 and imm_val < xlen': 0
'rs1_val < 0 and imm_val == 0': 0
'rs1_val > 0 and imm_val == 0': 0
'rs1_val < 0 and imm_val == (xlen-1)': 0
'rs1_val > 0 and imm_val == (xlen-1)': 0
'rs1_val == imm_val and imm_val > 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val >= 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val >= 0 and imm_val < xlen': 0
ifmt_base_shift_32w: &ifmt_base_shift_32w
'rs1_val < 0 and imm_val > 0 and imm_val < 32': 0
'rs1_val > 0 and imm_val > 0 and imm_val < 32': 0
'rs1_val < 0 and imm_val == 0': 0
'rs1_val > 0 and imm_val == 0': 0
'rs1_val < 0 and imm_val == 31': 0
'rs1_val > 0 and imm_val == 31': 0
'rs1_val == imm_val and imm_val > 0 and imm_val < 32': 0
'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < 32': 0
'rs1_val == 0 and imm_val >= 0 and imm_val < 32': 0
'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < 32': 0
'rs1_val == 1 and imm_val >= 0 and imm_val < 32': 0
rfmt_base_shift: &rfmt_base_shift
'rs1_val < 0 and rs2_val > 0 and rs2_val < xlen': 0
'rs1_val > 0 and rs2_val > 0 and rs2_val < xlen': 0
'rs1_val < 0 and rs2_val == 0': 0
'rs1_val > 0 and rs2_val == 0': 0
'rs1_val == rs2_val and rs2_val > 0 and rs2_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and rs2_val >= 0 and rs2_val < xlen': 0
'rs1_val == 0 and rs2_val >= 0 and rs2_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and rs2_val >= 0 and rs2_val < xlen': 0
'rs1_val == 1 and rs2_val >= 0 and rs2_val < xlen': 0
bfmt_base_branch_val_align_sgn: &bfmt_base_branch_val_align_sgn
'rs1_val > 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0
'rs1_val > 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0
'rs1_val < 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0
'rs1_val < 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0
'rs1_val == rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0
'rs1_val == rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0
'rs1_val > rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0
'rs1_val > rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0
'rs1_val < rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0
'rs1_val < rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0
bfmt_base_branch_val_align_unsgn: &bfmt_base_branch_val_align_unsgn
'rs1_val > 0 and rs2_val > 0': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val > 0': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val < 0': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val > 0 ': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val < 0 ': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val > 0 ': 0
'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val < 0 ': 0
rs1val_walking: &rs1val_walking
'walking_ones("rs1_val", xlen)': 0
'walking_zeros("rs1_val", xlen)': 0
'alternate("rs1_val",xlen)': 0
rs2val_walking: &rs2val_walking
'walking_ones("rs2_val", xlen)': 0
'walking_zeros("rs2_val", xlen)': 0
'alternate("rs2_val",xlen)': 0
rs3val_walking: &rs3val_walking
'walking_ones("rs3_val", xlen)': 0
'walking_zeros("rs3_val", xlen)': 0
'alternate("rs3_val",xlen)': 0
ifmt_immval_walking: &ifmt_immval_walking
'walking_ones("imm_val", 12)': 0
'walking_zeros("imm_val", 12)': 0
'alternate("imm_val",12)': 0
ifmt_immval_walking_len: &ifmt_immval_walking_len
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val",ceil(log(xlen,2)), False)': 0
ifmt_immval_walking_len_sub_3: &ifmt_immval_walking_len_sub_3
'walking_ones("imm_val", ceil(log(xlen,2))-3, False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2))-3, False)': 0
'alternate("imm_val", ceil(log(xlen,2))-3, False)': 0
ifmt_immval_walking_5u: &ifmt_immval_walking_5u
'walking_ones("imm_val", 5, False)': 0
'walking_zeros("imm_val", 5, False)': 0
'alternate("imm_val", 5, False)': 0
rs1val_walking_unsgn: &rs1val_walking_unsgn
'walking_ones("rs1_val", xlen,False)': 0
'walking_zeros("rs1_val", xlen,False)': 0
'alternate("rs1_val",xlen,False)': 0
rs2val_walking_unsgn: &rs2val_walking_unsgn
'walking_ones("rs2_val", xlen,False)': 0
'walking_zeros("rs2_val", xlen,False)': 0
'alternate("rs2_val",xlen,False)': 0
crfmt_val_comb_sgn: &crfmt_val_comb_sgn
'rs2_val > 0': 0
'rs2_val < 0': 0
cbimm_val_walking: &cbimm_val_walking
'walking_ones("imm_val", 6)': 0
'walking_zeros("imm_val", 6)': 0
'alternate("imm_val",6)': 0
ifmt_immval_walking_unsgn: &ifmt_immval_walking_unsgn
'walking_ones("imm_val", 12,False)': 0
'walking_zeros("imm_val", 12,False)': 0
'alternate("imm_val",12,False)': 0
rvp64_rs1val_sgn: &rvp64_rs1val_sgn
'rs1_val == (-2**63)': 0
'rs1_val == 0': 0
'rs1_val == (2**63-1)': 0
'rs1_val == 1': 0
rvp64_rs2val_sgn: &rvp64_rs2val_sgn
'rs2_val == (-2**63)': 0
'rs2_val == 0': 0
'rs2_val == (2**63-1)': 0
'rs2_val == 1': 0
rvp64_rs1val_unsgn: &rvp64_rs1val_unsgn
'rs1_val == 0': 0
'rs1_val == (2**64-1)': 0
'rs1_val == 1': 0
rvp64_rs2val_unsgn: &rvp64_rs2val_unsgn
'rs2_val == 0': 0
'rs2_val == (2**64-1)': 0
'rs2_val == 1': 0
rvp64_rs1val_walking_sgn: &rvp64_rs1val_walking_sgn
'walking_ones("rs1_val", 64)': 0
'walking_zeros("rs1_val", 64)': 0
'alternate("rs1_val",64)': 0
rvp64_rs2val_walking_sgn: &rvp64_rs2val_walking_sgn
'walking_ones("rs2_val", 64)': 0
'walking_zeros("rs2_val", 64)': 0
'alternate("rs2_val",64)': 0
rvp64_rs1val_walking_unsgn: &rvp64_rs1val_walking_unsgn
'walking_ones("rs1_val", 64, signed=False)': 0
'walking_zeros("rs1_val", 64, signed=False)': 0
'alternate("rs1_val",64, signed=False)': 0
rvp64_rs2val_walking_unsgn: &rvp64_rs2val_walking_unsgn
'walking_ones("rs2_val", 64, signed=False)': 0
'walking_zeros("rs2_val", 64, signed=False)': 0
'alternate("rs2_val",64, signed=False)': 0
rvp128_rs1val_sgn: &rvp128_rs1val_sgn
'rs1_val == 0': 0
'rs1_val == 1': 0
rvp128_rs2val_sgn: &rvp128_rs2val_sgn
'rs2_val == 0': 0
'rs2_val == 1': 0
rvp128_rs1val_walking_sgn: &rvp128_rs1val_walking_sgn
'walking_ones("rs1_val", 128)': 0
'walking_zeros("rs1_val", 128)': 0
'alternate("rs1_val",128)': 0
rvp128_rs2val_walking_sgn: &rvp128_rs2val_walking_sgn
'walking_ones("rs2_val", 128)': 0
'walking_zeros("rs2_val", 128)': 0
'alternate("rs2_val",128)': 0
zacas_op_comb: &zacas_op_comb
'rs1 != rs2 and rs1 != rd and rs2 != rd': 0
zacas_dcas_rs1val_sgn: &zacas_dcas_rs1val_sgn
'rs1_val == 0': 0
'rs1_val == 1': 0
zacas_dcas_rs2val_sgn: &zacas_dcas_rs2val_sgn
'rs2_val == 0': 0
'rs2_val == 1': 0
zacas128_rs1val_walking_sgn: &zacas128_rs1val_walking_sgn
'walking_ones("rs1_val", 128)': 0
'walking_zeros("rs1_val", 128)': 0
'alternate("rs1_val",128)': 0
zacas128_rs2val_walking_sgn: &zacas128_rs2val_walking_sgn
'walking_ones("rs2_val", 128)': 0
'walking_zeros("rs2_val", 128)': 0
'alternate("rs2_val",128)': 0
zacas64_rs1val_walking_sgn: &zacas64_rs1val_walking_sgn
'walking_ones("rs1_val", 64)': 0
'walking_zeros("rs1_val", 64)': 0
'alternate("rs1_val",64)': 0
zacas64_rs2val_walking_sgn: &zacas64_rs2val_walking_sgn
'walking_ones("rs2_val", 64)': 0
'walking_zeros("rs2_val", 64)': 0
'alternate("rs2_val",64)': 0

View file

@ -0,0 +1,752 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
fence:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
fence: 0
addi:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
addi: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
slti:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
slti: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
sltiu:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sltiu: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0
<<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn]
andi:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
andi: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
ori:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
ori: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
xori:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
xori: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
slli:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
slli: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
srai:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
srai: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
srli:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
srli: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
add:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
add: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sub:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sub: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
slt:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
slt: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sltu:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sltu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
and:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
and: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
or:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
or: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
xor:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
xor: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sll:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sll: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
srl:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
srl: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
sra:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sra: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
beq:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
beq: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bge:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bge: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bgeu:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bgeu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_unsgn
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'sp_dataset(xlen,signed=False)': 0
blt:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
blt: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bltu:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bltu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_unsgn
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'sp_dataset(xlen,signed=False)': 0
bne:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bne: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
lhu-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lhu: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lh-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lh: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lbu-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lbu: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lb-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lb: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lw-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lw: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
sh-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sh: 0
rs1:
<<: *rv32e_regs_mx0
rs2:
<<: *rv32e_regs
op_comb:
'rs1 != rs2': 0
val_comb:
<<: [ *base_rs2val_sgn]
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
abstract_comb:
<<: [*rs2val_walking]
sb-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sb: 0
rs1:
<<: *rv32e_regs_mx0
rs2:
<<: *rv32e_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
sw-align:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
sw: 0
rs1:
<<: *rv32e_regs_mx0
rs2:
<<: *rv32e_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
auipc:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
auipc: 0
rd:
<<: *rv32e_regs
val_comb:
'imm_val == 0': 0
'imm_val > 0': 0
'imm_val == ((2**20)-1)': 0
abstract_comb:
'sp_dataset(20,["imm_val"],signed=False)': 0
'walking_ones("imm_val", 20, False)': 0
'walking_zeros("imm_val", 20, False)': 0
'alternate("imm_val", 20, False)': 0
lui:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
lui: 0
rd:
<<: *rv32e_regs
val_comb:
'imm_val == 0': 0
'imm_val > 0': 0
'imm_val == ((2**20)-1)': 0
abstract_comb:
'sp_dataset(20,["imm_val"],signed=False)': 0
'walking_ones("imm_val", 20, False)': 0
'walking_zeros("imm_val", 20, False)': 0
'alternate("imm_val", 20, False)': 0
jal:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
jal: 0
rd:
<<: *rv32e_regs
val_comb:
'imm_val < 0' : 0
'imm_val > 0': 0
'imm_val == (-(2**(18)))': 0
'imm_val == ((2**(18)))': 0
jalr:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
jalr: 0
rs1:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
<<: *ifmt_immval_walking

View file

@ -0,0 +1,705 @@
sh1add:
config:
- check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True
mnemonics:
sh1add: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sh2add:
config:
- check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True
mnemonics:
sh2add: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sh3add:
config:
- check ISA:=regex(.*E.*Zba.*) ;def RVTEST_E = True
mnemonics:
sh3add: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
xnor:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
xnor: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
zext.h_32:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
zext.h: 0
base_op: pack
p_op_cond: rs2 == x0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0xFF80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
andn:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
andn: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
'bitmanip_dataset(xlen,["rs1_val","rs2_val"],False)': 0
clz:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
clz: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
ctz:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
ctz: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
cpop:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
cpop: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
max:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
max: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
maxu:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
maxu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
min:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
min: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
minu:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
minu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
orcb_32:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
orc.b: 0
base_op: gorci
p_op_cond: imm_val == 7
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0x1020408': 0
'rs1_val == 0x2040801': 0
'rs1_val == 0x4080102': 0
'rs1_val == 0x8010204': 0
abstract_comb:
<<: [*rs1val_walking_unsgn]
orn:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
orn: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
rev8_32:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
rev8: 0
base_op: grevi
p_op_cond: imm_val == 24
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0x1020408': 0
'rs1_val == 0x2040801': 0
'rs1_val == 0x4080102': 0
'rs1_val == 0x8010204': 0
abstract_comb:
'leading_ones(32, ["rs1_val"], [32])': 0
'trailing_ones(32, ["rs1_val"], [32])': 0
'leading_zeros(32, ["rs1_val"], [32])': 0
'trailing_zeros(32, ["rs1_val"], [32])': 0
'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0
rol:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
rol: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
ror:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zks.*) ;def RVTEST_E = True
mnemonics:
ror: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
rori:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkb.*) ;def RVTEST_E = True
- check ISA:=regex(.*.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*I.*Zks.*) ;def RVTEST_E = True
mnemonics:
rori: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","imm_val"],[32,5])': 0
'trailing_ones(32, ["rs1_val","imm_val"],[32,5])': 0
'leading_zeros(32, ["rs1_val","imm_val"],[32,5])': 0
'trailing_zeros(32, ["rs1_val","imm_val"],[32,5])': 0
sext.b:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
sext.b: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x8000': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sext.h:
config:
- check ISA:=regex(.*E.*Zbb.*) ;def RVTEST_E = True
mnemonics:
sext.h: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0xff80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
clmul:
config:
- check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkc.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
mnemonics:
clmul: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
clmulh:
config:
- check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zbkc.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zk.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zkn.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zks.*) ;def RVTEST_E = True
mnemonics:
clmulh: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
clmulr:
config:
- check ISA:=regex(.*E.*Zbc.*) ;def RVTEST_E = True
mnemonics:
clmulr: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
bclr:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bclr: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bclri:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bclri: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
bext:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bext: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bexti:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bexti: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
binv:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
binv: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
binvi:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
binvi: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
bset:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bset: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bseti:
config:
- check ISA:=regex(.*E.*Zbs.*) ;def RVTEST_E = True
mnemonics:
bseti: 0
rs1:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0

View file

@ -0,0 +1,6 @@
fencei:
config:
- check ISA:=regex(.*E.*Zifencei.*) ;def RVTEST_E = True
mnemonics:
fence.i: 0

View file

@ -0,0 +1,146 @@
misalign-lh:
cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True
config:
- check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True
mnemonics:
lh: 0
val_comb:
'ea_align == 1': 0
misalign-lhu:
config:
- check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True
mnemonics:
lhu: 0
val_comb:
'ea_align == 1': 0
misalign-lw:
config:
- check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True
mnemonics:
lw: 0
val_comb:
'ea_align == 1': 0
'ea_align == 2': 0
'ea_align == 3': 0
misalign-sh:
config:
- check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True
mnemonics:
sh: 0
val_comb:
'ea_align == 1': 0
misalign-sw:
config:
- check ISA:=regex(.*E.*); check hw_data_misaligned_support:=True ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*Zicsr.*) ;def RVTEST_E = True
mnemonics:
sw: 0
val_comb:
'ea_align == 1': 0
'ea_align == 2': 0
'ea_align == 3': 0
misalign2-jalr:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
jalr: 0
val_comb:
'imm_val%2 == 1 and ea_align == 2': 0
'imm_val%2 == 0 and ea_align == 2': 0
misalign1-jalr:
config:
- check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
jalr: 0
val_comb:
'imm_val%2 == 1 and ea_align == 1': 0
'imm_val%2 == 0 and ea_align == 1': 0
misalign-jal:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
jal: 0
val_comb:
'ea_align == 2': 0
misalign-bge:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bge: 0
val_comb:
' rs1_val>rs2_val and ea_align == 2': 0
misalign-bgeu:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bgeu: 0
val_comb:
' rs1_val>rs2_val and ea_align == 2': 0
misalign-blt:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
blt: 0
val_comb:
' rs1_val<rs2_val and ea_align == 2': 0
misalign-bltu:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bltu: 0
val_comb:
' rs1_val<rs2_val and ea_align == 2': 0
misalign-bne:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
bne: 0
val_comb:
' rs1_val!=rs2_val and ea_align == 2': 0
misalign-beq:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
- check ISA:=regex(.*E.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True ;def RVTEST_E = True
cond: check ISA:=regex(.*E.*) ;def RVTEST_E = True
mnemonics:
beq: 0
val_comb:
' rs1_val==rs2_val and ea_align == 2': 0

View file

@ -0,0 +1,446 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
cebreak:
config:
- check ISA:=regex(.*E.*Zicsr.*.C*) ;def RVTEST_E = True
mnemonics:
c.ebreak: 0
caddi4spn:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.addi4spn: 0
rd:
<<: *c_regs
val_comb:
'imm_val > 0' : 0
'imm_val == 1020': 0
abstract_comb:
'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0
'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0
clw:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.lw: 0
rs1:
<<: *c_regs
rd:
<<: *c_regs
op_comb:
'rs1 == rd': 0
'rs1 != rd': 0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
abstract_comb:
'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0
csw:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.sw: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0
cnop:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.nop: 0
val_comb:
abstract_comb:
<<: *cbimm_val_walking
caddi:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.addi: 0
rd:
<<: *rv32e_regs_mx0
val_comb:
<<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0
<<: [*rs1val_walking, *cbimm_val_walking]
cjal:
config:
- check ISA:=regex(.*RV32.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.jal: 0
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0
cli:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.li: 0
rd:
<<: *rv32e_regs
val_comb:
<<: [*cbfmt_immval_sgn]
abstract_comb:
'walking_ones("imm_val", 6)': 0
'walking_zeros("imm_val", 6)': 0
'alternate("imm_val", 6)': 0
caddi16sp:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.addi16sp: 0
rd:
x2: 0
val_comb:
<<: [*base_rs1val_sgn,*ifmt_val_comb_sgn]
'imm_val == -512': 0
'imm_val == 496': 0
abstract_comb:
<<: [*rs1val_walking]
'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0
'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0
'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0
clui:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.lui: 0
rd:
<<: *rv32e_regs_mx2
val_comb:
'rs1_val > 0 and imm_val > 32': 0
'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0
'rs1_val < 0 and imm_val > 32': 0
'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0
abstract_comb:
'walking_ones("imm_val", 6, False)': 0
'walking_zeros("imm_val", 6, False)': 0
'alternate("imm_val", 6, False)': 0
csrli:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.srli: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
csrai:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.srai: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
candi:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.andi: 0
rs1:
<<: *c_regs
val_comb:
<<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0
<<: [*rs1val_walking, *cbimm_val_walking]
csub:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.sub: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cxor:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.xor: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cor:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.or: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cand:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.and: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cj:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.j: 0
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0
cbeqz:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.beqz: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val > 0 and imm_val > 0': 0
'rs1_val < 0 and imm_val > 0': 0
'rs1_val == 0 and imm_val > 0': 0
'rs1_val > 0 and imm_val < 0': 0
'rs1_val < 0 and imm_val < 0': 0
'rs1_val == 0 and imm_val < 0': 0
<<: [*base_rs1val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
cbnez:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.bnez: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val > 0 and imm_val > 0': 0
'rs1_val < 0 and imm_val > 0': 0
'rs1_val == 0 and imm_val > 0': 0
'rs1_val > 0 and imm_val < 0': 0
'rs1_val < 0 and imm_val < 0': 0
'rs1_val == 0 and imm_val < 0': 0
<<: [*base_rs1val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
cslli:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.slli: 0
rd:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
clwsp:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.lwsp: 0
rd:
<<: *rv32e_regs_mx0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
abstract_comb:
'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0
cjr:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.jr: 0
rs1:
<<: *rv32e_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *base_rs1val_sgn_rs2val_zero
abstract_comb:
'sp_dataset(xlen)': 0
<<: *rs1val_walking
cmv:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.mv: 0
rs2:
<<: *rv32e_regs_mx0
rd:
<<: *rv32e_regs
op_comb:
'rs2 == rd and rs2 != 0': 0
'rs2 != rd and rs2 != 0': 0
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs2_val"])': 0
<<: [*rs2val_walking]
cadd:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.add: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cjalr:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.jalr: 0
rs1:
<<: *rv32e_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *base_rs1val_sgn_rs2val_zero
abstract_comb:
'sp_dataset(xlen)': 0
<<: *rs1val_walking
cswsp:
config:
- check ISA:=regex(.*E.*C.*) ;def RVTEST_E = True
mnemonics:
c.swsp: 0
rs2:
<<: *rv32e_regs_mx2
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0

View file

@ -0,0 +1,154 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
mul:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
mul: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
mulh:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
mulh: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
mulhu:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
mulhu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
mulhsu:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
mulhsu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn]
'rs1_val > 0 and rs2_val > 0': 0
abstract_comb:
'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0
<<: [*rs1val_walking, *rs2val_walking_unsgn]
div:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
div: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
divu:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
divu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
rem:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
rem: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
remu:
config:
- check ISA:=regex(.*E.*M.*) ;def RVTEST_E = True
mnemonics:
remu: 0
rs1:
<<: *rv32e_regs
rs2:
<<: *rv32e_regs
rd:
<<: *rv32e_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]

View file

@ -0,0 +1,752 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
fence:
config:
- check ISA:=regex(.*I.*)
mnemonics:
fence: 0
addi:
config:
- check ISA:=regex(.*I.*)
mnemonics:
addi: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
slti:
config:
- check ISA:=regex(.*I.*)
mnemonics:
slti: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
sltiu:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sltiu: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0
<<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn]
andi:
config:
- check ISA:=regex(.*I.*)
mnemonics:
andi: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
ori:
config:
- check ISA:=regex(.*I.*)
mnemonics:
ori: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
xori:
config:
- check ISA:=regex(.*I.*)
mnemonics:
xori: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0
<<: [*rs1val_walking, *ifmt_immval_walking]
slli:
config:
- check ISA:=regex(.*I.*)
mnemonics:
slli: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
srai:
config:
- check ISA:=regex(.*I.*)
mnemonics:
srai: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
srli:
config:
- check ISA:=regex(.*I.*)
mnemonics:
srli: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
<<: *ifmt_base_shift
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
add:
config:
- check ISA:=regex(.*I.*)
mnemonics:
add: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sub:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sub: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
slt:
config:
- check ISA:=regex(.*I.*)
mnemonics:
slt: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sltu:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sltu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
and:
config:
- check ISA:=regex(.*I.*)
mnemonics:
and: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
or:
config:
- check ISA:=regex(.*I.*)
mnemonics:
or: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
xor:
config:
- check ISA:=regex(.*I.*)
mnemonics:
xor: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sll:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sll: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
srl:
config:
- check ISA:=regex(.*I.*)
mnemonics:
srl: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
sra:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sra: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: *rfmt_base_shift
abstract_comb:
<<: [*rs1val_walking]
'sp_dataset(xlen,var_lst=["rs1_val"])': 0
'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0
'alternate("rs2_val", ceil(log(xlen,2)), False)': 0
beq:
config:
- check ISA:=regex(.*I.*)
mnemonics:
beq: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bge:
config:
- check ISA:=regex(.*I.*)
mnemonics:
bge: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bgeu:
config:
- check ISA:=regex(.*I.*)
mnemonics:
bgeu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_unsgn
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'sp_dataset(xlen,signed=False)': 0
blt:
config:
- check ISA:=regex(.*I.*)
mnemonics:
blt: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
bltu:
config:
- check ISA:=regex(.*I.*)
mnemonics:
bltu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_unsgn
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'sp_dataset(xlen,signed=False)': 0
bne:
config:
- check ISA:=regex(.*I.*)
mnemonics:
bne: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *bfmt_base_branch_val_align_sgn
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]
'sp_dataset(xlen)': 0
lhu-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lhu: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lh-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lh: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lbu-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lbu: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lb-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lb: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
lw-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lw: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
sh-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sh: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
op_comb:
'rs1 != rs2': 0
val_comb:
<<: [ *base_rs2val_sgn]
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
abstract_comb:
<<: [*rs2val_walking]
sb-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sb: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'ea_align == 2 and (imm_val % 4) == 0': 0
'ea_align == 2 and (imm_val % 4) == 1': 0
'ea_align == 2 and (imm_val % 4) == 2': 0
'ea_align == 2 and (imm_val % 4) == 3': 0
'ea_align == 1 and (imm_val % 4) == 0': 0
'ea_align == 1 and (imm_val % 4) == 1': 0
'ea_align == 1 and (imm_val % 4) == 2': 0
'ea_align == 1 and (imm_val % 4) == 3': 0
'ea_align == 3 and (imm_val % 4) == 0': 0
'ea_align == 3 and (imm_val % 4) == 1': 0
'ea_align == 3 and (imm_val % 4) == 2': 0
'ea_align == 3 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
sw-align:
config:
- check ISA:=regex(.*I.*)
mnemonics:
sw: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'ea_align == 0 and (imm_val % 4) == 0': 0
'ea_align == 0 and (imm_val % 4) == 1': 0
'ea_align == 0 and (imm_val % 4) == 2': 0
'ea_align == 0 and (imm_val % 4) == 3': 0
'imm_val > 0': 0
'imm_val < 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
auipc:
config:
- check ISA:=regex(.*I.*)
mnemonics:
auipc: 0
rd:
<<: *all_regs
val_comb:
'imm_val == 0': 0
'imm_val > 0': 0
'imm_val == ((2**20)-1)': 0
abstract_comb:
'sp_dataset(20,["imm_val"],signed=False)': 0
'walking_ones("imm_val", 20, False)': 0
'walking_zeros("imm_val", 20, False)': 0
'alternate("imm_val", 20, False)': 0
lui:
config:
- check ISA:=regex(.*I.*)
mnemonics:
lui: 0
rd:
<<: *all_regs
val_comb:
'imm_val == 0': 0
'imm_val > 0': 0
'imm_val == ((2**20)-1)': 0
abstract_comb:
'sp_dataset(20,["imm_val"],signed=False)': 0
'walking_ones("imm_val", 20, False)': 0
'walking_zeros("imm_val", 20, False)': 0
'alternate("imm_val", 20, False)': 0
jal:
config:
- check ISA:=regex(.*I.*)
mnemonics:
jal: 0
rd:
<<: *all_regs
val_comb:
'imm_val < 0' : 0
'imm_val > 0': 0
'imm_val == (-(2**(18)))': 0
'imm_val == ((2**(18)))': 0
jalr:
config:
- check ISA:=regex(.*I.*)
mnemonics:
jalr: 0
rs1:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
<<: *ifmt_immval_walking

View file

@ -0,0 +1,734 @@
sh1add:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zba.*)
mnemonics:
sh1add: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sh2add:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zba.*)
mnemonics:
sh2add: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
sh3add:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zba.*)
mnemonics:
sh3add: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
xnor:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
xnor: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
zext.h_32:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
zext.h: 0
base_op: pack
p_op_cond: rs2 == x0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0xFF80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
andn:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
andn: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
'bitmanip_dataset(xlen,["rs1_val","rs2_val"],False)': 0
clz:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
clz: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
ctz:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
ctz: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
cpop:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
cpop: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
<<: [*rs1val_walking_unsgn]
'leading_zeros(xlen, ["rs1_val"], [xlen], 11)': 0
'leading_ones(xlen, ["rs1_val"], [xlen], 10)': 0
'trailing_zeros(xlen, ["rs1_val"], [xlen], 12)': 0
'trailing_ones(xlen, ["rs1_val"], [xlen], 13)': 0
max:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
max: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
maxu:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
maxu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
min:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
min: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'bitmanip_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
minu:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
minu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
orcb_32:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
orc.b: 0
base_op: gorci
p_op_cond: imm_val == 7
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0x1020408': 0
'rs1_val == 0x2040801': 0
'rs1_val == 0x4080102': 0
'rs1_val == 0x8010204': 0
abstract_comb:
<<: [*rs1val_walking_unsgn]
orn:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
orn: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'bitmanip_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
rev8_32:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
rev8: 0
base_op: grevi
p_op_cond: imm_val == 24
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0x1020408': 0
'rs1_val == 0x2040801': 0
'rs1_val == 0x4080102': 0
'rs1_val == 0x8010204': 0
abstract_comb:
'leading_ones(32, ["rs1_val"], [32])': 0
'trailing_ones(32, ["rs1_val"], [32])': 0
'leading_zeros(32, ["rs1_val"], [32])': 0
'trailing_zeros(32, ["rs1_val"], [32])': 0
'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0
rol:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
rol: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
ror:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
ror: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
rori:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
- check ISA:=regex(.*I.*Zbkb.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
rori: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","imm_val"],[32,5])': 0
'trailing_ones(32, ["rs1_val","imm_val"],[32,5])': 0
'leading_zeros(32, ["rs1_val","imm_val"],[32,5])': 0
'trailing_zeros(32, ["rs1_val","imm_val"],[32,5])': 0
sext.b:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
sext.b: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x8000': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sext.h:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbb.*)
mnemonics:
sext.h: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0xff80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
clmul:
config:
- check ISA:=regex(.*I.*Zbc.*)
- check ISA:=regex(.*I.*Zbkc.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zkn.*)
mnemonics:
clmul: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
clmulh:
config:
- check ISA:=regex(.*I.*Zbc.*)
- check ISA:=regex(.*I.*Zbkc.*)
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
mnemonics:
clmulh: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
clmulr:
config:
- check ISA:=regex(.*I.*Zbc.*)
mnemonics:
clmulr: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
'rs1_val==1 and rs2_val==1': 0
'rs1_val==1 and rs2_val==0': 0
'rs1_val==1 and rs2_val==0x1000': 0
'rs1_val==0 and rs2_val==1': 0
'rs1_val==0 and rs2_val==0': 0
'rs1_val==0 and rs2_val==0x1000': 0
abstract_comb:
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
bclr:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bclr: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bclri:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bclri: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
bext:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bext: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bexti:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bexti: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
binv:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
binv: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
binvi:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
binvi: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
bset:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bset: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
# 'xlenlim("rs2_val", xlen )': 0
'walking_ones("rs1_val", ceil(log(xlen, 2)), False)': 0
'walking_ones("rs2_val", ceil(log(xlen, 2)), False)': 0
'leading_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "rs2_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "rs2_val"], [32,5])': 0
<<: [*rs1val_walking_unsgn,*rs2val_walking_unsgn]
bseti:
config:
- check ISA:=regex(.*I.*B.*)
- check ISA:=regex(.*I.*Zbs.*)
mnemonics:
bseti: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
# 'xlenlim("rs1_val", xlen)': 0
'leading_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_ones(32, ["rs1_val", "imm_val"], [32,5])': 0
'leading_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0
'trailing_zeros(32, ["rs1_val", "imm_val"], [32,5])': 0

View file

@ -0,0 +1,6 @@
fencei:
config:
- check ISA:=regex(.*I.*Zifencei.*)
mnemonics:
fence.i: 0

View file

@ -0,0 +1,537 @@
aes32dsi:
config:
- check ISA:=regex(.*RV32.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknd.*)
mnemonics:
aes32dsi: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
aes32dsmi:
config:
- check ISA:=regex(.*RV32.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknd.*)
mnemonics:
aes32dsmi: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
aes32esi:
config:
- check ISA:=regex(.*RV32.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zkne.*)
mnemonics:
aes32esi: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
aes32esmi:
config:
- check ISA:=regex(.*RV32.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zkne.*)
mnemonics:
aes32esmi: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
sm4ed:
config:
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zksed.*)
mnemonics:
sm4ed: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
sm4ks:
config:
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zksed.*)
mnemonics:
sm4ks: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'byte_count(32,["rs1_val","rs2_val","imm_val"])': 0
'uniform_random(20, 100, ["rs1_val","rs2_val","imm_val"], [32, 32, 2])': 0
sha256sig0:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zknh.*)
mnemonics:
sha256sig0: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sha256sig1:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zknh.*)
mnemonics:
sha256sig1: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sha256sum0:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zknh.*)
mnemonics:
sha256sum0: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sha256sum1:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zknh.*)
mnemonics:
sha256sum1: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sm3p0:
config:
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zksh.*)
mnemonics:
sm3p0: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sm3p1:
config:
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zksh.*)
mnemonics:
sm3p1: 0
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val"], [xlen])': 0
sha512sig0h:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sig0h: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
sha512sig0l:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sig0l: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
sha512sig1h:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sig1h: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
sha512sig1l:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sig1l: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
sha512sum0r:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sum0r: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
sha512sum1r:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*RV32.*I.*Zkn.*)
- check ISA:=regex(.*RV32.*I.*Zknh.*)
mnemonics:
sha512sum1r: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_ones("rs2_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
'walking_zeros("rs2_val", xlen, False)': 0
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
brev8_32:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zbkb.*)
mnemonics:
brev8: 0
base_op: grevi
p_op_cond: imm_val == 7
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
'rs1_val == 0x1020408': 0
'rs1_val == 0x2040801': 0
'rs1_val == 0x4080102': 0
'rs1_val == 0x8010204': 0
abstract_comb:
'leading_ones(64, ["rs1_val"], [32])': 0
'trailing_ones(64, ["rs1_val"], [32])': 0
'leading_zeros(64, ["rs1_val"], [32])': 0
'trailing_zeros(64, ["rs1_val"], [32])': 0
'bitmanip_dataset(xlen,["rs1_val"],signed=False)': 0
zip:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zbkb.*)
mnemonics:
zip: 0
base_op: shfli
p_op_cond: imm_val == 15
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val"],[xlen])': 0
'trailing_ones(32, ["rs1_val"],[xlen])': 0
'leading_zeros(32, ["rs1_val"],[xlen])': 0
'trailing_zeros(32, ["rs1_val"],[xlen])': 0
unzip:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zbkb.*)
mnemonics:
unzip: 0
base_op: unshfli
p_op_cond: imm_val == 15
rs1:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *ifmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val"],[xlen])': 0
'trailing_ones(32, ["rs1_val"],[xlen])': 0
'leading_zeros(32, ["rs1_val"],[xlen])': 0
'trailing_zeros(32, ["rs1_val"],[xlen])': 0
pack:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zbkb.*)
mnemonics:
pack: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
packh:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zbkb.*)
mnemonics:
packh: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
xperm8:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zbkx.*)
mnemonics:
xperm8: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
xperm4:
config:
- check ISA:=regex(.*I.*Zk.*)
- check ISA:=regex(.*I.*Zkn.*)
- check ISA:=regex(.*I.*Zks.*)
- check ISA:=regex(.*I.*Zbkx.*)
mnemonics:
xperm4: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
abstract_comb:
'uniform_random(20, 100, ["rs1_val","rs2_val"], [xlen, xlen])': 0
'leading_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_ones(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'leading_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0
'trailing_zeros(32, ["rs1_val","rs2_val"],[xlen,xlen])': 0

View file

@ -0,0 +1,158 @@
ecall:
config:
- check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True
mnemonics:
ecall: 0
ebreak:
config:
- check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True
mnemonics:
ebreak: 0
misalign-lh:
cond: check ISA:=regex(.*I.*Zicsr.*)
config:
- check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True
- check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True
mnemonics:
lh: 0
val_comb:
'ea_align == 1': 0
misalign-lhu:
config:
- check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True
- check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*Zicsr.*)
mnemonics:
lhu: 0
val_comb:
'ea_align == 1': 0
misalign-lw:
config:
- check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True
- check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*Zicsr.*)
mnemonics:
lw: 0
val_comb:
'ea_align == 1': 0
'ea_align == 2': 0
'ea_align == 3': 0
misalign-sh:
config:
- check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True
- check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*Zicsr.*)
mnemonics:
sh: 0
val_comb:
'ea_align == 1': 0
misalign-sw:
config:
- check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True
- check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*Zicsr.*)
mnemonics:
sw: 0
val_comb:
'ea_align == 1': 0
'ea_align == 2': 0
'ea_align == 3': 0
misalign2-jalr:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
jalr: 0
val_comb:
'imm_val%2 == 1 and ea_align == 2': 0
'imm_val%2 == 0 and ea_align == 2': 0
misalign1-jalr:
config:
- check ISA:=regex(.*I.*)
mnemonics:
jalr: 0
val_comb:
'imm_val%2 == 1 and ea_align == 1': 0
'imm_val%2 == 0 and ea_align == 1': 0
misalign-jal:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
jal: 0
val_comb:
'ea_align == 2': 0
misalign-bge:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
bge: 0
val_comb:
' rs1_val>rs2_val and ea_align == 2': 0
misalign-bgeu:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
bgeu: 0
val_comb:
' rs1_val>rs2_val and ea_align == 2': 0
misalign-blt:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
blt: 0
val_comb:
' rs1_val<rs2_val and ea_align == 2': 0
misalign-bltu:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
bltu: 0
val_comb:
' rs1_val<rs2_val and ea_align == 2': 0
misalign-bne:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
bne: 0
val_comb:
' rs1_val!=rs2_val and ea_align == 2': 0
misalign-beq:
config:
- check ISA:=regex(.*I.*C.*)
- check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True
cond: check ISA:=regex(.*I.*)
mnemonics:
beq: 0
val_comb:
' rs1_val==rs2_val and ea_align == 2': 0

View file

@ -0,0 +1,176 @@
clbu:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.lbu: 0
rs1:
<<: *c_regs
rd:
<<: *c_regs
op_comb:
'rs1 == rd': 0
'rs1 != rd': 0
val_comb:
'imm_val == 0': 0
'imm_val == 1': 0
'imm_val == 2': 0
'imm_val == 3': 0
clhu:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.lhu: 0
rs1:
<<: *c_regs
rd:
<<: *c_regs
op_comb:
'rs1 == rd': 0
'rs1 != rd': 0
val_comb:
'imm_val == 0': 0
'imm_val == 2': 0
clh:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.lh: 0
rs1:
<<: *c_regs
rd:
<<: *c_regs
op_comb:
'rs1 == rd': 0
'rs1 != rd': 0
val_comb:
'imm_val == 0': 0
'imm_val == 2': 0
csb:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.sb: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'imm_val == 0': 0
'imm_val == 1': 0
'imm_val == 2': 0
'imm_val == 3': 0
csh:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.sh: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'imm_val == 0': 0
'imm_val == 2': 0
csext.b:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*)
mnemonics:
c.sext.b: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0x8000': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
csext.h:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*)
mnemonics:
c.sext.h: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x800': 0
'rs1_val == 0xFF80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
czext.b:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.zext.b: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x80': 0
'rs1_val == 0x8000': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
czext.h:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*.Zbb.*)
mnemonics:
c.zext.h: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x800': 0
'rs1_val == 0xFF80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
cnot:
config:
- check ISA:=regex(.*I.*Zca.*Zcb.*)
mnemonics:
c.not: 0
rs1:
<<: *c_regs
op_comb:
<<: *r0fmt_op_comb
val_comb:
'rs1_val == 0': 0
'rs1_val == 0x800': 0
'rs1_val == 0xFF80': 0
abstract_comb:
'walking_ones("rs1_val", xlen, False)': 0
'walking_zeros("rs1_val", xlen, False)': 0
cmul:
config:
- check ISA:=regex(.*I.*M.*Zca.*Zcb.*)
mnemonics:
c.mul: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]

View file

@ -0,0 +1,170 @@
amoadd.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amoadd.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amoand.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amoand.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amoswap.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amoswap.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amoxor.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amoxor.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amoor.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amoor.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amomin.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amomin.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amominu.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amominu.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amomax.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amomax.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
amomaxu.w:
config:
- check ISA:=regex(.*32.*I.*A.*)
- check ISA:=regex(.*32.*I.*Zaamo.*)
mnemonics:
amomaxu.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*ramofmt_op_comb]
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]

View file

@ -0,0 +1,478 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
cebreak:
config:
- check ISA:=regex(.*I.*Zicsr.*.C*)
mnemonics:
c.ebreak: 0
caddi4spn:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.addi4spn: 0
rd:
<<: *c_regs
val_comb:
'imm_val > 0' : 0
'imm_val == 1020': 0
abstract_comb:
'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0
'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0
clw:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.lw: 0
rs1:
<<: *c_regs
rd:
<<: *c_regs
op_comb:
'rs1 == rd': 0
'rs1 != rd': 0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
abstract_comb:
'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0
csw:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.sw: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
'rs1 != rs2': 0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0
cnop:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.nop: 0
val_comb:
abstract_comb:
<<: *cbimm_val_walking
caddi:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.addi: 0
rd:
<<: *all_regs_mx0
val_comb:
<<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0
<<: [*rs1val_walking, *cbimm_val_walking]
cjal:
config:
- check ISA:=regex(.*RV32.*I.*C.*)
mnemonics:
c.jal: 0
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0
cli:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.li: 0
rd:
<<: *all_regs
val_comb:
<<: [*cbfmt_immval_sgn]
abstract_comb:
'walking_ones("imm_val", 6)': 0
'walking_zeros("imm_val", 6)': 0
'alternate("imm_val", 6)': 0
caddi16sp:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.addi16sp: 0
rd:
x2: 0
val_comb:
<<: [*base_rs1val_sgn,*ifmt_val_comb_sgn]
'imm_val == -512': 0
'imm_val == 496': 0
abstract_comb:
<<: [*rs1val_walking]
'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0
'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0
'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0
clui:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.lui: 0
rd:
x0: 0
x1: 0
x3: 0
x4: 0
x5: 0
x6: 0
x7: 0
x8: 0
x9: 0
x10: 0
x11: 0
x12: 0
x13: 0
x14: 0
x15: 0
x16: 0
x17: 0
x18: 0
x19: 0
x20: 0
x21: 0
x22: 0
x23: 0
x24: 0
x25: 0
x26: 0
x27: 0
x28: 0
x29: 0
x30: 0
x31: 0
val_comb:
'rs1_val > 0 and imm_val > 32': 0
'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0
'rs1_val < 0 and imm_val > 32': 0
'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0
abstract_comb:
'walking_ones("imm_val", 6, False)': 0
'walking_zeros("imm_val", 6, False)': 0
'alternate("imm_val", 6, False)': 0
csrli:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.srli: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
csrai:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.srai: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
candi:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.andi: 0
rs1:
<<: *c_regs
val_comb:
<<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0
<<: [*rs1val_walking, *cbimm_val_walking]
csub:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.sub: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cxor:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.xor: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cor:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.or: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cand:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.and: 0
rs1:
<<: *c_regs
rs2:
<<: *c_regs
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cj:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.j: 0
val_comb:
'imm_val > 0': 0
'imm_val < 0': 0
abstract_comb:
'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0
'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0
cbeqz:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.beqz: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val > 0 and imm_val > 0': 0
'rs1_val < 0 and imm_val > 0': 0
'rs1_val == 0 and imm_val > 0': 0
'rs1_val > 0 and imm_val < 0': 0
'rs1_val < 0 and imm_val < 0': 0
'rs1_val == 0 and imm_val < 0': 0
<<: [*base_rs1val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
cbnez:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.bnez: 0
rs1:
<<: *c_regs
val_comb:
'rs1_val > 0 and imm_val > 0': 0
'rs1_val < 0 and imm_val > 0': 0
'rs1_val == 0 and imm_val > 0': 0
'rs1_val > 0 and imm_val < 0': 0
'rs1_val < 0 and imm_val < 0': 0
'rs1_val == 0 and imm_val < 0': 0
<<: [*base_rs1val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
cslli:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.slli: 0
rd:
<<: *c_regs
val_comb:
'rs1_val < 0 and imm_val < xlen': 0
'rs1_val > 0 and imm_val < xlen': 0
'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0
'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0
'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0
abstract_comb:
'sp_dataset(xlen,["rs1_val"])': 0
<<: [*rs1val_walking]
'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0
'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0
'alternate("imm_val", ceil(log(xlen,2)), False)': 0
clwsp:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.lwsp: 0
rd:
<<: *all_regs_mx0
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
abstract_comb:
'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0
cjr:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.jr: 0
rs1:
<<: *all_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *base_rs1val_sgn_rs2val_zero
abstract_comb:
'sp_dataset(xlen)': 0
<<: *rs1val_walking
cmv:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.mv: 0
rs2:
<<: *all_regs_mx0
rd:
<<: *all_regs
op_comb:
'rs2 == rd and rs2 != 0': 0
'rs2 != rd and rs2 != 0': 0
val_comb:
<<: [*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen,["rs2_val"])': 0
<<: [*rs2val_walking]
cadd:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.add: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking,*rs2val_walking]
cjalr:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.jalr: 0
rs1:
<<: *all_regs_mx0
op_comb:
<<: *sfmt_op_comb
val_comb:
<<: *base_rs1val_sgn_rs2val_zero
abstract_comb:
'sp_dataset(xlen)': 0
<<: *rs1val_walking
cswsp:
config:
- check ISA:=regex(.*I.*C.*)
mnemonics:
c.swsp: 0
rs2:
<<: *all_regs_mx2
val_comb:
'imm_val > 0': 0
'imm_val == 0': 0
<<: [ *base_rs2val_sgn]
abstract_comb:
<<: [*rs2val_walking]
'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0
'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0
'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0

View file

@ -0,0 +1,154 @@
# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore
mul:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
mul: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
mulh:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
mulh: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
mulhu:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
mulhu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
mulhsu:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
mulhsu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *rfmt_op_comb
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn]
'rs1_val > 0 and rs2_val > 0': 0
abstract_comb:
'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0
<<: [*rs1val_walking, *rs2val_walking_unsgn]
div:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
div: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*rfmt_op_comb , *div_hardcoded_opcomb]
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
divu:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
divu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*rfmt_op_comb , *div_hardcoded_opcomb]
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]
rem:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
rem: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*rfmt_op_comb , *div_hardcoded_opcomb]
val_comb:
<<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn, *div_corner_case]
abstract_comb:
'sp_dataset(xlen)': 0
<<: [*rs1val_walking, *rs2val_walking]
remu:
config:
- check ISA:=regex(.*I.*M.*)
mnemonics:
remu: 0
rs1:
<<: *all_regs
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: [*rfmt_op_comb , *div_hardcoded_opcomb]
val_comb:
<<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn]
abstract_comb:
'sp_dataset(xlen,signed=False)': 0
<<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn]

Some files were not shown because too many files have changed in this diff Show more