In reply to Prat_0693:
The issue I see is that there is a sequence flow in your requirements.
Below is a solution based on my understanding of your requirements. Perhaps this can guide you into the approach you need.
import uvm_pkg::*; `include "uvm_macros.svh"
class C;
/* I want to randomize a variable "a" such that even if I randomize this 2 times or more,
* I should get atleast 1 "maxval" and 1 "minval".
For ex. `define aint 4 `define 10 10
I want to randomize variable a only on the basis of `aint (i.e only 4 times)
and I am required that I should get atleast one "0" and one "10"
(depending on the value of `10) and the rest two values of a can be between 0 and 10.
[Ben] Not clear requirements. Let me assume th following requirements:
1) within aint (e.g., 4) randomize calls, and within those 4 times,
2) there should be at least one 0 and one 10 */
// `define aint 4
// `define 10 10
int count;
bit found_min;
bit found_max;
rand int unsigned a;
function void do_randomize();
case (count)
0, 1 : begin :a01
count += 1'b1;
if (!randomize(a) with {a >=0; a<11;}) `uvm_error("MYERR", "This is a randomize error")
if(a==0) found_min=1'b1;
if(a==10) found_max=1'b1;
end :a01
2,3 : begin :a23
if(!found_min && !found_max) begin
if (!randomize(a) with
{a dist {0:=1, 10:=1};
}) `uvm_error("MYERR", "This is a randomize error")
if(a==0) found_min=1'b1;
if(a==10) found_max=1'b1;
end
else if(found_min && !found_max) begin
if (!randomize(a) with
{a dist {0:=0, 10:=1};
}) `uvm_error("MYERR", "This is a randomize error")
//if(a==0) found_min=1'b1;
if(a==10) found_max=1'b1;
end
else if(found_min && !found_max) begin
if (!randomize(a) with
{a dist {0:=1, 10:=0};
}) `uvm_error("MYERR", "This is a randomize error")
if(a==0) found_min=1'b1;
//if(a==10) found_max=1'b1;
end
else begin :a23e
if (!randomize(a) with
{ a dist {1'b1:=1, 1'b0:=3};
}) `uvm_error("MYERR", "This is a randomize error")
if(count !=3) begin
if(a==0) found_min=1'b1;
if(a==10) found_max=1'b1;
count += 1'b1;
end
else begin
count=0;
found_min=1'b0;
found_max=1'b0;
end
end :a23e
end :a23
default : $display("error in case");
endcase
endfunction :do_randomize
endclass
module top;
timeunit 1ns; timeprecision 100ps;
bit clk;
int a;
C c;
initial forever #10 clk=!clk;
initial begin
c=new();
repeat(200) begin
@(posedge clk);
c.do_randomize();
a=c.a;
$display("a %d, count %d, found_min %b, found_max %b", c.a, c.count, c.found_min, c.found_max);
end
$stop;
end
endmodule
# a 3, count 1, found_min 0, found_max 0
# a 6, count 2, found_min 0, found_max 0
# a 10, count 2, found_min 0, found_max 1
# a 0, count 3, found_min 1, found_max 1
# a 0, count 0, found_min 0, found_max 0
# a 6, count 1, found_min 0, found_max 0
# a 3, count 2, found_min 0, found_max 0
# a 0, count 2, found_min 1, found_max 0
# a 10, count 2, found_min 1, found_max 1
# a 1, count 3, found_min 1, found_max 1
# a 0, count 0, found_min 0, found_max 0
# a 6, count 1, found_min 0, found_max 0
# a 2, count 2, found_min 0, found_max 0
# a 0, count 2, found_min 1, found_max 0
# a 10, count 2, found_min 1, found_max 1
# a 0, count 3, found_min 1, found_max 1
# a 1, count 0, found_min 0, found_max 0
# a 8, count 1, found_min 0, found_max 0
# a 10, count 2, found_min 0, found_max 1
# a 1, count 3, found_min 0, found_max 1
# a 0, count 0, found_min 0, found_max 0
# a 6, count 1, found_min 0, found_max 0
# a 4, count 2, found_min 0, found_max 0
# a 0, count 2, found_min 1, found_max 0
# a 10, count 2, found_min 1, found_max 1
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr