Skip to content

Commit

Permalink
Merge pull request #2439 from XavierAubert/cv32e40p/load_store_compre…
Browse files Browse the repository at this point in the history
…ss_fix

CV32E40P fix for mem stress scenario with compressed instructions
  • Loading branch information
MikeOpenHWGroup committed May 16, 2024
2 parents 5dcf456 + 70c91ed commit 974da2f
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
11 changes: 9 additions & 2 deletions cv32e40p/env/corev-dv/cv32e40p_instr_base_test.sv
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class cv32e40p_instr_base_test extends corev_instr_base_test;
override_privil_reg();
override_debug_rom_gen();
override_instr_stream();
override_load_store_lib();
super.build_phase(phase);
endfunction

Expand Down Expand Up @@ -97,8 +98,8 @@ class cv32e40p_instr_base_test extends corev_instr_base_test;
string test_override_fp_instr_stream = "default";
if ($value$plusargs("test_override_riscv_instr_stream=%0d", test_override_riscv_instr_stream)) begin : TEST_OVERRIDE_RISCV_INSTR_STREAM
unique case(test_override_riscv_instr_stream)
1: begin
uvm_factory::get().set_type_override_by_type(riscv_rand_instr_stream::get_type(), cv32e40p_rand_instr_stream::get_type());
1: begin
uvm_factory::get().set_type_override_by_type(riscv_rand_instr_stream::get_type(), cv32e40p_rand_instr_stream::get_type());
end
endcase
end // TEST_OVERRIDE_RISCV_INSTR_STREAM
Expand Down Expand Up @@ -126,6 +127,12 @@ class cv32e40p_instr_base_test extends corev_instr_base_test;
end
endfunction

// to avoid stress tests to reserve all S0:A5 regs used by compressed instructions
virtual function void override_load_store_lib();
uvm_factory::get().set_type_override_by_type(riscv_multi_page_load_store_instr_stream::get_type(), cv32e40p_multi_page_load_store_instr_stream::get_type());
uvm_factory::get().set_type_override_by_type(riscv_mem_region_stress_test::get_type(), cv32e40p_mem_region_stress_test::get_type());
endfunction

virtual function void apply_directed_instr();
endfunction

Expand Down
4 changes: 3 additions & 1 deletion cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ package cv32e40p_instr_test_pkg;
`include "cv32e40p_privil_reg.sv"
`include "cv32e40p_debug_rom_gen.sv"
`include "cv32e40p_asm_program_gen.sv"
`include "cv32e40p_load_store_instr_lib.sv"

`include "cv32e40p_instr_base_test.sv"

// Push general purpose register to the debugger stack
Expand Down Expand Up @@ -497,7 +499,7 @@ package cv32e40p_instr_test_pkg;

end

// fixme: the irq handling logic flow need to be rework to consider nested irq scenario for fpu csr such as FS.
// fixme: the irq handling logic flow need to be rework to consider nested irq scenario for fpu csr such as FS.
// workaround_1 for MSTATUS.FS during nested irq by assuming FS always DIRTY prior irq handling.
if (cfg_corev.enable_nested_interrupt) begin
// always set FS to DIRTY prior mret
Expand Down
79 changes: 79 additions & 0 deletions cv32e40p/env/corev-dv/cv32e40p_load_store_instr_lib.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2018 Google LLC
* Copyright 2023 Dolphin Design
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


class cv32e40p_multi_page_load_store_instr_stream extends riscv_multi_page_load_store_instr_stream;
rand bit has_taken_avail_comp_reg[];
riscv_reg_t s0_a5_avail_regs[];

constraint with_compress_instructions_c {
has_taken_avail_comp_reg.size() == rs1_reg.size();
foreach(rs1_reg[i]) {
if (rs1_reg[i] inside {s0_a5_avail_regs}) {
has_taken_avail_comp_reg[i] == 1;
} else {
has_taken_avail_comp_reg[i] == 0;
}
}
// to make sure at least one is left for compress instructions
// count the number of ones (= taken comp regs), and contraint it to be less than the number of avail regs
if (cfg.disable_compressed_instr == 0) {
has_taken_avail_comp_reg.sum() < s0_a5_avail_regs.size();
}
}

`uvm_object_utils(cv32e40p_multi_page_load_store_instr_stream)
`uvm_object_new

function void pre_randomize();
super.pre_randomize();
s0_a5_avail_regs = {S0, S1, A0, A1, A2, A3, A4, A5};
s0_a5_avail_regs = s0_a5_avail_regs.find() with (!(item inside {cfg.reserved_regs, reserved_rd}));
endfunction
endclass


class cv32e40p_mem_region_stress_test extends riscv_mem_region_stress_test;
rand bit has_taken_avail_comp_reg[];
riscv_reg_t s0_a5_avail_regs[];

constraint with_compress_instructions_c {
has_taken_avail_comp_reg.size() == rs1_reg.size();
foreach(rs1_reg[i]) {
if (rs1_reg[i] inside {s0_a5_avail_regs}) {
has_taken_avail_comp_reg[i] == 1;
} else {
has_taken_avail_comp_reg[i] == 0;
}
}
// to make sure at least one is left for compress instructions
// count the number of ones (= taken comp regs), and contraint it to be less than the number of avail regs
if (cfg.disable_compressed_instr == 0) {
has_taken_avail_comp_reg.sum() < s0_a5_avail_regs.size();
}
}


`uvm_object_utils(cv32e40p_mem_region_stress_test)
`uvm_object_new

function void pre_randomize();
super.pre_randomize();
s0_a5_avail_regs = {S0, S1, A0, A1, A2, A3, A4, A5};
s0_a5_avail_regs = s0_a5_avail_regs.find() with (!(item inside {cfg.reserved_regs, reserved_rd}));
endfunction
endclass

0 comments on commit 974da2f

Please sign in to comment.