Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Commit

Permalink
Merge pull request #73 from ved-rivos/zacas
Browse files Browse the repository at this point in the history
Add unratified Zacas extension
  • Loading branch information
neelgala authored Aug 22, 2023
2 parents 9dac5e7 + 94e76e3 commit 24a4eb8
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 8 deletions.
5 changes: 3 additions & 2 deletions riscv_ctg/cross_comb.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
'pphrrformat' : '$instr $rd, $rs1, $rs2',
'ppbrrformat' : '$instr $rd, $rs1, $rs2',
'prrformat' : '$instr ',
'prrrformat' : '$instr'
'prrrformat' : '$instr',
'dcasrformat' : '$instr '
}
'''Dictionary to store instruction formats'''

Expand Down Expand Up @@ -497,4 +498,4 @@ def write_test(self, fprefix, cgf_node, usage_str, cov_label, full_solution):
label = cov_label,
extension = extension
)
)
)
89 changes: 89 additions & 0 deletions riscv_ctg/data/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ metadata:
all_regs_mx0: &all_regs_mx0 "['x'+str(x) for x in range(1,32 if 'e' not in base_isa else 16)]"
c_regs: &c_regs "['x'+str(x) for x in range(8,16)]"
pair_regs: &pair_regs "['x'+str(x) for x in range(2,32 if 'e' not in base_isa else 16, 2 if xlen == 32 else 1)]"
rv32rv64pair_regs: &rv32rv64pair_regs "['x'+str(x) for x in range(2,30 if 'e' not in base_isa else 16, 2)]"

aes32dsi:
sig:
Expand Down Expand Up @@ -10679,6 +10680,94 @@ amomaxu.d:
// 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)
amocas.w:
sig:
stride: 1
sz: 'XLEN/8'
xlen: [32,64]
std_op:
isa:
- IZacas
formattype: 'rformat'
rs1_op_data: *all_regs_mx0
rs2_op_data: *all_regs
rd_op_data: *all_regs
rs1_val_data: 'gen_sign_dataset(xlen)'
rs2_val_data: 'gen_sign_dataset(xlen)'

template: |-
// $comment
// opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset
TEST_CAS_OP($inst, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset);
amocas.d_32:
sig:
stride: 2
sz: 'XLEN/8'
xlen: [32]
std_op:
isa:
- IZacas
bit_width: 64
dcas_profile: 'pnp'
formattype: 'dcasrformat'
rs1_op_data: *all_regs_mx0
rs2_op_data: *rv32rv64pair_regs
rd_op_data: *rv32rv64pair_regs
rs1_val_data: 'gen_sign_dataset(64)'
rs2_val_data: 'gen_sign_dataset(64)'

template: |-
// $comment
// opcode: $inst ; dest($rd, $rd_hi) addr:$rs1; src:($rs2, $rs2_hi); swap_val:($rs2_val, $rs2_val_hi); swreg:$swreg; $offset
TEST_DCAS_OP(amocas.d, $rd, $rd_hi, $rs1, $rs2, $rs2_hi, $rs2_val, $rs2_val_hi, $swreg, $offset);
amocas.d_64:
sig:
stride: 1
sz: 'XLEN/8'
xlen: [64]
std_op:
isa:
- IZacas
formattype: 'rformat'
rs1_op_data: *all_regs_mx0
rs2_op_data: *all_regs
rd_op_data: *all_regs
rs1_val_data: 'gen_sign_dataset(xlen)'
rs2_val_data: 'gen_sign_dataset(xlen)'

template: |-
// $comment
// opcode: $inst ; dest:$rd; addr:$rs1; src:$rs2; swap_val:$rs2_val; swreg:$swreg; $offset
TEST_CAS_OP(amocas.d, $rd, $rs1, $rs2, $rs2_val, $swreg, $offset);
amocas.q:
sig:
stride: 2
sz: 'XLEN/8'
xlen: [64]
std_op:
isa:
- IZacas
bit_width: 128
dcas_profile: 'pnp'
formattype: 'dcasrformat'
rs1_op_data: *all_regs_mx0
rs2_op_data: *rv32rv64pair_regs
rd_op_data: *rv32rv64pair_regs
rs1_val_data: 'gen_sign_dataset(128)'
rs2_val_data: 'gen_sign_dataset(128)'

template: |-
// $comment
// opcode: $inst ; dest($rd, $rd_hi) addr:$rs1; src:($rs2, $rs2_hi); swap_val:($rs2_val, $rs2_val_hi), swreg:$swreg, $offset
TEST_DCAS_OP($inst, $rd, $rd_hi, $rs1, $rs2, $rs2_hi, $rs2_val, $rs2_val_hi, $swreg, $offset);
c.lbu:
sig:
stride: 1
Expand Down
11 changes: 8 additions & 3 deletions riscv_ctg/dsp_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,14 @@ def gen_pair_reg_data(instr_dict, xlen, _bit_width, p64_profile):
else:
bit_width1, bit_width2 = _bit_width, _bit_width

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
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:
Expand Down
36 changes: 33 additions & 3 deletions riscv_ctg/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def get_rm(opcode):
'pphrrformat': ['rs1', 'rs2', 'rd'],
'ppbrrformat': ['rs1', 'rs2', 'rd'],
'prrformat': ['rs1', 'rs2', 'rd'],
'prrrformat': ['rs1', 'rs2', 'rs3', 'rd']
'prrrformat': ['rs1', 'rs2', 'rs3', 'rd'],
'dcasrformat': ['rs1', 'rs2', 'rd']
}
''' Dictionary mapping instruction formats to operands used by those formats '''

Expand Down Expand Up @@ -125,7 +126,8 @@ def get_rm(opcode):
'pphrrformat': '["rs1_val"] + simd_val_vars("rs2", xlen, 16)',
'ppbrrformat': '["rs1_val"] + simd_val_vars("rs2", xlen, 8)',
'prrformat': '["rs1_val", "rs2_val"]',
'prrrformat': "['rs1_val', 'rs2_val' , 'rs3_val']"
'prrrformat': "['rs1_val', 'rs2_val' , 'rs3_val']",
'dcasrformat': '["rs1_val", "rs2_val"]'
}
''' Dictionary mapping instruction formats to operand value variables used by those formats '''

Expand Down Expand Up @@ -875,6 +877,14 @@ def eval_inst_coverage(coverpoints,instr):
elif 'bit_width' in self.opnode:
concat_simd_data(final_instr, self.xlen, self.opnode['bit_width'])

'''
Zacas introduces double xlen cas operations that need paired source and destination registers
'''
if any('Zacas' in isa for isa in self.opnode['isa']):
if 'dcas_profile' in self.opnode:
gen_pair_reg_data(final_instr, self.xlen, self.opnode['bit_width'], self.opnode['dcas_profile'])


return final_instr

def valreg(self,instr_dict):
Expand Down Expand Up @@ -903,6 +913,9 @@ def valreg(self,instr_dict):
if self.xlen == 32 and 'p64_profile' in self.opnode:
p64_profile = self.opnode['p64_profile']
paired_regs = self.opnode['p64_profile'].count('p')
if 'dcas_profile' in self.opnode:
dcas_profile = self.opnode['dcas_profile']
paired_regs = self.opnode['dcas_profile'].count('p')

regset = e_regset if 'e' in self.base_isa else default_regset
total_instr = len(instr_dict)
Expand Down Expand Up @@ -1023,6 +1036,9 @@ def swreg(self, instr_dict):
if self.xlen == 32 and 'p64_profile' in self.opnode:
p64_profile = self.opnode['p64_profile']
paired_regs = self.opnode['p64_profile'].count('p')
if 'dcas_profile' in self.opnode:
dcas_profile = self.opnode['dcas_profile']
paired_regs = self.opnode['dcas_profile'].count('p')

regset = e_regset if 'e' in self.base_isa else default_regset
total_instr = len(instr_dict)
Expand Down Expand Up @@ -1109,6 +1125,9 @@ def testreg(self, instr_dict):
if self.xlen == 32 and 'p64_profile' in self.opnode:
p64_profile = self.opnode['p64_profile']
paired_regs = p64_profile.count('p')
if 'dcas_profile' in self.opnode:
dcas_profile = self.opnode['dcas_profile']
paired_regs = dcas_profile.count('p')

for instr in instr_dict:
if 'rs1' in instr and instr['rs1'] in available_reg:
Expand Down Expand Up @@ -1161,6 +1180,11 @@ def correct_val(self,instr_dict):
if len(p64_profile) >= 3 and p64_profile[0]=='p':
for i in range(len(instr_dict)):
instr_dict[i]['correctval_hi'] = '0'
if 'dcas_profile' in self.opnode:
dcas_profile = self.opnode['dcas_profile']
if len(dcas_profile) >= 3 and dcas_profile[0]=='p':
for i in range(len(instr_dict)):
instr_dict[i]['correctval_hi'] = '0'
if self.fmt in ['caformat','crformat']:
normalise = lambda x,y: 0 if y['rs1']=='x0' else x
else:
Expand Down Expand Up @@ -1188,6 +1212,11 @@ def reformat_instr(self, instr_dict):
# instr_dict is already in the desired format for instructions that perform SIMD operations, or Zpsfoperand instructions in RV32.
if 'bit_width' in self.opnode or (self.xlen == 32 and 'p64_profile' in self.opnode):
return instr_dict
if any('Zacas' in isa for isa in self.opnode['isa']):
# 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'])
Expand Down Expand Up @@ -1271,9 +1300,10 @@ def __write_test__(self, file_name,node,label,instr_dict, op_node, usage_str):

if any('IP' in isa for isa in self.opnode['isa']):
code.append("RVTEST_VXSAT_ENABLE()")

if self.xlen == 32 and 'p64_profile' in self.opnode:
p64_profile = self.opnode['p64_profile']
if 'dcas_profile' in self.opnode:
dcas_profile = self.opnode['dcas_profile']

n = 0
is_int_src = any([self.opcode.endswith(x) for x in ['.x','.w','.l','.wu','.lu']])
Expand Down
49 changes: 49 additions & 0 deletions sample_cgfs/dataset.cgf
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,52 @@ datasets:
'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
36 changes: 36 additions & 0 deletions sample_cgfs/rv32zacas.cgf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# cover group format file for Zacas extension
amocas.w:
config:
- check ISA:=regex(.*Zacas.*)
opcode:
amocas.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *zacas_op_comb
val_comb:
<<: [*base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]

amocas.d_32:
config:
- check ISA:=regex(.*Zacas.*)
opcode:
amocas.d_32: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *pair_regs
rd:
<<: *pair_regs
op_comb:
<<: *zacas_op_comb
val_comb:
<<: [*zacas_dcas_rs1val_sgn, *zacas_dcas_rs2val_sgn, *rfmt_val_comb_sgn]
abstract_comb:
<<: [*zacas64_rs1val_walking_sgn, *zacas64_rs2val_walking_sgn]
54 changes: 54 additions & 0 deletions sample_cgfs/rv64zacas.cgf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# cover group format file for Zacas extension
amocas.w:
config:
- check ISA:=regex(.*Zacas.*)
opcode:
amocas.w: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *zacas_op_comb
val_comb:
<<: [*base_rs1val_sgn, *base_rs2val_sgn]
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]

amocas.d_64:
config:
- check ISA:=regex(.*Zacas.*)
opcode:
amocas.d_64: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *all_regs
rd:
<<: *all_regs
op_comb:
<<: *zacas_op_comb
val_comb:
<<: [*base_rs1val_sgn, *base_rs2val_sgn, *rfmt_val_comb_sgn]
abstract_comb:
<<: [*rs1val_walking, *rs2val_walking]

amocas.q:
config:
- check ISA:=regex(.*Zacas.*)
opcode:
amocas.q: 0
rs1:
<<: *all_regs_mx0
rs2:
<<: *pair_regs
rd:
<<: *pair_regs
op_comb:
<<: *zacas_op_comb
val_comb:
<<: [*zacas_dcas_rs1val_sgn, *zacas_dcas_rs2val_sgn, *rfmt_val_comb_sgn]
abstract_comb:
<<: [*zacas128_rs1val_walking_sgn, *zacas128_rs2val_walking_sgn]

0 comments on commit 24a4eb8

Please sign in to comment.