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

Вх. и Вых. порты типа real, помогите разобраться

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

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

library ieee;
use ieee.std_logic_1164.all;

entity Real is
    port(in1, in2 : in real;
         out1 : out real);
end entity Real;

architecture arcReal of Real is

begin
       out1 <= in1 * in2;
end architecture arcReal;

Но это так, написано чтобы разобраться почему не работает проект, представленный ниже. Тут мне надо просто перемножить матрицы(ну и транспонировать одну матрицу перед тем как на нее умножить) и результат как-то выдать на выход. Например для матрицы 4 на 4 сделать 16 вых.портов и подать на них значения элементов. Матрица состоит из элементов типа real. Так вот последней строчкой я пишу например out1 <= dcp(0)(0); и после добавления этой записи компилятор выдает ошибку CL192: mydcp.vhd(23): Can't convert expression to logic value

, причем указывает на строчку объявления матрицы variable img : matrix := ((254.0, 254.0, 7.0, 7.0), (254.0, 254.0, 7.0, 7.0), (254.0, 9.0, 7.0, 7.0), (254.0, 254.0, 7.0, 7.0));. Внизу представлен проект:

library ieee;
use ieee.std_logic_1164.all;

entity MyDCP is
    port(in1 : in real;
         inN : in integer;
         out1 : out real);
end entity MyDCP;

architecture arcMyDCP of MyDCP is
    -- N - размерность матрицы изображения, например 
    -- изображение 4 на 4
    constant N : integer := 4;
    -- определяем пользовательские типы:
    -- одномерный массив из N элементов типа real
    type massive is array (0 to N-1) of real range 0.0 to 10000.0;
    -- двумерный массив размера N на N из элементов типа real
    type matrix is array (0 to N-1) of massive;
begin
    process(in1)
        -- объявляем переменные:
        -- img - исходное изображение в виде матрицы N на N
        variable img : matrix := ((254.0, 254.0, 7.0, 7.0), (254.0, 254.0, 7.0, 7.0), (254.0, 9.0, 7.0, 7.0), (254.0, 254.0, 7.0, 7.0));
        -- kp - матрица косинусного преобразования
        variable kp : matrix := ((0.5, 0.5, 0.5, 0.5), (0.6533, 0.2706, -0.2706, -0.6533), (0.5, -0.5, -0.5, 0.5), (0.2706, -0.6533, 0.6533, -0.2706));
        -- dcp - матрица результат дискретного косинусного преобразования 
        variable dcp : matrix := ((0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0));    
        -- функция транспонирования матрицы
        function trans(a : matrix) return matrix is
            -- res - результат транспонирования матрицы a
            variable res : matrix := ((0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0));
            -- i, j - переменные-счетчики для циклов
            variable i : integer := 0;
            variable j : integer := 0;
        begin
            while (i < N) loop
                j := 0;
                while (j < N) loop
                    res(i)(j) := a(j)(i);
                    j := j + 1;
                end loop;
                i := i + 1;
            end loop;
            return res;
        end function trans;
        -- функция перемножения матриц, матрицы должны быть квадратными
        function umnoj(a : matrix; b : matrix) return matrix is
            -- res - матрица результат умножения матриц a и b
            variable res : matrix := ((0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0));
            -- i,j,k - переменные-счетчики 
            variable i, j, k : integer := 0;
            -- sum - переменная для накопления суммы
            variable sum : real := 0.0;
        begin
            while (i < N) loop
                j := 0;
                while (j < N) loop    
                    sum := 0.0;
                    k := 0;
                    while (k < N) loop
                        sum := sum + a(i)(k) * b(k)(j);
                        k := k + 1;
                    end loop;
                    res(i)(j) := sum;
                    j := j + 1;
                end loop;
                i := i + 1;
            end loop;
            return res;
        end function umnoj;
    begin
        -- выполняем дискретное косинусное преобразование
        -- умножаем матрицу kp на матрицу img
        dcp := umnoj(umnoj(kp, img), trans(kp));
        out1 <= dcp(0)(0);
    end process;
    
end architecture arcMyDCP;

Не поможите, разобраться в чем тут дело? И еще пара вопросиков: 1. Есть ли какая-нибудь функция, которая преобразует значение типа real в integer - отбрасывает дробную часть или округляет число? 2. Иногда при делении значения одной переменной на другое (тип real) компилятор выдает ошибку Right argument must evaluate to a constant integer power of 2, т.е. делитель должен быть целым числом, представимым как 2 в какой-нибудь степени, как это обойти?

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

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


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

Если я правильно понял, то речь идет о синтезе. Так вот, синтезаторы real не поддерживают - real это для чистого моделирования. Моделировать, ModelSimом например, можете сколько угодно, а вот синтезировать не получится.

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


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

Вообще по идее я этот проект должен импортировать в среду Triscend FastChip и залить в плату, в учебных целях, так что наверное это синтез. Sefo, а можете что-нибудь посоветовать чтобы преобразовать real в integer, как-нибудь округлить вещественное число можно или нет?

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


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

Округление к целому Вам не поможет. Прежде чем округлять результат его надо получить :) Дело в том, что синтезаторы "умеют" синтезировать математические операции только для целых чисел. Числа с плавающей точкой имеют более сложный формат, чем целые. Есть мантиса, экспонента и знак. Есть еще градации точности представления, в зависимости от которой находится количество бит на мантису и экспоненту. Поэтому real с точки зрения синтеза это "ни о чем" - откуда синтезатору знать в каком именно формате Вы хотите представить число c плавающей точкой? Real это просто "type real is range -1.0E308 to 1.0E308".

 

Вам нужно найти IP (или библиотеку) сумматоров, умножителей и пр. для плавающей точки для синтеза в виде модулей и "собрать" из них нужную схему. Пользовались бы Quartus было бы все просто - у него эти вещи есть в MegaWizard, а по Вашей системе ничего конкретного подсказать не могу.

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


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

Странно, в книге Сергиенко А.М. "VHDl язык для проектирования вычислительных устройств" (стр.47) есть небольшая запись про преобразование типов (в частности типа real к integer) и есть такая запись с2 := integer(123.5); и говорится что при выполнении этой инструкции результатом будет округление до ближайшего целого, т.е. 124. Попробовал написать что-то подобное - компилятор ошибок не выдал. Но потом попробовал привести таким образом, напр. y := integer(x); где y - integer, а x - real - выдает ошибку CD302: mydcp.vhd(82): Cast of incompatable types. Че за бред, понять не могу? Т.е. просто какое-то значение привести может, а значение переменной или сигнала - нет, почему?

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


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

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

 

На месте программистов синтезатора, я бы сделал именно прогонку.

 

Промоделировал в моделсиме вот такую штуку:

 

entity ABA is

port(A : in real);

end entity;

 

architecture ABCDE of ABA is

 

signal B : integer;

begin

B <= integer (A);

end architecture;

 

 

Всё компилируется. Дело именно в "туле". Каким вы пользуетесь тулом?

 

Кстати. Если вам надо сдать курсовую работу или что-то вроде (что-то что делается без железа) - то можно предоставить результат моделирования в моделсиме. Там, кажется, нет проблем с вещественными числами.

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

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


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

Если честно, я в этой теме полный профан, так что врят ли у меня получится по RTL-коду проекта понять суть происходящего. Просто я не могу понять, есть ли в VHDL функция которая бы привела тип real к типу integer, т.е. отбросила дробную часть или округлила до ближайшего целого. Вот например ссылка где вроде как делается приведение real к integer http://www.eece.unm.edu/faculty/pollard/types.html#TypeConv, но когда я пытаюсь написать что-то подобное в Synplify Pro, то комп-тор выдает ошибку Cast of incompatable types. Может я не подключаю какие-то библиотеки и пакеты? Просто вопрос мне не кажется достаточно оригинальным, и хочется надеяться что-то приведение как в большинстве языков осуществить можно, иначе это мега-минус мне кажется.

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


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

Если честно, я в этой теме полный профан, так что врят ли у меня получится по RTL-коду проекта понять суть происходящего. Просто я не могу понять, есть ли в VHDL функция которая бы привела тип real к типу integer, т.е. отбросила дробную часть или округлила до ближайшего целого. Вот например ссылка где вроде как делается приведение real к integer http://www.eece.unm.edu/faculty/pollard/types.html#TypeConv, но когда я пытаюсь написать что-то подобное в Synplify Pro, то комп-тор выдает ошибку Cast of incompatable types. Может я не подключаю какие-то библиотеки и пакеты? Просто вопрос мне не кажется достаточно оригинальным, и хочется надеяться что-то приведение как в большинстве языков осуществить можно, иначе это мега-минус мне кажется.

 

В VHDL есть такая функция - и вы её показали. И она работает в предназначенных для этого средах. Например есть люди, которые моделируют Сети Петри на VHDL, потому что удобно.

 

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

 

Судя по всему есть 2 решения:

1) Взять вашь код и заменить среду моделирования.

 

2) Взять вашу среду моделирования и забыть про REAL. Считайте что нет такого типа REAL и вам его надо реализовать через integer или взять готовую реализацию (более хитрую).

 

Проблема не в приведении типов. Вероятно это неправильно сообщение об ошибке. Проблема в самом типе REAL. В Symplyfy Pro нет поддержки этого типа. Он не компилируется.

 

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

 

Обьясню чуточку иначе:

Это мега-минус VHDL. Вы можете считать, что в нём нет real.

Это мега-минус C, C++m Lispa, Haskel - если вы опишете свой алгоритм на одном из этих языков, а потом скомпилируете их в Symplify PRO то он тоже выдаст вам ошибку.

Это мега минус почти любого (языка программирования или языка описания схем )

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

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


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

Понятно, возможно в Synplify зашит компилятор для старой версии VHDl, и поэтому он ругается. А не подскажите другие среды моделирования, которые могут компилировать VHDL-код и выдавать результат в виде edif-файла?

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


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

Я изменил ОБА своих предыдущих сообщения, добавив пример. Вам они должены быть ОЧЕНЬ интересены. Посмотрите пожалуйста. Может быть вопросы отпадут и появяться новые.

Повторяться не буду.

 

Понятно, возможно в Synplify зашит компилятор для старой версии VHDl, и поэтому он ругается. А не подскажите другие среды моделирования, которые могут компилировать VHDL-код и выдавать результат в виде edif-файла?

Если вам нужен edif, то Symplify это один из самых лучших "компиляторов" в этот формат (у нас принято называть такие "компиляторы" синтезаторами, а процесс превращения vhdl в edif не "компиляция", а "синтез". Я буду использовать эти термены. По сути, "компилятор" и "сентезатор" почти одно и то же, в деталях же, используются разные алгоритмы). ВСЕ синтезаторы в формат edif страдают это проблемой. Суть её кроется не в VHDL а в самом EDIF. Нет приемлимого способа преобразовать real в форму, которая выразима в edif.

 

Под edif я понимаю как сам edif так и схожие с ним форматы (их ещё иногда называют net-list'ы), которые обычно подаются на вход Quartus или ISE xilinx.

 

Если бы вам не нужен был edif или вобще никакой выходной формат, кроме как картинка - результат моделирования - вы бы смоли использовать real.

 

Мой синтезатор выдал вот такую штуку:

"Error (10414): VHDL Unsupported Feature error at qreal2int.vhd(2): cannot synthesize non-constant real objects or values"

 

Что похоже больше соответсвует истине.

 

На этапе компиляции всё прошло удачно. А вот в момент синтеза edif - вот такая вот ошибка.

 

Выход их этой ситуации предложил г-н. Sefo. По сути его решение, это библиотека, которая обходит эту проблему с real и edif'ом (netlist'ами). Однако её использование менне компактно и думать в её терминах немного сложнее. Зато если вы её освоите, ситуация и сам язык VHDL, как язык описания цифровых ИС, станет для вас более понятным. Обычно, такую библиотеку можно найти на Opencores.

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

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


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

Понятно, в общем насколько я понял синтезаторы не работают с типом real и даже если компиляция кода проходит нормально, то на этапе синтеза, т.е. преобразования описания компонента в виде VHDL-кода в его схему и создания edif-файла будет выдаваться ошибка. Если хочешь чтобы компонент выполнял операции с вещественными числами, то надо самому писать сумматоры, умножители итд для вещественных чисел в архитектурной форме проекта. Спасибо Arranje, Sefo за оказанную помощь, в принципе Sefo об этом сразу говорил, просто мне не хотелось заморачиваться с написанием сумматоров и пр. и я надеялся что все гораздо проще.

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


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

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

Именно.

 

Если хочешь чтобы компонент выполнял операции с вещественными числами, то надо самому писать сумматоры, умножители итд для вещественных чисел в архитектурной форме проекта.

Как вариант: можно взять уже готовые, отлаженные и хорошо работающие (надеюсь) написанные другими людьми. Они есть, если я правильно помню, в виде open source'ов.

Мне смутно припоминается сайт http://www.opencores.org/ - вроде там видел.

В любом случае можно поискать в интернетах.

 

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

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

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


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

Ну я же Вам сразу сказал:

 

синтезаторы real не поддерживают - real это для чистого моделирования. Моделировать, ModelSimом например, можете сколько угодно, а вот синтезировать НЕ получится.

 

И в следующем сообщении даже объяснил причины.

 

Любой язык HDL имеет двойное назначение - для моделирования и для синтеза. Причем для моделирования доступно всегда больше "средств", чем для синтеза.

 

Что касается тулов, то просто есть чистые синтезаторы, вроде Precision, есть чисто для моделирования вроде ModelSim и есть те, что позволяют делать и то и другое вроде ActiveHDL.

 

Так что, как я тоже уже говорил ищите готовые сумматоры, умножители и т.д. для вещественных чисел.

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


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

и есть те, что позволяют делать и то и другое вроде ActiveHDL.

 

ничего себе, альдек разработал собственный СИНТЕЗАТОР ? Скриптов к сторонним синтезаторам им стало не хватать ? :)

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


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

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

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

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

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

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

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

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

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

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