реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Сравнить два массива
Jenya7
сообщение Jul 12 2017, 07:30
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 383
Регистрация: 29-03-12
Пользователь №: 71 075



есть список команд и команда полученная по 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 - Jul 12 2017, 07:31
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jul 12 2017, 09:53
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 827
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



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

Даже если два типа определены абсолютно одинаково (например, std_ulogic_vector, signed, unsigned), это разные типы, и напрямую объекты этих типов между собой сравнивать нельзя.
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 12 2017, 10:04
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 19-10-13
Пользователь №: 78 795



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

Код
    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 - Jul 12 2017, 10:04
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 12 2017, 10:05
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 383
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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

Сообщение отредактировал Jenya7 - Jul 12 2017, 10:13
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 12 2017, 10:28
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 19-10-13
Пользователь №: 78 795



Цитата(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 строке? Скиньте лучше файл, если там никаких секретов нет) Так проще будет.
Go to the top of the page
 
+Quote Post
KalashKS
сообщение Jul 12 2017, 10:33
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 208
Регистрация: 7-02-11
Пользователь №: 62 755



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

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
);



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

Сообщение отредактировал KalashKS - Jul 12 2017, 10:34
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 12 2017, 10:36
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 383
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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;

теперь я сравниваю одинаковые типы. однако получаю ту же ошибку.
Прикрепленные файлы
Прикрепленный файл  parser.vhd ( 6.82 килобайт ) Кол-во скачиваний: 9
 
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jul 12 2017, 10:40
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 827
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(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;
Go to the top of the page
 
+Quote Post
KalashKS
сообщение Jul 12 2017, 10:57
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 208
Регистрация: 7-02-11
Пользователь №: 62 755



Вы объявили два разных типа двумерных массивов восьмибитных векторов и пытаетесь сравнить их между собой. 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);
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 12 2017, 11:42
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 383
Регистрация: 29-03-12
Пользователь №: 71 075



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

осталось написать тестбенч и проверить работает или нет. или в железо загоню и там проверю.
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 12 2017, 11:44
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 19-10-13
Пользователь №: 78 795



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


Команды только не забудьте на свои реальные поменять, а то я-то просто от балды значений натыкал, а они потом дальше пошли распространяться.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 12 2017, 11:52
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 383
Регистрация: 29-03-12
Пользователь №: 71 075



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

ну да. я думаю написать скриптик который по команде (stop, fwd, rev и.т.д) будет генерировать нужую строку для листа.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th November 2017 - 14:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.24549 секунд с 7
ELECTRONIX ©2004-2016