The purpose of this channel feature is to save all the incoming transaction to the specified file and play back the transaction from the file.
This will be useful when we want to recreate a random scenario in different environment. For example, you found a very interesting random scenario in 10G speed Ethernet. Now you want to use the same random scenario on 1G Ethernet. It may not be possible to reproduce the same scenario at 1G speed even with the SV random stability. The other way is to write a directed testcase to recreate the same scenario. Using this Record/playback feature, we can record the transaction in the 10G speed Ethernet and then play this scenario at 1G speed Ethernet.
One more advantage of this feature is, it allows us to shutdown the activities of some components. For Example, consider a layered protocol, the Ethernet. The Verification environment can be developed with layers of transactors corresponding to each protocol layer like, TCP over IP laver, IP fragment and reassembly layer, IP fragment over Ethernet and Ethernet layer. All these layers will be connected using channels. With record/playback feature, the input transaction to Ethernet layer can be recorded and in the next simulation, we can shutdown the TCP over IP laver, IP fragment and reassembly layer, IP fragment over Ethernet layers transactors and by playing back the recorded transactions. This will improve the memory consumption and execution speed.
Record/Playback is independent of Random stability. Changing the seed value will not affect the playback. This will give us an opportunity to test the DUT using a specific scenario of the high layer (Consider the previous example: Some interested scenario in IP fragment over Ethernet) with lot of different randomization using different seeds of lower layer protocol (Ethernet layer).
This will also help, when we cannot reproduce the random scenario using Seed. If you found a Bug in the DUT, and still you are in the development stage of your environment, you cannot stop the development in the environment till the bug is fixed. There are chances that the changes in the environment will not allow you to reproduce the same scenario even with the same seed. In this case, if you have stored the transactions, you can playback the transaction.
Now we will learn about the implementation.
Recording
To record the flow of transaction descriptors added through the channel instance, call the record method of that instance.
functionbit record(string filename);
The vmm_data::save() method must be implemented for recording. All the transaction which are added to channel using the vmm_channel::put() method are recorded and are avilabe for playback. A null filename stops the recording process. vmm_channel::record() method returns TRUE if the specified file was successfully opened.
RECORDING notification is indicated by vmm_channel::notify, when recording.
Playing Back
To playback the transactions in the recorded file, use the vmm_channel::playback() method.
This method will block the sources of the current channel like vmm_channl::put() method till the playback is completed. The vmm_data::load() method must be implemented for playback. The order of the transaction will be same as the order while recording. If the metered argument is TRUE, the transaction descriptors are added to the channel with the same relative time interval as they were originally put in when the file was recorded.
The success argument is set to TRUE if the playback was successful. If the playback process encounters an error condition such as a NULL (empty string) filename, a corrupt file or an empty file, then success is set to FALSE.
PLAYBACK_DONE notification is indicated by vmm_channel::notify, when playback is completed.
(S)EXAMPLE
Let us write an example to see how the record and playback works.
Record & Playback of channels can be used with atomic generator and scenario generators. Here is a simple transaction with its channel and atomic generator. We will use this atomic generator to generate transaction. The atomic generator has out_chan channel, this channel is used send the generated transaction. We will record and playback the transaction in the out_chan. I used Vmm_data macros for implementing all the required methods.
class trans extends vmm_data;
typedefenumbit {BAD_FCS=1'b0, GOOD_FCS=1'b1} kind_e;
// for declaring trans_channel
`vmm_channel(trans)
// for declaring trans_atomic_gen
`vmm_atomic_gen(trans, "Gen")
Now we will write a simple program to record and play back the above defined transaction.
Use the trans_atomic_gen to generate the transactions. This also the put the transactions in to out_chan channel. Call the start_xactor() method of the generator to start the generator of transaction. Call the record() method of out_chan to record the incoming transactions.
Now we will write a logic which gets the transaction from the channel and prints the content to terminal, so that we can observe the results.
The above the logic generates 3 transactions. Get the 3 transaction from the channel and print the content.
initial repeat(3)
begin #10;
gen.out_chan.get(tr);
tr.display();
end
(S)Complete source code
program main();
trans tr;
trans_atomic_gen gen = new("Atomic Gen",1);
bit success;
// This is the producer logic.
// Transactions are produced from Atomic generator in RECORD mode.
// Transactions are produced from recorded file in PLAYBACK mode.
initial begin
if($test$plusargs("RECORD"))
begin $display(" RECORDING started ");
gen.stop_after_n_insts = 3;
gen.start_xactor();
gen.out_chan.record("Trans_recordes.tr");
end elseif($test$plusargs("PLAYBACK"))
begin $display(" PLAYBACK started ");
tr = new();
gen.out_chan.playback(success,"Trans_recordes.tr",tr);
if(!success)
$display(" Failed to playback Trans_recordes.tr");
end else $display(" give +RECORD or +PLAYBACK with simulation command");
end
// This is consumer logic.
initial repeat(3)
begin #10;
gen.out_chan.get(tr);
tr.display();
end