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

Документация на System Verilog

Вы и CaPpuCcino здесь из самых опытных и активных.

СкАжите тоже, просто чуть больше читаем/читали %)

 

Давайте разберемся по порядку. Начнем со static и в чем потенциальные сложности для синтеза. В SV квалификатор static описывает время жизни объекта. Для освежения памяти обратимся к стандарту IEEE 1800-2007 -> 6.6 Scope and lifetime.

Any data declared outside a module, interface, task, or function are global in scope (can be used anywhere after its declaration) and have a static lifetime (exist for the whole elaboration and simulation time).

SystemVerilog data declared inside a module or interface, but outside a task, process, or function, are localin scope and static in lifetime (exist for the lifetime of the module or interface). This is roughly equivalent to C static data declared outside a function, which is local to a file.

Data declared in an automatic task, function, or block have the lifetime of the call or activation and a local scope. This is roughly equivalent to a C automatic variable.

Data declared in a static task, function, or block default to a static lifetime and a local scope.

....

SystemVerilog also allows data to be explicitly declared as static. Data declared to be static in an automatic task, function, or block have a static lifetime and a scope local to the block. This is like C static data declared within a function.

...

It is permissible to hierarchically reference any static variable unless the variable is declared inside an unnamed block. This includes static variables declared inside automatic tasks and functions.

Теперь смотрите что происходит когда в интерфейсе есть статическая функция. Интерфейс объект статический, импортировать функции вы можете в любые объекты. Тогда что вам мешает через переменную в статической функции передать информацию из одного модуля в другой? Или разделить переменную между модулями? Ведь с точки зрения языка все верно. Но при синтезе возникает парадигма ХДЛ : модули могут обмениваться сигналами только через порты ввода/вывода. В случае использования интерфейса он рассматривается как веник проводов и обмен идет через него. Использование статических функций это потенциальная мина, так же как и использование глобальных сигналов в SV/VHDL, ИМХО поэтому возможность синтеза таких объектов и не рассматривается.

 

Теперь про SV объекты вида интерфейс.

Если рассматривать интерфейс как веник проводов, а массив интерфейсов как массив веников проводов, то никаких проблем синтеза нет, за исключением возможных багов синтезатора с его сборкой/разборкой. Но ИМХО как только вы пойдете дальше: импорт/экспорт функций, которые работают с сигналами интерфейса, выражения в модпортах, прототипы функций и т.д. В общем все то что дает синтезатору большую свободу чем "взять этот сигнал и подцепить его к этому" ждите сюрпризов. Я считаю что лучше я потрачу немного времени сейчас, чем потом потрачу много больше времени что бы выяснить что не так или почему при апдейте синтезатора все сломалось.

Кроме того, как уже говорил я достаточно критично отношусь к необходимости применения интерфейса, особенно при point-point соединениях. Вопросы увеличения скорости разработки я решил другими методами. В моих проекта в среднем ~20-30 портов на модуль, на его вставку/подключение у меня уходит не больше 5/30 секунд. Также мне иногда приходиться переводить свои модули по чистый V, при моем стиле описания на это тоже уходим мало времени %)

 

В общем решать вам. Свою точку зрения я озвучил.

 

Авторы утверждают (третья цитата), что когда не определен modport (т.е. не заданы направления) все nets становятся inout, а все var становятся ref.

Книгу эту читал давно, надо смотреть контекст. Но посмотрите шире на интерфейс. Ведь не обязательно использовать все сигналы интерфейса для интреконнекта. Например для отладки я делал интерфейс-память. Т.е. в интерфейсе была логика синхронной памяти (по некоторым источникам это даже синтезируемо). Думаю насчет ref авторы как раз и имели в виду использование переменных интерфейса, которые не используются для интерконнекта.

 

Но вы уверяете, что это не приведет к разным результатам pre- and post-syntethis, если правильно работать. Хорошо, буду внимательным :)

Когда я пишу я стараюсь четко понимать какой будет результат синтеза той или иной конструкции. Если мы расходимся во мнениях с синтезатором, то начинаю смотреть почему. ИМХО чем "прямолинейнее" написан код тем результат синтеза более однозначен.

 

У меня похожая ситуация, но ModelSim вместо Questa.

VCS – симулятор. Для моделирования Synopsys позиционирует Syphony HLS. Ни тот, ни другой не пробовал. Может у вас есть комментарий?

Что скажете о Synplify или Quartus сам по себе не хуже?

Моделсим сильно кастирован в области поддержки SV моделирования. По VCS это к SM и yes. Использовал симплифай когда сидел на хилых, но на альтере мне хватает ква. SV он понимает получше некоторых + удобно бегать по разным вьюверам. Правда у него иногда бывают такие заскоки в синтезе, что лечиться только макросом и вставкой примитива целевой FPGA %)

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


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

Ни капли не сомневаюсь что иногда интерфейсы полезны, но при их применении надо учитывать

 

1. переносимость. не все синтезаторы вас поймут.

Я про это тоже упомянул - переносимость есть проблема в настоящее время для синтеза.

 

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

Почему даст головную боль? Если можно вынести какие-то пучки логически связанные между собой в другое место, а в точке применения заменить это одной строкой - это достойная цель. Это уменьшает загроможденность кода, повышает читабельность. Конечно, ради трех-четырех сигналов так делать не стоит, но когда их набирается с десяток, уже можно подумать. Хотя я так не делаю - лень мне. :)

 

Те же задачи лучше решить структурами или массивами портов Ну и делать интерфейс для 3-4 проводов смысла нет.

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

 

Массив портов тоже проблемы не решает: массив - это всегда объект, содержащий объекты одинакового типа. А это далеко не все ситуации покрывает. Т.ч. эти средства - не альтернатива интерфейсам.

 

 

3. ограниченность. интерфейсы это не тип сигнала, а отдельный объект + они не наследуются.

А обычные порты наследуются, что-ли? :) Я бы не стал в данном контексте ненаследуюемость относить к недостаткам. Интерфейс решает несколько другие задачи.

 

 

Т.е. ситуаций, где интерфейсы реально помогают, а не делают вид что помогают достаточно мало.

Вот не согласен! Мой пример. Есть у меня, скажем, контроллер памяти (там арбитр, SDRAM контроллер и т.д.), к нему из модулей есть доступ из энного количества мест - порядка 8. И нужно организовать указанное количество "сосок" к памяти. С буферизацией и прочим хозяйством. Тащит это пачку сигналов для коннекта: стартовый адрес для обращения, количество слов для транзакции, порт данных, сигнал загрузки данных в буфер, флаги буфера (FIFO), направление записи и т.д. и т.п. И вот приходилось весь этот набор сигналов таскать в портах модулей. А уж с именам-то танцы были - сигналы-то все похожие, придумать нормальные имена, чтобы из них было легко видно, что за сигнал и к чему относится, сами знаете, плохо формализуемая задача. Короче, решил попробовать реализовать это на интерфейсах и не пожалел. Код интерфейса (это для записи, для чтения чуть отличается, парой сигналов):

 

interface wr_agent_if; 

   bit                      start;      // start write data from buffer to memory
   bit                      up;         // write direction
   bit                      load;       // load data to FIFO buffer enable signal
   bit  [ `ADDR_WIDTH-1:0]  start_addr; // start address to writing
   bit  [ `DATA_WIDTH-1:0]  data;       // 
   bit  [`COUNT_WIDTH-1:0]  count;      // number of words to write
   bit                      busy;       // busy flag, indicates that writing is in progress
   bit  [`COUNT_WIDTH-1:0]  fifo_cnt;   // number of word in FIFO
   bit                      full;       // FIFO full flag
   bit                      empty;      // fifo empte flag

   modport agent
   (
       output start,
       output up,
       output load,
       output start_addr,
       output count,
       output data,
       input  busy,
       input  fifo_cnt,
       input  full,
       input  empty
   );

   modport port
   (
       input  start,
       input  up,
       input  load,
       input  start_addr,
       input  count,
       input  data,
       output busy,
       output fifo_cnt,
       output full,
       output empty
   );

endinterface

 

А использование:

 

module ...
    ...
    wr_agent_if.agent           sdr_wr,
    wr_agent_if.agent           bf_wr,
    ...

 

В итоге, никакой путаницы, порты модуля все как на ладони, прежнее нагромождение десятков однотипных сигналов вспоминаю как страшный сон.

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


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

Почему даст головную боль? Если можно вынести какие-то пучки логически связанные между собой в другое место, а в точке применения заменить это одной строкой - это достойная цель. Это уменьшает загроможденность кода, повышает читабельность. Конечно, ради трех-четырех сигналов так делать не стоит, но когда их набирается с десяток, уже можно подумать. Хотя я так не делаю - лень мне. :)

Читайте внимательнее то что я писал. Например проект, 30 модулей, на эти модули пусть будет 15 уникальных интерфейсов. Дальше работу можете представить...

 

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

А кто ей запретит. Структура такой же тип данных как и все остальные типы. Да без направления, ну будет вместо одного интерфейса, две структуры. Как в VHDL.

 

А обычные порты наследуются, что-ли? :) Я бы не стал в данном контексте ненаследуюемость относить к недостаткам. Интерфейс решает несколько другие задачи.

если мне нужно расширить интерфейс модуля, то я вписываю именно то что мне надо в карту портов. А вот что вы будете делать если вам нужно к модулю с интерфейсом в 5 сигналов, добавить еще 5 сигналов из другого интерфейса? И опять все сведется к рукопашке.

 

Вот не согласен! Мой пример.

Да конечно, мы все делаем 8ми портовые контроллеры памяти в каждом проекте..... Читайте внимательнее, ваш случай как раз тот, когда интерфейс вам помог. Но можно легко и просто было сделать и без интерфейсов. Не понимаю ваши танцы с именами

 

//
// component is wishbone system bus based upon crossbar switch architecture for pM_N masters and pS_N slaves
//

`include "define.vh"

module wb_cross
#(
 parameter int              pM_N                      =  4 ,
 parameter int              pS_N                      =  4 ,
 parameter int              pA_W                      = 32 ,
 parameter int              pD_W                      = 32 ,
 parameter int              pSEL_W                    =  4 ,
`ifdef MODEL_TECH
 parameter bit [pA_W-1 : 0] pS_ADDR_BASE [0 : pS_N-1] = '{default : '0} ,
 parameter bit [pA_W-1 : 0] pS_ADDR_MASK [0 : pS_N-1] = '{default : '0} ,
 parameter bit [pM_N-1 : 0] pS_ACCESS_EN [0 : pS_N-1] = '{default : '1} ,
`else
 parameter bit [pA_W-1 : 0] pS_ADDR_BASE [0 : pS_N-1] = '{32'h0000_0000, 32'h4000_0000, 32'h8000_0000, 32'hC000_0000} ,
 parameter bit [pA_W-1 : 0] pS_ADDR_MASK [0 : pS_N-1] = '{32'h3FFF_FFFF, 32'h3FFF_FFFF, 32'h3FFF_FFFF, 32'h3FFF_FFFF} ,
 parameter bit [pM_N-1 : 0] pS_ACCESS_EN [0 : pS_N-1] = '{4'hF         , 4'hF         , 4'hF         , 4'hF         } ,
`endif
 parameter bit              pS_ADDR_ERR_DISABLE       =  0 , // disable slave address check logic
 parameter bit              pS_ACCESS_ERR_DISABLE     =  0 , // disable slave access  check logic
 parameter bit              pLOCK                     =  1
)
(
 wb_clk     ,
 wb_rst     ,
 wb_m_cyc_i ,
 wb_m_stb_i ,
 wb_m_we_i  ,
 wb_m_adr_i ,
 wb_m_dat_i ,
 wb_m_sel_i ,
 wb_m_ack_o ,
 wb_m_err_o ,
 wb_m_rty_o ,
 wb_m_dat_o ,
 wb_s_ack_i ,
 wb_s_err_i ,
 wb_s_rty_i ,
 wb_s_dat_i ,
 wb_s_cyc_o ,
 wb_s_stb_o ,
 wb_s_we_o  ,
 wb_s_adr_o ,
 wb_s_dat_o ,
 wb_s_sel_o
);

 

вот этот модуль я вставляю за 5 секунд, не путаюсь в именах и соединяю со схемой секунд за 30ть. %)

 

 parameter int              pM_N                      =  4 ;
 parameter int              pS_N                      =  4 ;
 parameter int              pA_W                      = 32 ;
 parameter int              pD_W                      = 32 ;
 parameter int              pSEL_W                    =  4 ;
 parameter bit [pA_W-1 : 0] pS_ADDR_BASE [0 : pS_N-1] = '{32'h0000_0000, 32'h4000_0000, 32'h8000_0000, 32'hC000_0000} ;
 parameter bit [pA_W-1 : 0] pS_ADDR_MASK [0 : pS_N-1] = '{32'h3FFF_FFFF, 32'h3FFF_FFFF, 32'h3FFF_FFFF, 32'h3FFF_FFFF} ;
 parameter bit [pM_N-1 : 0] pS_ACCESS_EN [0 : pS_N-1] = '{4'hF         , 4'hF         , 4'hF         , 4'hF         } ;
 parameter bit              pS_ADDR_ERR_DISABLE       =  0 ;
 parameter bit              pS_ACCESS_ERR_DISABLE     =  0 ;
 parameter bit              pLOCK                     =  1 ;



 logic                wb_cross__wb_clk                  ;
 logic                wb_cross__wb_rst                  ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_cyc_i              ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_stb_i              ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_we_i               ;
 logic   [pA_W-1 : 0] wb_cross__wb_m_adr_i [0 : pM_N-1] ;
 logic   [pD_W-1 : 0] wb_cross__wb_m_dat_i [0 : pM_N-1] ;
 logic [pSEL_W-1 : 0] wb_cross__wb_m_sel_i [0 : pM_N-1] ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_ack_o              ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_err_o              ;
 logic   [pM_N-1 : 0] wb_cross__wb_m_rty_o              ;
 logic   [pD_W-1 : 0] wb_cross__wb_m_dat_o [0 : pM_N-1] ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_ack_i              ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_err_i              ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_rty_i              ;
 logic   [pD_W-1 : 0] wb_cross__wb_s_dat_i [0 : pS_N-1] ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_cyc_o              ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_stb_o              ;
 logic   [pS_N-1 : 0] wb_cross__wb_s_we_o               ;
 logic   [pA_W-1 : 0] wb_cross__wb_s_adr_o [0 : pS_N-1] ;
 logic   [pD_W-1 : 0] wb_cross__wb_s_dat_o [0 : pS_N-1] ;
 logic [pSEL_W-1 : 0] wb_cross__wb_s_sel_o [0 : pS_N-1] ;

 assign wb_cross__wb_clk     = '0 ;
 assign wb_cross__wb_rst     = '0 ;
 assign wb_cross__wb_m_cyc_i = '0 ;
 assign wb_cross__wb_m_stb_i = '0 ;
 assign wb_cross__wb_m_we_i  = '0 ;
 assign wb_cross__wb_m_adr_i = '0 ;
 assign wb_cross__wb_m_dat_i = '0 ;
 assign wb_cross__wb_m_sel_i = '0 ;
 assign wb_cross__wb_s_ack_i = '0 ;
 assign wb_cross__wb_s_err_i = '0 ;
 assign wb_cross__wb_s_rty_i = '0 ;
 assign wb_cross__wb_s_dat_i = '0 ;

 

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

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


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

А кто ей запретит. Структура такой же тип данных как и все остальные типы. Да без направления, ну будет вместо одного интерфейса, две структуры. Как в VHDL.

И чем это лучше одного интерфейса? Точно так же надо описывать отдельно типы структуры, только придется держать в голове, что вот, де, эти две структуры - они логически связаны (части одного целого).

 

если мне нужно расширить интерфейс модуля, то я вписываю именно то что мне надо в карту портов. А вот что вы будете делать если вам нужно к модулю с интерфейсом в 5 сигналов, добавить еще 5 сигналов из другого интерфейса? И опять все сведется к рукопашке.

Не понял вопроса. И там и там придется руками добавлять.

 

 

Да конечно, мы все делаем 8ми портовые контроллеры памяти в каждом проекте..... Читайте внимательнее, ваш случай как раз тот, когда интерфейс вам помог. Но можно легко и просто было сделать и без интерфейсов. Не понимаю ваши танцы с именами

 

//
// component is wishbone system bus based upon crossbar switch architecture for pM_N masters and pS_N slaves
//

`include "define.vh"

module wb_cross
#(
 parameter int              pM_N                      =  4 ,

 

вот этот модуль я вставляю за 5 секунд, не путаюсь в именах и соединяю со схемой секунд за 30ть. %)

 

 parameter int              pM_N                      =  4 ;
 parameter int              pS_N                      =  4 ;

 

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

Читабельность я бы не похвалил - загромождение. Хотя о стилях спорить, вы правы - это путь к холивару. Не будем. :)

 

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

 

Кстати, поделитесь, пожалуйста, технологией применения скриптов? Откуда вы их запускаете - из шелла или прямо из слика?

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


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

И чем это лучше одного интерфейса? Точно так же надо описывать отдельно типы структуры, только придется держать в голове, что вот, де, эти две структуры - они логически связаны (части одного целого).

Тем что это тип данных, а не объект как интерфейс.

 

Не понял вопроса. И там и там придется руками добавлять.

Да так и есть. Но в моем случае я всего лишь расширил карту портов модуля, а вам придеться переделывать базовые интерфейсы. По идее ничего страшного, ну будут таскаться пути без фанаутов, но мой стиль явно описывать все порты модуля. Кроме того это все красиво в случае применения интерфейса для point-point соединения. Для двунаправленных mult-point, point-multi соединений вам все равно придеться ручками прописывать интерфейсы каждого модуля и их соединение друг с другом. Те же яйца только в профиль.

 

Читабельность я бы не похвалил - загромождение. Хотя о стилях спорить, вы правы - это путь к холивару. Не будем. :)

Это Copy-Past. Но я вообще их не читаю, т.к. знаю что скрипт работает без ошибок. Порой даже забываю как модули описываются %)

 

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

В том то и дело, что понятие эффективности и красивости кода несколько разные. ИМХО применение интерфейса не всегда оправдано.

 

Кстати, поделитесь, пожалуйста, технологией применения скриптов? Откуда вы их запускаете - из шелла или прямо из слика?

на праздниках напишу в блоге как я автоматизирую разработку. Там же выложу скрипт-генератор. %)

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


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

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

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

ЗЫ: кстати я не католик, да и в Питере я сейчас :)

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


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

Денис, благодарю за обстоятельный ответ и советы! И все же...

 

Тогда что вам мешает через переменную в статической функции передать информацию из одного модуля в другой? Или разделить переменную между модулями?

Для того, чтобы из одного модуля обратиться к переменной, объявленной в другом модуле (в том числе переменной в функции внутри этого модуля), потребуется иерархическая ссылка. Такая ссылка не синтезируемая, что ограничивает обмен информацией между модулями только через сигналы их портов. Получить синтезируемый вариант, указанных в цитате возможностей не удастся.

Модуль, импортирующий статическую функцию (или задачу) из интерфейса, получает собственную локальную копию этой функции. Функция будет в непосредственной области видимости только содержащего ее модуля. Если другой модуль импортирует из интерфейса ту же функцию, тогда для этого модуля будет сделана своя локальная копия этой же функции. Одно и тоже имя переменной функции в разных модулях это на самом деле две различные переменные. Реализовать обмен информации между модулями через переменную в импортируемой функции или сделать ее общей для нескольких модулей не удастся без привлечения иерархических ссылок. Ограничение синтеза последних является более общим правилом без привязки к импорту из интерфейсов.

Так вот, пока не вижу препятствий для синтеза статических функций импортированных в модули из интерфейса... Либо мои рассуждения не точны, либо есть неизвестная мне пока информация.

 

на праздниках напишу в блоге как я автоматизирую разработку. Там же выложу скрипт-генератор. %)

Можно адрес?

Где-то вы писали о своих открытых проектах. Было бы очень поучительно для меня

 

 

вы меня натолкнули на мысль...

рад, что хоть чем-то оказался полезным

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


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

Для того....

Реализовать обмен информации между модулями через переменную в импортируемой функции или сделать ее общей для нескольких модулей не удастся без привлечения иерархических ссылок.

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

 

Модуль, импортирующий статическую функцию (или задачу) из интерфейса, получает собственную локальную копию этой функции. Функция будет в непосредственной области видимости только содержащего ее модуля. Если другой модуль импортирует из интерфейса ту же функцию, тогда для этого модуля будет сделана своя локальная копия этой же функции. Одно и тоже имя переменной функции в разных модулях это на самом деле две различные переменные.

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

interface pipa;

 function static int get (int data);
   int tmp = 0;
   $display("enter %0t, state %0d, name %m", $time, tmp);
   tmp   = tmp + data * 3 ;
   $display("exit  %0t, state %0d, name %m", $time, tmp);
   return tmp;
 endfunction

 modport a (import get );
endinterface

module a_unit (input clk, pipa p, output int led1, led2);

 int cnt;

 always_ff @(posedge clk) begin : one
   cnt   <= cnt + 1'b1;

   led1  <= p.get(cnt);
   led2  <= p.get(cnt);
 end

endmodule


module top (input clk, output int led1, led2);

 pipa p ();

 a_unit a (clk, p.a, led1, led2);

endmodule


// synthesis translate_off
module tb ;

 bit clk;
 int led1, led2;

 top top (clk, led1, led2);

 initial begin : clk_gen
   clk <= 1'b0;
   #5ns forever #5ns clk = ~clk;
 end

endmodule
// synthesis translate_on

посмотрите на результат моделирования когда функция static, а потом когда automatic. Если не сможете объяснить разницу в результатах моделирования, спрашивайте обсудим. Из разницы результатов моделирования и следует объяснение авторов данное в книге

An automatic task or function allocates new storage each time it is called. When a module calls an imported task or function, a new copy is allocated. This allows synthesis to treat the task or function as if were a local copy within the module.

Хотя, если отдавать себе отчет в том что делаете, я бы заменил в предупреждении авторов must на should %)

 

Можно адрес?

Где-то вы писали о своих открытых проектах. Было бы очень поучительно для меня

Мои и не только блоги про разные аспекты разработки. Блог про мой подход к автоматизации разработки пока еще не писал. Открытый проект. Ну и часть проектов по форуму разбросана %)

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


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

Вот вам пример почему статик не всегда добро

Пример написан настолько прозрачно, с точки зрения цели его создания, что первое прочтение и ожидаемое поведение полностью совпали с результатами моделирования для обоих вариантов: static and automatic.

В попытке найти ответ на свой исходный вопрос о поведении импортированных из интерфейса статических функций в модули, дополнил ваш пример еще одним экземпляром модуля a_unit установленным в модуль top.

 

interface pipa;

 function static int get (int data);
int tmp = 0;
$display("enter %0t, state %0d, name %m", $time, tmp);
tmp   = tmp + data * 3;
$display("exit  %0t, state %0d, name %m", $time, tmp);
return tmp;
 endfunction

 modport a (import get );

endinterface

module a_unit (input clk, pipa p, output int led1, led2);

 int cnt;

 always_ff @(posedge clk) begin : one
cnt   <= cnt + 1'b1;

led1  <= p.get(cnt);
led2  <= p.get(cnt);
 end

endmodule

module top (input clk, output int led1, led2, led3, led4);

 pipa p ();

 a_unit a (clk, p.a, led1, led2);
 a_unit b (clk, p.a, led3, led4);

endmodule


// synthesis translate_off
module tb;

 bit clk;
 int led1, led2, led3, led4;

 top top (clk, led1, led2, led3, led4);

 initial begin : clk_gen
clk <= 1'b0;
#5ns forever #5ns clk = ~clk;
 end

endmodule
// synthesis translate_on

Если функция get объявлена с automatic – все выходные порты: led1 – led4 имеют одинаковые и независимые друг от друга значения, что является ожидаемым результатом.

Если функция get объявлена с static – led2 вычисляется с учетом текущего значения led1 (согласен), при этом led3 вычисляется с учетом текущего значения led2 (удивлен), а led4 - с учетом текущего значения led3.

Я ожидал, что поскольку led1 и led2 вычисляются в одном экземпляре модуля, а led3 и led4 – в другом, то led1 будет тождественным led3, а led2 - led4. Этого можно добиться в такой редакции

 

...
module top (input clk, output int led1, led2, led3, led4);

  pipa p (), q ();

  a_unit a (clk, p.a, led1, led2);
  a_unit b (clk, q.a, led3, led4);
  
endmodule
...

Но это уже другая история.

Возвращаясь к примеру с двумя экземплярами модуля и одним экземпляром интерфейса, напрашивается вывод: статические функции, объявленные в интерфейсе и импортируемые в модули не имеют своих собственных локальных копий в модулях. Во всяком случае, это справедливо по отношению к ModelSim SE PLUS 6.5 Rev. 2009.01.

 

Синтезировал этот пример в Quartus 9.0 SP1. Пришлось убрать, во-первых, modport из интерфейса и, во-вторых, static из объявления функции по причине отсутствия поддержи. Без явного указания времени жизни функция предполагается статической (проверил это в ModelSim). Результат получился аналогичным, как при моделировании с автоматической функцией get.

Вспоминаются слова Нильса Бора о том, что понять – значит привыкнуть и пользоваться.

 

Денис, спасибо за время и внимание, которые вы мне уделили.

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


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

Денис, спасибо за время и внимание, которые вы мне уделили.

Вам спасибо, а то уже стал забывать основы, все ДСП, да ДСП %)

 

 

IEEE Std. 1800™-2009 (SystemVerilog) Ready for Purchase & Download

добрые люди залейте в закрома %)

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


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

IEEE Std. 1800™-2009 (SystemVerilog) Ready for Purchase & Download

добрые люди залейте в закрома %)

Можно и внешнюю ссылку оставить, не свои будут благодарны...

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


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

IEEE Std. 1800™-2009 (SystemVerilog) Ready for Purchase & Download

добрые люди залейте в закрома %)

 

 

uploads/DOCs/SystemVerilog/05354441.pdf

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


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

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

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

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

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

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

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

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

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

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