diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d032c1e..c947908a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Only when a release to the main branch is done, the contents of the WIP-DEV are versioned header while the `WIP-DEV` is left empty ## [WIP-DEV] +- Added support of Zcb from Code Size Reduction Extension. - Added support of Standard Atomic (A) Extension (RV32 and RV64), excluding the LR/SC instruction. - Updating CONTRIBUTING.rst to capture the new git strategy adopted to follow a monthly release cadence. diff --git a/riscv_ctg/data/template.yaml b/riscv_ctg/data/template.yaml index 346aa23d..e598adff 100644 --- a/riscv_ctg/data/template.yaml +++ b/riscv_ctg/data/template.yaml @@ -10317,7 +10317,7 @@ 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) amoadd.w: sig: @@ -10678,3 +10678,222 @@ amomaxu.d: // $comment // opcode: $inst ; op1:$rs1; op2:$rs2; dest:$rd; op1val:$rs1_val; op2val:$rs2_val TEST_AMO_OP($inst, $rd, $rs1, $rs2, $rs1_val, $rs2_val, $swreg, $offset) + +c.lbu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.lhu: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.lh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rd_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'clformat' + rs1_val_data: '[0]' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode: $inst; op1:$rs1; dest:$rd; immval:$imm_val + TEST_LOAD($swreg,$testreg,$index,$rs1,$rd,$imm_val,$offset,$inst,0) + +c.sb: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sh: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'csformat' + rs1_val_data: '[0]' + rs2_val_data: 'gen_sign_dataset(xlen)' + imm_val_data: 'gen_usign_dataset(2)' + template: |- + + // $comment + // opcode:$inst; op1:$rs1; op2:$rs2; op2val:$rs2_val; immval:$imm_val + TEST_STORE($swreg,$testreg,$index,$rs1,$rs2,$rs2_val,$imm_val,$offset,$inst,0) + +c.sext.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.sext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_sign_dataset(xlen)+gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.b: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[128]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.h: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb_Zbb + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.zext.w: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [64] + std_op: + isa: + - I_Zca_Zcb_Zba + formattype: 'ckformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.not: + sig: + stride: 1 + sz: 'XLEN/8' + xlen: [32,64] + std_op: + isa: + - I_Zca_Zcb + formattype: 'kformat' + rs1_op_data: *c_regs + rs1_val_data: 'gen_usign_dataset(xlen)+[65408]' + template: |- + + // $comment + // opcode: $inst ; op1=dest:$rs1 ; op1val:$rs1_val; + TEST_CRD_OP($inst, $rs1, $correctval, $rs1_val, $swreg, $offset, $testreg) + +c.mul: + sig: + stride: 1 + sz: 'XLEN/8' + rs1_op_data: *c_regs + rs2_op_data: *c_regs + xlen: [32,64] + std_op: + isa: + - IM_Zca_Zcb + formattype: 'crformat' + operation: 'hex((rs1_val * rs2_val) & (2**(xlen)-1))' + 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; op1val:$rs1_val; op2val:$rs2_val + TEST_CR_OP( $inst, $rs1, $rs2, $correctval, $rs1_val, $rs2_val, $swreg, $offset, $testreg) diff --git a/riscv_ctg/generator.py b/riscv_ctg/generator.py index 035b97d5..742549d1 100644 --- a/riscv_ctg/generator.py +++ b/riscv_ctg/generator.py @@ -58,6 +58,7 @@ def get_rm(opcode): 'cbformat': ['rs1'], 'cjformat': [], 'kformat': ['rs1','rd'], + 'ckformat': ['rs1'], # 'frformat': ['rs1', 'rs2', 'rd'], 'fsrformat': ['rs1', 'rd'], # 'fr4format': ['rs1', 'rs2', 'rs3', 'rd'], @@ -103,6 +104,7 @@ def get_rm(opcode): 'cbformat': "['rs1_val', 'imm_val']", 'cjformat': "['imm_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'])", diff --git a/sample_cgfs/rv32i_zcb.cgf b/sample_cgfs/rv32i_zcb.cgf new file mode 100644 index 00000000..86ba722a --- /dev/null +++ b/sample_cgfs/rv32i_zcb.cgf @@ -0,0 +1,174 @@ + +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 + 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] + \ No newline at end of file diff --git a/sample_cgfs/rv64i_zcb.cgf b/sample_cgfs/rv64i_zcb.cgf new file mode 100644 index 00000000..0b9a48f9 --- /dev/null +++ b/sample_cgfs/rv64i_zcb.cgf @@ -0,0 +1,188 @@ + +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 + +czext.w: + config: + - check ISA:=regex(.*I.*Zca.*Zcb.*.Zba.*) + mnemonics: + c.zext.w: 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 + 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]