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.
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.
virtualfunction 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");
returnnull;
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.
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.
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
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();