UVM:将序列拆分到不同的子序列发生器上

时间:2014-09-25 09:29:35

标签: system-verilog uvm

在DUT上我有两个通道,每个通道包括一个数据接口和一个边带接口。沿着这些频道发送的交易必须按顺序排列,但是一个频道可以在另一个频道赶上时停止。即: 我将事务A发送到通道0,事务C发送到通道1,但通道1将不接受事务C,直到通道0收到事务B。

此外,数据接口可能比每个通道上的边带接口慢,并且某些边带事务不需要与它们一起发送数据。

目前,测试设置为创建单独的数据和边带序列,将它们放入队列,然后将队列分成多个通道并发送它们。然而,随着通道上的接口改变和每个配置的不同通道数量,这变得难以维持。理想情况下,我想编写测试序列,以便它不知道有多少通道或者哪个接口需要抽象事务的数据。

顶部序列应该只生成如下序列:

'uvm_do(open_data_stream_sequence);
'uvm_do_with(send_data_sequence, {send_data_sequence.packet_number == 0;});
'uvm_do_with(send_data_sequence, {send_data_sequence.packet_number == 1;});
'uvm_do_with(send_data_sequence, {send_data_sequence.packet_number == 2;});
'uvm_do_with(send_data_sequence, {send_data_sequence.packet_number == 3;});
'uvm_do(close_data_stream_sequence);

这种方法的问题在于我不希望一个通道阻止另一个或一个接口阻止另一个,除非两个都被阻止。如果我使用上面的虚拟序列,当我想将open_data_stream_sequence传输到另一个通道时,send_data_sequence可能会停止该单个通道,或者它可能会在边带接口上停止,但我想管道send_data_sequence数据事务进入同一通道的数据接口。

然而,我正在努力弄清楚如何在子序列之间实现仲裁。我想到了序列分层和使用fifos只在所有接口在一种中间层饱和时停止。我缺少什么样的UVM技巧?

2 个答案:

答案 0 :(得分:1)

我认为没有办法绕过编写一些能够理解当前频道状态并以最佳方式安排事情的代码(如果测试需要,则故意不是最佳的)。例如,当数据通道停止时,您必须进行一定数量的排队才能允许没有数据的边带请求传递数据请求。

仍然可以将其封装在基类虚拟序列中,让它称之为“调度程序”,使刺激对其实现无动于衷。调度程序将具有' start_sequence' API在通道的序列发生器上启动给定序列,或者在通道未停止时将其排队以启动它。测试编写者可以将子类调度程序'对于他想写的每个顶级序列,并放入" start_sequence(data0); start_sequence(DATA1); start_sequence(sideband0);"调用,其中每个dataN / sidebandM虚拟序列看起来就像你在问题中描述的那样。

' start_sequence'应立即返回以允许通道完全饱和,或者可以在所有通道饱和时阻止以减少不必要的排队。

答案 1 :(得分:0)

我不完全明白你的拖延条件是什么,但我可以告诉你的是,它无论如何都会变得复杂。

您编写的代码将以线性方式执行,但您所描述的是并行行为。您可以做的是并行启动所有序列,并根据事件阻止或释放驱动它们。这些事件将非常适合您的应用程序:

fork
  'uvm_do(open_data_stream_sequence);

  begin
    @(unblock_channel_0);
    'uvm_do_with(send_data_sequence, {send_data_sequence.packet_number == 0;});
  end

  // ...

  begin
    @(done_e);
    'uvm_do(close_data_stream_sequence);
  end
join