def gen_amo_instr(self): allowed_lr_instr = [] allowed_sc_instr = [] if riscv_instr_group_t.RV32A in rcs.supported_isa: allowed_lr_instr.append(riscv_instr_name_t.LR_W) allowed_sc_instr.append(riscv_instr_name_t.SC_W) if riscv_instr_group_t.RV64A in rcs.supported_isa: allowed_lr_instr.append(riscv_instr_name_t.LR_D) allowed_sc_instr.append(riscv_instr_name_t.SC_D) self.lr_instr = riscv_instr.get_rand_instr( include_instr=allowed_lr_instr) self.sc_instr = riscv_instr.get_rand_instr( include_instr=allowed_sc_instr) with self.lr_instr.randomize_with(): # self.lr_instr.rs1 == self.rs1_reg[0] # TODO Getting error with vsc.if_then(self.reserved_rd.size > 0): self.lr_instr.rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.lr_instr.rd.not_inside(vsc.rangelist(cfg.reserved_regs)) # self.lr_instr.rd != self.rs1_reg[0] # TODO with self.sc_instr.randomize_with(): # self.sc_instr.rs1 == self.rs1_reg[0] # TODO with vsc.if_then(self.reserved_rd.size > 0): self.sc_instr.rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.sc_instr.rd.not_inside(vsc.rangelist(cfg.reserved_regs)) # self.sc_instr.rd != self.rs1_reg[0] # TODO self.instr_list.extend((self.lr_instr, self.sc_instr))
def randomize_instr(self, instr, is_in_debug=0, disable_dist=0, include_group=[]): exclude_instr = [] is_SP_in_reserved_rd = riscv_reg_t.SP in self.reserved_rd is_SP_in_reserved_regs = riscv_reg_t.SP in cfg.reserved_regs is_SP_in_avail_regs = riscv_reg_t.SP in self.avail_regs if ((is_SP_in_reserved_rd or is_SP_in_reserved_regs) or (len(self.avail_regs) > 0 and not is_SP_in_avail_regs)): exclude_instr.append(riscv_instr_name_t.C_ADDI4SPN.name) exclude_instr.append(riscv_instr_name_t.C_ADDI16SP.name) exclude_instr.append(riscv_instr_name_t.C_LWSP.name) exclude_instr.append(riscv_instr_name_t.C_LDSP.name) # Post-process the allowed_instr and exclude_instr lists to handle # adding ebreak instructions into the debug ROM. if is_in_debug: if (cfg.no_ebreak and cfg.enable_ebreak_in_debug_rom): self.allowed_instr.extend([ riscv_instr_name_t.EBREAK.name, riscv_instr_name_t.C_EBREAK.name ]) elif (not cfg.no_ebreak and not cfg.enable_ebreak_in_debug_rom): exclude_instr.extend([ riscv_instr_name_t.EBREAK.name, riscv_instr_name_t.C_EBREAK.name ]) instr = riscv_instr.get_rand_instr(include_instr=self.allowed_instr, exclude_instr=exclude_instr, include_group=include_group) instr = self.randomize_gpr(instr) return instr
def gen_amo_instr(self): for i in range(self.num_amo): self.amo_instr.append(riscv_instr.get_rand_instr( include_category=[riscv_instr_category_t.AMO])) with self.amo_instr[i].randomize_with(): with vsc.if_then(self.reserved_rd.size > 0): self.amo_instr[i].rd.not_inside(vsc.rangelist(self.reserved_rd)) with vsc.if_then(cfg.reserved_regs.size > 0): self.amo_instr[i].rd.not_inside(vsc.rangelist(cfg.reserved_regs)) self.amo_instr[i].rs1.inside(vsc.rangelist(self.rs1_reg)) self.amo_instr[i].rd.inside(vsc.rangelist(self.rs1_reg)) self.instr_list.insert(0, self.amo_instr[i])
def post_randomize(self): order = [] RA = cfg.ra order = [0] * self.num_of_jump_instr self.jump = [0] * self.num_of_jump_instr for i in range(len(order)): order[i] = i random.shuffle(order) self.setup_allowed_instr(1, 1) jal = [riscv_instr_name_t.JAL] if not cfg.disable_compressed_instr: jal.append(riscv_instr_name_t.C_J) if rcs.XLEN == 32: jal.append(riscv_instr_name_t.C_JAL) # First instruction self.jump_start = riscv_instr.get_instr(riscv_instr_name_t.JAL) with self.jump_start.randomize_with() as it: self.jump_start.rd == RA self.jump_start.imm_str = "{}f".format(order[0]) self.jump_start.label = self.label # Last instruction self.jump_end = self.randomize_instr(self.jump_end) self.jump_end.label = "{}".format(self.num_of_jump_instr) for i in range(self.num_of_jump_instr): self.jump[i] = riscv_instr.get_rand_instr(include_instr=[jal[0]]) with self.jump[i].randomize_with() as it: if self.jump[i].has_rd: vsc.dist(self.jump[i].rd, [ vsc.weight(riscv_reg_t.RA, 5), vsc.weight(vsc.rng(riscv_reg_t.SP, riscv_reg_t.T0), 1), vsc.weight(vsc.rng(riscv_reg_t.T2, riscv_reg_t.T6), 2) ]) self.jump[i].rd.not_inside(cfg.reserved_regs) self.jump[i].label = "{}".format(i) for i in range(len(order)): if i == self.num_of_jump_instr - 1: self.jump[order[i]].imm_str = "{}f".format( self.num_of_jump_instr) else: if order[i + 1] > order[i]: self.jump[order[i]].imm_str = "{}f".format(order[i + 1]) else: self.jump[order[i]].imm_str = "{}b".format(order[i + 1]) self.instr_list.append(self.jump_start) self.instr_list.extend(self.jump) self.instr_list.append(self.jump_end) for i in range(len(self.instr_list)): self.instr_list[i].has_label = 1 self.instr_list[i].atomic = 1
def gen_push_stack_instr(self, stack_len, allow_branch=1): self.stack_len = stack_len self.init() self.push_stack_instr = [0] * (self.num_of_reg_to_save + 1) for i in range(len(self.push_stack_instr)): self.push_stack_instr[i] = riscv_instr() self.push_stack_instr[0] = \ riscv_instr.get_instr(riscv_instr_name_t.ADDI.name) with self.push_stack_instr[0].randomize_with() as it: self.push_stack_instr[0].rd == cfg.sp self.push_stack_instr[0].rs1 == cfg.sp self.push_stack_instr[0].imm == (~cfg.stack_len + 1) self.push_stack_instr[0].imm_str = '-{}'.format(self.stack_len) for i in range(len(self.saved_regs)): if rcs.XLEN == 32: self.push_stack_instr[i + 1] = riscv_instr.get_instr( riscv_instr_name_t.SW.name) with self.push_stack_instr[i + 1].randomize_with() as it: self.push_stack_instr[i + 1].rs2 == self.saved_regs[i] self.push_stack_instr[i + 1].rs1 == cfg.sp self.push_stack_instr[i + 1].imm == 4 * (i + 1) else: self.push_stack_instr[i + 1] = riscv_instr.get_instr( riscv_instr_name_t.SD.name) with self.push_stack_instr[i + 1].randomize_with() as it: self.push_stack_instr[i + 1].rs2 == self.saved_regs[i] self.push_stack_instr[i + 1].rs1 == cfg.sp self.push_stack_instr[i + 1].imm == 8 * (i + 1) self.push_stack_instr[i + 1].process_load_store = 0 if allow_branch: # TODO # vsc.randomize(self.enable_branch) pass else: self.enable_branch = 0 if self.enable_branch: self.branch_instr = \ riscv_instr.get_rand_instr(include_category=[riscv_instr_name_t.BRANCH.name]) self.branch_instr.randomize() self.branch_instr.imm_str = self.push_start_label self.branch_instr.brach_assigned = 1 self.push_stack_instr[0].label = self.push_start_label self.push_stack_instr[0].has_label = 1 self.branch_instr.extend(self.push_stack_instr) self.mix_instr_stream(self.push_stack_instr) for i in range(len(self.instr_list)): self.instr_list[i].atomic = 1 if self.instr_list[i].label == '': self.instr_list[i].has_label = 0
def post_randomize(self): self.init_instr = [None] * self.num_of_avail_regs for i in range(len(self.init_val_type)): if self.init_val_type[i] == int_numeric_e.Zero: self.init_val[i] = 0 elif self.init_val_type[i] == int_numeric_e.AllOne: self.init_val[i] = 1 elif self.init_val_type[i] == int_numeric_e.NegativeMax: self.init_val[i] = 1 << (rcs.XLEN - 1) self.init_instr[i] = riscv_pseudo_instr() self.init_instr[i].rd = self.avail_regs[i] self.init_instr[i].pseudo_instr_name = riscv_pseudo_instr_name_t.LI self.init_instr[i].imm_str = "0x%0x" % (self.init_val[i]) self.instr_list.append(self.init_instr[i]) for i in range(self.num_of_instr): instr = riscv_instr.get_rand_instr( include_category = ['ARITHMETIC'], exclude_group = ['RV32C', 'RV64C', 'RV32F', 'RV64F', 'RV32D', 'RV64D']) instr = self.randomize_gpr(instr) self.instr_list.append(instr) super().post_randomize()
def post_randomize(self): for i in range(len(self.loop_cnt_reg)): self.reserved_rd.append(self.loop_cnt_reg[i]) for i in range(len(self.loop_limit_reg)): self.reserved_rd.append(self.loop_limit_reg[i]) # Generate instructions that mixed with the loop instructions self.initialize_instr_list(self.num_of_instr_in_loop) self.gen_instr(1) # Randomize the key loop instructions self.loop_init_instr = [0] * 2 * self.num_of_nested_loop self.loop_update_instr = [0] * self.num_of_nested_loop self.loop_branch_instr = [0] * self.num_of_nested_loop self.loop_branch_target_instr = [0] * self.num_of_nested_loop for i in range(self.num_of_nested_loop): # Instruction to init the loop counter try: self.loop_init_instr.insert(2 * i, riscv_instr.get_rand_instr()) # TODO '''self.loop_update_instr[i] = riscv_instr.get_rand_instr( include_instr = [riscv_instr_name_t.ADDI])''' # Removed include_instr ADDI for now to avoid unrecognized colon with self.loop_init_instr[2 * i].randomize_with(): self.loop_init_instr[2 * i].rd == self.loop_cnt_reg[i] self.loop_init_instr[2 * i].rs1 == riscv_reg_t.ZERO self.loop_init_instr[2 * i].imm == self.loop_init_val[i] self.loop_init_instr[2 * i].comment = \ pkg_ins.format_string("init loop {} counter".format(i)) except Exception: logging.critical("Cannot randomize loop init1 instruction") sys.exit(1) # Instruction to init loop limit try: self.loop_init_instr[2 * i + 1] = riscv_instr.get_rand_instr() # TODO '''self.loop_update_instr[i] = riscv_instr.get_rand_instr( include_instr = [riscv_instr_name_t.ADDI])''' # Removed include_instr ADDI for now to avoid unrecognized colon with self.loop_init_instr[2 * i + 1].randomize_with(): self.loop_init_instr[2 * i + 1].rd == self.loop_limit_reg[i] self.loop_init_instr[2 * i + 1].rs1 == riscv_reg_t.ZERO self.loop_init_instr[2 * i + 1].imm == self.loop_limit_val[i] self.loop_init_instr[2 * i + 1].comment = \ pkg_ins.format_string("init loop {} limit".format(i)) except Exception: logging.critical("Cannot randomize loop init2 instruction") sys.exit(1) # Branch target instruction, can be anything self.loop_branch_target_instr[i] = riscv_instr.get_rand_instr( include_category=[ riscv_instr_category_t.ARITHMETIC.name, riscv_instr_category_t.LOGICAL.name, riscv_instr_category_t.COMPARE.name ], exclude_instr=[riscv_instr_name_t.C_ADDI16SP]) try: with self.loop_branch_target_instr[i].randomize_with(): with vsc.if_then(self.loop_branch_target_instr[i].format == riscv_instr_format_t.CB_FORMAT): self.loop_branch_target_instr[i].rs1.not_inside( vsc.rangelist(self.reserved_rd)) self.loop_branch_target_instr[i].rs1.not_inside( vsc.rangelist(cfg.reserved_regs)) with vsc.if_then( self.loop_branch_target_instr[i].has_rd == 1): self.loop_branch_target_instr[i].rd.not_inside( vsc.rangelist(self.reserved_rd)) self.loop_branch_target_instr[i].rd.not_inside( vsc.rangelist(cfg.reserved_regs)) except Exception: logging.critical("Cannot randomize branch target instruction") sys.exit(1) self.loop_branch_target_instr[i].label = pkg_ins.format_string( "{}_{}_t".format(self.label, i)) # Instruction to update loop counter self.loop_update_instr[i] = riscv_instr.get_rand_instr() # TODO '''self.loop_update_instr[i] = riscv_instr.get_rand_instr( include_instr = [riscv_instr_name_t.ADDI])''' # Removing include_instr ADDI for now to avoid unrecognized colon # Commenting for now due to key error '''with self.loop_update_instr[i].randomize_with(): self.loop_update_instr[i].rd == self.loop_cnt_reg[i] self.loop_update_instr[i].rs1 == self.loop_cnt_reg[i] self.loop_update_instr[i].imm == self.loop_step_val[i]''' self.loop_update_instr[i].comment = pkg_ins.format_string( "update loop {} counter".format(i)) # Backward branch instruction self.loop_branch_instr[i] = riscv_instr.get_rand_instr( include_instr=[self.branch_type[i]]) self.loop_branch_instr[i].randomize() with self.loop_branch_instr[i].randomize_with(): self.loop_branch_instr[i].rs1 == self.loop_cnt_reg[i] # Getting PyVSC related error # TODO '''with vsc.if_then((self.branch_type[i] != riscv_instr_name_t.C_BEQZ) or (self.branch_type[i] != riscv_instr_name_t.C_BNEZ)): self.loop_branch_instr[i].rs2 == self.loop_limit_reg[i] ''' self.loop_branch_instr[i].comment = pkg_ins.format_string( "branch for loop {}".format(i)) self.loop_branch_instr[i].imm_str = self.loop_branch_target_instr[ i].label self.loop_branch_instr[i].branch_assigned = 1 # Randomly distribute the loop instruction in the existing instruction stream self.build_loop_instr_stream() self.mix_instr_stream(self.loop_instr, 1) for i in range(len(self.instr_list)): if (self.instr_list[i].label != ""): self.instr_list[i].has_label = 1 else: self.instr_list[i].has_label = 0 self.instr_list[i].atomic = 1