packets per second (pps),bits per second (bps)。帧头8bytes,帧与帧间隔12bytes,payload在64-1518byets之间。
Pack()是uvm_object的函数。下图是重载do_pack()函数的代码。
m_packed_size清零。然后执行do_pack(packer);,即重载的do_pack()。
调用宏,对m_bits和count赋值。
执行set_packed_size()时,将计算的count值给m_packed_size。
pack()最终返回m_packed_size的值。
这个例子payload为64byetes。Update_bucket()的主要作用是记录当前is_relevant()的执行时间,计算在间隔时间内bucket已经存的bits。wait_for_relevant()是执行延迟,当is_relevant返回0时,wait_for_relevant()才执行。速率和周期是test层设置好的。
这里bucket的计算思想类似于:水池储水,进水量不定(随机),出水量固定。
Mixin
这里的设计思想主要是运用:代码重构,多继承以达到sequence的多样性。以下是文章举例:
B. Refactoring the Relevance Sequence as a Mixin
接下来就运用mixin的思想,把bucket的相关算法函数和底层机制分开。
standard_seq继承于uvm_seqence#(item),有body()。
Rate_mixin继承于T,有关于bucket的算法。
test中使用rate_mixin#(standard_seq) rate_seq_t;,则名为rate_seq_t的自定义类型是兼有body()和关于bucket的算法。
上图是使用mixin的测试结果。
添加访问模式
relevance中记录relevance_sequence_mixin类型的seq,relevance_sequence_mixin中记录relevance类的实例。
图8所示,uvm_sequencer调用is_relevant()时,即调用relevance_sequence_mixin中重载的is_relevant()。relevance_sequence_mixin中重载的is_relevant()访问每个relevance中的is_relevant()。将所有relevance中的is_relevant()返回值相与后的值作为relevance_sequence_mixin中is_relevant()的返回值,如果是0,则执行relevance_sequence_mixin中的wait_for_relevat()。wait_for_relevat()只执行所有relevance中最短的延迟。
uvm_sequencer同时调用seq1和seq2的is_relevant(),即访问seq1.assoc_q[i]和seq2.assoc_q[i]内每个rate实例的is_relevant()。假设seq1和seq2的返回值都是0,则执行seq1.wait_for_relevant()和seq2.wait_for_relevant(),即并行执行seq1.assoc_q[i]和seq2.assoc_q[i]内每个rate实例的wait_for_relevant(),2个seq的 wait_for_relevant()执行完其中之一跳出循环。再调用seq1和seq2的is_relevant(),往复循环。
速率控制
存储控制。unmatched()函数是返回队列expect_q内所有item的size和。
文章中举例以下复杂场景,提供对应代码: