Перейти к содержанию
    

Всем привет!

 

Может кто-то привести примеры реального использования клокинг блоков внутри интерфейса. Интересует именно использование входных выходных задержек.

Как драйверят сигналы со стороны тесбенча, и как эти сигналы подключатся ос стороны модуля.

 

Никак не могу понять выгоды от клокингблоков, все какое-то надуманное

 

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тут есть хорошие примеры по использованию clocking-блоков внутри интерфейсов. Лично мое мнение, что clocking-блоки удобны для моделирования времянки, т.к. задержки в случае необходимости нужно менять в одном месте. Но если смешивать clocking-событие с другими событиями, то могут возникнуть гонки сигналов. Я нашел одно решение по избеганию гонок - после другого события подождать 2 события clocking-блока прежде чем совершать операции чтения/записи с сигналами clocking-блока. Сейчас я не использую clocking-блоки, т.к. следить за другими событиями не удобно, а другого решения для устранения гонок я не нашел. Ну и вобщем-то без clocking-блоков можно легко обойтись

Изменено пользователем Fitc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Довольно узкая задача, но иногда возникает при разработке ASIC – экспресс моделирование нетлиста блока, подготавливаемого, например, как хардмакро, для интеграции в топологию более высокого уровня. С помощь CB очень удобно управлять временными разбежками между клоком и данными. Во всяком случае это намного проще, чем для каждого сигнала в отдельности внедрять линии задержки.

Некоторые сторонние модели, с которыми мы работали, имели особенности поведения при наличии гонок сигналов. Для них также наиболее простым способом было просто настроить задердку в CB.

В остальном при штатном цифровом моделировании (если нет необходимости явным образом играться с задержками клок - данные) кроме дополнительной инкапсуляции наверное бонусов особых нет, зато есть ряд дополнительных проблем при отладке агентов, поскольку сигнал интерфейса не равен сигналу внутри клокинг блока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понятно что и без них можно. Можно вообще без систем верилога.

 

Я себе это так видел. Есть у нас шина с времянкой и клоком. Пишем ее интерфейс, пишем внутри клок блоки, и пишем таски чтения и записи, и дальше можно спокойно вызывать просто таски из тестбенча не думаю над тем где граница клока, не указывая явно @(posedge ...) ни в тасках ни в тестбенче, а весь обмен сам по границе клока выйдет. Но что-то похоже фиаско, потому что реально все расползается, сигналы множатся и ездят. Бред какой-то, или я что-то не так делаю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

/* Тактовый генератор 250MHz */
  initial begin
    PLC_N = 1'b0;
    #2ns forever #2ns PLC_N = !PLC_N;
  end

/* Тактовый блок по умолчанию */
  default clocking cc @(posedge PLC_N);
  endclocking

Дальше использую только цифры. Равны периоду cc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это снаружи, а хочется внутри интерфейса. Хочется делать законченные объекты, которые все несут с собой.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В остальном при штатном цифровом моделировании (если нет необходимости явным образом играться с задержками клок - данные) кроме дополнительной инкапсуляции наверное бонусов особых нет, зато есть ряд дополнительных проблем при отладке агентов, поскольку сигнал интерфейса не равен сигналу внутри клокинг блока.

 

Была обратная проблема: агент неправильно воспринимал сигнал интерфейса без клокинг блока.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну видать там просто были не 0 выход и 1степ вход.

 

Но это все не приближает меня к разгадке:) как правильно и красиво клокинг блоки использовать в интерфейсах. Примерчик бы какой, где оно облегчает жизнь....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну видать там просто были не 0 выход и 1степ вход.

 

Но это все не приближает меня к разгадке:) как правильно и красиво клокинг блоки использовать в интерфейсах. Примерчик бы какой, где оно облегчает жизнь....

Не очень понятно, какой пример вам нужен. Такой пойдет? К сожалению не компилил, но суть я думаю понятна?

interface my_interface;
  
  bit clk, rst_n;
  
  logic full;
  logic empty;
  logic[7:0] data;
  
  logic wr_n;
  logic rd_n;
  
  clocking cb @(posedge clk);
    default input #2ns output #2ns; 
    
  input                      full;
  input                      empty;
  input   #3ns output        data;

  input        output  #4ns  wr_n;
  input        output  #3ns  rd_n;
  endclocking
  
  function void init_sigs();
    wr_n  = 1;
    rd_n  = 1;
  endfunction
  
  function bit is_empty();
    return (cb.empty == 1);
  endfunction

  function bit is_full();
    return (cb.full == 1);
  endfunction
  
  function void set_write(bit wr_enable);
    cb.wr_n  <=  !wr_enable;
  endfunction
  
  function void set_read(bit rd_enable);
    cb.rd_n  <=  !rd_enable;
  endfunction
  
  function void set_data(logic[7:0] a);
    cb.data <= a;
  endfunction
  
  task wait_clk(int n = 1);
    repeat(n) @cb;
  endtask
  
  task wait_reset_end();
    @(posedge rst_n);
    wait_clk();
  endtask
endinterface

module top;
  
  always mi.clk = #10 ~mi.clk;
  
  initial begin
    mi.rst_n = 0;
    #100;
    mi.rst_n = 1;
  end
  
  initial begin
    mi.init_sigs();
    mi.wait_reset_end();
    
    forever begin
      mi.wait_clk();
      mi.set_write(0);
      mi.set_read(0);
      
      if(!mi.is_full()) begin
        mi.set_write(1);
        mi.set_data($urandom_range(100));
        ...
      end
      else 
      ...
    end
  end
  
  my_interface mi();
  
  dut my_dut(mi.clk, mi.rst_n, ...);
endmodule

Изменено пользователем Fitc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Суть понятна, да.... Но смысл нет:)

 

Что вы получили дописав в этот интерфейс клокинг блок?

@(cb) вместо @(posedge clk)?

 

при этом wr_n и cb.wr_n сразу разлетелись, и прямое подключение в модуль грозит Больше бедами чем радостью. cb.wr_n нельзя будет воткнуть в модуль, будет ругань про неверное присвоение подклокового сигнала, а присоединить просто wr_n не будет изменять подклоковый cb.wr_n и вообще грозит развалом всей синхронизации...

 

То есть у меня основная претензия что cb.signal и signal - по сути это разные вещи получается... для выхода signal зависит от cb.signal, но наоборот нет. И вместо обещанного сокращения и упрощения, я получаю кучу оверкода и возможных проблем с синхронизацией. И в чем блин бизнес?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

------------------------------------------------------------------------

В общем на текущий момент у меня получается вот так

 

interface test_i(input clk);
    logic data;
    logic strb;
    
    clocking cb @(posedge clk);
        input #3 data;
        output #2 strb;
    endclocking
    
    initial begin
        data <= 0;
        cb.strb <= 0;
    end

endinterface


module tb;
....
reg clk = 0;
test_i ti(clk);
....

endmodule

 

 

поле data надо менять через ti.data = 1; или ti.cb.data <= 1; Читать его из cb.data, этот же порт присоединять к модулю. Это выравнивает данные по границе клока, при этом если они появляются мене чем за 3 нСек, их значение получиться на следующем такте. Тут все работает как хотелось.

 

С полем strb сложнее, менять его можно как ti.strb так и ti.cb.strb, при этом изменение через ti.cb.strb меняет и ti.strb, а наоборот нет. Смена через ti.cb.strb возможна только через <=, если надо его присоединить к порту модуля необходим колхоз с проводком на выход модуля и awlays @* с постоянным присвоением этого проводка через <= в ti.cb.strb. При этом always_comd тоже годиться, но выглядит крайне не логично.

 

Добавление модпортов тоже немного адски....

------------------------

 

блин адский ад, если сделать 2 клокинг блока, и в них один сигнал в обоих сделать аутом, то изменение в одном клокинг блоке не влияет на другой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Clocking blocks предназначены для сопряжения по феншую верификационной части с собственно испытуемым объектом (DUT). По феншую = чтобы при всех возможных design race conditions они корректно отрабатывались (в соответсвующих SystemVerilog event/timing regions).

 

Все хорошо описано в книге SystemVerilog for Verification, Chris Spear, Greg Tumbush, ISBN 978-1-4614-0714-0 (это для 3-го издания). Конкретно - глава Chapter 4 Connecting the Testbench and Design.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что вы получили дописав в этот интерфейс клокинг блок?

Я получил задержки установки сигналов относительно фронта и возможность считывания сигналов за определенное время до фронта.

 

@(cb) вместо @(posedge clk)?

@(cb) позволяет не писать явно фронт частоты, по которому я хочу выполнить действие.

Вне program-блока не стоит пытаться считывать значения переменных через clocking block (например, cb.data) после event control конструкции (например, @(posedge clk)) или другого события, отличного от @(cb), т.к. возникают гонки между старым значением переменной и новым. Об этом явно написано в стандарте 1800-2009 (под рисунком 14-1). Для меня это важно, т.к. я по множесту причин не использую блок program, а также это создает мне неудобство при взаимодействии sequence и драйвера в uvm, но это все решаемо путем слежения за другими событиями.

 

при этом wr_n и cb.wr_n сразу разлетелись, и прямое подключение в модуль грозит Больше бедами чем радостью. ..., а присоединить просто wr_n не будет изменять подклоковый cb.wr_n и вообще грозит развалом всей синхронизации...

Где пруфы? Всегда так делаю и все работает, благо в стандарте аналогичные примеры есть (см. подраздел 14.8).

 

И вместо обещанного сокращения и упрощения, я получаю кучу оверкода и возможных проблем с синхронизацией. И в чем блин бизнес?!

 

Не знаю, как у вас я использую подход, описанный в ссылке в моем первом посте, где вместо виртуальных интерфейсов используются классы, а функции и таски, в представленном мною примере в предыдущем посте, содержатся в классах и они хорошо инкапсулируют подробности реализации интерфейса, что хорошо сказывается на повторной используемости и мне неважно используется ли clocking блок при установке/чтении сигналов или нет, я просто вызываю методы. Никто вас не заставляет писать также. А плюсы в clocking блоке в том, что фронт частоты (posedge, negedge) и задержки задаются в одном месте, а дальше используется только событие clocking (например, @cb) и идентификаторы (например, cb.data).

 

поле data надо менять через ti.data = 1; или ti.cb.data <= 1; Читать его из cb.data, этот же порт присоединять к модулю. Это выравнивает данные по границе клока, при этом если они появляются мене чем за 3 нСек, их значение получиться на следующем такте. Тут все работает как хотелось.

 

С полем strb сложнее, менять его можно как ti.strb так и ti.cb.strb, при этом изменение через ti.cb.strb меняет и ti.strb, а наоборот нет. Смена через ti.cb.strb возможна только через <=, если надо его присоединить к порту модуля необходим колхоз с проводком на выход модуля и awlays @* с постоянным присвоением этого проводка через <= в ti.cb.strb. При этом always_comd тоже годиться, но выглядит крайне не логично.

 

Добавление модпортов тоже немного адски....

------------------------

 

блин адский ад, если сделать 2 клокинг блока, и в них один сигнал в обоих сделать аутом, то изменение в одном клокинг блоке не влияет на другой

А можете рассказать, что именно вы хотите написать и какой результат вам нужен?

 

Также не понятно, что вам мешает обращаться к сигналам только через clocking block

Изменено пользователем Fitc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Начну с конца.

Мне нравится при стимуляциях когда выходные сигналы появляются не по фронту клока, а чуть позже - это увеличивает читаемость. Плюс потенциальная возможность увеличить широту проверок вводя всякого рода задержки в шинах, например можно симулировать разбежку данных в шине при сопряжении частот.

Это можно делать руками и снаружи интерфейса, но мне кажется что именно для этого и сделан код блок, и хочется его загнать в интерфейс чтобы получить собранный реюзный кусок.

 

Так что в итоге это академическая задача образовательного толка, хочется понять как оно правильно используется, потому что реально все немного не очевидно.

 

По поводу ссылки, спасибо я прочел, тут у меня тоже есть уточняющий вопрос, здорово если вы ответите:

Я обычно интерфейсы с тасками работы пихал в параметризированные классы драйверов, мне казалось это удобнее, в одном месте объявляю экземпляр класса драйвера и интерфейс с одинаковыми параметрами.

Что дает предложенный подход? Как я понимаю он позволяет не передавать в класс параметры интерфейса не связанные с работой класса, то есть класс потенциально может иметь меньше параметров чем интерфейс.

Есть еще какие-то бонусы?

 

Еще важный вопрос, вы можете подключать к модулям сигналы cb.data, объявленные в клок блоке как output просто напрямую, типа my_module(.data(cb.data), ...)? Это точно?

Моя среда меня с этой идеей послала, сказала клоковый сигнал надо драйвить клоково. То есть подключение сигнала к порту среда воспринимает как assign, а для клокового оутпута

assign недопустим, приходиться делать wire подключенный к порту и дополнительный always @* в котором его пихать через <= в клоковый сигнал, тогда работает.

 

 

В целом на сегодня у меня практически сложилась картина, сейчас найду время проверить правильность понимания и может все будет хорошо.:)

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в интерфейсе

 

....
default clocking cb_env @(posedge clk);
    default input #1step output #2ns;
    output a;
    output b;
    output c;
    ...
endclocking 
.....

task set;
   ##0;
   a <= 1;
   ##1;
   b <= 1;
   ##1;
   c <= 1;
   ##2;
   a <= 0;
   b <= 0;
   c <= 0;
endtask

 

 

почему если вызывать таск с паузами кратными периоду клоку, время от времени сигналы начинаются подниматься по парно в одном такте (ab, bc)? ну что за!? что я не так то сделал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...