Muscat 0 13 февраля, 2013 Опубликовано 13 февраля, 2013 · Жалоба Всем привет В VHDL бывают ситуациями, когда надо собрать несколько разных шин в одну большую, проделать какую то операцию (например посчитать CRC , передать в память, протолкнуть в другой компонент), после чего снова собрать. Часто это приходится делать руками, например constant w1: integer:=5; constant w2: integer:=8; constant w3: integer:=2; signal i_sig1: std_logic_vector (w1-1 downto 0); signal i_sig2: std_logic_vector (w2-1 downto w1); signal i_sig3: std_logic_vector (w3-1 downto w); signal bus1: std_logic_vector (w3+w2+w1-1 downto 0); --Собиратель bus1<=( i_sig3 & i_sig2 & i_sig1); --Разбиратель o_sig1<=bus1(w1-1 downto 0); o_sig2<=bus1(w1+w2-1 downto w1); o_sig2<=bus1(w1+w2+w3-1 downto w1+w2); Основная проблема конечно в разбирателе. Когда переменных много, то приходится вводить промежуточные константы (w2_lim=w1+w2), а когда надо собрать 8 шин получается совсем уж страшные пирамиды. Если работа идет с заранее заданной структурой record, то там можно написать 2 метода "собрать-разобрать" для данной ситуации, но хочется иметь универсальный инструмент, чтобы работали это следующим образом --Функция взятия ширины constant bus_width:intger:= fget_width(sig1,sig2,sig3); bus1: std_logic_vector (bus_width-1 downto 0); --Собиратель bus1<=fbunch(i_sig1,i_sig2,i_sig3); --Разбиратель fslit(bus1,o_sig1,o_sig2,o_sig3); Ну и совсем уж имперский комфорт, это формировать лист указателей list1:=(sig1,sig2,sig3), после чего во все места передавать именно этот лист в качестве аргумента. Какие пути я пока вижу 1) Писать функцию. Возможно ли в VHDL написать функцию с переменным числом параметров? Есть ли примеры? 2) Если нельзя, то использовать возможность перегрузки. При использовании циклов можно быстро написать 20 функций, принимающих от 1 до 20 сигналов на вход с одинаковым именем. В зависимости от количества переменных будет вызывать соответствующая. Вроде тупой подход, но зато точно позволит достичь результата за разумное время. 3) Городить структуры типа record, куда затакливать sig1,sig2, но это все снова универсально 4) В VHDL 2008 есть какие то новые плюшки для работы с функциями. Кто знает, есть ли там возможность реализовать написанное выше? Или велосипед уже готов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 14 февраля, 2013 Опубликовано 14 февраля, 2013 · Жалоба Хорошо было бы писать так: function fsplit(di:std_logic_vector, do:out std_logic_vector) return std_logic_vector is begin do := di(di'high downto di'high-do'length+1); return di(di'high - do'length downto di'low); end function; и вкладывать друг в друга такие функции, сколько нужно. Вот только сделать out параметр в функции нельзя, только в процедуре. Я сделал несколько стандартных процедур разбирателей для двух и трёх сигналов, больше обычно не требуется:). Лучше было бы использовать & в левой части присваивания, но древняя религия не позволяет. В случае 20 параметров особо интересно получается, если они ещё разных типов, поскольку не все инструменты правильно воспринимают преобразование типа в фактических параметрах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 5 15 февраля, 2013 Опубликовано 15 февраля, 2013 · Жалоба VHDL позволяет создать тип сигнала RECORD - то есть шину с именоваными сигналами type ahb_slv_out_type is record hready : std_ulogic; -- transfer done hresp : std_logic_vector(1 downto 0); -- response type hrdata : std_logic_vector(AHBDW-1 downto 0); -- read data bus hsplit : std_logic_vector(15 downto 0); -- split completion hcache : std_ulogic; -- cacheable hirq : std_logic_vector(NAHBIRQ-1 downto 0); -- interrupt bus hconfig : ahb_config_type; -- memory access reg. hindex : integer range 0 to NAHBSLV-1; -- diagnostic use only end record; потом объявляем in, out или сигнал такого типа и доступ через . ahbso : out ahb_slv_out_type; ------------- ahbso.hirq <= irqvec; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muscat 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба yes, в заглавном посте особо оговоренно, что речь идет не о постоянных структуах record, а необходимости собирать в шины разные сигналы. вы ответили на вопрос как назначить record в record, что понятно.Но а) Если уж говорить об использовании record'ов для межсоединений, то необходимо создавать часть интерфейса in, часть интерфейса out б) Речь идет о назначении рекода в шину, а не в другой рекорд. Timmy Если я правильно вас понял, то по объему кода и читаемости вложение функции в функцию будет сравнимо с пирамидой констант, как в примере выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 19 февраля, 2013 Опубликовано 19 февраля, 2013 · Жалоба Timmy Если я правильно вас понял, то по объему кода и читаемости вложение функции в функцию будет сравнимо с пирамидой констант, как в примере выше. С функцией было бы вот так: sig4 <= fsplit(sig3, fsplit(sig2, fsplit(sig1, bus))); ИМХО, гораздо лучше любого другого варианта, но, к сожалению, нереализуемо. Реализуемо с процедурой и переменной смещения: i:=bus'low; fsplit(sig1,i,bus); fsplit(sig2,i,bus); fsplit(sig3,i,bus); fsplit(sig4,i,bus); Что внутри fsplit написать, думаю, очевидно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться