Иерархический вызов задачи без определений

У меня есть модуль BFM, предоставленный поставщиком, созданный глубоко в моей иерархии; назовем путь top.dut.u1.u2.bfm1. API BFM немного архаичен и неудобен для наших нужд. Я хотел бы написать «объект» (класс? интерфейс? что-то еще?), который будет предоставлять задачи с более простым интерфейсом вызова и может вызывать задачи конкретного BFM, с которым он был «связан». Это "связь", которую я не могу понять.

У меня есть простая версия, определенная как модуль, который использует `define для указания пути к BFM, что-то вроде:

`define BFM top.dut.u1.u2.bfm1
module bfm_wrapper;
  ...
  task read_burst(...);
    ...
    `BFM.read_burst(...);
  endtask;
  ...
endmodule

Очевидно, что это не очень многоразовое использование. Как заменить `BFM чем-то более переносимым или абстрагированным на следующий более высокий уровень?

Я относительный новичок в SystemVerilog, и я еще даже не использую UVM, но я рискну, если есть что-то, что поможет. Любая помощь приветствуется.

[Обновление] Несколько ограничений, о которых я не упомянул:

  1. I can't change or replace the vendor-supplied BFM. I'd prefer to not even wrap it (i.e., instantiate it in my wrapper).
  2. For reasons that I don't want to go into here, the BFM needs to be instantiated inside the DUT. Changing that would require more effort than I can invest right now.

person Jabberwock    schedule 26.02.2016    source источник
comment
Я не уверен, что понимаю, как использовать bind в этой ситуации. Вы говорите привязать bfm_wrapper к области, в которой создается экземпляр BFM? Если да, то что мне поставить вместо `BFM в приведенном выше (псевдо)коде?   -  person Jabberwock    schedule 26.02.2016
comment
Ваша оболочка может bind перейти к u2 модулю или пути. В оболочке есть собственная задача read_burst, которая использует ссылку вверх по имени IEEE1800- 2012 §23.8. Сама оболочка может содержать код для связывания вашего вспомогательного кода с классами, виртуальными интерфейсами, uvm_config_db и т. д.   -  person Greg    schedule 27.02.2016
comment
Если я bind перейду на u2, я все еще не знаю, как сослаться на BFM. Чтобы оболочку можно было использовать повторно, я не могу предположить, что она называется bfm1. На самом деле я не хочу предполагать, что существует только один BFM (например, если u2 содержит две независимые шины). Или вы имели в виду привязку к bfm1? Я прочитаю ссылки и посмотрю, сработает ли это.   -  person Jabberwock    schedule 27.02.2016


Ответы (2)


Связывание вместе с абстрактными интерфейсами поможет вам подключиться к BFM. Взгляните на две мои статьи на DVCon.

http://www.doulos.com/downloads/events/DVCon_08_abstractBFM_final.pdf

http://events.dvcon.org/2012/proceedings/papers/01P_3.pdf

[ОБНОВИТЬ]

package bfm_pkg;
interface class bfm_api;
   pure virtual task read_burst(...);
endclass
endpackage

module bfm_wrapper;
 import bfm_pkg::*;
  ...
  class wrapper extends bfm_api;
  task read_burst(...);
    `BFM.read_burst(...);
  endtask;
  endclass
  wrapper h = new();
endmodule

Затем из ваших классов вы можете написать

import bfm_pkg;:*;
class someclass
  bfm_api h;
  task foo;
   ...
   h.read_burst(...);
  endtask
endclass

Теперь вам просто нужно получить дескриптор h в вашем bfm_wrapper для h внутри объекта foo. Если вы используете UVM, то здесь поможет uvm_config_db, в противном случае вам нужно будет создать собственный механизм для копирования дескриптора h.

person dave_59    schedule 27.02.2016
comment
Спасибо. Я все еще работаю над документами, но есть один вопрос (который теперь отражен в моем исходном посте): можно ли это сделать без изменения или перемещения исходного BFM? Если да, то я до сих пор не понимаю, как ссылаться на BFM из повторно используемой части кода. - person Jabberwock; 28.02.2016
comment
Извините, если я туплю, но в вашем коде выше все еще есть `BFM. Это та часть, от которой я пытаюсь избавиться. - person Jabberwock; 29.02.2016
comment
Если вы измените bfm to the name of the module that represents bfm1, then you bind`, bfm_wrapper в этот модуль. Допустим, модуль был vendor_bfm. Вызов vendor_bfm.read_burst() теперь является восходящей ссылкой. - person dave_59; 29.02.2016

Окончательный ответ (сначала предложенный @toolic и @Greg, позже @dave_59) состоит в том, чтобы использовать bind для динамического размещения оболочки, где BFM поставщика можно найти с «ссылкой вверх по имени» (в частности, поместив оболочку внутри поставщик БФМ). Итак, мой код выше будет выглядеть примерно так:

`define BFM top.dut.u1.u2.bfm1
module top;
  ...
  // Instantiate my wrapper code inside of the vendor's BFM
  bind `BFM bfm_wrapper my_bfm();

  // BFM commands go here
  initial begin
    wait (`BFM.reset === 0) @(posedge `BFM.clk);
    `BFM.my_bfm.my_read_burst(...);
    ...
  end
endmodule

module bfm_wrapper;
  ...
  task my_read_burst(...);
    ...
    read_burst(...);
  endtask;
  ...
endmodule

Мои извинения, если есть опечатки. Мой код не выглядел точно так же.

Обратите внимание, что я не полностью избавился от define. Для этого, вероятно, потребуются более элегантные методы из статей @dave_59. Но я, по крайней мере, убрал его из повторно используемой части кода, чего на данный момент достаточно.

person Jabberwock    schedule 29.02.2016