Functional Verification Master: System Verilog language and UVM methodology
Wednesday, May 26, 2021
Monday, May 24, 2021
constraint example
class A;
rand bit[7:0] x[], y[];
constraint x_y_val
{
x.size() inside {[0:15]};
y.size() inside {[0:15]};
(x.size() + y.size()) <= 16;
foreach(x[i])
{
x[i] inside{[0:16]};
}
foreach(y[i])
{
y[i] inside{[0:16]};
}
unique{x,y};
}
endclass
module top();
A a;
initial
begin
a=new;
for(int i=0;i<2;i++)
begin
a.randomize;
$display("%0p", a);
end
end
endmodule
Monday, July 17, 2017
cast p_sequencer m_sequencer details
We can use p_sequencer as a handle to the sequencer and through that we can access other sequencers or environment hierarchy in the sequence where uvm_declare_p_sequencer macro has been used.
Below is my understanding and relevant information. You may please correct if required.
`define uvm_declare_p_sequencer(SEQUENCER) \
SEQUENCER p_sequencer;\
virtual function void m_set_p_sequencer();\
super.m_set_p_sequencer(); \
if( !$cast(p_sequencer, m_sequencer)) \
`uvm_fatal("DCLPSQ", \
$sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name())) \
endfunction
SEQUENCER p_sequencer;\
virtual function void m_set_p_sequencer();\
super.m_set_p_sequencer(); \
if( !$cast(p_sequencer, m_sequencer)) \
`uvm_fatal("DCLPSQ", \
$sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name())) \
endfunction
p_sequencer type is specified in the argument(SEQUENCER) of `uvm_declare_p_sequencer macro.
When we call `uvm_declare_p_sequencer from sequence, it calls super.m_set_p_sequencer function, which internally will call m_set_sequencer of uvm_base_sequencer.
When we call start task of sequence, it internally calls for set_item_context, set_item_context calls set_sequencer, set_sequencer assigns handle of sequencer (which we have passed in start task of sequence) to m_sequencer using static cast (***This is first casting or down casting)
virtual function void set_sequencer(uvm_sequencer_base sequencer);
m_sequencer = sequencer;
m_set_p_sequencer();
endfunction
set_sequencer also calls m_set_p_sequencer(declaring `uvm_declare_p_sequencer macro should override the m_set_p_sequencer hence m_set_p_sequencer defined in macro should be executed) which will cast m_sequencer back into p_sequencer using dynamic $cast. (***This is reverse casting or up casting)
MY QUESTIONs:
1. Why do we need this reverse/up casting? what is intended and achieved with this step?
2. Can we pass virtual sequencer as an argument to uvm_declare_p_sequencer inside both virtual sequence and non-virtual sequence?
3. In case when we are using virtual sequence, and passed virtual sequencer as an argument to uvm_declare_p_sequencer inside it , when we call this virtual sequence from test , we pass null in the start task of the virtual sequence. In this case what will happen? m_sequencer = null and then , m_sequencer = p_sequencer and p_sequencer = m_sequencer , is that correct understanding? OR m_sequencer = p_sequencer and then m_sequencer = null and p_sequencer = m_sequencer , is that correct understanding?
1. Why do we need this reverse/up casting? what is intended and achieved with this step?
2. Can we pass virtual sequencer as an argument to uvm_declare_p_sequencer inside both virtual sequence and non-virtual sequence?
3. In case when we are using virtual sequence, and passed virtual sequencer as an argument to uvm_declare_p_sequencer inside it , when we call this virtual sequence from test , we pass null in the start task of the virtual sequence. In this case what will happen? m_sequencer = null and then , m_sequencer = p_sequencer and p_sequencer = m_sequencer , is that correct understanding? OR m_sequencer = p_sequencer and then m_sequencer = null and p_sequencer = m_sequencer , is that correct understanding?
Labels:
cast,
m_sequencer,
p_sequencer,
uvm_declare_p_sequencer
Saturday, July 15, 2017
conc_cast_dynamic_up_vs_down
class Base;
endclass
class Exten extends Base;
endclass
program main;
initial begin
Base B;
Exten E;
B = new();
//##E = new(); //##DEBUG: MASTER: doing this will also not allow us to down cast
if(!$cast(E,B)) begin //##DEBUG: MASTER: NOTE: as this unsuccessful cast will return '0' value
$display("\n");
$display(" Base class object B can'T be assigned to Extended class Handle.");
$display(" So this implies 'down casting is not possible'\n");
end
// Deallocate object B
//##DEBUG: MASTER: NOTICE: even if we do not include below null assignment, result will be same
B = null;
E = new();
if($cast(B,E)) begin //##DEBUG: MASTER: NOTE: as this successful cast will return '1' value
$display(" Extended class object E can be assigned to Base class Handle.");
$display(" So this implies 'up casting is only possible'\n");
end
end
endprogram
//##DEBUG: MASTER: run results
/*
ncsim> run
Base class object B can'T be assigned to Extended class Handle.
So this implies 'down casting is not possible'
Extended class object E can be assigned to Base class Handle.
So this implies 'up casting is only possible'
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
*/
endclass
class Exten extends Base;
endclass
program main;
initial begin
Base B;
Exten E;
B = new();
//##E = new(); //##DEBUG: MASTER: doing this will also not allow us to down cast
if(!$cast(E,B)) begin //##DEBUG: MASTER: NOTE: as this unsuccessful cast will return '0' value
$display("\n");
$display(" Base class object B can'T be assigned to Extended class Handle.");
$display(" So this implies 'down casting is not possible'\n");
end
// Deallocate object B
//##DEBUG: MASTER: NOTICE: even if we do not include below null assignment, result will be same
B = null;
E = new();
if($cast(B,E)) begin //##DEBUG: MASTER: NOTE: as this successful cast will return '1' value
$display(" Extended class object E can be assigned to Base class Handle.");
$display(" So this implies 'up casting is only possible'\n");
end
end
endprogram
//##DEBUG: MASTER: run results
/*
ncsim> run
Base class object B can'T be assigned to Extended class Handle.
So this implies 'down casting is not possible'
Extended class object E can be assigned to Base class Handle.
So this implies 'up casting is only possible'
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
*/
conc_cast_cases_updown_null_static_dynamic
class Parent ;
virtual task disp ();
$display(" This is class Parent ");
endtask
endclass
class Child extends Parent ;
task disp ();
$display(" This is class Child ");
endtask
endclass
program main ;
Parent P;
Child C;
initial
begin
C = new();
$display(" DEBUG: MASTER: step1: doing P = C ");
P=C;
$display(" DEBUG: MASTER: step2: calling P.disp() ");
P.disp();
$display(" DEBUG: MASTER: step3: calling C.disp() ");
C.disp();
$display(" DEBUG: MASTER: step4: doing C=null ");
C=null;
$display(" DEBUG: MASTER: step5: doing $cast(C,P) ");
$display(" $cast(C,P) = %b ",$cast(C,P));
//##C=P; //##static cast is not working !!!???
$cast(C,P); //##dynamic cast is working
//##C=P; //##static cast is not working !!!???
$display(" DEBUG: MASTER: step6: calling C.disp() ");
C.disp();
end
endprogram
//## DEBUG: MASTER: run results
/*
ncsim> run
DEBUG: MASTER: step1: doing P = C
DEBUG: MASTER: step2: calling P.disp()
This is class Child
DEBUG: MASTER: step3: calling C.disp()
This is class Child
DEBUG: MASTER: step4: doing C=null
DEBUG: MASTER: step5: doing $cast(C,P)
$cast(C,P) = 00000000000000000000000000000001
DEBUG: MASTER: step6: calling C.disp()
This is class Child
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
./conc_cast_updown_null_static_dynamic.sv:13 program main ;
ncsim> exit
*/
virtual task disp ();
$display(" This is class Parent ");
endtask
endclass
class Child extends Parent ;
task disp ();
$display(" This is class Child ");
endtask
endclass
program main ;
Parent P;
Child C;
initial
begin
C = new();
$display(" DEBUG: MASTER: step1: doing P = C ");
P=C;
$display(" DEBUG: MASTER: step2: calling P.disp() ");
P.disp();
$display(" DEBUG: MASTER: step3: calling C.disp() ");
C.disp();
$display(" DEBUG: MASTER: step4: doing C=null ");
C=null;
$display(" DEBUG: MASTER: step5: doing $cast(C,P) ");
$display(" $cast(C,P) = %b ",$cast(C,P));
//##C=P; //##static cast is not working !!!???
$cast(C,P); //##dynamic cast is working
//##C=P; //##static cast is not working !!!???
$display(" DEBUG: MASTER: step6: calling C.disp() ");
C.disp();
end
endprogram
//## DEBUG: MASTER: run results
/*
ncsim> run
DEBUG: MASTER: step1: doing P = C
DEBUG: MASTER: step2: calling P.disp()
This is class Child
DEBUG: MASTER: step3: calling C.disp()
This is class Child
DEBUG: MASTER: step4: doing C=null
DEBUG: MASTER: step5: doing $cast(C,P)
$cast(C,P) = 00000000000000000000000000000001
DEBUG: MASTER: step6: calling C.disp()
This is class Child
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
./conc_cast_updown_null_static_dynamic.sv:13 program main ;
ncsim> exit
*/
conc_cast_p_then_null_c_then_use_casted_p
class Parent ;
virtual task disp ();
$display(" This is class Parent ");
endtask
endclass
class Child extends Parent ;
task disp ();
$display(" This is class Child ");
endtask
endclass
program main ;
Parent P;
Child C;
initial
begin
C = new();
P=C;
C = null;
P.disp();
end
endprogram
//##run results: DEBUG: MASTER
/*
ncsim> run
This is class Child
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
./conc_cast_then_null_then_use_casted.sv:13 program main ;
ncsim> exit
*/
virtual task disp ();
$display(" This is class Parent ");
endtask
endclass
class Child extends Parent ;
task disp ();
$display(" This is class Child ");
endtask
endclass
program main ;
Parent P;
Child C;
initial
begin
C = new();
P=C;
C = null;
P.disp();
end
endprogram
//##run results: DEBUG: MASTER
/*
ncsim> run
This is class Child
Simulation complete via implicit call to $finish(1) at time 0 FS + 1
./conc_cast_then_null_then_use_casted.sv:13 program main ;
ncsim> exit
*/
conc_cast_staticcompile_vs_dynamicrun
class parent_;
virtual function foo_();
$display("I am parent with member of values ");
endfunction
endclass
class child_ extends parent_;
bit foo_mem;
function foo_();
//##void'(super.foo_()); //##DEBUG: MASTER: regardless of casting/virtual, you may want to uncomment this to see the super effect, when function returns nothing , you should use with void
$display("I am child with member of values %d",foo_mem);
endfunction
endclass
module foo_foo;
parent_ parent_handle;
parent_ parent_handle_1;
child_ child_handle;
initial begin
child_handle = new();
$cast(parent_handle,child_handle); //##DEBUG: MASTER: This is dynamic cast and it can be called as task or func. It will return 0 at RUNTIME if not proper valid casting.
parent_handle_1 = child_handle; //##DEBUG: MASTER: This is static cast and will give COMPILETIME error if not proper
void'(parent_handle_1.foo_()); //##DEBUG: MASTER: when function returns nothing , you should use with void
void'(parent_handle.foo_()); //##DEBUG: MASTER: when function returns nothing , you should use with void
$display("BOTH DYNAMIC AND STATIC CASTING GAVE SAME RESULT");
end
endmodule
//##run results:
/*
ncsim> run
I am child with member of values 0 //##DEBUG: MASTER: --> function called from parent_handle_1, but after casting with child_handle
I am child with member of values 0 //##DEBUG: MASTER: --> function called from parent_handle, but after casting with child_handle
BOTH DYNAMIC AND STATIC CASTING GAVE SAME RESULT
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit
*/
Subscribe to:
Posts (Atom)