2014-09-25 30 views
0

在DUT上,我有两个通道,每个通道由数据接口和边带接口组成。这些频道发送的交易必须按顺序进行,但其中一个频道可能会停滞,而另一个频道会赶上。 IE: 我发送事务A向下通道0,事务C向下通道1,但通道1将不接受事务C,直到通道0已收到事务B为止。UVM:将序列拆分到不同的子顺序器上

此外,数据接口可能比每个接口上的边带接口慢渠道和某些边带交易不需要与他们一起发送数据。

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

顶部顺序应该只是产生这样的序列:

'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); 

这种方法的问题是,我不想一个通道阻断其他的或者一个接口来阻止对方,除非双方都停止回。如果我使用如上所述的虚拟序列,则当我想要将send_data_sequence传输到其他通道时,open_data_stream_sequence可能会失去该单个通道,或者它可能会在边带接口上停顿,但我想要将send_data_sequence数据事务处理到同一通道的数据接口。

但是我正在努力弄清楚如何在子程序之间实现仲裁。我想过序列分层和使用fifos只在所有接口在中间层饱和的时候才会停止。是否有错误的UVM技巧?

回答

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 
+0

该代码将同时启动open_data_stream和close_data_stream序列,可能在打开之前将其关闭 - 这可能不太好。我认为他希望并行运行多个开放式数据数据数据序列,而不是并行运行该序列的各个部分。 – Stan 2014-09-27 23:37:53

+0

是的,你就在这里,我更新了答案。基本上你在我所设想的(排队)中所建议的事情是这样的事件(即排队逻辑触发事件)。 – 2014-09-28 04:28:06

1

我不认为有让周围写一些代码,明白以最佳的方式(当前信道状态和进度的事情或故意未优化的方式,如果测试需要它)。例如,当数据通道停止时,您将不得不进行一定数量的排队以便允许无数据的边带请求传递数据请求。

这仍然可以被封装在一个基类虚拟序列中,我们称之为'调度器',以这种方式刺激忽略了它的实现。调度程序将有一个'start_sequence'API,它可以启动通道序列器上给定的序列,或者在通道未停止时将其排队以启动它。测试编写者可以为他想要写入的每个顶层序列分配“调度程序”,并放入“start_sequence(data0); start_sequence(data1); start_sequence(sideband0);”呼叫,其中每个dataN/sidebandM虚拟序列看起来像您在问题中描述的那个。

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