0

在 DUT 上,我有两个通道,每个通道由一个数据接口和一个边带接口组成。沿着这些通道发送的事务必须按顺序发送,但一个通道可能会在另一个通道赶上时停止。IE:我在通道 0 下发送交易 A,在通道 1 下发送交易 C,但在通道 0 收到交易 B 之前,通道 1 不会接受交易 C。

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

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

顶部序列应该只生成这样的序列:

'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 技巧吗?

4

2 回答 2

1

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

这仍然可以封装在一个基类的虚拟序列中,我们称之为“调度器”,这样刺激就不会注意到它的实现。调度程序将有一个“start_sequence”API,它在通道的序列器上启动给定的序列,或者将其排队以在通道没有停止时立即启动它。测试编写者可以为他想要编写的每个顶级序列子类“调度程序”,并放入“start_sequence(data0); start_sequence(data1); start_sequence(sideband0);” 调用,其中每个 dataN/sidebandM 虚拟序列看起来像您在问题中描述的序列。

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

于 2014-09-27T23:36:48.150 回答
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
于 2014-09-25T16:01:35.630 回答