Jump to content

    

numeric_std

как использовать эту библиотеку правильно? одни ошибки лезут

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;


ENTITY adder16 IS
    PORT ( 
            Cin     : IN     STD_LOGIC;
            X, Y     : IN     STD_LOGIC_VECTOR(15 DOWNTO 0);
            S         : OUT     STD_LOGIC_VECTOR(15 DOWNTO 0);
            Cout    : OUT     STD_LOGIC );
END adder16;

ARCHITECTURE Behavior OF adder16 IS    
        SIGNAL Xs : UNSIGNED(15 DOWNTO 0);
        SIGNAL Ys : UNSIGNED(15 DOWNTO 0); 
    SIGNAL Sum : UNSIGNED(16 DOWNTO 0);
BEGIN
    Xs <= unsigned(X);
        Ys <= unsigned(Y);
    Sum <= ('0' & Xs) + Ys + Cin;
    S <= std_logic_vector(Sum(15 DOWNTO 0));
    Cout <= Sum(16);
END Behavior;

 

 Line 21: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"

 

Любое сложение с STD_logic дает ошибку....

 

 

А такой вариант как? Вроде уже синтезируется , но есть ли ошибки?

 

library IEEE;
use IEEE.STD_logic_1164.all;
use IEEE.Numeric_STD.all;
entity summer is 
    port ( data1    : in  std_logic_vector(3 downto 0);
             data2    : in  std_logic_vector(3 downto 0);
             c    : in  std_logic;
             carry    : out std_logic;
             data_o    : out    std_logic_vector(3 downto 0)
             
    );
    end entity;

architecture ad of summer is 
signal    tmp1    :    unsigned(3 downto 0);
signal    tmp2    :    unsigned(1 downto 0);
begin
    tmp1     <= unsigned('0' & (data1(2 downto 0)))+unsigned('0' & (data2(2 downto 0)))+('0'& c);
    tmp2    <= ('0' & data1(3))+('0' & data2(3))+('0'&tmp1(3));
    data_o<= std_logic_vector(tmp2(0)&tmp1(2 downto 0));
    carry    <=    tmp2(1);
    
end;

Edited by go2winner

Share this post


Link to post
Share on other sites
как использовать эту библиотеку правильно? одни ошибки лезут

 

    Sum <= ('0' & Xs) + Ys + Cin;

 

 Line 21: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"

 

Любое сложение с STD_logic дает ошибку....

Правильно. Функции сложения unsigned или signed с std_logic нет. Можно такой workaround:

    Sum <= ('0' & Xs) + Ys + unsigned'('0' & Cin);

 

Или напишите свою, если таких сложений у вас много.

Share this post


Link to post
Share on other sites

Здравствуйте!

Как сложить отдельные биты вектора чтобы в результате получилось целое цисло?

Конструкция вида

signal A : unsigned (7 downto 0);
signal B : integer range 0 to 15;
...
B <= A(7)+A(6)+A(5)+A(4)+A(3)+A(2)+A(1)+A(0);

при компиляции выдаёт ошибку.

Сейчас в качестве костыля написал

Signal A0, A1, A2, A3, A4, A5, A6, A7 : integer range 0 to 1;
...
if A(0)='1'
  then A0 <= 1;
  else A0 <= 0;
end if;
if A(1)='1'
  then A1 <= 1;
  else A1 <= 0;
end if;
...
и т.д.
...
B <= A0+A1+A2+A3+A4+A5+A6+A7;

Разумеется, вычисление A0 - A7 происходит в другом процессе раньше, чем B.

Код работает, но он некрасивый и мне не нравится, ибо громоздкий.

Как можно выйти из положения?

Share this post


Link to post
Share on other sites
51 minutes ago, MrGalaxy said:

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

VHDL просто космос....я бы функцию написал, а там классически sum = 0; for (blablabla) if bit(i)  sum = sum + 1

Share this post


Link to post
Share on other sites

Подозреваю, что дело в приведении типов (VHDL имеет строгую типизацию), поскольку само сложение для UNSIGNED'ов возможно, если включён один из пакетов numeric_std или std_logic_arith. Можно попробовать что-то вроде:

B <= INTEGER( A(7)+A(6)+A(5)+A(4)+A(3)+A(2)+A(1)+A(0) );

Т.е. указать явное приведение типа результата. Сам проверить прям сейчас не могу.

Share this post


Link to post
Share on other sites
41 минуту назад, des00 сказал:

VHDL просто космос

В отличие от Верилога, где вся математика прибита гвоздями намертво сидит в ядре, в VHDL математика вынесена во внешние библиотеки (то самый numeric std, который оперирует типом std_logic_vector, который в свою очередь тоже определён во внешней библиотеке).

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

18 минут назад, SII сказал:

Можно попробовать что-то вроде

Нельзя. В стандарте нет функций сложения std_logic.

Share this post


Link to post
Share on other sites
39 minutes ago, andrew_b said:

В отличие от Верилога, где вся математика прибита гвоздями намертво сидит в ядре, в VHDL математика вынесена во внешние библиотеки (то самый numeric std, который оперирует типом std_logic_vector, который в свою очередь тоже определён во внешней библиотеке).

есть такое, да, я лет 5 сидел на VHDL, пока не ушел на SV

Share this post


Link to post
Share on other sites
2 hours ago, andrew_b said:

Нельзя. В стандарте нет функций сложения std_logic

1. В моём примере складываются UNSIGNED'ы и приводятся к INTEGER'у. Какая ошибка у человека возникла, он не сообщил, так что я предположил, что дело было в несоответствии типов.

2. Есть сложение STD_LOGIC_VECTOR.

3. Даже если чего-то действительно нет, можно написать свой (пользовательский) оператор и потом им спокойно пользоваться.

Share this post


Link to post
Share on other sites
3 минуты назад, SII сказал:

В моём примере складываются UNSIGNED'ы

Где?

4 минуты назад, SII сказал:

Какая ошибка у человека возникла, он не сообщил

Сезон отпусков закончился, телепаты вышли на работу. Вопрошающий складывает std_loigc'и, поэтому ошибка очевидна.

Share this post


Link to post
Share on other sites
1 minute ago, andrew_b said:

Где? 

Сезон отпусков закончился, телепаты вышли на работу. Вопрошающий складывает std_loigc'и, поэтому ошибка очевидна.

Вот что было написано про проблему:

Quote

 

Как сложить отдельные биты вектора чтобы в результате получилось целое цисло?

Конструкция вида


signal A : unsigned (7 downto 0);
signal B : integer range 0 to 15;
...
B <= A(7)+A(6)+A(5)+A(4)+A(3)+A(2)+A(1)+A(0);

при компиляции выдаёт ошибку.

 

Как видите, исходные операнды -- UNSIGNED, результат -- INTEGER.

Share this post


Link to post
Share on other sites
6 минут назад, SII сказал:

Как видите, исходные операнды -- UNSIGNED

 

A(i) -- элемент массива A. Массив имеет тип unsigned. Внимание, вопрос: какой тип имеет A(i)?

Share this post


Link to post
Share on other sites

Приветствую!

37 minutes ago, andrew_b said:

A(i) -- элемент массива A. Массив имеет тип unsigned. Внимание, вопрос: какой тип имеет A(i)?

A(i)  будет ieee.std_logic_1164.STD_ULOGIC  - угадал?  Во всяком случае modelsim так ругается при компиляции. :wink:

На сколько я понимаю сложить биты в VHDL без явного преобразования типов невозможно  

Удачи! Rob.

Share this post


Link to post
Share on other sites
26 минут назад, RobFPGA сказал:

A(i)  будет ieee.std_logic_1164.STD_ULOGIC  - угадал?

Да. Только зачем угадывать, если можно посмотреть в код пакета.

27 минут назад, RobFPGA сказал:

На сколько я понимаю сложить биты в VHDL без явного преобразования типов невозможно

Так об этом и тема.

Share this post


Link to post
Share on other sites
6 hours ago, MrGalaxy said:

B <= A(7)+A(6)+A(5)+A(4)+A(3)+A(2)+A(1)+A(0);

Увы VHDL не делает автоматическое расширение операндов, в отличии от Verilog. Поэтому Вам придётся считать единицы через отдельную функцию (что-то вроде if A(i) = '1' then cnt <= cnt + '1'; и далее перебор в цикле параметра i).

Лиьбо второй вариант сложить сумму во временное хранилище:


	signal A : unsigned (7 downto 0);
	signal sum_A : unsigned (2 downto 0);
	sum_A <= ("00" & A(7)) + ("00" & A(6)) + ("00" & A(5)) + ("00" & A(4)) +
      				("00" & A(3)) + ("00" & A(2)) + ("00" & A(1)) + ("00" & A(0));

А уже потом перевести в Интеджер

1 hour ago, andrew_b said:

A(i) -- элемент массива A. Массив имеет тип unsigned. Внимание, вопрос: какой тип имеет A(i)?

один элетент -  std_logic. Или просто bit. разница не очень большая для синтезатора

p.s. Лучше не использовать векторы unsigned и signed без крайней необходимости, а оставаться в пределах std_logic. Будет меньше мороки

Share this post


Link to post
Share on other sites
1 минуту назад, Nick_K сказал:

Лучше не использовать векторы unsigned и signed без крайней необходимости, а оставаться в пределах std_logic.

Типы надо использовать по назначению. Если это математика, то unsigned и signed без вариантов. Причём их стандартного пакета numeric_std, а не из проприетарного legacy std_logic_arith и Co.

unsigned и signed это однозначно числа. std_logic_vector в общем случае числом не является. Это просто массив бит. Ещё он используется в интерфейсах в целях унификации.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now