diff --git a/src/isa/riscv_compressed_instr.sv b/src/isa/riscv_compressed_instr.sv index 02fdf338..a603262f 100644 --- a/src/isa/riscv_compressed_instr.sv +++ b/src/isa/riscv_compressed_instr.sv @@ -33,12 +33,19 @@ class riscv_compressed_instr extends riscv_instr; } // C_ADDI16SP is only valid when rd == SP if (instr_name == C_ADDI16SP) { + rs1 == SP; rd == SP; } if (instr_name inside {C_JR, C_JALR}) { rs2 == ZERO; rs1 != ZERO; } + // These formats potentially have rd == rs1 + if (format inside {CA_FORMAT, CB_FORMAT, CI_FORMAT, CR_FORMAT}) { + if (has_rd && has_rs1) { + rd == rs1; + } + } } constraint imm_val_c { @@ -156,7 +163,13 @@ class riscv_compressed_instr extends riscv_instr; has_rs1 = 1'b0; has_imm = 1'b0; end - CI_FORMAT, CIW_FORMAT: begin + CI_FORMAT: begin + if (instr_name inside {C_LI, C_LUI, C_LWSP, C_NOP, C_EBREAK}) begin + has_rs1 = 1'b0; + end + has_rs2 = 1'b0; + end + CIW_FORMAT: begin has_rs1 = 1'b0; has_rs2 = 1'b0; end @@ -166,7 +179,7 @@ class riscv_compressed_instr extends riscv_instr; has_rd = 1'b0; end CB_FORMAT: begin - if (instr_name != C_ANDI) has_rd = 1'b0; + if (instr_name inside {C_BEQZ, C_BNEZ}) has_rd = 1'b0; has_rs2 = 1'b0; end endcase diff --git a/src/riscv_instr_stream.sv b/src/riscv_instr_stream.sv index 9e980da8..b1703077 100644 --- a/src/riscv_instr_stream.sv +++ b/src/riscv_instr_stream.sv @@ -228,24 +228,30 @@ class riscv_rand_instr_stream extends riscv_instr_stream; end endfunction - function void randomize_instr(output riscv_instr instr, - input bit is_in_debug = 1'b0, - input bit disable_dist = 1'b0, - input riscv_instr_group_t include_group[$] = {}); - riscv_instr_name_t exclude_instr[]; + function void update_excluded_instr(ref riscv_instr_name_t exclude_instr[], + input bit is_in_debug = 1'b0); if ((SP inside {reserved_rd, cfg.reserved_regs}) || ((avail_regs.size() > 0) && !(SP inside {avail_regs}))) begin - exclude_instr = {C_ADDI4SPN, C_ADDI16SP, C_LWSP, C_LDSP}; + exclude_instr = {exclude_instr, C_ADDI4SPN, C_ADDI16SP, C_LWSP, C_LDSP}; end - // Post-process the allowed_instr and exclude_instr lists to handle - // adding ebreak instructions to the debug rom. + // Post-process the exclude_instr lists to handle adding ebreak instructions to the debug rom. if (is_in_debug) begin - if (cfg.no_ebreak && cfg.enable_ebreak_in_debug_rom) begin - allowed_instr = {allowed_instr, EBREAK, C_EBREAK}; - end else if (!cfg.no_ebreak && !cfg.enable_ebreak_in_debug_rom) begin + if (!cfg.no_ebreak && !cfg.enable_ebreak_in_debug_rom) begin exclude_instr = {exclude_instr, EBREAK, C_EBREAK}; end end + endfunction + + function void randomize_instr(output riscv_instr instr, + input bit is_in_debug = 1'b0, + input bit disable_dist = 1'b0, + input riscv_instr_group_t include_group[$] = {}); + riscv_instr_name_t exclude_instr[]; + update_excluded_instr(exclude_instr, is_in_debug); + // Post-process the allowed_instr lists to handle adding ebreak instructions to the debug rom. + if (is_in_debug && cfg.no_ebreak && cfg.enable_ebreak_in_debug_rom) begin + allowed_instr = {allowed_instr, EBREAK, C_EBREAK}; + end instr = riscv_instr::get_rand_instr(.include_instr(allowed_instr), .exclude_instr(exclude_instr), .include_group(include_group)); @@ -270,17 +276,11 @@ class riscv_rand_instr_stream extends riscv_instr_stream; if (has_rd) { rd != reserved_rd[i]; } - if (format == CB_FORMAT) { - rs1 != reserved_rd[i]; - } } foreach (cfg.reserved_regs[i]) { if (has_rd) { rd != cfg.reserved_regs[i]; } - if (format == CB_FORMAT) { - rs1 != cfg.reserved_regs[i]; - } } // TODO: Add constraint for CSR, floating point register ) diff --git a/src/riscv_loop_instr.sv b/src/riscv_loop_instr.sv index c2fcecc6..9cdc8216 100644 --- a/src/riscv_loop_instr.sv +++ b/src/riscv_loop_instr.sv @@ -113,7 +113,10 @@ class riscv_loop_instr extends riscv_rand_instr_stream; `uvm_object_new function void post_randomize(); + riscv_instr_name_t exclude_instr[]; reserved_rd = {loop_cnt_reg, loop_limit_reg}; + // Figure out which instructions we can no longer use after the loop regs are decided + update_excluded_instr(exclude_instr); // Generate instructions that mixed with the loop instructions initialize_instr_list(num_of_instr_in_loop); gen_instr(1'b1); @@ -144,11 +147,8 @@ class riscv_loop_instr extends riscv_rand_instr_stream; // Branch target instruction, can be anything loop_branch_target_instr[i] = riscv_instr::get_rand_instr( .include_category({ARITHMETIC, LOGICAL, COMPARE}), - .exclude_instr({C_ADDI16SP})); + .exclude_instr(exclude_instr)); `DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_target_instr[i], - if (format == CB_FORMAT) { - !(rs1 inside {reserved_rd, cfg.reserved_regs}); - } if (has_rd) { !(rd inside {reserved_rd, cfg.reserved_regs}); }, "Cannot randomize branch target instruction")