|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



VMM SCENARIO GENERATOR




Atomic generator generates individual data items or transaction descriptors. Each item is generated independently of other items in a random fashion. Atomic generator is simple to describe and use.

Unlike atomic generator, a scenario generator generates a sequence of transaction.


(S)Example of sequence of transaction:


CPU instructions like LOAD__A,LOAD__B,ADD_A_B,STORE_C.
Packets with incrementing length.
Do write operation to address "123" and then do the read to address "123".

It is very unlikely that atomic generator to generate transaction in the above ordered sequence. With scenario generator, we can generate these sequence of transaction.

VMM provides `vmm_scenario_gen() macro for quickly creating a scenario generator.


`vmm_scenario_gen(class_name, "Class Description");


The macro defines classes named <class_name>_scenario_gen, <class_name>_scenario, <class_name>_scenario_election , <class_name>_scenario_gen_callbacks and <class_name>_atomic_scenario.


class custom_scenario_gen extends vmm_xactor;
class custom_scenario extends vmm_data;
class custom_atomic_scenario extends custom_scenario;
class custom_scenario_election;
class custom_scenario_gen_callbacks extends vmm_xactor_callbacks

(S)<class_name>_scenario:


This scenario generator can generate more than one scenario. Each scenario which can contain more than one transaction is described in a class which is extended from <class_name>_scenario.

For each scenario, following variables must be constraint.
Length: number of transactions in an array.
Repeated: number of times to repeat this scenario.


(S)<class_name>_atomic_scenario:


This class is a atomic scenario. This is the default scenario. This scenario is a random transactions.


(S)<class_name>_scenario_election:


This class is the arbiter which determines the order that the known scenarios are applied. By default, scenarios are elected atomically. User can extend this class to define an order in which the scenarios should be picked.


(S)<class_name>_scenario_gen:


This class is the scenario generator which generates the transactions and sends out using output channel. This class has a queue of scenario objects. Each scenario contains transaction instances in an array.


(S)<class_name>_scenario_gen_callbacks:


This class provides callback mechanism. There are two callback methods define. pre_scenario_randomize() and post_scenario_gen() which are called at pre-randomization of the scenario and post-generation of the scenario respectively.





Example



Let us write an example.

Following is the transaction class which we will use to write a scenario generator.



class instruction extends vmm_data;
vmm_log log;
typedef enum {LOAD__A,LOAD__B,ADD_A_B,SUB_A_B,STORE_C } kinds_e;
rand kinds_e inst;

function new();
super.new(this.log);
endfunction:new

virtual function string psdisplay(string prefix = "");
psdisplay = $psprintf(" Instruction : %s | stream_id : %0d | scenario_id : %0d ",inst.name(),stream_id,scenario_id);
endfunction:psdisplay

virtual function vmm_data allocate();
instruction tr = new;
allocate = tr;
endfunction:allocate

virtual function vmm_data copy(vmm_data cpy = null);
instruction to;
if (cpy == null)
to = new;
else
if (!$cast(to, cpy)) begin
`vmm_fatal(this.log, "Attempting to copy to a non instruction instance");
return null;
end
super.copy_data(to);
to.inst = this.inst;
copy = to;
endfunction:copy
endclass




The above transaction crests CPU instructions.

Let us consider that sequence of instruction LOAD__A,LOAD__B,ADD_A_B,STORE_C is a interesting scenario and LOAD__A,LOAD__B,SUB_A_B,STORE_C is also an interesting scenario.
When instructions are generated, we want to generate these 2 sequences of instruction. Let us see how to generate these 2 sequence of instructions .

As we have already discussed, `vmm_scenario_gen() creates use full class for cscenario generation.

1) Use `vmm_scenario_gen() macro to declare the scenario classes.


`vmm_scenario_gen(instruction, "Instruction Scenario Generator")


This macro will create following classs

instruction_scenario_gen
instruction_scenario
instruction_atomic_scenario
instruction_scenario_election
instruction_scenario_gen_callbacks

2) Define interesting scenarios by extending inst_scenario;


class instruction_scenario_add_sub extends instruction_scenario;


3) Define the first scenario. It is sequence of instructions for addition operation.

a) Declare a variable for identifying the scenario.


int addition_scenario_id ;


Each scenario has more than one inductions. All these instructions are in a queue "items" which is already defined in "instruction_scenario".

The rand varible "scenario_kind", which pre defined in the vmm_scenario class, will randomly select one of the defined scenarios. "scenario_kind" varible has the id of the current scenario. So we have to define the addition scenario, when the "scenario_kind" value is addition_scenario_id.

b) Constrain the scenario kind,


constraint addition_scenario_items {
if($void(scenario_kind) == addition_scenario_id) {


c) The number of instructions define in a scenario is specified by the predefined variable "length". In our example, we have 4 instructions. So constrain the length to 4.


length == 4;


d) The predefined variable "repeated" used to control if the VMM scenario generator would run the scenario more than once each time it is created. We are not interested in repeating so, constrain it to 0


repeated == 0;


e) Constrain the individual items based on the requirements if this scenario is selected. Our requirement in this example is that "inst" should follow the sequence LOAD__A,LOAD__B,ADD_A_B,STORE_C


foreach(items[i])
if(i == 0)
this.items[i].inst == instruction::LOAD__A;
else if(i == 1)
this.items[i].inst == instruction::LOAD__B;
else if(i == 2)
this.items[i].inst == instruction::ADD_A_B;
else if(i == 3)
this.items[i].inst == instruction::STORE_C;



4)Define second scenario. It is Sequence of instructions for subtraction operation.


a) Declare a variable for identifying the scenario.


int subtraction_scenario_id ;


b) Constrain the scenario kind,


constraint subtraction_scenario_items {
if($void(scenario_kind) == subtraction_scenario_id) {


c) Constrain the length


length == 4;


d) Constrain the repeated


repeated == 0;


e) Constrain the items


foreach(items[i])
if(i == 0)
this.items[i].inst == instruction::LOAD__A;
else if(i == 1)
this.items[i].inst == instruction::LOAD__B;
else if(i == 2)
this.items[i].inst == instruction::SUB_A_B;
else if(i == 3)
this.items[i].inst == instruction::STORE_C;


5)Define constructor method.

a) call the super.new() method.

Get a unique Ids from the define_scenario() method for each scenario.
define_scenario() is predefined in *_scenario class.


function new();
this.addition_scenario_id = define_scenario(" ADDITION ",4);
this.subtraction_scenario_id = define_scenario(" SUBSTRACTION ",4);
endfunction



With this, we completed the implementation of scenarios.


Scenario Code


`vmm_scenario_gen(instruction,"Instruction Scenario Generator")

class instruction_scenario_add_sub extends instruction_scenario;

///////////////////////////////////////////////////////////////
////// ADDITION SCENARIO //////////
///////////////////////////////////////////////////////////////

int addition_scenario_id ;

constraint addition_scenario_items {
if($void(scenario_kind) == addition_scenario_id) {
repeated == 0;
length == 4;
foreach(items[i])
if(i == 0)
this.items[i].inst == instruction::LOAD__A;
else if(i == 1)
this.items[i].inst == instruction::LOAD__B;
else if(i == 2)
this.items[i].inst == instruction::ADD_A_B;
else if(i == 3)
this.items[i].inst == instruction::STORE_C;
}
}

///////////////////////////////////////////////////////////////
////// ASUBTRACTION SCENARIO //////////
///////////////////////////////////////////////////////////////

int subtraction_scenario_id ;

constraint subtraction_scenario_items {
if($void(scenario_kind) == subtraction_scenario_id) {
repeated == 0;
length == 4;
foreach(items[i])
if(i == 0)
this.items[i].inst == instruction::LOAD__A;
else if(i == 1)
this.items[i].inst == instruction::LOAD__B;
else if(i == 2)
this.items[i].inst == instruction::SUB_A_B;
else if(i == 3)
this.items[i].inst == instruction::STORE_C;
}
}

function new();
this.addition_scenario_id = define_scenario(" ADDITION ",4);
this.subtraction_scenario_id = define_scenario(" SUBSTRACTION ",4);
endfunction

endclass

Testcase



Now we will write a test case to see how to above defined scenario works.

1) Declare scenario generator


instruction_scenario_gen gen;


2) Declare the scenario which we defined earlier.


instruction_scenario_add_sub sce_add_sub;


3) Construct the generator and scenarios.


gen = new("gen",0);
sce_add_sub = new();


4) set the number of instances and scenarios generated by generator to 20 and 4 respectevy.


gen.stop_after_n_insts = 20;
gen.stop_after_n_scenarios = 4;


5) Scenario generators store all the scenarios in scenario_set queue. So, we have to add the scenario which we constructed above to the queue.


gen.scenario_set[0] = sce_add_sub;


6) Start the generator


gen.start_xactor();


7) Similar t the Atomic generator, the transactions created by the scenario generator are sent to out_chan channel.
Get the instructions from the out_chan channel and print the content.


repeat(20) begin
gen.out_chan.get(inst);
inst.display();

(S) Testcase code

program test();

instruction_scenario_gen gen;
instruction_scenario_add_sub sce_add_sub;
instruction inst;

initial
begin
gen = new("gen",0);
sce_add_sub = new();

//gen.log.set_verbosity(vmm_log::DEBUG_SEV,"/./","/./");
gen.stop_after_n_insts = 20;
gen.stop_after_n_scenarios = 4;

gen.scenario_set[0] = sce_add_sub;

gen.start_xactor();

repeat(20) begin
gen.out_chan.get(inst);
inst.display();
end

end

endprogram

(S)Down load the source code


vmm_scenario.tar
Browse the code in vmm_scenario.tar


(S)Command to simulate
vcs -sverilog -ntb_opts rvm -f filelist -R

Observe the log file, you can see the both the scenarios.

(S)Logfile

Instruction : LOAD__A | stream_id : 0 | scenario_id : 0
Instruction : LOAD__B | stream_id : 0 | scenario_id : 0
Instruction : ADD_A_B | stream_id : 0 | scenario_id : 0
Instruction : STORE_C | stream_id : 0 | scenario_id : 0

Instruction : LOAD__A | stream_id : 0 | scenario_id : 1
Instruction : LOAD__B | stream_id : 0 | scenario_id : 1
Instruction : ADD_A_B | stream_id : 0 | scenario_id : 1
Instruction : STORE_C | stream_id : 0 | scenario_id : 1

Instruction : LOAD__A | stream_id : 0 | scenario_id : 2
Instruction : LOAD__B | stream_id : 0 | scenario_id : 2
Instruction : SUB_A_B | stream_id : 0 | scenario_id : 2
Instruction : STORE_C | stream_id : 0 | scenario_id : 2

Instruction : LOAD__A | stream_id : 0 | scenario_id : 3
Instruction : LOAD__B | stream_id : 0 | scenario_id : 3
Instruction : ADD_A_B | stream_id : 0 | scenario_id : 3
Instruction : STORE_C | stream_id : 0 | scenario_id : 3



Index
Introduction
Vmm Log
Vmm Env
Vmm Data
Vmm Channel
Vmm Atomic Generator
Vmm Xactor
Vmm Callback
Vmm Test
Vmm Channel Record And Playback
Vmm Scenario Generator
Vmm Opts

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer