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

Давайте обговорим создание программируемого коммутатора на VHDL! :)

**мечтательно:

вот ежели использовать (рулить налету) трассировочные ресурсы самой FPGA... :rolleyes:

Кстати, это теоритически возможно - делается partition с коммутатором 64->64 (простыми соединениями), после чего оно загружается в partial reconfiguration mode. Проблема в том, что к софту, генерирующему таблицу коммутации придется привесить изрядный кусок ISE :wacko:

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


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

Кстати, это теоритически возможно - делается partition с коммутатором 64->64 (простыми соединениями), после чего оно загружается в partial reconfiguration mode. Проблема в том, что к софту, генерирующему таблицу коммутации придется привесить изрядный кусок ISE :wacko:

 

Не так все просто. Partial reconfiguration mode оперирует целыми колонками CLB, от низа кристала до его верха. Т.е. туда нужно будет помещать сразу множество коммутаторов.

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


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

Че то у меня не выходит каменный цветок... :crying:

 

Вот решил забабахать отдельный модуль и просимулировать его.

 

Есть 4-х портовый вход загрузки адреса коммутатора (K), есть последовательный вход загрузки данных в регистр (S_in). Надо за один такт переставить все значения в регистре на 16 по адресам в коммутаторе. Ну, задача такая уже обговаривалась выше. Есть и решение (см. выше). Однако, когда стал проводить симуляцию, то симулятор ругается оченно.... Вход unsigned ему не нравится...

Причем в Check Syntax ругался на to_integer, пришлось применить conv_integer.

Помогите разобраться плз. Че то с типами данных не сложилось....

 

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.Std_logic_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;


entity Mux16 is
    Port ( 
              K : in  unsigned (3 downto 0);
              clk : in  STD_LOGIC;
              rst : in STD_LOGIC;
              S_in : in unsigned;
              reg_out : out  unsigned (15 downto 0);
              start : in  STD_LOGIC;
              load : in  STD_LOGIC);
end Mux16;

architecture Behavioral of Mux16 is
   signal subst_store : unsigned (63 downto 0);
   signal reg : unsigned (15 downto 0);
   subtype tIndex is unsigned(3 downto 0);
   type tSUBST is array(15 downto 0) of tIndex;
   signal iSUBST   : tSUBST;
begin

process (clk)
variable i:integer;
begin

if rising_edge(CLK) then
  if rst='1' then 
    for i in 0 to 15 loop
            iSUBST(i) <= (others => '0');
        end loop;
  elsif (load='1' and start='0') then
    subst_store<=subst_store(59 downto 0) & K;
    reg<=reg(14 downto 0) & S_in;
  elsif (load='0' and start='0') then 
    for i in 15 downto 0 loop
         iSubst(i)<=subst_store(i*4+3 downto i*4);
    end loop; 
  elsif (load='0' and start='1') then
    for i in 15 downto 0 loop
        reg_out(i) <= reg(conv_integer(iSUBST(i)));
         end loop;
  elsif (load='1' and start='1') then
         reg_out <= reg;
  end if;  
end if;  


end process;

end Behavioral;

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


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

Если S_in - последовательный вход, то пусть он будет, например, std_logic. :)

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


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

В подробности не вдавался, но на первый взгляд проблема в conv_integer. Эта функция предназначена для работы с std_logic_vector. Для преобразования unsigned нужно использовать to_integer из пакета NUMERIC_STD.

 

Ну и конечно S_in должен быть std_logic.

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


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

Значится так-с....

Вот что сделал - и скомпилировалось!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.Std_logic_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity Mux2x32 is
    Port ( 
      K : in  std_logic_vector (3 downto 0);
      clk : in  STD_LOGIC;
      rst : in STD_LOGIC;
      S_in : in std_logic;
      reg_out : out  std_logic_vector (15 downto 0);
      start : in  STD_LOGIC;
      load : in  STD_LOGIC);
end Mux2x32;

architecture Behavioral of Mux2x32 is
   signal subst_store : std_logic_vector (63 downto 0);
   signal reg : std_logic_vector (15 downto 0);
   subtype tIndex is std_logic_vector (3 downto 0);
   type tSUBST is array(15 downto 0) of tIndex;
   signal iSUBST   : tSUBST;
begin

process (clk)
variable i:integer;
begin

if rising_edge(CLK) then
  if rst='1' then 
    for i in 0 to 15 loop
            iSUBST(i) <= (others => '0');
        end loop;
  elsif (load='1' and start='0') then
    subst_store<=subst_store(59 downto 0) & K;
    reg<=reg(14 downto 0) & S_in;
  elsif (load='0' and start='0') then 
    for i in 15 downto 0 loop
         iSubst(i)<=subst_store(i*4+3 downto i*4);
    end loop; 
  elsif (load='0' and start='1') then
    for i in 15 downto 0 loop
      reg_out(i) <= reg(conv_integer(iSUBST(i)));
        end loop;
  elsif (load='1' and start='1') then
         reg_out <= reg;
  end if;  
end if;  


end process;

end Behavioral;

 

Залез в Language Templates - там все есть....

 

Теперь другое...

В симмуляторе вроде подстановка работает, но как то своей жизнью...:)

Соотношение 1 и 0 не меняется, однако по какому алгоритму оно работает - загадка, по крайней мере для меня...:(

Щас попытаюсь скинуть бенчмарк, может получится...

 

Ну вот, например, после того, как load='1' начинается загрузка подстановки (К) и регистра (S_in), который должен менять свое содержимое по подстановке.

Смотрим, 12-я ячейка регистра = "1" (345 нс).

После прихода сигнала start="1" применяется подстановка.

Смотрим на коммутатор - 12-й ячейке соответствует подстановка в "7". Смотрим reg_out(7)-там тоже "1".

И т.д. Но вот 6-я ячейка регистра = "1" (645 нс). должна переходить в "4". Однако! reg_out(4)='0'! Ну и еще в некоторых местах... Подскажите, что не так!

 

Если подставляю подстановку, являющуюся счетчиком (адреса идут по порядку, один за другим), то все получается....

post-34329-1217187583_thumb.jpg

post-34329-1217190835_thumb.jpg

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


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

В процессе в одном блоке

if rising_edge(CLK) then
end if;

для всех подблоков if описывайте один и тот же сигнал или набор сигналов, иначе у Вас вместо триггеров получатся латчи. Если не получается, разделяйте описание на несколько блоков "if rising_edge(CLK) then".

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


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

В процессе в одном блоке
if rising_edge(CLK) then
end if;

для всех подблоков if описывайте один и тот же сигнал или набор сигналов, иначе у Вас вместо триггеров получатся латчи. Если не получается, разделяйте описание на несколько блоков "if rising_edge(CLK) then".

 

По-моему Вы ошибаетесь. Латчи получаются при описании, основанном на чувствительности по уровню, а не по фронту. Разница в этом, а не в наборе сигналов, которые указываются в "подблоках if".

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


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

Так к чему мы пришли? Есть какая-то бага? Мне одно не понятно- почему при одной подстановке - все хорошо, а при другой - сбой. Ведь кол-во 1 и 0 остается неизменным. Комбинаторика просто не работает....

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


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

makc, точно, я ошибся, латчи не причем... :) Просто в данном случае слишком уж все перемешано у автора в одном месте... имхо

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


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

Так к чему мы пришли? Есть какая-то бага? Мне одно не понятно- почему при одной подстановке - все хорошо, а при другой - сбой. Ведь кол-во 1 и 0 остается неизменным. Комбинаторика просто не работает....

 

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

 

 

 

makc, точно, я ошибся, латчи не причем... :) Просто в данном случае слишком уж все перемешано у автора в одном месте... имхо

 

Это еще не перемешано... Процесс помещается на один экран и условий всего-ничего. Подчас получается, что процесс размазан на пару-тройку экранов и условий в несколько раз больше, вот тогда немудрено запутаться.

Mux2x32.rar

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


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

makc, ну например, в представленном коде через elsifы есть довольно неочевидная завязка сигнала rst на разрешение выходного регистра. Не страшно, конечно, но все же... не знаю планировалось ли это, но вряд ли... И вообще, по-моему, даже для большого процесса неплохо разделять конструкции формирования сигналов(и ошибок меньше и читать проще).

Можно было бы написать почти то же, например, так:

process (clk, subst_store)
variable i:integer;
begin
    for i in 15 downto 0 loop
        iSubst(i) <= subst_store(i*4+3 downto i*4);
    end loop; 
    -- Load
    if rising_edge(CLK) then
        if rst='1' then 
            subst_store <= (others => '0');
        elsif (load='1' and start='0') then 
            for i in 15 downto 0 loop
                subst_store <= subst_store(59 downto 0) & K;
            end loop;
        end if;
    end if;
    if rising_edge(CLK) then
        if (load='1' and start='0') then 
            reg <= reg(14 downto 0) & S_in;
        end if;
    end if;
    -- Out
    if rising_edge(CLK) then
        if (load='0' and start='1') then
            for i in 15 downto 0 loop
                reg_out(i) <= reg(conv_integer(iSUBST(i)));
            end loop;
        elsif (load='1' and start='1') then
            reg_out <= reg;
        end if;
    end if;
end process;

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


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

makc, ну например, в представленном коде через elsifы есть довольно неочевидная завязка сигнала rst на разрешение выходного регистра. Не страшно, конечно, но все же... не знаю планировалось ли это, но вряд ли... И вообще, по-моему, даже для большого процесса неплохо разделять конструкции формирования сигналов(и ошибок меньше и читать проще).

 

Почему завязка сигнала rst не очевидна? По-моему, напротив, более чем очевидна, т.к. rst в этом случае имеет наивысший приоритет, как первое проверяемое условие при выполнении активной части процесса. Кроме того, чем это впринципе отличается от Вашего описания в части работы с subst_store? А вообще говоря, это дело вкуса. Но с моей личной точки зрения, не имеет смысла писать много раз одни и те же конструкции типа "if rising_edge(CLK) then" и "if rst='1' then", особенно если обрабатываемые сигналы логически связаны между собой. Этим достигается повышение связности описания, при условии правильного упорядочивания содержимого процесса.

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


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

По моему, мы уже углубились в филосовствование! :) Спасибо за оптимизацию кода - обязательно учту!

Но, как бы вопрос не снят с повестки дня. С бегущей единицей - все в порядке, у меня тоже получалось. А вот со случайным заполнением коммутатора - сразу не бьет результат с ожидаемым... Я тут посидел, поанализировал, получается, что все адреса идут задом наперед, допустим, если:

 

1 2 3 4 5 6 7 8

4 5 8 1 2 7 3 6

 

то в рез-те, почему то имеем:

1 - 6, 2-3, 3-7, 4-2, 5-1, 6-8, 7-5, 8-4

 

Менял порядок загрузки S_in, ставил reg_out(i) <= reg(conv_integer(iSUBST(15-i))); менял порядок загрузки К в subst_store = все пофигу. Рез-т не менялся... Может я неправильно симулирую...

Попробуйте Вы, может у Вас выйдет....

 

Пожалуйста, если получится с произвольным коммутатором - ответьте! Как исправить?

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


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

По моему, мы уже углубились в филосовствование! :) Спасибо за оптимизацию кода - обязательно учту!

Но, как бы вопрос не снят с повестки дня. С бегущей единицей - все в порядке, у меня тоже получалось. А вот со случайным заполнением коммутатора - сразу не бьет результат с ожидаемым... Я тут посидел, поанализировал, получается, что все адреса идут задом наперед, допустим, если:

 

1 2 3 4 5 6 7 8

4 5 8 1 2 7 3 6

 

то в рез-те, почему то имеем:

1 - 6, 2-3, 3-7, 4-2, 5-1, 6-8, 7-5, 8-4

 

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

 

Т.е. если брать подстановку 91E72A36048B5CDF и входное значение 1234 (hex), то результат получается 884С (hex). И действительно, посмотрев по разрядам: 15 разряд входа идет на 0 разряд выхода (0), 13 разряд входа идет на 1 разряд выхода (0), 12 разряд входа идет на 2 разряд выхода (1) и т.д. В чем проблема?

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


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

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

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

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

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

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

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

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

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

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