System verilog 为什么UVM的约束随机化不起作用?

System verilog 为什么UVM的约束随机化不起作用?,system-verilog,uvm,System Verilog,Uvm,我有一些简化的测试结构。testcaseapb\u write\u verify2y\u test调用apb\u write\u verify2y\u seq,然后调用apb\u write\u seq 但是,m_seq.m_addr=16'h0010(在apb_write_verify2y_test)未按其应传给m_apb_write_seq.m_addr 如果我更改apb\u write\u verify2y\u seq中的行,如下所示,则该行正常工作: assert(m_apb_write

我有一些简化的测试结构。testcase
apb\u write\u verify2y\u test
调用
apb\u write\u verify2y\u seq
,然后调用
apb\u write\u seq

但是,
m_seq.m_addr=16'h0010
(在
apb_write_verify2y_test
)未按其应传给
m_apb_write_seq.m_addr

如果我更改
apb\u write\u verify2y\u seq
中的行,如下所示,则该行正常工作:

assert(m_apb_write_seq.randomize() with {m_apb_write_seq.m_addr == 16'h0010;});  
你能帮我一下吗

class apb_write_verify2y_test extends apb_base_test;
    `uvm_component_utils(apb_write_verify2y_test)
    virtual task run_phase(uvm_phase phase);
        apb_write_verify2y_seq m_seq;
        phase.raise_objection(.obj(this));
        m_seq = apb_write_verify2y_seq::type_id::create(.name("m_seq"));
        m_seq.m_addr = 16'h0010;
        m_seq.start(m_env.m_apb_agent.m_apb_seqr);
        #10ns ;
        phase.drop_objection(.obj(this));
    endtask: run_phase

class apb_write_verify2y_seq extends uvm_sequence#(apb_seq_item);
    `uvm_object_utils(apb_write_verify2y_seq)
    logic [15:0]  m_addr;
    task body();
        apb_write_seq m_apb_write_seq;
        repeat (2) begin
            m_apb_write_seq = apb_write_seq::type_id::create(.name("m_apb_write_seq"));
            assert(m_apb_write_seq.randomize() with {m_apb_write_seq.m_addr == m_addr;});
            `uvm_info("debug1", $sformatf("m_seq has m_addr=%h, m_apb_write_seq.m_addr=%h", m_addr, m_apb_write_seq.m_addr ), UVM_HIGH);
            m_apb_write_seq.start(m_sequencer);
        end
    endtask: body

class apb_write_seq extends uvm_sequence#(apb_seq_item);
    `uvm_object_utils(apb_write_seq)
    rand logic [15:0]  m_addr;
    task body();
        apb_seq_item m_apb_seq_item;
        m_apb_seq_item = apb_seq_item::type_id::create(.name("m_apb_seq_item"));
        start_item(m_apb_seq_item);
        assert(m_apb_seq_item.randomize() with { m_apb_seq_item.tr_addr == m_addr;});
        finish_item(m_apb_seq_item);
    endtask
带有{}函数的
.randomize()将首先在随机对象的范围内搜索变量。如果在目标对象中找不到它,那么它将从调用随机化函数的地方搜索局部范围。名称
m_addr
存在于
apb_write_verify2y_seq
apb_write_seq
中。对于当前代码,两个
m_addr
都引用了
m_apb_write_seq
中的同一变量

您想使用
local::
scope操作符告诉randomize只搜索当前范围

assert(m_apb_write_seq.randomize() with {m_addr == local::m_addr;});
这种方式
m_addr
指的是
m_apb_write_seq
范围,而
local::m_addr
指的是
apb_write_verify2y_seq
范围。

.randomize()和{}
函数将首先搜索随机对象范围内的变量。如果在目标对象中找不到它,那么它将从调用随机化函数的地方搜索局部范围。名称
m_addr
存在于
apb_write_verify2y_seq
apb_write_seq
中。对于当前代码,两个
m_addr
都引用了
m_apb_write_seq
中的同一变量

您想使用
local::
scope操作符告诉randomize只搜索当前范围

assert(m_apb_write_seq.randomize() with {m_addr == local::m_addr;});

这种方式
m_addr
指的是
m_apb_write_seq
范围,
local::m_addr
指的是
apb_write_verify2y_seq
范围。

,你好,格雷格,谢谢你的回答。我试过了,它正在工作。我也试过一点,如果我把它像{m_addr==apb_cfg::m_addr;},这也是有效的。嗨,格雷格,谢谢你的回答。我试过了,它正在工作。我也试过一点,如果我把它像{m_addr==apb_cfg::m_addr;}一样,这也是有效的。