Hello, I’m trying to learn SystemVerilog, and I’m currently doing randomization.
I have following package and a class inside it:
package RGB_specific;
parameter true = 1'b1;
parameter false = 1'b0;
typedef struct {rand byte R,G,B;} RGB_t;
class RGB_random;
rand RGB_t pixel;
constraint Reds {pixel.R > pixel.B; pixel.R > pixel.G;} //make pixel mostly red
constraint Blues {pixel.B > pixel.R; pixel.B > pixel.G;} //mostly blue
constraint Greens {pixel.G > pixel.R; pixel.G > pixel.B;} //mostly green
function void SetReds;
Reds.constraint_mode(true);
Greens.constraint_mode(false);
Blues.constraint_mode(false);
endfunction
function void SetGreens;
Reds.constraint_mode(false);
Greens.constraint_mode(true);
Blues.constraint_mode(false);
endfunction
function void SetBlues;
Reds.constraint_mode(false);
Greens.constraint_mode(false);
Blues.constraint_mode(true);
endfunction
function new; //constructor
SetReds;
endfunction
endclass
endpackage
Now, I have my DUT that does nothing except pass its inputs to outputs (it’s clocked)
module DUT(clock,px_in,px_out);
import RGB_specific::*;
input logic clock;
input RGB_random px_in;
output RGB_random px_out;
// DUT just checks that data arrives
always @(posedge clock) begin
$display("px_in: %h %h %h at time %t",
px_in.pixel.R, px_in.pixel.G, px_in.pixel.B, $time);
px_out <= px_in;
end
endmodule : DUT
And I tried to connect this in my TOP module:
module top;
import RGB_specific::*;
bit clock;
//clock generator
always begin
#5
clock = 0;
#5
clock = 1;
end
RGB_random px_in, px_out;
//construct objects
initial begin
px_in = new;
px_out = new;
end
//instantiate dut
DUT U1(clock,px_in,px_out);
//always randomize values of input
always @(posedge clock) begin
void'(px_in.randomize());
end
//when any of the output values change, print new output values
always @(px_out.pixel.R or px_out.pixel.G or px_out.pixel.B) begin
$display("px_out: %h %h %h at time %t", px_out.pixel.R,px_out.pixel.G,px_out.pixel.B, $time);
end
endmodule : top
Q1: Now, this all seemingly works fine, outputs get values from inputs. But, I have a question, as you see I also watch $time, and here is the output my QuestaSim gives me:
px_in: 00 00 00 at time 10
px_out: 7b 02 28 at time 10
px_in: 7b 02 28 at time 20
px_out: d2 c7 8a at time 20
px_in: d2 c7 8a at time 30
First it shows me outputs, and then tells me inputs with #10 delay. Everything is clocked on posedge, so I don’t see how this can happen.
Q2: But, even worse, I tried to avoid race condition and randomize on negative edge
always @(negedge clock) begin
void'(px_in.randomize());
end
And then, I don’t get any of the output lines… Like its combinational, not sequential circuit.
Q3: QuestaSim also gives me this warning:
Variable ‘/top/px_out’, driven via a port connection, is multiply driven. See top.sv(24). (it points to a line where constructor is called). Why is that?
Thank you in advance!