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

Vivado BD как спрятать параметризируемые порты AXI

13 минут назад, andrew_b сказал:

Почему это? Все модули компилируются независимо друг от друга.

Там есть ключик для этого. Кажется, @des00 это и имел в виду - опция "-mfcu". В одном режиме оно компилируется как отдельные единицы компиляции (как в Си - в отдельные объектные файлы), а в другом - сразу скопом весь список за раз (и при этом там получается общее пространство объектов и макросов).

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


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

4 minutes ago, dxp said:

Там есть ключик для этого. Кажется, @des00 это и имел в виду - опция "-mfcu". В одном режиме оно компилируется как отдельные единицы компиляции (как в Си - в отдельные объектные файлы), а в другом - сразу скопом весь список за раз (и при этом там получается общее пространство объектов и макрсов).

Да, именно так. Если компилировать файлы по отдельности или потом в проекте поправить один файл при отладке и скомпилировать, квеста до 10.2с ругается на несовместимость структур. Но это в том случае, если они описаны как инклуд файлы, с пакетами не пробовал. 

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


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

Приветствую!

1 hour ago, dxp said:

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

Увы  массив разнотипных сущностей  в SV не создать (не только интерфейсов, а вообще) - ведь  SV  язык с жесткой типизацией. А инстансы интерфейсов одного типа, но с разными параметрами с точки зрения SV имеет разный тип:cray2: А иногда руки так и чешутся сделать что-то универсальное с подобием приведения типов в С/С++. Но увы. 

Ну а массивы  однотипных инстансов без проблем (надеюсь). Будь то переменные, интерфейсы или модули. 

Удачи! Rob.

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


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

12 минут назад, RobFPGA сказал:

или модули

Что и массив модулей можно создать? А как к ним порты цеплять - синтаксис объявления массива как-то не очень предполагает такие финты. Это, кстати, в полной мере относится и к интерфейсам - там-то тоже ведь сигналы можно передавать при объявлении.

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


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

Приветствую!

2 hours ago, dxp said:

Что и массив модулей можно создать? А как к ним порты цеплять

Можно :)   Да так же как и обычно  - главное чтобы ширина была правильной - при назначении порта разрядностью N идет  выборка очередных N bit из переменной. 

Spoiler

interface if_test #(DATA_WH=4) (input wire clk, rst);
  logic               ena ;
  logic [DATA_WH-1:0] data;
endinterface

(* keep_hierarchy="yes" *)
module prc_cnt #(WH=4) (
  if_test cnt_if[WH]
);

generate
  for (genvar gi=0; gi<WH; ++gi) begin : g_cnt
    always_ff @(posedge cnt_if[gi].clk) begin
      if (cnt_if[gi].rst) begin
        cnt_if[gi].data <= '0;
      end
      else if (cnt_if[gi].ena) begin
        cnt_if[gi].data <= cnt_if[gi].data + 1'b1;
      end
    end
  end
endgenerate
endmodule

(* keep_hierarchy="yes" *)
module test_inv #(parameter INV=1) (
  input  wire        clk,
  input  wire        rst,
  input  wire        in ,
  output logic [1:0] ou
);

assign ou[0] = (INV==1) ? ~in : in;

always_ff @(posedge clk) begin
  ou[1] <= rst ? '0 : ( (INV==1) ? ~in : in);
end
endmodule

(* keep_hierarchy="yes" *)
module test_if1 #(parameter
  CNT_NUM = 3,
  DATA_WH = 4
) (
  input  wire                             clk, // Clock
  input  wire                             rst, // Synchronous reset active hight
  input  wire  [CNT_NUM-1:0]              din,
  output logic [CNT_NUM-1:0][DATA_WH-1:0] dou
);

(* keep="true" *)
if_test #(DATA_WH) count_if [CNT_NUM] (clk, rst);

(* keep="true" *)
wire [2*CNT_NUM-1:0] w_din;

test_inv #(1) i_inv [CNT_NUM-1:0] (.clk(clk), .rst(rst), .in(din), .ou(w_din));

generate
  for (genvar gi=0; gi<CNT_NUM; ++gi) begin : g_io
    assign count_if[gi].ena = w_din[gi*2+0] & ~w_din[gi*2+1]; // din[gi];
    assign dou[gi] = count_if[gi].data;
  end
endgenerate

prc_cnt #(CNT_NUM) i_prc_cnt (count_if);

endmodule

 

Получается такая симпатичная картинка 

Удачи! Rob.

array_if_mod1.png

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


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

Приветствую!

Причем как оказалось можно и так 

...
//prc_cnt #(CNT_NUM) i_prc_cnt (count_if);
prc_cnt #(1) i_prc_cnt[CNT_NUM] (count_if);
...

Можно было и не делать отдельный модуль (test_inv) для примера :boast: Как говорится - найдите 3 отличия.

Удачи! Rob.

array_if_mod2.png

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


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

@RobFPGA как всегда убедителен. :wink2: Но всё равно что-то меня останавливает от использования массива интерфейсов в портах. :acute:

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


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

Параметризировать интерфейсы, конечно хорошая идея. Но по сути тут все прекрасно понимают, что эти танцы с бубном в основном будут использованы для AXI/Avalon. Отсюда у меня возник вопрос: а имеет смысл не возиться с n-количественными портами AXIа создать и подключить всё нужное через один? Сделать как-бы парсер в один порт, а уже играть с адресацией внутренних компонентов, зарделением работы во времени и т.д. А на выходе иметь уже нужные шины данных: РАМки, Регистры, периферию

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


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

Приветствую!

21 hours ago, dxp said:

что-то меня останавливает от использования массива интерфейсов в портах

Подумаешь - всего лишь массив интересов :wink:  - а как вам такое  :shok: 

//test_pq
 typedef struct packed {
    st_WDATA_t    wrd ;
    logic [15:12] sel ;
    logic [ 11:0] addr;
  } st_WBUS_t;

  typedef struct packed {
    st_WDATA_t  wrd   ;
    logic [3:0] addr_h;
    logic [3:0] addr_l;
  } st_A_t;

  typedef struct packed {
    st_WDATA_t  wrd   ;
    logic [3:0] addr_h;
    logic [5:0] addr_l;
  } st_B_t;
...
(* keep_hierarchy="yes" *)
module test_st #(parameter
  int  A_NUM  = 1                 ,
  int  B_NUM  = 2                 ,
  type T_IN   = test_pq::st_WBUS_t,
  type T_OU_A = test_pq::st_A_t   ,
  type T_OU_B = test_pq::st_B_t
) (
  input  wire   clk        ,
  input  wire   rst        ,
  input  T_IN   wbus       ,
  output T_OU_A ou_a[A_NUM],
  output T_OU_B ou_b[B_NUM]
);
...

 

1 hour ago, Nick_K said:

эти танцы с бубном в основном будут использованы для AXI/Avalon

Вопрос не в типе шины, а в попытке хитрым вывертом обойти  принципиальное ограничение V/SV  в невозможности параметрами контролировать число портов (и по возможности разного типа).

Удачи! Rob.

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


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

4 минуты назад, RobFPGA сказал:

Подумаешь - всего лишь массив интересов :wink:  - а как вам такое  :shok: 

Не уловил акцента. :unknw:

 

Кстати, я пробовал массив интерфейсов и наткнулся на то, что оно (в частности, квеста) не позволяет с ними работать банально в цикле - говорит, что неконстантный индекс не разрешается. Смотрю ваши примеры - там везде generate ... for. Это несколько иной контекст - тут просто каждый инстанс как бы канализируется (свои блоки создаются и т.д.). А когда просто внутри, например, always_ff в цикле пробежаться по массиву - фигвам. С массивами структур такой проблемы нет.

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


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

3 minutes ago, dxp said:

А когда просто внутри, например, always_ff в цикле пробежаться по массиву - фигвам.

Наверное это поведение перекочевало с VHDL. Там всё настолько типизированно, что к реальным нетам можно и нужно обращаться только в генерируемых структурах. А если и есть возможность "в цикле for...loop" то оно такого может насинтезить, что хоть стреляйся.

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


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

28 минут назад, Nick_K сказал:

Наверное это поведение перекочевало с VHDL.

Сомневаюсь. Циклы внутри блоков - обычное дело для верилогов, там по сути выполняется просто loop unrolling, т.е. цикл - просто способ компактно записать повторяющиеся действия. И прекрасно работает с массивами простых типов и даже структур. С массивом интерфейсов что-то не заладилось.

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


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

Приветствую!

23 minutes ago, dxp said:

Не уловил акцента. :unknw:

Массив портов типы которых задаются параметрами модуля. Прикольно, но и сомнительно с точки зрения полезности. 

33 minutes ago, dxp said:

А когда просто внутри, например, always_ff в цикле пробежаться по массиву - фигвам.

Печально, но это так.  И трудно понять почему же так :scratch_one-s_head:

Удачи! Rob.

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


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

On 9/6/2019 at 5:35 PM, dxp said:

 А когда просто внутри, например, always_ff в цикле пробежаться по массиву - фигвам. С массивами структур такой проблемы нет.

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

Работает ли это для синтеза, не проверял)

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


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

10 часов назад, des00 сказал:

Если для моделирования

Не, мне для синтеза.

 

Обнаружил такую неприятность. Есть простейшая структура:

typedef struct
{
  logic a;
  logic b;
}
slon_t;

Она передаётся в модуль как:

module ...
(
  ...
  output slot_t slon[N],
  ...
);
  

Далее есть примерно такой код:

always_ff @(posedge clk) begin
  ...
  for(int i = 0; i < N; ++i) begin
     slon[i].a <= ...
  end
end

...

always_comb begin
  for(int i = 0; i < N; ++i) begin
     slon[i].b = ...
  end
end  

  

Квеста 10.7с выдаёт ошибку, что де объект 'slon' используемый в одном процедурном блоке, используется в другом. Бред! Реально-то там же разные объекты в разных блоках задействуются, а структура - это просто агрегатный тип. Она же не пакованная.

 

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

 

В итоге обошёл так: завел просто местные массивы  и присвоил полям структуры в одном always_comb блоке в цикле:

logic [N-1:0] a;
logic [N-1:0] b;

always_comb begin
  for(int i = 0; i < N; ++i) begin
     slon[i].a = a[i];
     slon[i].b = b[i];
  end
end

А по коду уже работаю с 'a' и 'b'. Стало даже в чём-то удобнее - например, можно обнулить массив простым присваиванием 0 (со структурой приходилось цикл писать).

 

Единственное, гложет сомнение - может я всё-таки что-то делаю не так? Если да, поправьте.

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


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

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

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

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

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

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

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

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

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

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