Byte_array_mfb environment
This environment has two high-level agents. The first one is a byte array agent and it works with data. The second one is a logic vector agent which works with metadata. This package contains two environments. Environment RX generates data and metadata and sends them to the DUT. Environment TX generates the DST_RDY signal and observes the TX interface.
The environment is configured by these four parameters: mfb documentation.
REGIONS
REGIONS_SIZE
BLOCK_SIZE
META_WIDTH
Top sequencers and sequences
In the RX direction, there are two sequencers: the first is a Byte Array sequencer that handles MFB_DATA. The second is a Logic Vector sequencer that handles MFB_METADATA. Both sequencers pull the data from sequences together.
In the TX direction, there is one sequencer of type mfb::sequencer #(), which generates the DST_RDY signal.
Both directions have two analysis_exports. One export is for the Byte Array transactions, and the second is for the Logic Vector (metadata) transactions.
Configuration
The config class has three variables.
Variable |
Description |
---|---|
active |
Set to UVM_ACTIVE if the agent is active, otherwise set to UVM_PASSIVE. |
interface_name |
The name of the interface under which you can find it in the UVM config database. |
meta_behave |
The moment when the metadata are being generated and valid: config_item::META_SOF => valid with the SOF, config_item::META_EOF => valid with the EOF. |
seq_cfg |
Configure a low-level sequence that converts byte_array to MFB words. |
The top level the environment contains the reset_sync class, which is required for reset synchronization. The example shows how to connect the reset to the byte_array_mfb environment and basic configuration.
class test extends uvm_test
`uvm_componet_utils(test::base)
reset::agent m_resets;
byte_array_mfb::env_rx#(...) m_env;
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
byte_array_mfb::config_item m_cfg;
m_resets = reset::agent::type_id::create("m_reset", this);
m_cfg = new();
m_cfg.active = UVM_ACTIVE;
m_cfg.interface_name = "MFB_IF";
m_cfg.meta_behav = config_item::META_SOF;
m_cfg.cfg = new();
m_cfg.cfg.space_size_set(128, 1024);
uvm_config_db#(byte_array_mfb_env::config_item)::set(this, "m_eth", "m_config", m_cfg);
m_env = byte_arra_mfb::env_rx#(...)::type_id::create("m_env", this);
endfunction
function void connect_phase(uvm_phase phase);
m_reset.sync_connect(m_env.reset_sync);
endfunction
endclass
Low sequence configuration
configuration object config_sequence contain two function.
Function |
Type |
Description |
---|---|---|
probability_set(min, max) |
[percentige] |
set probability of no inframe gap. probability_set(100,100) => no inframe gap |
space_size_set(min, max) |
[bytes] |
set min and max space between two packets. |
RX Inner sequences
For the RX direction exists one base sequence class “sequence_simple_rx_base” which simplifies creating others sequences. It processes the reset signal and exports virtual function create_sequence_item. In this function can child create mfb::sequence_item what they like. Other important function in “sequence_simple_rx_base” class is try_get() which downloads required data from base array agent. It is also important to note that the base class is state oriented. Following table describes internal states.
State |
Description |
---|---|
state_packet_none |
No data for packet |
state_packet_new |
new packet has been read by function try_get |
state_packet_data |
process is somewhere in middle of packet |
state_pakcet_space |
Process send all data and generate space before new packet |
state_packet_space_new |
Randomize new space size before new packet |
The environment has three sequences. The table below describes them. In the default, the RX env runs sequence_lib_rx.
Sequence |
Description |
---|---|
sequence_simple_rx |
A basic random sequence. This sequence behaves very variably. |
sequence_full_speed_rx |
The sequence gets data and then sends them as quickly as possible. |
sequence_stop_rx |
This sequence doesn’t send any data. There are no data on the interface. |
sequence_lib_rx |
Repetitively randomly choose one of the sequences above and run it. |
The example below shows how to change the inner sequence to test the maximum throughput. The environment runs the sequence_full_speed_rx instead of the sequence_lib_rx.
class mfb_rx_speed#(...) extends byte_array_mfb_env::sequence_lib_rx#(...);
function new(string name = "mfb_rx_speed");
super.new(name);
init_sequence_library();
endfunction
virtual function void init_sequence(config_sequence param_cfg = null);
if (param_cfg == null) begin
this.cfg = new();
end else begin
this.cfg = param_cfg;
end
this.add_sequence(byte_array_mfb_env::sequence_full_speed_rx #(REGIONS, REGION_SIZE, BLOCK_SIZE, ITEM_WIDTH, META_WIDTH)::get_type());
endfunction
endclass
class test extends uvm_test
`uvm_componet_utils(test::base)
byte_arra_mfb::env_rx#(...) m_env;
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
...
byte_array_mfb_env::sequence_lib_rx#(...)::type_id::set_inst_override(mfb_rx_speed#(...)::get_type(),
{this.get_full_name(), ".m_env.*"});
m_env = byte_arra_mfb::env_rx#(...)::type_id::create("m_env", this);
endfunction
endclass