RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1003771
Accepted
Андрей Солодовников
Андрей Солодовников
Asked:2020-07-17 17:12:35 +0000 UTC2020-07-17 17:12:35 +0000 UTC 2020-07-17 17:12:35 +0000 UTC

是否可以将 uvm_tlm_analysis_fifo 连接到 uvm_driver?

  • 772

有必要将模块的输出连接到其受控输入uvm_driver。在我看来是这样的:

                  -----       ---------------------
                 | MON |---->|uvm_tlm_analysis_fifo|
                  -----       ---------------------
                    ^                    |
                    |                    |
 -------------      |      -------       |
|             |---------->| slave |      v
|     DUT     |            -------    --------
|             |<---------------------| master |
 -------------                        --------

我尝试了以下方法:

typedef class seq_item extends uvm_sequence_item;
typedef class driver extends uvm_driver(seq_item);

class agent extends uvm_agent;
    `uvm_component_utils(agent)
    uvm_analysis_port#(seq_item) ap;
    uvm_tlm_analysis_fifo#(seq_item) fifo;
    driver                       drv;

    function new(string name, uvm_component parent);
        super.new(name,parent);
    endfunction: new

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        ap  = new("ap", this);
        fifo= new("fifo",this); 
        drv = driver::type_id::create("driver", this);
    endfunction: build_phase

    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        ap.connect(fifo.analysis_export);
        drv.seq_item_port.connect(fifo.get_peek_export);
    endfunction: connect_phase

    task main_phase(uvm_phase phase);
        seq_item trans;
        phase.raise_objection(this);
        repeat(5) begin
            trans = seq_item::type_id::create("inTrans");
            assert(trans.randomize());
            ap.write(trans);
        end
        phase.drop_objection(this);
    endtask
endclass: agent

这是一个最小的、独立的、可重现的示例:

`include "uvm_macros.svh"
package t;
    import uvm_pkg::*;
    class seq_item extends uvm_sequence_item;
        `uvm_object_utils(seq_item)

        rand bit [31:0]            data;
        function new(string name = "seq_item");
            super.new(name);
        endfunction: new
    endclass: seq_item

    class driver extends uvm_driver#(seq_item);
        `uvm_component_utils(driver)
        function new (string name, uvm_component parent);
            super.new(name, parent);
        endfunction: new

        task main_phase(uvm_phase phase);
            fork
                super.main_phase(phase);
            join_none
            forever begin
                seq_item_port.get_next_item(req);
                `uvm_info(get_type_name(),$psprintf("Got item with data: %h",req.data),UVM_NONE);
                seq_item_port.item_done();
            end
        endtask: main_phase
    endclass: driver

    class test extends uvm_test;
        `uvm_component_utils(test)
        uvm_analysis_port#(seq_item) ap;
        uvm_tlm_analysis_fifo#(seq_item) fifo;

        driver                       drv;

        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction: new
        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            ap  = new(.name("apb_ap"), .parent(this));
            fifo= new("fifo",this); 
            drv = driver        ::type_id::create(.name("driver"), .parent(this) );
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            ap.connect(fifo.analysis_export);
            drv.seq_item_port.connect(fifo.get_peek_export);
        endfunction: connect_phase

        task main_phase(uvm_phase phase);
            seq_item trans;
            phase.raise_objection(this);
            repeat(5) begin
                trans = seq_item::type_id::create("inTrans");
                assert(trans.randomize());
                ap.write(trans);
            end
            phase.drop_objection(this);
        endtask
    endclass: test
endpackage

module top();
    import uvm_pkg::*;
    import t::*;
    initial begin
        run_test();
    end
endmodule

这会产生以下错误:

 ** Error: (vsim-7065) 5.sv(51): Illegal assignment to class mtiUvm.uvm_pkg::uvm_port_base #(class mtiUvm.uvm_pkg::uvm_sqr_if_base #(class work.t::seq_item, class work.t::seq_item)) from class mtiUvm.uvm_pkg::uvm_get_peek_imp #(class work.t::seq_item, class mtiUvm.uvm_pkg::uvm_tlm_fifo_base #(class work.t::seq_item))
#    Time: 0 ns  Iteration: 0  Region: /t File: 5.sv
# ** Error: (vsim-8754) 5.sv(51): Actual input arg. of type 'class mtiUvm.uvm_pkg::uvm_get_peek_imp #(class work.t::seq_item, class mtiUvm.uvm_pkg::uvm_tlm_fifo_base #(class work.t::seq_item))' for formal 'provider' of 'connect' is not compatible with the formal's type 'class mtiUvm.uvm_pkg::uvm_port_base #(class mtiUvm.uvm_pkg::uvm_sqr_if_base #(class work.t::seq_item, class work.t::seq_item))'.

上述方案如何实施?

system-verilog
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Андрей Солодовников
    2020-07-17T17:12:35Z2020-07-17T17:12:35Z

    您无法将 fifo 连接到驱动程序,因为它只能连接到seq_item_export组件uvm_sequencer。
    因此,生成的方案将采用以下形式:

                      -----       ---------
                     | MON |---->|sequencer|
                      -----      |   ------|
                        ^        |  | fifo |
                        |         --------- 
     -------------      |    -------     |
    |             |-------->| slave |    v
    |     DUT     |          -------  --------
    |             |<-----------------| master |
     -------------                    --------
    

    要强制排序器根据请求 get_next_item 从 fifo 传输对象,而不是从运行在其上的序列传输对象,您需要从uvm_sequencer一个新类继承该方法将被覆盖,并且还添加了我们的 fifo:

    class fifo_sequencer#(type REQ=uvm_sequence_item,RSP=REQ) extends uvm_sequencer#(REQ,RSP);
        `uvm_component_param_utils(fake_sequencer#(REQ,RSP))
    
        uvm_tlm_analysis_fifo#(REQ) fifo;
    
        function new(string name, uvm_component parent);
            super.new(name, parent);
            fifo = new("fifo", this);
        endfunction
    
        task get_next_item(output REQ t);
            fifo.get_peek_export.get(t);
        endtask
    
        function void item_done(RSP item = null);
            if (item != null) begin
                seq_item_export.put_response(item);
            end
        endfunction
    endclass
    

    另外值得注意的是,除了 task 之外get_next_item,还必须重新定义 item_done 函数,否则会报错

    Item_done() 调用时没有未完成的请求因此,通过上述更改,最小示例将采用以下形式:

    `include "uvm_macros.svh"
    package t;
        import uvm_pkg::*;
    
        class seq_item extends uvm_sequence_item;
            `uvm_object_utils(seq_item)
    
            rand bit [31:0]            data;
            function new(string name = "seq_item");
                super.new(name);
            endfunction: new
        endclass: seq_item
    
        class driver extends uvm_driver#(seq_item);
            `uvm_component_utils(driver)
            function new (string name, uvm_component parent);
                super.new(name, parent);
            endfunction: new
    
            task main_phase(uvm_phase phase);
                fork
                    super.main_phase(phase);
                join_none
                forever begin
                    seq_item_port.get_next_item(req);
                    `uvm_info(get_type_name(),$psprintf("Got item with data: %h",req.data),UVM_NONE);
                    seq_item_port.item_done();
                end
            endtask: main_phase
        endclass: driver
    
        class fifo_sequencer#(type REQ=uvm_sequence_item,RSP=REQ) extends uvm_sequencer#(REQ,RSP);
            `uvm_component_param_utils(fifo_sequencer#(REQ,RSP))
    
            uvm_tlm_analysis_fifo#(REQ) fifo;
    
            function new(string name, uvm_component parent);
                super.new(name, parent);
                fifo = new("fifo", this);
            endfunction
    
            task get_next_item(output REQ t);
                fifo.get_peek_export.get(t);
            endtask
    
            function void item_done(RSP item = null);
                if (item != null) begin
                    seq_item_export.put_response(item);
                end
            endfunction
        endclass
    
        class test extends uvm_test;
            `uvm_component_utils(test)
            uvm_analysis_port#(seq_item) ap;
    
            driver                      drv;
            fifo_sequencer#(seq_item)   sqr;
    
            function new(string name, uvm_component parent);
                super.new(name,parent);
            endfunction: new
            function void build_phase(uvm_phase phase);
                super.build_phase(phase);
                ap  = new("apb_ap", this);
                sqr = fifo_sequencer#(seq_item) ::type_id::create("sequencer", this);
                drv = driver                    ::type_id::create("driver", this);
            endfunction: build_phase
    
            function void connect_phase(uvm_phase phase);
                super.connect_phase(phase);
                ap.connect(sqr.fifo.analysis_export);
                drv.seq_item_port.connect(sqr.seq_item_export);
            endfunction: connect_phase
    
            task main_phase(uvm_phase phase);
                seq_item trans;
                phase.raise_objection(this);
                repeat(5) begin
                    trans = seq_item::type_id::create("inTrans");
                    assert(trans.randomize());
                    ap.write(trans);
                end
                phase.drop_objection(this);
            endtask
        endclass: test
    endpackage
    
    module top();
        import uvm_pkg::*;
        import t::*;
        initial begin
            run_test();
        end
    endmodule
    
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5