Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сравнить два массива
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Jenya7
есть список команд и команда полученная по 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

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

Даже если два типа определены абсолютно одинаково (например, std_ulogic_vector, signed, unsigned), это разные типы, и напрямую объекты этих типов между собой сравнивать нельзя.
Tausinov
А мне кажется, тут еще в самом начале с типами ошибка. И должно быть что-то типа такого:

Код
    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
    );


В этом случае побайтовое сравнение должно пройти, т.к. сравниваются элементы уже известных типов, а не собственных.
Jenya7
Цитата(andrew_b @ Jul 12 2017, 15:53) *
Как только вы пишете слово 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, тут наверно что то похожее.

Цитата(Tausinov @ Jul 12 2017, 16:04) *
А мне кажется, тут еще в самом начале с типами ошибка. И должно быть что-то типа такого:

Код
    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
Tausinov
Цитата(Jenya7 @ Jul 12 2017, 13:05) *
так компайлер ругается
Error (10515): VHDL type mismatch error at parser.vhd(71): std_ulogic type does not match string literal


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

commands_list у вас получился массивом 8-битных векторов. Соответственно commands_list(i) - восьмибитный вектор, который вы сравниваете с массивом векторов command.name.
То же самое со вторым примером, где вы вытаетесь сравнить бит commands_list(i)(j) с восьмибитным вектором command.name(j).
Чтобы все заработало вам надо объявить новый тип. Ну и commands_list, наверно, по смыслу должен быть константой.
CODE
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
);



В принципе выше то же самое написали. И да, лучше код целиком кидайте.
Jenya7
Цитата(KalashKS @ Jul 12 2017, 16:33) *
Как видится мне, у вас принципиальная ошибка в типах.

commands_list у вас получился массивом 8-битных векторов. Соответственно commands_list(i) - восьмибитный вектор, который вы сравниваете с массивом векторов command.name.
То же самое со вторым примером, где вы вытаетесь сравнить бит commands_list(i)(j) с восьмибитным вектором command.name(j).
Чтобы все заработало вам надо объявить новый тип. Ну и commands_list, наверно, по смыслу должен быть константой.
CODE
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;

теперь я сравниваю одинаковые типы. однако получаю ту же ошибку.
andrew_b
Цитата(Jenya7 @ Jul 12 2017, 13:05) *
а как тогда написать функцию сравнения? В С# был 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;
KalashKS
Вы объявили два разных типа двумерных массивов восьмибитных векторов и пытаетесь сравнить их между собой. VHDL этого напрямую не позволяет. Сравнивайте поэлементно, т.к. типы элементов объявленных саммивов совпадают - std_logic_vector(7 downto 0).
Или, как написали выше, объявите один тип, например,
CODE

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);
Jenya7
спасибо большое.
финальная версия такая
Код
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;

осталось написать тестбенч и проверить работает или нет. или в железо загоню и там проверю.
Tausinov
Цитата(Jenya7 @ Jul 12 2017, 14:42) *
осталось написать тестбенч и проверить работает или нет. или в железо загоню и там проверю.


Команды только не забудьте на свои реальные поменять, а то я-то просто от балды значений натыкал, а они потом дальше пошли распространяться.
Jenya7
Цитата(Tausinov @ Jul 12 2017, 17:44) *
Команды только не забудьте на свои реальные поменять, а то я-то просто от балды значений натыкал, а они потом дальше пошли распространяться.

ну да. я думаю написать скриптик который по команде (stop, fwd, rev и.т.д) будет генерировать нужую строку для листа.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.