The channel is the interface mechanism used by transactors to transfer transactions. Transaction objects are produced or consumed by a transactor. Transactor can be a generator or a driver or a scoreboard. In Transaction-level modeling multiple processes communicate with each other by sending transactions through channels. For example, to transfer a transaction from generator to a driver, we don't need to send at signal level. To transfer a transaction from Driver to DUT, physical signals are used. The channel transfers transactions between the verification components, and it serves as a synchronizing agent between them.
Channels are similar to SystemVerilog mailboxes with advanced features. Vmm Channels provides much richer feature functionality than a SV mailbox. vmm channels are superset of mailboxs.
Some of the the benefits of channels over mailboxes:
Dynamic reconfiguration
Inbuilt notifications
Strict type checking
Out of order usage
task tee() for easy scoreboarding
Record and playback
task sneak() for monitors
Using `vmm_channel() macro , channels can be created.
`vmm_channel(Custom_vmm_data)
The above macro creates a channel Custom_vmm_data_channel . There are various methods to access the channels.
In the following example, we will see
1) Channel creation using macros.
2) Constructing a channel.
3) Pushing a transaction in to channel.
4) Popping out a transaction from the channel.
We will create a channel for vmm_data for this example. Users can create a channel for any transaction which is derived from the vmm_data class. You can try this example by creating channel for Packet class which is discussed in previous section.
1) Define a channel using macro
`vmm_channel(vmm_data)
2) Construct an object of channel which is defined by the above macro.
vmm_data_channel p_c = new("p_c","chan",10);
3) Push a packet p_put in to p_c channel.
p_c.put(p_put);
4) Get a packet from p_c channel.
p_c.get(p_put);
Complete Example
`vmm_channel(vmm_data)
program test_channel();
vmm_data p_put,p_get;
vmm_data_channel p_c = new("p_c","chan",10);
int i;
initial repeat(10)
begin #( $urandom()%10);
p_put = new(null);
p_put.stream_id = i++;
$display(" Pushed a packet in to channel with id %d",p_put.stream_id);
p_c.put(p_put); // Pushing a transaction in to channel
end
initial forever begin p_c.get(p_get); // popping a transaction from channel.
$display(" Popped a packet from channel with id %d",p_get.stream_id);
end endprogram
(S) Command to run the simulation vcs -sverilog -f filelist -R -ntb_opts rvm -ntb_opts dtm
(S) Log report
Pushed a packet in to channel with id 0 Popped a packet from channel with id 0 Pushed a packet in to channel with id 1 Popped a packet from channel with id 1 Pushed a packet in to channel with id 2 Popped a packet from channel with id 2 Pushed a packet in to channel with id 3 Popped a packet from channel with id 3 Pushed a packet in to channel with id 4 Popped a packet from channel with id 4 Pushed a packet in to channel with id 5 Popped a packet from channel with id 5 Pushed a packet in to channel with id 6 Popped a packet from channel with id 6 Pushed a packet in to channel with id 7 Popped a packet from channel with id 7 Pushed a packet in to channel with id 8 Popped a packet from channel with id 8 Pushed a packet in to channel with id 9 Popped a packet from channel with id 9
Vmm Channel Methods.
function new ( string name, stringinstance,
intunsigned full = 1, intunsigned empty = 0, bit fill_as_bytes = 0 );
functionvoid reconfigure (int full = -1, int empty = -1, logic fill_as_bytes = 1'bx );
functionintunsigned full_level ( );
functionintunsigned empty_level ( );
functionintunsigned level ( );
functionintunsigned size ( );
functionbit is_full ( );
functionvoid flush ( );
functionvoid sink ( );
functionvoid flow ( );
functionvoid lock ( bit [1:0] who );
functionvoid unlock ( bit [1:0] who );
functionbit is_locked ( bit [1:0] who );
task put ( class_name obj, int offset = -1 );
functionvoid sneak ( class_name obj, int offset = -1 );
function class_name unput ( int offset = -1 );
task get ( output class_name obj, inputint offset = 0 );
task peek ( output class_name obj, inputint offset = 0 );
task activate ( output class_name obj, inputint offset = 0 );
function class_name active_slot ( );
function class_name start ( );
function class_name complete ( vmm_data status = null );
function class_name remove ( );
function active_status_e status ( );
task tee ( output class_name obj );
functionbit tee_mode ( bit is_on );
functionvoid connect ( vmm_channel downstream );
function class_name for_each ( bit reset = 0 );
functionintunsigned for_each_offset ( );
functionbit record ( string filename );
taskbit playback ( outputbit success, inputstring filename,
input vmm_data loader, inputbit metered = 0 );