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

Собиратель разбиратель сигналов в шины

Всем привет

 

В 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 есть какие то новые плюшки для работы с функциями. Кто знает, есть ли там возможность реализовать написанное выше? Или велосипед уже готов?

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


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

Хорошо было бы писать так:

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 параметров особо интересно получается, если они ещё разных типов, поскольку не все инструменты правильно воспринимают преобразование типа в фактических параметрах.

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


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

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;

 

 

 

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


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

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

вы ответили на вопрос как назначить record в record, что понятно.Но

а) Если уж говорить об использовании record'ов для межсоединений, то необходимо создавать часть интерфейса in, часть интерфейса out

б) Речь идет о назначении рекода в шину, а не в другой рекорд.

 

Timmy Если я правильно вас понял, то по объему кода и читаемости вложение функции в функцию будет сравнимо с пирамидой констант, как в примере выше.

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


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

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 написать, думаю, очевидно.

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


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

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

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

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

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

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

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

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

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

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