Analysis Components & Techniques(从AnalysisConnectionst_Two styles...开始)

上一篇 / 下一篇  2018-12-26 16:03:55

   Two styles of implementation 

       你可以采用两种方法来实现具有多个输入流的analysis component的行为。这些方法基本上是等同的,因为使用一种方法的任何实现都可以使用另一种方法等效地实现。大多数时候,它只是归结为个人偏好。
       在一种方法中,您直接实现所有write()函数,并在包含组件中声明imp连接。因为write()函数必须是非阻塞的,所以不能直接与其他流执行任何同步。如果需要同步,则必须将事务存储在某种存储元素(例如fifo或关联数组)中,并提供单独的进程(通常在run()任务中)以执行同步。
        在另一种方法中,为每个输入流提供嵌入式analysis fifo,并声明分层analysis export以在外部向别的组件公开显示fifo即可。在这种情况下,write()函数由fifos提供,它们将事务存入fifo数据结构。然后,您可以通过run()任务实现analysis组件的功能。使用此方法需要额外的步骤将analysis fifos连接到analysis exports。

  Multiple Transaction Streams Without Synchronization

       当analysis组件需要对多个事务流进行采样时,会增加编写组件行为的复杂性。
       将uvm_analysis_imps与多个流一起使用时的一个复杂因素是每个uvm_analysis_imp都希望绑定到write()函数。由于组件中只能有一个名为write()的函数,因此需要一种解决方法。UVM通过定义`uvm_analysis_imp_decl宏来提供解决方法。此宏允许您声明一个专门的“imp”样式分析导出,该导出调用名为write_SUFFIX的函数,您可以在其中指定_SUFFIX。

       【此处需一副图】

       // Declare the suffixes that will be appended to the imps and functions
       `uvm_analysis_imp_decl(_BEFORE)
       `uvm_analysis_imp_decl(_AFTER)

       class delay_analyzer extends uvm_component;
          `uvm_component_utils(delay_analyzer)

          // Declare the imps using the suffixes declared above.
          // The first parameter is the transaction type.
          // The second parameter is the type of component that implements the interface
          // Usually, the second parameter is the same as the containing component type 

          uvm_analysis_imp_BEFORE #(alu_txn, delay_analyzer) before_export;
          uvm_analysis_imp_AFTER #(alu_txn, delay_analyzer) after_export;

          real m_before[$];
          real m_after[$];
          real last_b_time, last_a_time;
          real longest_b_delay, longest_a_delay;

           function new( string name , uvm_component parent) ;
              super.new( name , parent );
              last_b_time = 0.0;
              last_a_time = 0.0;
          endfunction

         // Implement the interface function by appending the function name with
         // the suffix declared in the macro above.
         function void write_BEFORE(alu_txn t);
            real delay;
            delay = $realtime - last_b_time;
            last_b_time = $realtime;
            m_before.push_back(delay);
         endfunction

         function void build_phase( uvm_phase phase );
         // The second argument to the imp constructor is a handle to the object
         // that implements the interface functions. It should be of the type
         // specified in the declaration of the imp. Usually, it is "this".
            before_export = new("before_export", this);
            after_export = new("after_export", this);
         endfunction

          function void extract_phase( uvm_phase phase );
             foreach (m_before[i])
                if (m_before[i] > longest_b_delay) longest_b_delay = m_before[i];
             foreach (m_after[i])
                if (m_after[i] > longest_a_delay) longest_a_delay = m_after[i];
          endfunction

           function void check_phase( uvm_phase phase );
              string s;
              if (longest_a_delay > 100.0) begin
                 $sformat(s, "Transaction delay too long: %5.2f",longest_a_delay);
                 uvm_report_warning("Delay Analyzer",s);
              end
              if (longest_b_delay > 100.0) begin
                 $sformat(s, "Transaction delay too long: %5.2f",longest_a_delay);
                 uvm_report_warning("Delay Analyzer",s);
              end
           endfunction

           function void report_phase( uvm_phase phase );
              uvm_report_info("Delay Analyzer", $sformatf("Longest BEFORE delay: %5.2f", longest_b_delay));
              uvm_report_info("Delay Analyzer", $sformatf("Longest AFTER delay: %5.2f", longest_a_delay));            endfunction

       endclass

       
  Multiple Transaction Streams With Synchronization

       当analysis组件的所需行为允许每个流的处理独立完成时,直接实现write()函数会更容易。但是,许多情况需要事务流之间的同步,以便数据不会丢失。例如,有序比较器有两个流,一个来自Predictor,另一个来自Monitor。它必须等到它有一对匹配的事务(每个流中有一个),此时才能进行比较。
       在这种情况下,您可以在两个write()函数中手动执行所有同步工作,而不是实例化两个analysis_fifos并在Comparator上放置两个分层exports。由于您没有在write()函数中实现Comparator的行为,因此需要采用不同的方法。在这种情况下,您可以在组件的run()任务中实现Comparator行为,并使用analysis fifos上的阻塞操作来执行必要的同步。

       【此处需插一幅图】

        class comparator_inorder extends uvm_component;
           `uvm_component_utils(comparator_inorder)

           uvm_analysis_export #(alu_txn) before_export;
           uvm_analysis_export #(alu_txn) after_export;

           uvm_tlm_analysis_fifo #(alu_txn) before_fifo, after_fifo;
           int m_matches, m_mismatches;

           function new( string name , uvm_component parent) ;
              super.new( name , parent );
              m_matches = 0;
              m_mismatches = 0;
          endfunction

          function void build_phase( uvm_phase phase );
             before_fifo = new("before_fifo", this);
             after_fifo = new("after_fifo", this);
             before_export = new("before_export", this);
             after_export = new("after_export", this);
          endfunction

          function void connect_phase( uvm_phase phase );
             before_export.connect(before_fifo.analysis_export);
             after_export.connect(after_fifo.analysis_export);
          endfunction

          task run_phase( uvm_phase phase );
             string s;
             alu_txn before_txn, after_txn;
             forever begin
                before_fifo.get(before_txn);
                after_fifo.get(after_txn);
                if (!before_txn.compare(after_txn)) begin
                   $sformat(s, "%s does not match %s", before_txn.convert2string(), after_txn.convert2string());                    uvm_report_error("Comparator Mismatch",s);
                   m_mismatches++;
                end else begin
                   m_matches++;
                end
             end
          endtask

           function void report_phase( uvm_phase phase );
              uvm_report_info("Inorder Comparator", $sformatf("Matches: %0d", m_matches));     
              uvm_report_info("Inorder Comparator", $sformatf("Mismatches: %0d", m_mismatches));
           endfunction

        endclass

        对于更复杂的同步需求,您将使用多个write_SUFFIX()函数的组合,这些函数将事务数据放入某种共享数据结构,以及run()任务中的代码以执行协调和控制。

        (在上在线下载源代码示例)。


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2019-01-12  
  12345
6789101112
13141516171819
20212223242526
2728293031  

数据统计

  • 访问量: 19260
  • 日志数: 75
  • 建立时间: 2018-09-03
  • 更新时间: 2018-12-29

RSS订阅

Open Toolbar
魔域私服 魔域私服 魔域私服 魔域私服 魔域私服

          <dfn id='xb1fp'><optgroup id='28jt5'></optgroup></dfn><tfoot id='aneft'><bdo id='2ge42'><div id='l7a3v'></div><i id='q3xyp'><dt id='gzzps'></dt></i></bdo></tfoot>

          <ul id='38ml4'></ul>