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

Сравнить два массива

есть список команд и команда полученная по UART

type commands is array(0 to COM_SIZE) of std_logic_vector(7 downto 0);

signal commands_list : commands(0 to COM_COUNT) := 
(
    x"73746F700000", --stop
    x"667764000000", --fwd
    x"726576000000"  --rev
);

type com_str is array (0 to 31) of std_logic_vector(7 downto 0);
type arg_str is array (0 to 9) of std_logic_vector(7 downto 0);

type com is
record
      name : com_str;
      arg1 : arg_str;
      arg2 : arg_str;
      arg3 : arg_str;
      name_len : integer;
end record;
        
signal command : com;

 

Сравниваю весь массив

for i in 0 to COM_COUNT loop  
    if (commands_list(i) /=  command.name) then
     end if;  
end loop;

И побайтово

for i in 0 to COM_COUNT loop
    for j in 0 to command.name_len loop    
    if (commands_list(i)(j) /=  command.name(j)) then
     end if;
    end loop;      
end loop;

В обоих случаях получаю ошибку

Error (10327): VHDL error at parser.vhd(253): can't determine definition of operator ""/="" -- found 0 possible definitions

 

Не могу сообразить в чем подвох.

Изменено пользователем Jenya7

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


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

Как только вы пишете слово type, вы вводите абсолютно новый тип, для которого не определена ни одна операция. Вы сами для нового типа должны написать функции сравнения.

 

Даже если два типа определены абсолютно одинаково (например, std_ulogic_vector, signed, unsigned), это разные типы, и напрямую объекты этих типов между собой сравнивать нельзя.

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


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

А мне кажется, тут еще в самом начале с типами ошибка. И должно быть что-то типа такого:

 

    type commands is array(5 downto 0) of std_logic_vector(7 downto 0);
    type commands_l is array(natural range <>) of commands;

    signal commands_list : commands_l(2 downto 0) := (
    0 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --stop
    1 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --fwd
    2 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21")  --rev
    );

 

В этом случае побайтовое сравнение должно пройти, т.к. сравниваются элементы уже известных типов, а не собственных.

Изменено пользователем Tausinov

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


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

Как только вы пишете слово type, вы вводите абсолютно новый тип, для которого не определена ни одна операция. Вы сами для нового типа должны написать функции сравнения.

 

Даже если два типа определены абсолютно одинаково (например, std_ulogic_vector, signed, unsigned), это разные типы, и напрямую объекты этих типов между собой сравнивать нельзя.

понял. не знал. но record всегда создается через type. я не могу создать record так

record com is

name : com_str;

arg1 : arg_str;

arg2 : arg_str;

arg3 : arg_str;

name_len : integer;

end record;

 

а как тогда написать функцию сравнения? В С# был operator override, тут наверно что то похожее.

 

А мне кажется, тут еще в самом начале с типами ошибка. И должно быть что-то типа такого:

 

    type commands is array(5 downto 0) of std_logic_vector(7 downto 0);
    type commands_l is array(natural range <>) of commands;

    signal commands_list : commands_l(2 downto 0) := (
    0 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --stop
    1 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --fwd
    2 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21")  --rev
    );

так компайлер ругается

Error (10515): VHDL type mismatch error at parser.vhd(71): std_ulogic type does not match string literal

Изменено пользователем Jenya7

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


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

так компайлер ругается

Error (10515): VHDL type mismatch error at parser.vhd(71): std_ulogic type does not match string literal

 

А что в 71 строке? Скиньте лучше файл, если там никаких секретов нет) Так проще будет.

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


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

Как видится мне, у вас принципиальная ошибка в типах.

 

commands_list у вас получился массивом 8-битных векторов. Соответственно commands_list(i) - восьмибитный вектор, который вы сравниваете с массивом векторов command.name.

То же самое со вторым примером, где вы вытаетесь сравнить бит commands_list(i)(j) с восьмибитным вектором command.name(j).

Чтобы все заработало вам надо объявить новый тип. Ну и commands_list, наверно, по смыслу должен быть константой.

type t_commands_list is array(natural range <>) of commands;

constant commands_list : t_commands_list (0 to COM_COUNT):=
(
   x"73746F700000", --stop
   x"667764000000", --fwd
   x"726576000000"  --rev
);

 

 

В принципе выше то же самое написали. И да, лучше код целиком кидайте.

Изменено пользователем KalashKS

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


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

Как видится мне, у вас принципиальная ошибка в типах.

 

commands_list у вас получился массивом 8-битных векторов. Соответственно commands_list(i) - восьмибитный вектор, который вы сравниваете с массивом векторов command.name.

То же самое со вторым примером, где вы вытаетесь сравнить бит commands_list(i)(j) с восьмибитным вектором command.name(j).

Чтобы все заработало вам надо объявить новый тип. Ну и commands_list, наверно, по смыслу должен быть константой.

type t_commands_list is array(natural range <>) of commands;

constant commands_list : t_commands_list (0 to COM_COUNT):=
(
   x"73746F700000", --stop
   x"667764000000", --fwd
   x"726576000000"  --rev
);

 

 

В принципе выше то же самое написали. И да, лучше код целиком кидайте.

 

Я выкинул record

type com_str is array (0 to 31) of std_logic_vector(7 downto 0);
type arg_str is array (0 to 9) of std_logic_vector(7 downto 0);

signal rx_command : com_str;
signal arg1 : arg_str;
signal arg2 : arg_str;
signal arg3 : arg_str;

теперь я сравниваю одинаковые типы. однако получаю ту же ошибку.

parser.vhd

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


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

а как тогда написать функцию сравнения? В С# был operator override, тут наверно что то похожее.
В VHDL перегрузка функций по умолчанию. Нужная функция выбирается по типам аргументов и возвращаемого значения.

 

Но я на вашем месте не разводил бы зоопарк типов. Чем типов меньше, тем жить легче.

 

type str_t is array(integer range<>) of std_logic_vector(7 downto 0)

type commands is array(integer range<>) of str_t(0 to COM_SIZE);

constant commands_list : commands(0 to COM_COUNT) :=
(
    x"73746F700000", --stop
    x"667764000000", --fwd
    x"726576000000"  --rev
);

type com is
record
      name : str_t(0 to 31);
      arg1 : str_t(0 to 9);
      arg2 : str_t(0 to 9);
      arg3 : str_t(0 to 9);
      name_len : integer;
end record;
        
signal command : com;

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


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

Вы объявили два разных типа двумерных массивов восьмибитных векторов и пытаетесь сравнить их между собой. VHDL этого напрямую не позволяет. Сравнивайте поэлементно, т.к. типы элементов объявленных саммивов совпадают - std_logic_vector(7 downto 0).

Или, как написали выше, объявите один тип, например,

type byte_array is array(natural range <>) of std_logic_vector(7 downto 0);
type t_commands_list is array (natural range <>) of byte_array(0 to 31);

signal commands_list : t_commands_list(0 to COM_COUNT) := 
(
   0 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --stop
   1 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --fwd
   2 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21")  --rev	
);
signal rx_command:byte_array(0 to 31);

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


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

спасибо большое.

финальная версия такая

type str_t is array(integer range<>) of std_logic_vector(7 downto 0);
type commands is array(integer range<>) of str_t(0 to COM_SIZE);

constant commands_list : commands(0 to COM_COUNT) := 
(
     0 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --stop
    1 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21"), --fwd
    2 => (0 => x"00", 1 => x"01", 2 => x"10", 3 => x"11", 4 => x"20", 5 => x"21")  --rev
    
);

signal rx_command : str_t(0 to 31);
signal arg1 : str_t(0 to 9);
signal arg2 : str_t(0 to 9);
signal arg3 : str_t(0 to 9);

 

и тогда оператор сравнения компилируется

for i in 0 to COM_COUNT loop
    if (commands_list(i) /=  rx_command) then
      end if;      
end loop;

осталось написать тестбенч и проверить работает или нет. или в железо загоню и там проверю.

 

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


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

осталось написать тестбенч и проверить работает или нет. или в железо загоню и там проверю.

 

Команды только не забудьте на свои реальные поменять, а то я-то просто от балды значений натыкал, а они потом дальше пошли распространяться.

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


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

Команды только не забудьте на свои реальные поменять, а то я-то просто от балды значений натыкал, а они потом дальше пошли распространяться.

ну да. я думаю написать скриптик который по команде (stop, fwd, rev и.т.д) будет генерировать нужую строку для листа.

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


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

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

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

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

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

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

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

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

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

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