diff --git a/CHANGELOG.md b/CHANGELOG.md index 0371043a..09465921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ Please note the header `WIP-DEV` is to always remain indicating the changes done 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 +## [WIP-DEV] +- Added support for CMO extension + ## [0.12.2] - 2024-03-06 - Add Zfa support. (PR#60) - Initial covergroups for Zvk* instructions (PR#61) @@ -19,7 +22,7 @@ versioned header while the `WIP-DEV` is left empty - 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 +- 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 @@ -30,7 +33,7 @@ versioned header while the `WIP-DEV` is left empty - Add unratified Zaamo subcomponent of A extension - Add unratified B extension - Fix issues with csr_comb -- Minor fix in kslraw.u in rv32ip +- 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 @@ -69,7 +72,7 @@ versioned header while the `WIP-DEV` is left empty ## [0.10.2] - 2022-10-20 - Fixed use of lowercase LI. -- Fixed correctval to ?? in comments. +- Fixed correctval to ?? in comments. - Fixed sw to SREG for K tests. - Added canaries and signature boundary labels. diff --git a/riscv_ctg/data/template.yaml b/riscv_ctg/data/template.yaml index d1f87c8d..76d97dae 100644 --- a/riscv_ctg/data/template.yaml +++ b/riscv_ctg/data/template.yaml @@ -10414,7 +10414,129 @@ czero.nez: // $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) + TEST_RR_OP($inst, $rd, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) + +cbo.zero: + std_op: + sig: + stride: 1 + sz: 'RVMODEL_CBZ_BLOCKSIZE' + xlen: [32,64] + isa: + - IZicboz_Zicsr + formattype: 'zformat' + rs1_op_data: *all_regs_mx0 + rs1_val_data: 'gen_usign_dataset(12)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op1val:$rs1_val + TEST_CBO($swreg,$rs1,$inst,$rs1_val) + +cbo.clean: + std_op: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + isa: + - IZicbom_Zicsr + formattype: 'zformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op1val:$rs1_val + TEST_CBO($swreg,$rs1,$inst,$rs1_val) + +cbo.flush: + std_op: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + isa: + - IZicbom_Zicsr + formattype: 'zformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op1val:$rs1_val + TEST_CBO($swreg,$rs1,$inst,$rs1_val) + +cbo.inval: + std_op: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + isa: + - IZicbom_Zicsr + formattype: 'zformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; op1val:$rs1_val + TEST_CBO($swreg,$rs1,$inst,$rs1_val) + +prefetch.i: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicbop_Zicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + imm_val_data: '[v << 5 for v in gen_sign_dataset(7)]' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PREFETCH($swreg,$rs1,$inst,$imm_val) + +prefetch.r: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicbop_Zicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + imm_val_data: '[v << 5 for v in gen_sign_dataset(7)]' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PREFETCH($swreg,$rs1,$inst,$imm_val) + +prefetch.w: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - IZicbop_Zicsr + formattype: 'iformat' + rs1_op_data: *all_regs + rs1_val_data: 'gen_usign_dataset(xlen) + gen_sp_dataset(xlen,True)' + imm_val_data: '[v << 5 for v in gen_sign_dataset(7)]' + template: |- + + // $comment + // opcode: $inst ; op1:$rs1; dest:$rd; op1val:$rs1_val; immval:$imm_val + TEST_PREFETCH($swreg,$rs1,$inst,$imm_val) amoadd.w: sig: diff --git a/riscv_ctg/env/arch_test.h b/riscv_ctg/env/arch_test.h index e93a7d54..2114646c 100644 --- a/riscv_ctg/env/arch_test.h +++ b/riscv_ctg/env/arch_test.h @@ -3,6 +3,12 @@ #ifndef NUM_SPECD_INTCAUSES #define NUM_SPECD_INTCAUSES 16 #endif +#ifndef RVMODEL_CBZ_BLOCKSIZE + #define RVMODEL_CBZ_BLOCKSIZE 64 +#endif +#ifndef RVMODEL_CMO_BLOCKSIZE + #define RVMODEL_CMO_BLOCKSIZE 64 +#endif //#define RVTEST_FIXED_LEN #ifndef UNROLLSZ #define UNROLLSZ 5 @@ -64,6 +70,15 @@ la reg,val;\ .option pop; #endif + +#define ADDI(dst, src, imm) /* helper*/ ;\ +#if (imm<=2048) ;\ + addi dst, src, imm ;\ +#else ;\ + LI( dst, imm) ;\ + addi dst, src, dst ;\ +#endif + #if XLEN==64 #define SREG sd #define LREG ld @@ -931,7 +946,22 @@ LI(testreg,imm_val) ;\ sub rs1,rs1,testreg ;\ inst rs2, imm_val(rs1) ;\ nop ;\ -nop +nop + +#define TEST_CBO(swreg,rs1,inst,imm_val) ;\ +LI(rs1,imm_val&(RVMODEL_CBZ_BLOCKSIZE-1)) ;\ +add rs1,rs1,swreg ;\ +inst (rs1) ;\ +nop ;\ +nop ;\ +ADDI(swreg, swreg, RVMODEL_CBZ_BLOCKSIZE) + +#define TEST_PREFETCH(swreg,rs1,inst,imm_val) ;\ +LI(rs1,rs1_val) ;\ +inst imm_val(rs1) ;\ +nop ;\ +nop ;\ +ADDI(swreg, swreg, RVMODEL_CBZ_BLOCKSIZE) #define TEST_LOAD(swreg,testreg,index,rs1,destreg,imm_val,offset,inst,adj) ;\ LA(rs1,rvtest_data+(index*4)+adj-imm_val) ;\ diff --git a/riscv_ctg/generator.py b/riscv_ctg/generator.py index 9f3fc8d0..e77c1687 100644 --- a/riscv_ctg/generator.py +++ b/riscv_ctg/generator.py @@ -113,7 +113,8 @@ def get_rm(opcode): 'ppbrrformat': ['rs1', 'rs2', 'rd'], 'prrformat': ['rs1', 'rs2', 'rd'], 'prrrformat': ['rs1', 'rs2', 'rs3', 'rd'], - 'dcasrformat': ['rs1', 'rs2', 'rd'] + 'dcasrformat': ['rs1', 'rs2', 'rd'], + 'zformat': ['rs1'] } ''' Dictionary mapping instruction formats to operands used by those formats ''' @@ -147,7 +148,6 @@ def get_rm(opcode): 'cjformat': "['imm_val']", 'ckformat': "['rs1_val']", 'kformat': "['rs1_val']", - 'ckformat': "['rs1_val']", # 'frformat': "['rs1_val', 'rs2_val', 'rm_val', 'fcsr']", 'fsrformat': "['rs1_val','fcsr'] + get_rm(opcode) + \ ([] if not is_nan_box else ['rs1_nan_prefix']) + \ @@ -170,7 +170,8 @@ def get_rm(opcode): 'ppbrrformat': '["rs1_val"] + simd_val_vars("rs2", xlen, 8)', 'prrformat': '["rs1_val", "rs2_val"]', 'prrrformat': "['rs1_val', 'rs2_val' , 'rs3_val']", - 'dcasrformat': '["rs1_val", "rs2_val"]' + 'dcasrformat': '["rs1_val", "rs2_val"]', + 'zformat': "['rs1_val']" } ''' Dictionary mapping instruction formats to operand value variables used by those formats ''' @@ -1135,6 +1136,7 @@ def swreg(self, instr_dict): else: FLEN = 0 XLEN = max(self.opnode['xlen']) + RVMODEL_CBZ_BLOCKSIZE = XLEN SIGALIGN = max(XLEN,FLEN)/8 stride_sz = eval(suffix) for instr in instr_dict: @@ -1297,7 +1299,7 @@ def reformat_instr(self, instr_dict): # instr_dict is already in the desired format for Zacas dcas instructions if 'bit_width' in self.opnode or 'dcas_profile' in self.opnode: return instr_dict - + # Fix all K instructions to be unsigned to output unsigned hex values into the test. Its # only a cosmetic difference and has no impact on coverage is_unsigned = any('IZk' in isa for isa in self.opnode['isa']) @@ -1321,8 +1323,9 @@ def reformat_instr(self, instr_dict): if '0x' in value: value = '0x' + value[2:].zfill(int(self.xlen/4)) value = struct.unpack(size, bytes.fromhex(value[2:]))[0] + # value = toint(value) else: - value = int(value) + value = toint(value) # value = '0x' + struct.pack(size,value).hex() #print("test",hex(value)) instr_dict[i][field] = hex(value) @@ -1429,7 +1432,7 @@ def __write_test__(self, file_name,node,label,instr_dict, op_node, usage_str): # dval = (instr['rs{0}_val'.format(i)],self.iflen) data.extend(instr['val_section']) if instr['swreg'] != sreg or eval(instr['offset'],{}, - {'FLEN':width,'XLEN':self.xlen,'SIGALIGN':max(self.xlen,self.flen)/8}) == 0: + {'FLEN':width,'XLEN':self.xlen,'RVMODEL_CBZ_BLOCKSIZE':self.xlen, 'SIGALIGN':max(self.xlen,self.flen)/8}) == 0: sign.append(signode_template.substitute( {'n':n,'label':"signature_"+sreg+"_"+str(regs[sreg]),'sz':sig_sz})) n = stride diff --git a/sample_cgfs/cmo.cgf b/sample_cgfs/cmo.cgf new file mode 100644 index 00000000..d4346eb2 --- /dev/null +++ b/sample_cgfs/cmo.cgf @@ -0,0 +1,86 @@ +# For Licence details look at https://github.com/riscv-software-src/riscv-ctg/-/blob/master/LICENSE.incore + +cbo.zero: + config: + - check ISA:=regex(.*I.*Zicboz.*Zicsr.*) + mnemonics: + cbo.zero: 0 + rs1: + <<: *all_regs_mx0 + val_comb: + abstract_comb: + 'walking_ones("rs1_val", 12, False)': 0 + 'walking_zeros("rs1_val", 12, False)': 0 + 'uniform_random(20, 100, ["rs1_val"], [12])': 0 + +cbo.clean: + config: + - check ISA:=regex(.*I.*Zicbom.*Zicsr.*) + mnemonics: + cbo.clean: 0 + rs1: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn] + +cbo.flush: + config: + - check ISA:=regex(.*I.*Zicbom.*Zicsr.*) + mnemonics: + cbo.flush: 0 + rs1: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn] + +cbo.inval: + config: + - check ISA:=regex(.*I.*Zicbom.*Zicsr.*) + mnemonics: + cbo.inval: 0 + rs1: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_unsgn] + abstract_comb: + <<: [*rs1val_walking_unsgn] + +prefetch.i: + config: + - check ISA:=regex(.*I.*Zicbop.*Zicsr.*) + mnemonics: + prefetch.i: 0 + rs1: + <<: *all_regs + val_comb: + <<: [*zicbop_ifmt_val_comb_unsgn, *base_rs1val_unsgn, *ifmt_base_immval11_5_sgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_11_5] + +prefetch.r: + config: + - check ISA:=regex(.*I.*Zicbop.*Zicsr.*) + mnemonics: + prefetch.r: 0 + rs1: + <<: *all_regs + val_comb: + <<: [*zicbop_ifmt_val_comb_unsgn, *base_rs1val_unsgn, *ifmt_base_immval11_5_sgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_11_5] + +prefetch.w: + config: + - check ISA:=regex(.*I.*Zicbop.*Zicsr.*) + mnemonics: + prefetch.w: 0 + rs1: + <<: *all_regs + val_comb: + <<: [*zicbop_ifmt_val_comb_unsgn, *base_rs1val_unsgn, *ifmt_base_immval11_5_sgn] + abstract_comb: + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_11_5] diff --git a/sample_cgfs/dataset.cgf b/sample_cgfs/dataset.cgf index a1a1a01f..5133ef96 100644 --- a/sample_cgfs/dataset.cgf +++ b/sample_cgfs/dataset.cgf @@ -180,7 +180,7 @@ datasets: x13: 0 x14: 0 x15: 0 - + all_regs_mx2: &all_regs_mx2 x1: 0 x3: 0 @@ -295,7 +295,7 @@ datasets: 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 @@ -307,7 +307,7 @@ datasets: '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 @@ -320,12 +320,11 @@ datasets: '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 @@ -346,7 +345,7 @@ datasets: 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 @@ -364,12 +363,23 @@ datasets: '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 + zicbop_ifmt_val_comb_unsgn: &zicbop_ifmt_val_comb_unsgn + 'rs1_val == imm_val and rs1_val == 0': 0 + 'rs1_val < imm_val and rs1_val != 0': 0 + 'rs1_val > imm_val 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_immval11_5_sgn: &ifmt_base_immval11_5_sgn + 'imm_val == (-2**(12-1)) & 0b00000': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(12-1)-1) & 0b00000': 0 + 'imm_val == 1<<5': 0 + ifmt_base_immval_sgn_len: &ifmt_base_immval_sgn_len 'imm_val == (-2**(ceil(log(xlen,2))-1))': 0 'imm_val == 0': 0 @@ -435,7 +445,7 @@ datasets: '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 @@ -480,12 +490,17 @@ datasets: 'walking_ones("imm_val", 5, False)': 0 'walking_zeros("imm_val", 5, False)': 0 'alternate("imm_val", 5, False)': 0 - + + ifmt_immval_walking_11_5: &ifmt_immval_walking_11_5 + 'walking_ones("imm_val", 7, signed = True, scale_func = lambda x: x << 5)': 0 + 'walking_zeros("imm_val", 7, signed = True, scale_func = lambda x: x << 5)': 0 + 'alternate("imm_val", 7, signed = True, scale_func = lambda x: x << 5)': 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 @@ -499,7 +514,7 @@ datasets: '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