RobFPGA 27 16 декабря, 2020 Опубликовано 16 декабря, 2020 · Жалоба Приветствую Возник вот такой вопрос- Есть интерфейс с пучком сигналов которые для удобства определены как структура interface if_TEST #(ID_WH=3) ; typedef struct packed { u1_t [ID_WH-1:0] sig0; u1_t sig1; u7_t sig2; //... } st_TEST_t; st_TEST_t st; bit valid; bit ready; modport in (input st, valid, output ready); modport ou (output st, valid, input ready); endinterface и хочется мне в месте где такой интерфейс применяется получить актуальную ширину структуры в битах. Поскольку реальное значение будет зависит от параметра который меняется при инстанцировании интерфейса. Казалось бы что проще module test (if_TEST.in if_test, ...); localparam ST_WH = $bits(if_test.st); ... module top (...); if_TEST #(4) if_test (); test i_test(.if_test(if_test), ...); ... На что получаю в Modelsim (Intel start edition 2020.1/2020.3) маловразумительную ошибку - ** Error: (vsim-8894) In instance ".../i_test" parameter reference "if_test.st" through interface port "if_test" is not valid when the actual interface in the instance is an arrayed instance element or below a generate construct." Маловразумительную потому что этот интерфейс инстанцирован сам по себе - ни как array, ни из под generate. Самое прикольное что в Qu все синтезируется как надо, а в Modelsim такая вот засада. Вот и ломаю голову как сделать чтобы и в симе и в синтезе получать нужное заначене ширины. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 17 декабря, 2020 Опубликовано 17 декабря, 2020 · Жалоба Сам с таким напрямую не сталкивался, но товарищ мой на что-то подобное нарывался. И насколько помню, он придумал обходной финт (подробностей не помню, могу напутать, но вроде так): внутри интерфейса он завёл функцию, которую экспортировал (зачем-то это было нужно), и эта функция и возвращала ему размер. По коду получилось даже красивее - вроде инкапсуляции. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 17 декабря, 2020 Опубликовано 17 декабря, 2020 · Жалоба Приветствую! 8 hours ago, dxp said: Сам с таким напрямую не сталкивался, но товарищ мой на что-то подобное нарывался. И насколько помню, он придумал обходной финт (подробностей не помню, могу напутать, но вроде так): внутри интерфейса он завёл функцию, которую экспортировал (зачем-то это было нужно), и эта функция и возвращала ему размер. По коду получилось даже красивее - вроде инкапсуляции. :) Чем дальше в лес тем толще глюки ... Я тоже решил сначала, сделаю стандартно и красиво - через функцию interface if_TEST #(ID_WH=3) ; ... localparam ST_SIZE = $bits(st); function int st_size(); return $bits(st); endfunction function [$bits(st)-1:0] st_wh(); return 1'b1; endfunction modport in (input st, valid, output ready, import st_size, st_wh); modport ou (output st, valid, input ready, import st_size, st_wh); endinterface module test (if_TEST.in if_test, ...); localparam ST_WH = if_test.st_size(); Ms: Error: External function 'if_test.st_size' may not be used in a constant expression. Qu: Error, ST_WH==0 fifo i_fifo #(.WR_WH(if_test.st_size()), Ms: Error: External function 'if_test.st_size' may not be used in a constant expression. Qu: Error, ST_WH==0 ... Облом, Ms, ругается что мол функция для параметров должна быть константной, а внешняя функция из interface таковой может и не быть. Qu получает из функции фигу 0. ... через localparam в interface module test (if_TEST.in if_test, ...); localparam ST_WH = if_test.ST_SIZE; Ms: Ok. Qu: Error (10742): Verilog HDL error at ...: constant expression cannot contain a hierarchical identifier fifo i_fifo #(.WR_WH(if_test.ST_SIZE), Ms: Ok. Qu: Error (10742): Verilog HDL error at ...: constant expression cannot contain a hierarchical identifier ... Ms: Ok, Qu: Облом Дальше пошли хитрости и трюки - объявим функцию в interface и получим не ее значение, а формальную ширину выхода module test (if_TEST.in if_test, ...); localparam ST_WH = $bits(if_tx_frm.st_wh); fifo i_fifo #(.WR_WH(ST_WH)), ... Ms: Облом, получаемый размер структуры не соответствует реальному, а равен значение с параметром по умолчанию. В Qu все Ok!. Вытаскиваем из interface тип структуры, создаем локальную структуру с таким типом и от нее берем ширину. (Классический путь героя - в обход ) module test (if_TEST.in if_test, ...); typedef if_test.st_ST_t st_t; st_t st; localparam ST_WH = $bits(st); fifo i_fifo #(.WR_WH($bits(st)), .RD_WH(ST_WH), ... Но путь героя тернист - поскольку в Ms для RD_WH мы получаем одно значение ширины (неправильное, по умолчанию), а для WR_WH другое (правильное и актуальное)! То есть - localparam ST_WH = $bits(st); ST_WH != $bits(st); !!! Решил совместить два последних варианта в один, в interface будет функция возвращающая структуру ... function st_ST_t get_st(); return st; endfunction modport in (input st, valid, output ready, import get_st); ... а затем будем получать ширину значения возвращаемую этой функции module test (if_TEST.in if_test, ...); fifo i_fifo #(.WR_WH($bits(if_test.get_st)), .RD_WH($bits(if_test.get_st)), ... Как ни странно эта помесь удава с ежом работает, но только напрямую, без присвоения промежуточным localparam Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 18 декабря, 2020 Опубликовано 18 декабря, 2020 · Жалоба Как-то у вас всё сложно. Я спросил у товарища, он мне показал код. interface hash_pkt_pipeline_switch_fabric_i #( parameter type DATA_T = logic [7:0], parameter int STAGE_NUM = 2, parameter logic [1:STAGE_NUM] MUX_AUX_ENA = STAGE_NUM'('0), parameter logic [1:STAGE_NUM] MUX_MAIN_OUT_GET = STAGE_NUM'('0) ) ( ); ... function automatic int f_data_width(); return $bits(DATA_T); endfunction : f_data_width ... modport pipeline_port( //--- import function int f_data_width(), import function int f_stage_num(), import function MuxSelect_t f_mux_aux_ena(), //--- input mux_aux_in, output mux_main_in ); ... Использование: module ..._m #( parameter type DATA_T = logic [7:0], parameter int STAGE_NUM = 2 ) ( input logic clk, input logic rst, hash_pkt_pipeline_switch_fabric_i.pipeline_port switch_fabric, ... ... if(switch_fabric.f_data_width() != $bits(DATA_T)) begin ... Работает у него в квесте и виваде. Возможно тут проблема в том, что localparam в модуле вычисляется раньше, чем оживают объекты, к которым относятся и порты интерфейсов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 18 декабря, 2020 Опубликовано 18 декабря, 2020 · Жалоба Приветствую! 10 hours ago, dxp said: Работает у него в квесте и виваде. Спасибо вам и вашему товарищу! Увы, у меня другая комбинация проблем - Modelsim AE и Qu Standard. Qu к сожалению не поддерживает передачу type через parameter. К тому же как оказывается с точки зрения Ms это разные ситуации - когда тип структуры передан как параметр в interface или когда тип структуры определен внутри interface. В первом случае (в коде вашего товарища) действительно функцию можно использовать как константную, во втором (в моем) увы – Ms ругается на не-константность функции. Чертовщина однако какая-то 10 hours ago, dxp said: Возможно тут проблема в том, что localparam в модуле вычисляется раньше, чем оживают объекты, к которым относятся и порты интерфейсов. Это и понятно что есть какая-то гонка констант в процессе инициализации сима. Но я с таким еще не сталкивался. Правда давно было что то похожее, связанное с неопределенностью работы константной функций если она использует parameters напрямую в теле функций, а не через аргументы. Но чтобы вот так - присвоенное значения locаlparam было неравно тому что присваивали встретил в первый раз. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 33 20 декабря, 2020 Опубликовано 20 декабря, 2020 · Жалоба А почему бы решить задачу, вычисляя значение "снаружи" - т.е. без задействования внутренних структур, ведь исходные значения всех параметров известны, ну и просто тогда из них и вычислить (через функцию, например) искомое? Ну да, не особо красиво - работа в глобальном пространстве, но зато просто и переносимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 20 декабря, 2020 Опубликовано 20 декабря, 2020 · Жалоба Приветствую! 5 hours ago, dxp said: А почему бы решить задачу, вычисляя значение "снаружи" - т.е. без задействования внутренних структур, ведь исходные значения всех параметров известны, ну и просто тогда из них и вычислить (через функцию, например) искомое? Ну да, не особо красиво - работа в глобальном пространстве, но зато просто и переносимо. В том то и дело что размер не всегда известен. Размер части полей структур зависит от внешних параметров, которые задаются пользователем при инстанцирование модуля. К тому же таких разных интерфейсов нужно под три десятка и почти все они проходят через разного типа FIFO. Вот и возникла идея упростить жизнь себе ленивому выработав единый шаблон таких интерфейсов. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 июля, 2021 Опубликовано 5 июля, 2021 · Жалоба Приветствую! Вторая часть "марлезонского балета" Мигрирую проект из под Qu в Vivado (v2020.2). При синтезе опять получаю ошибки на знакомые места if_TEST_A #(.ID_WH(WH)) if_A_name (...); if_TEST_B #(.ID_WH(WH)) if_B_name (...); localparam ST_A_WH = $bits(if_A_name.st_TEST_t); localparam ST_B_WH = $bits(if_B_name.st_TEST_t); // $bits(if_B_name.st); Vv ругается что не может найти иерархический путь для if_B_name.st_TEST_t. Но странно что ругается только на строку с if_B_name (рельное имя изменено). И при этом нормально компилит предыдущую строку с if_A_name Причем в результате экспериментов видно что вот не нравится ему почему-то какая-то комбинация имени интерфейса, порядка определения интерфейса и еще чего то там, но из нескольких подобных определений констант все время ругается только на одну!!! Даже если переименовать определение интерфейса или имя инстанса. Если же этот localparam задать просто константой то все остальные подобные определения нормально синтезируются! Мистика какая-то Исследовав еще немного эти паранормальные явления нашел что работает вариант с прямым получением ширины через $bits() modue_name #( .A_WH($bits(if_A_name.st_ST_TEST_t)), .B_WH($bits(if_B_name.st)) ) ... А еще копнув узнал что если обернуть все в generate то предыдущий вариант тоже работает if_TEST_A #(.ID_WH(WH)) if_A_name (...); if_TEST_B #(.ID_WH(WH)) if_B_name (...); genarate localparam ST_A_WH = $bits(if_A_name.st); localparam ST_B_WH = $bits(if_B_name.st_TEST_t); modue_name #( .A_WH(ST_A_WH), .B_WH(ST_B_WH) ) ... ... endgenerate Теперь вот придется ломать голову как все же делать в рабочем проекте чтобы не поломалось если звезды не так сойдутся Ну или все переписывать для передачи типа структуры через parametr А это я еще в xsim не проверял .... Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба А вот с Vivado можно было бы и в Xilinx вопрос заслать - чего это он так вдруг? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться