Randomization failing

Hi everyone,
I am new to system verilog. I am facing a issue in randomizing. No compilation error. No fatal error during simulation. But i get following when I do the run -a.
Error: test_1_write_read_dp.sv(15): Invalid call to class::randomize() via null class reference.

Time: 0 ns Iteration: 1 Region: /top_dp_sv_unit::environment::run

With this little info i am not able to get a head start to debug.
Plz give some inputs.

Thanks in advance.

In reply to spat:

You have to show us the code that’s failing. At least line 15 of your file.

In reply to Tudor Timi:

Following is the code Tudor, thnx!

class packet;
rand bit cs_0,cs_1,we_0,we_1,oe_0,oe_1;
rand integer addr_0,addr_1;
rand integer data_0, data_1;
endclass

class test;
packet sti;
//packet pac1;
mailbox #(packet) mail;
mailbox #(packet) mail1;

function new(mailbox mail_dr, mailbox mail_sb);
this.mail = mail;
this.mail = mail1;
endfunction

task generate_s(input integer iteration);
repeat(iteration)
begin
if(sti.randomize()) with {cs_0==1; we_0==1; cs_1==1; we_1==0; oe_1==0; }) // line 15
begin
// pac1 = pac;
$display(“********************”);
mail.put(sti);
mail1.put(sti);
$display(“randomization successfull”);
end
else $display(“failed”);
end
endtask
endclass

Calling randomize() doesn’t allocate objects. You have to call it on objects that were already created. In your case sti is null. You have to create it before:


sti = new();
if(sti.randomize() with {cs_0==1; we_0==1; cs_1==1; we_1==0; oe_1==0; })
//...

In reply to Tudor Timi:

Thanks so much Tudor… Thats working now.
I have two more things to be discussed:

  1. After getting done with that, I came across another issue, pertaining to put methods from the generator, which I did solve but I yet haven’t understood the essence of the issue I was facing. So if you look into task generate_s() inside class test (highlighted by comment XXXXXXXXXXXXXXX & YYYYYYYYYYYYYYYY in the following), I was using two separate mailboxes mail and mail1 and to put the object sti of the packet. I was getting them in drivers and scoreboards as mail & mail1 respectively.

task generate_s(input integer iteration);
repeat(iteration)
begin
if(sti.randomize()) with {cs_0==1; we_0==1; cs_1==1; we_1==0; oe_1==0; }) // line 15
begin

$display(“********************”);
mail.put(sti); // XXXXXXXXXXXXXXX
mail1.put(sti); //YYYYYYYYYYYYYYYY
$display(“randomization successfull”);
end
else $display(“failed”);
end
endtask
The fatal error i used to get on doing run -a was again bad hanlde reference making the questa sim hang, whaich had to restarted! On debugging it, all I did now is just using one mail to put from test and get in scoreboard and driver. Basically got rid of mail1. Things work fine. Validated this by displaying the randomized values in all the 3 classes and they are same. Need to understand why using two mailboxes was a issue?

  1. I have this inout problem. the error I get is (highlighted byXXXXXXXXXX & YYYYYYYYYYYYYY in driver class )

** Error: (vsim-8220) driver_dp.sv(30): This or another usage of ‘intf.data_0’ inconsistent with ‘net’ object.

Region: /top_dp_sv_unit

** Error: (vsim-8220) driver_dp.sv(31): This or another usage of ‘intf.data_1’ inconsistent with ‘net’ object.

Region: /top_dp_sv_unit

Error loading design

data_1 & data_0 are the dual ports.
CODES*****
interface*
interface int_dp(input bit clk);
logic cs_0;
logic we_0;
logic oe_0;
logic cs_1;
logic we_1;
logic oe_1;
logic [11:0] addr_1;
logic [11:0] addr_0;
wire [7:0] data_0;
wire [7:0] data_1;
modport tb (output cs_0,cs_1,we_0,we_1,oe_0,oe_1,addr_1,addr_0,clk, data_1,data_0);
endinterface
TOP*
module top;
bit systemclk;

int_dp intf(systemclk); // interface instantiation

ram_dp_srw DUT(
.clk(systemclk), // dut instantiation
.cs_0(intf.cs_0),
.cs_1(intf.cs_1),
.we_0(intf.we_0),
.we_1(intf.we_1),
.oe_0(intf.oe_0),
.oe_1(intf.oe_1),
.address_0_in(intf.addr_0),
.address_1_in(intf.addr_1),
.data_0(intf.data_0),
.data_1(intf.data_1));

testcase testcase_0(intf); // program block instantiation

initial begin
#100000 $finish;
end

initial begin //clk generation
systemclk = 0;
forever
#5 systemclk = ~systemclk;
end

endmodule

Driver****
class driver;
packet sti;

virtual int_dp.tb intf;

mailbox #(packet) mail;

function new (virtual int_dp.tb intf, mailbox #(packet) mail);
this.intf = intf;
this.mail = mail;
endfunction

task drive(input integer iteration);
repeat(iteration)
begin
mail.get(sti);
$display(" packet at driver = %p", sti);
@(posedge (intf.clk));
begin
intf.cs_0 <= sti.cs_0;
intf.we_0 <= sti.we_0;
intf.oe_0 <= sti.oe_0;
intf.cs_1 <= sti.cs_1;
intf.we_1 <= sti.we_1;
intf.oe_1 <= sti.oe_1;
intf.addr_0 <= sti.addr_0;
intf.addr_1 <= sti.addr_1;
intf.data_0 <= sti.data_0; //XXXXXXXXXXXXXXXXXXXXXXX
intf.data_1 <= sti.data_1; //YYYYYYYYYYYYYYYYYYYYYYY
end
end
endtask
endclass

Would be extremely happy to have your inputs! Thanks in advance. I have been facing this inout issue since my verilog times.

In reply to spat:

Declaring data_1 data_0 as logic in the interface gives a conflict in the top module saying:
** Error: (vsim-3053) top_dp.sv(30): Illegal inout port connection for “port ‘data_0’”.

Region: /top/DUT

** Error: (vsim-3053) top_dp.sv(30): Illegal inout port connection for “port ‘data_1’”.

Region: /top/DUT

In reply to spat:

I’m guessing that your data_0 and data_1 ports are declared as ‘inout’. In this case, you can’t connect logic data types to it. Instead, you need to use the wires like you had originally declared.

My approach is to create all connections in an interface as wire, and also create related register variables. I will then create a set of assign statements to the wires based on the output enables.

In reply to cgales:

For your mailbox problem, I’d guess you had also forgotten to create mail1 and it was null (that’s what “bad handle or reference” means).

For your second problem, you’re not allowed to drive nets (interface elements of type wire) from procedural code (in your case a task). You can only drive nets from continuous assign statements. Declaring them as logic messed up your top level module because you were expecting wires there (it seems like you’re trying to connect these signals to an inout port of the DUT. Whether these signals are supposed to be wires or logics, I cannot say, since I don’t know your full setup (though it seems you want wires as the DUT’s ports are bidirectional). To read up on the topic of connecting TB and DUT together, I’d suggest this paper from Dave Rich.

P.S. I wouldn’t hijack a thread like this with further questions that aren’t related to the thread name, but rather create a new one for each question. Remember, you’re not just asking for yourself, but for other people who might have the same problem in the future.

In reply to Tudor Timi:

Thanks both!
I shall work on the guidelines you both provided.
Tudor, my apologies for extending the thread without having relevance to the subject. I shall be careful henceforth.