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

Как передать parameter в модуль через interface?

Что есть на данный момент:

interface    timer_interface
#(    parameter                        WDTH            =    1,
                                    COMPARE_NUM        =    1,
                                    CAPTURE_NUM        =    1    )
(    input    bit                clk,
    input    bit                nrst                            );

    typedef    struct    packed
    {
        bit        [COMPARE_NUM-1:0]    [WDTH-1:0]        inp;
        bit        [COMPARE_NUM-1:0]                    out;
    }    compare_t;

    typedef    struct    packed
    {
        bit        [CAPTURE_NUM-1:0]                    inp;
        bit        [CAPTURE_NUM-1:0]    [WDTH-1:0]        out;
    }    capture_t;

    bit                                            enable;
    bit                                            overflow;
    bit                            [WDTH-1:0]        period;
    bit                            [WDTH-1:0]        preset;
    bit                            [WDTH-1:0]        counter;
    compare_t                                    compare;
    capture_t                                    capture;

endinterface

 

 

module    test_timer();
...
    timer_interface
        #(    .WDTH(            COUNTER_WDTH        ),
            .COMPARE_NUM(    COMPARE_NUM            ),
            .CAPTURE_NUM(    CAPTURE_NUM            )    )
        timer_if
        (    .clk(            clk                    ),
            .nrst(            nrst                )    );

    Timer
        #(    .WDTH(            COUNTER_WDTH        ),
            .COMPARE_NUM(    COMPARE_NUM            ),
            .CAPTURE_NUM(    CAPTURE_NUM            )    )
        dut
        (    .timer_if(        timer_if            )    );
...
endmodule

 

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

module    test_timer();
...
    timer_interface
        #(    .WDTH(            COUNTER_WDTH        ),
            .COMPARE_NUM(    COMPARE_NUM            ),
            .CAPTURE_NUM(    CAPTURE_NUM            )    )
        timer_if
        (    .clk(            clk                    ),
            .nrst(            nrst                )    );

    Timer
        dut
        (    .timer_if(        timer_if            )    );
...
endmodule

 

 

P.S.

'define не предлагать. :)

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


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

Дополню. Вопросы возникают здесь, в нижнем по иерархии модуле:

module    Timer
#(    parameter                        WDTH            =    1,
                                    COMPARE_NUM        =    1,
                                    CAPTURE_NUM        =    1    )

(    timer_interface                    timer_if                );

    ////////////////////////////////////////////////////////////////////////////
    typedef    struct    packed
    {
        bit        [COMPARE_NUM-1:0]    [WDTH-1:0]        inp;
        bit        [COMPARE_NUM-1:0]                    out;
    }    compare_t;

    typedef    struct    packed
    {
        bit        [CAPTURE_NUM-1:0]                    inp;
        bit        [CAPTURE_NUM-1:0]    [1:0]            latch;
        bit        [CAPTURE_NUM-1:0]    [WDTH-1:0]        out;
    }    capture_t;

    ////////////////////////////////////////////////////////////////////////////
    bit                                            clk;
    bit                                            nrst;
    bit                                            enable;
    bit                                            counter_max;
    bit                                            overflow;
    bit                [WDTH-1:0]                    period;
    bit                [WDTH-1:0]                    preset;
    bit                [WDTH-1:0]                    counter;
    compare_t                                    compare;
    capture_t                                    capture;

...
endmodule

 

Например, как вытащить из interface параметр WDTH и применить в модуле Timer.

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


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

Например, как вытащить из interface параметр WDTH и применить в модуле Timer.

timer_if.WDTH не работает ?

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


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

timer_if.WDTH не работает ?

Тысяча благодарностей! :) Я же чуял, что есть простое и элегантное решение. Но почему-то сам не сообразил.

 

Моделсим проглотил, без вопросов. Осталось проверить в Квартусе.

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


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

Проверил в Квартусе:

localparam                    WDTH                =    timer_if.WDTH;

parameter                    WDTH                =    timer_if.WDTH;

typedef    struct    packed
{
    bit        [timer_if.COMPARE_NUM-1:0]    [timer_if.WDTH-1:0]        inp;
    bit        [timer_if.COMPARE_NUM-1:0]                            out;
}    compare_t;

 

Ошибка одна и та же:

Error (10742): Verilog HDL error at timer.sv(9): constant expression cannot contain a hierarchical identifier

 

Константное выражение не может содержать иерархическую "." Тот факт, что обращение тоже к константе, Квартус мало волнует. :(

 

Может будут еще идеи?

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


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

Квартус абсолютно прав.

Тот факт, что обращение тоже к константе, Квартус мало волнует. :(

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

Может будут еще идеи?

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

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


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

Хорошо бы освежить стандарт в памяти, прежде чем на него ссылаться. Да и в целом посмотреть, что происходит при elab, а что раньше. В симуляторе все отлично работает сквозь слои иерархии (см.). И defparam (квартус, кстати, когда-то поддерживал), и force, и получение значений объектов модуля минуя порты, иначе тестирование было бы крайне утомительным процессом с внесением изменений в rtl.

 

Его это и не должно волновать. Согласно стандарту, параметры вычисляются при связывании(elaboration) проекта, когда иерархии ещё не существует.

 

Доступ сквозь иерархию запрещен в синтезаторах, чтобы синтезируемый проект был "чистым", без "навесного монтажа".

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


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

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

Похоже, это то, что нужно. Судя по:

Packages

 

In Verilog 2001 and 1995, there was no way to share common code (task and function) across modules without using `include compiler directive. Packages provide ways to have common code to be shared across multiple modules. SystemVerilog provides package support to help share following:

- parameters

- data

- type

- task

- function

- sequence

- property

 

Остается главный вопрос, это синтезируется на данный момент? Не получится как с классами, которые Квартус [пока?] не умеет синтезировать?

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


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

Хорошо бы освежить стандарт в памяти, прежде чем на него ссылаться. Да и в целом посмотреть, что происходит при elab, а что раньше.

Спасибо, кэп.

В симуляторе все отлично работает сквозь слои иерархии (см.).

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

И defparam (квартус, кстати, когда-то поддерживал), и force, и получение значений объектов модуля минуя порты, иначе тестирование было бы крайне утомительным процессом с внесением изменений в rtl.

Смешались вместе кони, люди©. И да, "хорошо бы"© внимательно читать исходное сообщение, "прежде чем"© отвечать на него. Не благодарите.

Доступ сквозь иерархию запрещен в синтезаторах, чтобы синтезируемый проект был "чистым", без "навесного монтажа".

Не сочтите за придирку, но стандарта на синтез SV пока не существует. Внезапно, да?

 

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


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

То, что Вы не привели исходный код "всего отлично работающего сквозь слои иерархии" и не указали симулятор, это ведь недоразумение, правда?

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

 

Однако, предлагаю венуться к моим чаяниям. ;) С синтезом package проблем не должно быть?

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


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

Остается главный вопрос, это синтезируется на данный момент? Не получится как с классами, которые Квартус [пока?] не умеет синтезировать?

Как водится, нужно читать доки на синтезатор. Использую Precision, выводы примерно такие:

- parameters - нет проблем, если их типы - синтезируемые

- data - не синтезируются и правильно делают

- type - нет проблем, если они синтезируемые

- task - не знаю, не пробовал

- function - использовал только константные функции

- sequence - слаб в данном вопросе, но эта штука не для синтеза

- property - аналогично

 

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


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

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

Так ведь я не у Вас его просил. Кроме того, Ваш код не запустится, он не полный, а телепатировать я не умею :)

 

ЗЫ:Всё, я устал. Берём VCS. Вот код(cool.sv):

interface MyCoolInterface;
  parameter MyCoolParameter = 16;
endinterface: MyCoolInterface

module MyCoolModule();
  MyCoolInterface MCI();
  localparam MyCoolParameter = MCI.MyCoolParameter;
  typedef bit[MyCoolParameter-1:0] MyCoolType;
  initial $finish;
endmodule: MyCoolModule

Компилируем:

vlogan -full64 -nc -q -sverilog ./rtl/cool.sv

Получаем:

Error-[NCE] Non-constant expression
  The following expression should be a constant.
  Expression: MCI.MyCoolParameter
  "./rtl/cool.sv", 8
  Source info:   localparam MyCoolParameter = MCI.MyCoolParameter;

1 error

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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