UVM/UVM Cookbook/Sequences/VirtualSequencer — различия между версиями
ANA (обсуждение | вклад) м |
ANA (обсуждение | вклад) м (→Virtual sequences that run on virtual sequencers) |
||
Строка 17: | Строка 17: | ||
=== Virtual sequences that run on virtual sequencers === | === Virtual sequences that run on virtual sequencers === | ||
− | A virtual sequence is designed to run on a virtual sequencer by adding code that gets the handles to the sub-sequencers from the virtual sequencer. The most convenient way to do this is to extend virtual sequences from a base class that does the sequencer handle assignment. The virtual sequencer is is part of the UVM component hierarchy and so its sub-sequencer references can be assigned during the connect phase. | + | <!-- A virtual sequence is designed to run on a virtual sequencer by adding code that gets the handles to the sub-sequencers from the virtual sequencer. The most convenient way to do this is to extend virtual sequences from a base class that does the sequencer handle assignment. The virtual sequencer is is part of the UVM component hierarchy and so its sub-sequencer references can be assigned during the connect phase. |
+ | --> | ||
+ | Виртуальная последовательность предназначена для работы на виртуальном sequencer`е с помощью добавления кода, который получает ручки управления (указатели на? handles to) sub-sequencer`ами из виртуального sequencer`а. Самый удобный способ сделать это состоит в наследовании виртуальных последовательностей от базового класса, который делает назначение указателей sequencer`ов. Виртуальный sequencer является частью иерархии компонентов UVM и, таким образом, его ссылки sub-sequencer`ов могут быть заданы во время фазы подключения (connect phase). | ||
− | Typically, a virtual sequencer is inserted inside the env of a block level testbench, with the connect method of the block level env being used to assign the sub-sequencer handles. Since the virtual_sequence is likely to be in overall control of the simulation, it is usually created in the test run method and started on the virtual sequencer - i.e. virtual_sequence.start(virtual_sequencer); | + | <!-- Typically, a virtual sequencer is inserted inside the env of a block level testbench, with the connect method of the block level env being used to assign the sub-sequencer handles. Since the virtual_sequence is likely to be in overall control of the simulation, it is usually created in the test run method and started on the virtual sequencer - i.e. virtual_sequence.start(virtual_sequencer); |
+ | --> | ||
+ | Как правило, виртуальный sequencer вставляется внутрь окружения (env) блочного уровня тесбенча, с метод подключения (connect method) окружения (env), использованного для назначения (задания) указателей sub-sequencer`ов. Поскольку virtual_sequence, вероятно, будет осудествлять общий контроль процесса моделирования (simulation), она обчно создаётся в методе run класса test и стартует на virtual sequencer`е - т.е. virtual_sequence.start (virtual_sequencer); | ||
− | A useful coding guideline is to give the sub-sequencers inside the virtual sequence a name that respresents the interface that they are associated with, this makes life easier for the test writer. For instance, the sequencer for the master bus interface could be called "bus_master" rather than "master_axi_sequencer". | + | <!-- A useful coding guideline is to give the sub-sequencers inside the virtual sequence a name that respresents the interface that they are associated with, this makes life easier for the test writer. For instance, the sequencer for the master bus interface could be called "bus_master" rather than "master_axi_sequencer". |
+ | --> | ||
+ | Полезным стилем кодирования (coding guideline) является назначать sub-sequencer`ам внутри виртуальной последовательности имя, которое представляет интерфейс, с которым они связаны, это делает жизнь легче для разработчиков теста (класса test?). Например, sequencer для мастер (ведущей) шины интерфейса можно назвать "bus_master", а не "master_axi_sequencer". | ||
{| cellspacing="0" cellpadding="10" border="0" | {| cellspacing="0" cellpadding="10" border="0" | ||
|- | |- | ||
− | | <div dir="ltr"><div><big><source lang="verilog">// Virtual sequencer class: | + | | <div dir="ltr"><div><big><source lang="verilog"> |
+ | // Virtual sequencer class: | ||
class virtual_sequencer extends uvm_virtual_sequencer; | class virtual_sequencer extends uvm_virtual_sequencer; | ||
Строка 127: | Строка 134: | ||
|} | |} | ||
− | Chaining Virtual Sequencers for vertical reuse | + | Chaining Virtual Sequencers for vertical reuse |
− | When creating integrated verification environments that reuse block level envs, the virtual sequencers at the different levels of the testbench hierarchy can be chained together, allowing virtual sequences or sub-sequences to be run at any level. To achieve this level of flexibility, both the sub-sequencer handles and the virtual sequencer handles need to be encapsulated at each successive level. | + | [[Файл:Virtual_sequencer_soc_level.gif|Virtual sequencer soc level.gif]] |
+ | |||
+ | <!-- When creating integrated verification environments that reuse block level envs, the virtual sequencers at the different levels of the testbench hierarchy can be chained together, allowing virtual sequences or sub-sequences to be run at any level. To achieve this level of flexibility, both the sub-sequencer handles and the virtual sequencer handles need to be encapsulated at each successive level. | ||
+ | --> | ||
+ | При создании интегрированных сред проверки, которые повторно использовать envs уровня блока, виртуальные секвенсоры на различных уровнях испытательный стенд иерархии могут быть соединены вместе, позволяя виртуальным последовательности или суб-последовательности, которые будут работать на любом уровне. Чтобы достичь этого уровня гибкости, оба суб-секвенсор ручки и виртуальные секвенсор ручки должны быть обнесены на каждом последующем уровне. | ||
{| cellspacing="0" cellpadding="10" border="0" | {| cellspacing="0" cellpadding="10" border="0" |
Версия 11:07, 27 июня 2014
- UVM Tutorial for Candy Lovers
Виртуальная последовательность (virtual sequence) представляет собой последовательность, которая управляет процессом генерации воздействий, используя несколько sequencer`ов. Поскольку последовательности, sequencer`ы и драйверы ориентированы на интерфейсах, почти все тестбенчи требуют виртуальную последовательность для координирования (синхронизации) входных воздействий, подаваемых по различным интерфейсам и взаимодействия между ними.
Виртуальная последовательность может быть реализована в одним из двух способов, рекомендуемым способом является использование автономной виртуальной последовательности и "исторической" альтернативой является использование виртуальной последовательности, которая предназначена для запуска на виртуальном sequencer`е (virtual sequencer), как описано ниже.
Виртуальный sequencer это sequencer, который не подключен к driver`у непосредственно, но содержит ручки управления для sequencer`ов в иерархии тесбенча.
Virtual sequences that run on virtual sequencers
Виртуальная последовательность предназначена для работы на виртуальном sequencer`е с помощью добавления кода, который получает ручки управления (указатели на? handles to) sub-sequencer`ами из виртуального sequencer`а. Самый удобный способ сделать это состоит в наследовании виртуальных последовательностей от базового класса, который делает назначение указателей sequencer`ов. Виртуальный sequencer является частью иерархии компонентов UVM и, таким образом, его ссылки sub-sequencer`ов могут быть заданы во время фазы подключения (connect phase).
Как правило, виртуальный sequencer вставляется внутрь окружения (env) блочного уровня тесбенча, с метод подключения (connect method) окружения (env), использованного для назначения (задания) указателей sub-sequencer`ов. Поскольку virtual_sequence, вероятно, будет осудествлять общий контроль процесса моделирования (simulation), она обчно создаётся в методе run класса test и стартует на virtual sequencer`е - т.е. virtual_sequence.start (virtual_sequencer);
Полезным стилем кодирования (coding guideline) является назначать sub-sequencer`ам внутри виртуальной последовательности имя, которое представляет интерфейс, с которым они связаны, это делает жизнь легче для разработчиков теста (класса test?). Например, sequencer для мастер (ведущей) шины интерфейса можно назвать "bus_master", а не "master_axi_sequencer".
// Virtual sequencer class: class virtual_sequencer extends uvm_virtual_sequencer; `uvm_component_utils(virtual_sequencer) // Note that the handles are in terms that the test writer understands bus_master_sequencer bus; gpio_sequencer gpio; function new(string name = "virtual_sequencer", uvm_component parent = null); super.new(name, parent); endfunction endclass: virtual_sequencer class env extends uvm_env; // Relevant parts of the env which combines the // virtual_sequencer and the bus and gpio agents // // Build: function void build_phase( uvm_phase phase ); m_bus_agent = bus_master_agent::type_id::create("m_bus_agent", this); m_gpio_agent = gpio_agent::type_id::create("m_gpio_agent", this); m_v_sqr = virtual_sequencer::type_id::create("m_v_sqr", this); endfunction: build_phase // Connect - where the virtual_sequencer is hooked up: // Note that these references are constant in the context of this env function void connect_phase( uvm_phase phase ); m_v_sqr.bus = m_bus_agent.m_sequencer; m_v_sqr.gpio = m_gpio_agent.m_sequencer; endfunction: connect_phase endclass:env // Virtual sequence base class: // class virtual_sequence_base extends uvm_sequence #(uvm_sequence_item); `uvm_object_utils(virtual_sequence_base) // This is needed to get to the sub-sequencers in the // m_sequencer virtual_sequencer v_sqr; // Local sub-sequencer handles bus_master_sequencer bus; gpio_sequencer gpio; function new(string name = "virtual_sequence_base"); super.new(name); endfunction // Assign pointers to the sub-sequences in the base body method: task body(); if(!$cast(v_sqr, m_sequencer)) begin `uvm_error(get_full_name(), "Virtual sequencer pointer cast failed"); end bus = v_sqr.bus; gpio = v_sqr.gpio; endtask: body endclass: virtual_sequence_base // Virtual sequence class: // class example_virtual_seq extends virtual_sequence_base; random_bus_seq bus_seq; random_gpio_chunk_seq gpio_seq; `uvm_object_utils(example_virtual_seq) function new(string name = "example_virtual_seq"); super.new(name); endfunction task body(); super.body; // Sets up the sub-sequencer pointers gpio_seq = random_gpio_chunk_seq::type_id::create("gpio_seq"); bus_seq = random_bus_seq::type_id::create("bus_seq"); repeat(20) begin bus_seq.start(bus); gpio_seq.start(gpio); end endtask: body endclass: example_virtual_seq // Inside the test class: // task run; example_virtual_sequence test_seq = example_virtual_sequencer::type_id::create("test_seq"); //... test_seq.start(m_env.m_v_sqr); //... endtask: run |
Chaining Virtual Sequencers for vertical reuse
При создании интегрированных сред проверки, которые повторно использовать envs уровня блока, виртуальные секвенсоры на различных уровнях испытательный стенд иерархии могут быть соединены вместе, позволяя виртуальным последовательности или суб-последовательности, которые будут работать на любом уровне. Чтобы достичь этого уровня гибкости, оба суб-секвенсор ручки и виртуальные секвенсор ручки должны быть обнесены на каждом последующем уровне.
// Virtual sequencer from the UART env class uart_env_virtual_sqr extends uvm_virtual_sequencer; // .. uart_sequencer uart; bus_sequencer bus; // .. endclass: uart_env_virtual_sqr // Virtual sequencer from the GPIO env class gpio_env_virtual_sqr extends uvm_virtual_sequencer; // .. gpio_sequencer gpio; bus_sequencer bus; // .. endclass: gpio_env_virtual_sqr // Virtual sequencer from the SoC env class soc_env_virtual_sqr extends uvm_virtual_sequencer; //.. // Low level sequencers to support virtual sequences running across // TB hierarchical boundaries uart_sequencer uart; bus_sequencer uart_bus; gpio_sequencer gpio; bus_sequencer gpio_bus; // Virtual sequencers to support existing virtual sequences // uart_env_virtual_sqr uart_v_sqr; gpio_env_virtual_sqr gpio_v_sqr; // Low level sequencer pointer assignment: // This has to be after connect because these connections are // one down in the hierarchy function void end_of_elaboration(); uart = uart_v_sqr.uart; uart_bus = uart_v_sqr.bus; gpio = gpio_v_sqr.gpio; gpio_bus = gpio_v_sqr.bus; endfunction: end_of_elaboration endclass: soc_env_virtual_sqr |
Coding Guideline: Virtual Sequences should check for null sequencer pointers before executing
Virtual sequence implementations are based on the assumption that they can run sequences on sub-sequencers within agents. However, agents may be passive or active depending on the configuration of the testbench. In order to prevent test cases crashing with null handle errors, virtual sequences should check that all of the sequencers that they intend to use have valid handles. If a null sequencer handle is detected, then they should bring the test case to an end with an uvm_report_fatal call.
// Either inside the virtual sequence base class or in // an extension of it that will use specific sequencers: task body(); if(!$cast(v_sqr, m_sequencer)) begin `uvm_error(get_full_name(), "Virtual sequencer pointer cast failed") end if(v_sqr.gpio == null) begin `uvm_fatal(get_full_name(), "GPIO sub-sequencer null pointer: this test case will fail, check config or virtual sequence") end else begin gpio = v_sqr.gpio; end if(v_sqr.gpio_bus == null) begin `uvm_fatal(get_full_name(), "BUS sub-sequencer null pointer: this test case will fail, check config or virtual sequence") end else begin gpio_bus = v_sqr.gpio_bus; end endtask: body |