uvm sequence Arbitration
多个序列尝试访问单个驱动器时,执行序列的序列器会通过称为仲裁(arbitration)的过程按特定顺序调度这些序列。可根据称为仲裁模式(arbitration modes)的特定标准,将序列器配置为优先允许某些序列访问驱动器。
Example
要理解不同的仲裁模式,我们首先需要构建一个包含序列发生器(sequencer)和驱动器(driver)环境的测试平台。需要注意的是,那些不需要访问驱动器或通过start_item
和finish_item
执行序列项的序列无需经过仲裁。因此,如果在同一个序列发生器上启动多个简单序列,它们将并行执行。
1. Data class
名为 base_class
的类代表一个数据对象,该对象将被发送至驱动器,以便驱动器能将其转换为被测设备接口上的协议级引脚翻转信号。为清晰演示仲裁机制,我们对此类定义进行了简化处理。
class base_pkt extends uvm_sequence_item;`uvm_object_utils(base_pkt)function new(string name = "base_pkt");super.new(name);endfunctionrand bit[7:0] addr;
endclass
2.driver
假设一个驱动程序接受一个类型为 base_pkt 的数据对象,并翻转 DUT 的引脚。
class base_driver extends uvm_driver #(base_pkt);`uvm_component_utils(base_driver)function new(string name = "base_driver", uvm_component parent=null);super.new(name, parent);endfunction// Assume that the packet is driven across to the DUT within 10ns// after which the driver calls item_done()virtual task run_phase(uvm_phase phase);base_pkt m_pkt;forever beginseq_item_port.get_next_item(m_pkt);#10 `uvm_info ("DRV", $sformatf("Drive packet with addr=0x%0h", m_pkt.addr), UVM_LOW)seq_item_port.item_done();endendtask
endclass
3. Environment
环境类实例化了一个序列发生器和一个驱动器,并在它们之间建立连接。
class base_env extends uvm_env;`uvm_component_utils(base_env)function new(string name="base_env", uvm_component parent=null);super.new(name, parent);endfunctionbase_driver m_drv;uvm_sequencer#(base_pkt) m_seqr;virtual function void build_phase(uvm_phase phase);super.build_phase(phase);m_drv = base_driver::type_id::create("m_drv", this);m_seqr = uvm_sequencer#(base_pkt)::type_id::create("m_seqr", this);endfunctionvirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);m_drv.seq_item_port.connect(m_seqr.seq_item_export);endfunction
endclass
4. sequence
名为base_seq
的序列类会创建数据包,并由上述定义的序列器执行。该数据包将被发送至驱动器,并处于阻塞状态,直至驱动器调用item_done
方法。
由于单个序列器上会启动该序列的多个实例,因此声明了名为seq_num
的变量来区分不同序列。同时通过使数据包地址唯一化,以识别具体由哪个序列负责通过驱动器发送数据。
class base_seq extends uvm_sequence;`uvm_object_utils(base_seq)function new(string name="base_seq");super.new(name);endfunctionint seq_num;virtual task body();base_pkt m_pkt = base_pkt::type_id::create("m_pkt");`uvm_info(get_name(), $sformatf("Started body"), UVM_LOW)start_item(m_pkt);m_pkt.randomize() with { addr == seq_num; };finish_item(m_pkt);#10 `uvm_info(get_name(), $sformatf("Ended body"), UVM_LOW)endtask
endclass
5. test
下面定义了一个基础测试类,用于构建测试环境和所有序列。该类还包含一个额外功能,用于显示环境中序列器当前的仲裁方案。根据该仲裁方案,序列器会按照特定顺序向驱动程序授予所有序列的访问权限。
class base_test extends uvm_test;`uvm_component_utils(base_test)function new(string name="base_test", uvm_component parent=null);super.new(name, parent);endfunctionbase_seq m_seq[6];base_env m_env;virtual function void build_phase(uvm_phase phase);super.build_phase(phase);foreach(m_seq[i]) beginm_seq[i] = base_seq::type_id::create($sformatf("m_seq_%0d", i));m_seq[i].seq_num = i;endm_env = base_env::type_id::create("m_env", this);endfunctionvirtual function void show_arb_cfg();UVM_SEQ_ARB_TYPE cur_arb;cur_arb = m_env.m_seqr.get_arbitration();`uvm_info("TEST", $sformatf("Seqr set to %s", cur_arb.name()), UVM_LOW)endfunction
endclass
UVM_SEQ_ARB_FIFO
这是默认的仲裁模式,UVM序列器会启动它们而不考虑其优先级。
Without priority
class arb_fifo_test extends base_test;`uvm_component_utils(arb_fifo_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_FIFO);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr);m_seq[1].start(m_env.m_seqr);m_seq[2].start(m_env.m_seqr);m_seq[3].start(m_env.m_seqr);joinphase.drop_objection(this);endtask
endclass
UVM_INFO @ 0: reporter [RNTST] Running test arb_fifo_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_FIFO
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
With priority
Lets add some priorities to the sequence when they are started on the sequencer and see how they behave.
class arb_fifo_test extends base_test;`uvm_component_utils(arb_fifo_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_FIFO);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr, .this_priority(100));m_seq[1].start(m_env.m_seqr, .this_priority(200));m_seq[2].start(m_env.m_seqr, .this_priority(300));m_seq[3].start(m_env.m_seqr, .this_priority(400));joinphase.drop_objection(this);endtask
endclass
UVM_INFO @ 0: reporter [RNTST] Running test arb_fifo_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_FIFO
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
UVM_SEQ_ARB_RANDOM
在这里,sequencer 将随机启动序列,而不考虑它们的优先级。
Without priority
class arb_random_test extends base_test;`uvm_component_utils(arb_random_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_RANDOM);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr);m_seq[1].start(m_env.m_seqr);m_seq[2].start(m_env.m_seqr);m_seq[3].start(m_env.m_seqr);joinphase.drop_objection(this);endtask
endclass
UVM_INFO @ 0: reporter [RNTST] Running test arb_random_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_RANDOM
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
With priority
Lets add some priorities to the sequence when they are started on the sequencer and see how they behave.
class arb_random_test extends base_test;`uvm_component_utils(arb_random_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_RANDOM);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr, .this_priority(100));m_seq[1].start(m_env.m_seqr, .this_priority(200));m_seq[2].start(m_env.m_seqr, .this_priority(300));m_seq[3].start(m_env.m_seqr, .this_priority(400));joinphase.drop_objection(this);endtask
endclass
UVM_INFO @ 0: reporter [RNTST] Running test arb_random_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_RANDOM
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
UVM_SEQ_ARB_STRICT_FIFO
该模式始终优先处理优先级最高的序列。多个具有相同优先级的序列将采用类似先进先出(FIFO)的仲裁机制。本次测试中,我们将增加序列数量,以便在同一优先级上存在多个序列。
Without priority
class arb_strict_fifo_test extends base_test;`uvm_component_utils(arb_strict_fifo_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr);m_seq[3].start(m_env.m_seqr);m_seq[1].start(m_env.m_seqr);m_seq[2].start(m_env.m_seqr);m_seq[4].start(m_env.m_seqr);m_seq[5].start(m_env.m_seqr);joinphase.drop_objection(this);endtask
endclass
当未指定优先级时,确保输出与UVM_SEQ_ARB_FIFO仲裁模式相同。
UVM_INFO @ 0: reporter [RNTST] Running test arb_strict_fifo_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_STRICT_FIFO
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 50: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x4
UVM_INFO testbench.sv(27) @ 60: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Ended body
UVM_INFO testbench.sv(41) @ 60: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x5
UVM_INFO testbench.sv(27) @ 70: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 70: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 70: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
With priority
class arb_strict_fifo_test extends base_test;`uvm_component_utils(arb_strict_fifo_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr, .this_priority(100));m_seq[1].start(m_env.m_seqr, .this_priority(200));m_seq[2].start(m_env.m_seqr, .this_priority(200));m_seq[3].start(m_env.m_seqr, .this_priority(200));m_seq[4].start(m_env.m_seqr, .this_priority(200));m_seq[5].start(m_env.m_seqr, .this_priority(400));joinphase.drop_objection(this);endtask
endclass
Note that priorities affect output in UVM_SEQ_ARB_STRICT_FIFO mode.
UVM_INFO @ 0: reporter [RNTST] Running test arb_strict_fifo_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_STRICT_FIFO
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x5
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 50: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x4
UVM_INFO testbench.sv(27) @ 60: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Ended body
UVM_INFO testbench.sv(41) @ 60: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 70: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 70: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 70: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
UVM_SEQ_ARB_STRICT_RANDOM
此模式将始终优先处理优先级最高的序列。多个优先级相同的序列将随机选取。本次测试中,我们将增加序列数量,以便在同一优先级下拥有更多序列。
Without priority
class arb_strict_random_test extends base_test;`uvm_component_utils(arb_strict_random_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_STRICT_RANDOM);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr);m_seq[3].start(m_env.m_seqr);m_seq[1].start(m_env.m_seqr);m_seq[2].start(m_env.m_seqr);m_seq[4].start(m_env.m_seqr);m_seq[5].start(m_env.m_seqr);joinphase.drop_objection(this);endtask
endclass
Note that this is similar to UVM_SEQ_ARB_RANDOM mode when there are no priorities.
UVM_INFO @ 0: reporter [RNTST] Running test arb_strict_random_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_STRICT_RANDOM
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x4
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x5
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Ended body
UVM_INFO testbench.sv(41) @ 50: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 60: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 60: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 70: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 70: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 70: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
With priority
class arb_strict_random_test extends base_test;`uvm_component_utils(arb_strict_random_test)function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);super.run_phase(phase);phase.raise_objection(this);m_env.m_seqr.set_arbitration(UVM_SEQ_ARB_STRICT_RANDOM);show_arb_cfg();forkm_seq[0].start(m_env.m_seqr, .this_priority(100));m_seq[1].start(m_env.m_seqr, .this_priority(200));m_seq[2].start(m_env.m_seqr, .this_priority(200));m_seq[3].start(m_env.m_seqr, .this_priority(200));m_seq[4].start(m_env.m_seqr, .this_priority(200));m_seq[5].start(m_env.m_seqr, .this_priority(400));joinphase.drop_objection(this);endtask
endclass
请注意,具有相同优先级的 m_seq_1 到 m_seq_4 是以随机顺序输出的。将此与 UVM_SEQ_ARB_STRICT_FIFO 模式进行比较,在该模式下这些序列是按先进先出(FIFO)顺序输出的。
UVM_INFO @ 0: reporter [RNTST] Running test arb_strict_random_test...
UVM_INFO testbench.sv(90) @ 0: uvm_test_top [TEST] Seqr set to UVM_SEQ_ARB_STRICT_RANDOM
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Started body
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Started body
UVM_INFO testbench.sv(41) @ 10: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x5
UVM_INFO testbench.sv(27) @ 20: uvm_test_top.m_env.m_seqr@@m_seq_5 [m_seq_5] Ended body
UVM_INFO testbench.sv(41) @ 20: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x1
UVM_INFO testbench.sv(27) @ 30: uvm_test_top.m_env.m_seqr@@m_seq_1 [m_seq_1] Ended body
UVM_INFO testbench.sv(41) @ 30: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x4
UVM_INFO testbench.sv(27) @ 40: uvm_test_top.m_env.m_seqr@@m_seq_4 [m_seq_4] Ended body
UVM_INFO testbench.sv(41) @ 40: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x2
UVM_INFO testbench.sv(27) @ 50: uvm_test_top.m_env.m_seqr@@m_seq_2 [m_seq_2] Ended body
UVM_INFO testbench.sv(41) @ 50: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x3
UVM_INFO testbench.sv(27) @ 60: uvm_test_top.m_env.m_seqr@@m_seq_3 [m_seq_3] Ended body
UVM_INFO testbench.sv(41) @ 60: uvm_test_top.m_env.m_drv [DRV] Drive packet with addr=0x0
UVM_INFO testbench.sv(27) @ 70: uvm_test_top.m_env.m_seqr@@m_seq_0 [m_seq_0] Ended body
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 70: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 70: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
UVM_SEQ_ARB_WEIGHTED
在这种模式下,选择高优先级序列的概率更高。
UVM_SEQ_ARB_USER
如果以上模式均不能满足您的需求,您可以创建自定义仲裁方案。您只需新建一个继承自uvm_sequencer
的序列器,并定义其user_priority_arbitration
函数即可。
summary
sequencer 的仲裁对于多个sequence绑定在一个sequencer 时 ,在base test 上使用
sequencer.set_arbitration(xxxx)的方式实现仲裁方法选择;
sequence.start(srquencer,parent_sequencer,this_priority,call_pre) 。上述代码使用显示端口引用方式(.端口名称(端口赋值)),支持端口任意顺序赋值;
带*_strict_*和weighted 仲裁方法会看this_priority 的值,其他不看,赋值也会被忽略;
*_fifo的仲裁方法会,权重相同时,执行顺序与start的顺序有关(fifo 时保序入,保序出);
*_random的仲裁方法会,权重相同时,会随机轮询;