Hello everyone,
I was trying to write constraints on class variables in a top level class and the problem is the class handles themselves are dynamic arrays. To present my problem I put together a stripped off version of my code by referring to other posts, especially the one located here: Constraint for object dynamic array
Here is the sample code to represent my issue:
class cpu_core_class;
rand int core_count;
constraint c_core_count {
core_count inside {[32'd1:32'd16]};
}
function new();
endfunction: new
endclass: cpu_core_class
class memory_controller_class;
rand int controller_count;
constraint c_controller_count {
controller_count inside {[32'd1:32'd16]};
}
function new();
endfunction: new
endclass: memory_controller_class
class hardware_config_class;
rand cpu_core_class cpu_cores;
rand memory_controller_class memory_controllers;
function new();
cpu_cores = new();
memory_controllers = new();
endfunction: new
endclass: hardware_config_class
class cache_size_class;
rand int size_kb;
constraint c_size_kb {
size_kb inside {[32'd16:32'd1048576]};
}
function new();
endfunction: new
endclass: cache_size_class
class params_memory_class;
rand cache_size_class cache_size;
function new();
cache_size = new();
endfunction: new
endclass: params_memory_class
class params_cpu_class;
function new();
endfunction: new
endclass: params_cpu_class
class params_class;
rand hardware_config_class hardware;
rand params_memory_class memory[];
rand params_cpu_class cpu[];
local const int unsigned MAX_UNITS = 32;
function new();
hardware = new();
memory = new[MAX_UNITS];
cpu = new[MAX_UNITS];
endfunction: new
constraint c_max_memory_bandwidth{
(memory.sum() with ($clog2(item.cache_size.size_kb))) + ($clog2(hardware.cpu_cores.core_count)) <= 20;
}
constraint c_hardware{
cpu.size() == hardware.cpu_cores.core_count;
memory.size() == hardware.memory_controllers.controller_count;
}
function void pre_randomize();
foreach(cpu[i]) begin
cpu[i] = new;
memory[i] = new;
end
endfunction: pre_randomize
endclass: params_class
module random();
params_class params;
initial begin
params = new();
if(!params.randomize()) begin
$error("Randomization Failed after turning off structural params randomization");
end else begin
$display("CPU Size: %0d", params.cpu.size());
$display("Memory Size: %0d", params.memory.size());
end
end
endmodule
The above code is also located in the eda playground link here :
I see that I get exactly what I want for few seeds but for other seeds, the above code is hitting constraint resolution failure (indicating that for the seeds that dint fail, it was just a coincidence)
Here is a sample error:
# testbench.sv(82): randomize() failed due to conflicts between the following constraints:
# testbench.sv(31): memory[1].cache_size.c_size_kb { (memory[1].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(31): memory[0].cache_size.c_size_kb { (memory[0].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(31): memory[2].cache_size.c_size_kb { (memory[2].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(31): memory[3].cache_size.c_size_kb { (memory[3].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(31): memory[4].cache_size.c_size_kb { (memory[4].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(31): memory[5].cache_size.c_size_kb { (memory[5].cache_size.size_kb inside { [16:1048576] }); }
# testbench.sv(60): c_max_memory_bandwidth { ((($clog2(memory[0].cache_size.size_kb) + $clog2(memory[1].cache_size.size_kb) + $clog2(memory[2].cache_size.size_kb) + $clog2(memory[3].cache_size.size_kb) + $clog2(memory[4].cache_size.size_kb) + $clog2(memory[5].cache_size.size_kb) + $clog2(memory[6].cache_size.size_kb) + $clog2(memory[7].cache_size.size_kb)) + $clog2(hardware.cpu_cores.core_count)) <= 20); }
# Given:
# bit signed [31:0] memory[1].cache_size.size_kb
# bit signed [31:0] memory[0].cache_size.size_kb
# bit signed [31:0] memory[2].cache_size.size_kb
# bit signed [31:0] memory[3].cache_size.size_kb
# bit signed [31:0] memory[4].cache_size.size_kb
# bit signed [31:0] memory[5].cache_size.size_kb
# bit signed [31:0] memory[6].cache_size.size_kb
# bit signed [31:0] memory[7].cache_size.size_kb
# bit signed [31:0] hardware.cpu_cores.core_count
I was expecting the .size() to be calculated such that the constraint c_max_memory_bandwidth is satisfied. But looks like that is not the case here.
Can someone please suggest what is going on or a workaround for this issue?
Thanks and regards,