OVM/OVM методология/Основы Testbench — различия между версиями
Vidokq (обсуждение | вклад) (→5.2 Введение в HFPB (Harry Foster peripheral bus)) |
Vidokq (обсуждение | вклад) (→5.2.1 HFPB Операция чтения) |
||
Строка 128: | Строка 128: | ||
===5.2.1 HFPB Операция чтения=== | ===5.2.1 HFPB Операция чтения=== | ||
+ | |||
+ | Рисунок 5-6 иллюстрирует HFPB операции чтения с участием устройства управления шиной и ведомым (нулем)(без ведомых). Так же, как и в операции записи, так как на первом такте сигналы выбора ведомого (SEL) и разрешения шины (EN) не установлены, наша шина находится в INACTIVE состоянии, как мы ранее определили в нашей концептуальной state-машине (см. рисунок 5-4). Временная диаграмма сигналов address, write, select, enable та же для операции чтения, как была и для операции записи. В случае чтения, ведомый должен поместить данные на шину для доступа ведущего во время ACTIVE цикла, который на Рисуноке 5-6 показан в третьем тактовом интервале. Как и операция записи, второй операции чтения следующей сразу за первой разрешается чтение от ранее выбранного ведомого устройства. Тем не менее, шина должен всегда возвращаться в START цикл после завершения каждого ACTIVE цикла. | ||
+ | |||
+ | ==5.3 RTL модель управляемой памяти== | ||
+ | |||
+ | Теперь, мы будем расширять на нашем уровне транзакций например пример с устройством управления и ведомым устройством, заменив уровень транзакции ведомого на драйвер и модель ведомого на уровне контактов. Мы также введем монитор. | ||
+ | |||
+ | [[Файл:sc_g_5.3_p1.png]] | ||
+ | |||
+ | Первое, что бросается в глаза нашем масштабном примере является то, что управление памятью, и управляемое устройство(память), и транспортный канал идентичен с таким же блокам из предыдущего примера. Это приложение повторного использования, применяя компоненты без изменений в различных ситуациях. Мы вставили драйвера и ведомое устройство уровня контактов. Мы также добавили монитор. Монитор является дополнением к драйверу, в то время, как роль драйвера заключается в преобразовании потока операций в переключения на шине, роль монитора - наблюдение за активностью на шине и преобразование этой активности в поток операций. Как и на уровне транзакций управляемой памяти, основной цикл драйвера - бесконечный цикла. Однако, так как драйвер управляет шиной, то его работа (обусловлена тактовым сигналом) происходит по тактовому сигналу. Структура драйвера может быть основана на кодировании конечного автомата с использованием функции case. | ||
+ | |||
+ | <source lang="verilog">forever begin | ||
+ | @(posedge m_bus_if.master.clk) // переключение по тактам | ||
+ | ... | ||
+ | case(m_state) // описание конечного автомата с использованием case | ||
+ | INACTIVE : begin | ||
+ | ... | ||
+ | end | ||
+ | START : begin | ||
+ | ... | ||
+ | end | ||
+ | ACTIVE : begin | ||
+ | ... | ||
+ | end | ||
+ | endcase | ||
+ | end // forever</source> |
Версия 01:47, 27 марта 2013
Содержание |
Основы Testbench
Чтобы ответить на вопросы does-it-work, мы должны провести разработку с известными входными воздействиями и определить, реагирует ли конструкция так, как задумано. То есть, мы должны контролировать и наблюдать за DUT.
5.1 драйвера и мониторы
Два из наиболее фундаментальных объектов в тестбенчах являются драйвера и мониторы. Драйвер преобразует поток операций в переключения на выводе на уровне интерфейса. Монитор делает обратное, он преобразует переключения на уровне контактного интерфейса в поток операций. Драйверы используются для управления DUT путем применения воздействий, а в мониторы используются для наблюдения за ответами. Чтобы понять, как создавать и использовать драйверы и мониторов, мы начнем пример с уровня транзакций, который иллюстрирует генератор воздействий (memory master) связанный с управляемой памятью. Управляемая память находится напротив драйвера. В то время как истинный драйвер имеет пин-уровень связи, управляемая память его не имеет. Чтобы управляемая память и драйверы были вместе, их интерфейсы обмена интерфейсов и их архитектуры тоже вместе (объединены). После построения понимания на уровне транзакций, например, мы будем расширять его использование на контактный уровень общения, обмена. В memory master генерирует поток запросов операций(транзакций) и отправляет их через транспортный канал в memory slave. Ведомый обрабатывает каждый запрос и формирует ответ, который он посылает обратно к ведущему через транспортный канал.
Во-первых, давайте посмотрим на канал связи из этого примера, то есть через что происходит соединения и передача потоков данных между компонентами. Транспортный канал состоит из двух противоположных FIFO, один для запросов и один для ответов и транспортного интерфейса. Memory master подключается к транспортному интерфейсу канала. Как вы, возможно, помните из раздела 3.4.3, транспортный интерфейс позволяет гарантировать memory master, что запросы и ответы будут синхронизированы. Ведомый интерфейс, как следует из названия, предназначена для устройств, которые должны отвечать на запросы, в то время, транспортный интерфейс для устройств, которые генерируют запросы.
Memory master использует свой порт для повторного вызова функции transport(), которая вызывает запрос на посылку запроса в FIFO транспортный канал. transport() также блокируется, пока ответ доступен. Ведомый вызывает функцию get(), которая извлекает запрос, затем обрабатывает его, генерирует ответ, и посылает ответ обратно в FIFO используя put(). Наконец, функция transport(), которая была в состоянии ожидания ответа, теперь может вернуть ответ memory master.
Основной цикл master'a содержит тесты самоконтроля. Это порождает ряд записей в памятью и сохранение тех, кто записывает ссылку в очередь. Затем происходит считывание из всех ячеек памяти только то, что было записано, и сравниваются каждое считанное значение с стоящими в очереди.
62 for(int i = 0; i < bursts; i++) begin 63 req = new(); 64 65 addr = $random & addr_mask; 66 size = ($random & ‘h1f) +1; // size > 0 && size <= 32 67 68 // write loop 69 for(j = 0; j < size; j++) begin 70 req.set_addr(addr); 71 data = $random & data_mask; 72 refq.push_back(data); 73 req.set_wdata(data); 74 req.set_write(); 75 req.set_slave_id(0); 76 transport_port.transport(req,rsp); 77 // ignore response 78 addr++; 79 #0; 80 end 81 82 // read loop 83 addr -= size; 84 for(j = 0; j < size; j++) begin 85 req.set_addr(addr); 86 req.set_wdata(0); 87 req.set_read(); 88 req.set_slave_id(0); 89 transport_port.transport(req,rsp); 90 data = rsp.get_rdata(); 91 refd = refq.pop_front(); 92 if(data != refd) begin 93 $sformat(s, “data mismatch: %x != %x”, 94 data, refd); 95 ovm_report_error(“compare”, s); 96 end 97 addr++; 98 #0; 99 end 100 end
Основной цикл состоит из двух под-циклов, цикл записи и чтения цикла. Цикл записи генерирует случайное число для операций записи. Для каждой записи, он генерирует случайное значение данных, которые хранятся как в очереди ссылок (refq) и помещает его в объект запроса. Transport() отправляет запрос в канал запросов и блокируется, пока ответ не доступен. Цикл чтения считывает те же адреса в том же порядке и сравнивает каждое считанное значение со значением в очереди ссылок. Если есть несоответствие, то подается сигнал об ошибке. Основной цикл из memory slave получает каждый запрос, декодирует его, обрабатывает его и выдает ответ.
50 forever begin 51 slave_port.get(req); 52 assert($cast(rsp, req.clone())); 53 54 addr = req.get_addr(); 55 if(req.is_read()) begin 56 data = m.read(addr); 57 rsp.set_rdata(data); 58 end 59 else begin 60 data = req.get_wdata(); 61 m.write(addr, data); 62 end 63 64 slave_port.put(rsp); 65 #1; 66 end 67 endtask
Обратите внимание, что ведомый использует бесконечный цикл, в то время, как мастер имеет ограниченный цикл. Ведомый не имеет возможности узнать наперед сколько запросов будет обрабатывать. Мастер - тот кто определяет, сколько запросов будет обработано. Чтобы отправить ответ, мы создаем объект ответа, сделав точную копию запроса с помощью функция clone(), а затем если нужно заменяем в ответе поля. Этот тип событий представляет собой ссылки, когда объекты запроса и ответа имеют одинаковые типы, как в данном случае. Простое представление приемник-передатчка как генератор воздействий и драйвер есть общая идиома для OVM testbenches. Самым простым решением является прямая подачи из генератора воздействий, который посылает операций для управления пакетами в драйвере. Более сложные механизмы включают такие вещи, как несколько последовательностей работающих параллельно через (обрабочик событий)sequencer драйвера. Во всех этих случаях идея та же: один или несколько элементов тестбенча порождают операций и, возможно, (имеют возможность) получить ответы из подключенных драйверов. Драйвер преобразует поток транзакций на уровень переключений на контактах.
5.2 Введение в HFPB (Harry Foster peripheral bus)
В этой и следующей главе нескольких главах, мы проиллюстрируем построение тестбенча с использованием простого, не конвейерного протокола шины, который называют протоколом HFPB. HFPB является аббревиатурой, что расшифровывается как Гарри Фостер периферийная шина, которая названа в честь Гарри Фостера, который первый предложил этот формат. Гарри черпал вдохновение для протокола из AMBA ARM-APB протокола. В таблице ниже приводится краткая информация о шине сигналы для нашего простого примера nonpipelined шины.
Name | Description |
---|---|
clk | All bus transfers occur on the rising edge of clk. |
rst | An active high bus reset. |
sel | These signals indicate that a slave has been selected. Each slave has its own select (for example, sel[0] for slave 0). However, for our simple example, we assume a single slave. |
en | Strobe for active phase of bus. |
write | When high, write access. When low, read access. |
addr[7:0] | Address bus. |
rdata[7:0] | Read data bus driven when write is low. |
wdata[7:0] | Write data bus driven when write is high. |
Эти сигналы связаны между ведущим и ведомым, как показано на следующем рисунке.
Протокол работает в трех состояниях, INACTIVE, START, ACTIVE. Отношения и переходы между состояниями показаны на рисунке 5-4.
После сброса (то есть, rst==1’b1), шина инициализирует по умолчанию INACTIVE состояние, а значит оба sel и en сняты. Чтобы начать передачу, SEL, выбирается один ведомый компонент. Шина остается в начальном состоянии START только в течение одного тактового цикла и будет переключаться ACTIVE состояние по следующему фронту тактового сигнала. ACTIVE состояние длится всего один такт для передачи данных. Затем шина перейдет обратно в начальное START состояние, если требуется еще одна передача, которая будет показана, когда сигнал выбора остается включенным. Однако, если не требуется еще одной посылки, шина возвращается в неактивное INACTIVE состояние, тогда мастер снимает сигнал выбора sel ведомого и включает сигнал активации шины (enable). Адрес ( addr[7:0]), контроль записи (write), и разрешение передачи (en) должны оставаться неизменными при переходе от START до ACTIVE состоянии. Однако, это не является обязательным требованием, то что эти сигналы должны оставаться неизменными при переходе от ACTIVE состояния назад к START состоянию.
5.2.1 HFPB Операция записи
Рисунок 5-5 иллюстрирует операцию записи для протокола шины HFPB с участием ведущей шины и одного ведомого устройства.
На первом такте, так как выбор ведомого (SEL) и разрешение шины (EN) сигналы не установлены, наша шина находится в INACTIVE состоянии, как мы ранее определен в нашей концептуальной машине состояния (см. Рисунок 5-4) и изображено на рисунке 5-5. Переменных состояния на рисунке 5-4 на самом деле является концептуальным изображением состояний шины, а не физической реализацией состояний в дизайне. Первое переключение вызывает START цикл, который инициирует ведущее устройство, включая одну из ведомых линий выбора(sel). Для нашего примера, мастер устанавливает SEL по переднему фронту на втором тактовом интервале. Во время START цикла, мастер посылает правильный адрес на шине и в следующем цикле ставит достоверных данные на шине. Эти данные будут записываться в выбранный ведомый компонент. Передача данных (называемый ACTIVE цикл) на самом деле происходит, когда ведущий устанавливает сигнал разрешения шины(en). В нашем случае его можно обнаружить на третьем тактовом интервале. Адреса, данные и сигналы управления все остается в силе на протяжении ACTIVE цикла. Когда ACTIVE цикл завершается, сигнал разрешения шины(EN) снимается управляющим шиной, и таким образом завершает один текущий цикл операции записи. Когда мастер закончит передачу всех данных в ведомое устройство, он снимет сигнал выбора ведомого устройства (например, SEL). В противном случае, сигнал выбора ведомого устройства остается включенным, и шина возвращается в START состояние цикла, чтобы начать другую операцию записи. Не является обязательным то, что бы значения адреса и данных были неизменны при переходе от ACTIVE цикла назад к START циклу.
5.2.1 HFPB Операция чтения
Рисунок 5-6 иллюстрирует HFPB операции чтения с участием устройства управления шиной и ведомым (нулем)(без ведомых). Так же, как и в операции записи, так как на первом такте сигналы выбора ведомого (SEL) и разрешения шины (EN) не установлены, наша шина находится в INACTIVE состоянии, как мы ранее определили в нашей концептуальной state-машине (см. рисунок 5-4). Временная диаграмма сигналов address, write, select, enable та же для операции чтения, как была и для операции записи. В случае чтения, ведомый должен поместить данные на шину для доступа ведущего во время ACTIVE цикла, который на Рисуноке 5-6 показан в третьем тактовом интервале. Как и операция записи, второй операции чтения следующей сразу за первой разрешается чтение от ранее выбранного ведомого устройства. Тем не менее, шина должен всегда возвращаться в START цикл после завершения каждого ACTIVE цикла.
5.3 RTL модель управляемой памяти
Теперь, мы будем расширять на нашем уровне транзакций например пример с устройством управления и ведомым устройством, заменив уровень транзакции ведомого на драйвер и модель ведомого на уровне контактов. Мы также введем монитор.
Первое, что бросается в глаза нашем масштабном примере является то, что управление памятью, и управляемое устройство(память), и транспортный канал идентичен с таким же блокам из предыдущего примера. Это приложение повторного использования, применяя компоненты без изменений в различных ситуациях. Мы вставили драйвера и ведомое устройство уровня контактов. Мы также добавили монитор. Монитор является дополнением к драйверу, в то время, как роль драйвера заключается в преобразовании потока операций в переключения на шине, роль монитора - наблюдение за активностью на шине и преобразование этой активности в поток операций. Как и на уровне транзакций управляемой памяти, основной цикл драйвера - бесконечный цикла. Однако, так как драйвер управляет шиной, то его работа (обусловлена тактовым сигналом) происходит по тактовому сигналу. Структура драйвера может быть основана на кодировании конечного автомата с использованием функции case.
forever begin @(posedge m_bus_if.master.clk) // переключение по тактам ... case(m_state) // описание конечного автомата с использованием case INACTIVE : begin ... end START : begin ... end ACTIVE : begin ... end endcase end // forever