Дискретное косинусное преобразование с использованием VHDL
Я работаю над дискретным косинусным преобразованием с использованием VHDL. Я пытаюсь преобразовать код VHDL из целого числа в стандартный логический вектор. Я применил некоторые методы, которые я прочитал в Интернете и из учебников, но это не сработало. Ниже приведен код, который я пытался преобразовать. Я хотел бы, чтобы длина входного файла была 8 бит, а выходной - 12 бит. Спасибо.
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in INTEGER;
Done : out BIT;
Dout : out INTEGER
);
end dct;
architecture behavioral of dct is
begin
process
type RF is array ( 0 to 7, 0 to 7 ) of INTEGER;
variable i, j, k : INTEGER;
variable InBlock : RF;
variable COSBlock : RF;
variable TempBlock : RF;
variable OutBlock : RF;
variable A, B, P, Sum : INTEGER;
begin
Вот тот, который я попробовал после прочтения некоторых книг, и я продолжаю получать ошибки.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dct is
port (
Clk : in std_logic;
Start : in std_logic;
Din_temp: in INTEGER;
temp := conv_std_logic_vector(Din_temp, 8);
Done : out std_logic;
Dout_temp: out INTEGER;
temp := conv_std_logic_vector(Dout_temp, 9));
end dct;
architecture behavioral of dct is
begin
process
type RF is matrix( 0 to 7, 0 to 7 ) of ;
variable i, j, k : std_logic_vector(7 downto 0);
variable InBlock : RF;
variable COSBlock : RF;
variable TempBlock : RF;
variable OutBlock : RF;
variable A, B, P, Sum : std_logic_vector(7 downto 0);
begin
2 ответа
Целые числа отлично синтезируются и прекрасно работают как порты, поэтому, если ваш модуль работает удовлетворительно и правильно синтезируется, оставьте его в покое.
Хорошей практикой является использование целых чисел в диапазоне: например, если Din, Dout представляют значения в диапазоне от 0 до 255, создайте для них либо новый целочисленный тип, либо подтип:
type Int_8 is new Integer range 0 to 255; -- or
subtype Int_8 is Integer range 0 to 255;
(Разница в том, что подтипы можно свободно смешивать с другими целыми числами, но случайное смешивание нового типа с целым числом будет помечено компилятором как ошибка).
Преимущество этого состоит в том, что синтез не будет пытаться создавать 32-битные математические блоки, где требуется только 8 (или 3 или 19) бит. Обычно это происходит, а затем обрезает лишние биты позже, чтобы больше не стоить затворов, а просто заполняет файлы отчетов сообщениями "обрезка избыточной логики"...
Однако я предполагаю, что проблема, с которой вы столкнулись, заключается в том, чтобы связать это ядро с другими частями проекта, реализованными в менее просвещенном виде, которые имеют порты std_logic_vector.
Затем вы можете реализовать оболочку для адаптации этого ядра DCT к среде std_logic_vector. Я использовал разные методы для разных сигналов портов: преобразования в картах портов более точные, но у некоторых инструментов есть проблемы (ошибки), обрабатывающие их. Поэтому я использовал внутренние сигналы в качестве адаптеров для Start и Dout, чтобы показать, как можно обойти такие проблемы. На самом деле, выберите один или другой!
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity std_lv_dct is
port (
Clk : in std_logic;
Start : in std_logic;
Din : in std_logic_vector(7 downto 0);
Done : out std_logic;
Dout : out std_logic_vector(11 downto 0);
);
end std_lv_dct;
architecture wrapper of std_lv_dct is
Dout_int : integer range 0 to 4095;
Start_int : bit;
begin
-- internal signals as type adapters
Dout <= std_logic_vector(to_unsigned(Dout_int),11);
Start_int <= to_bit(Start);
-- direct entity instantiation for the real core
Transform : entity work.dct
port map(
Clk => to_bit(Clk),
Start => Start_int,
Din => to_integer(unsigned(Din)),
std_logic(Done) => Done,
Dout => Dout_int
);
end architecture wrapper;
Кажется, что вы объединили объявление объекта с назначением сигнала; это не работает так! сохраните сущность такой, какой она была, и используйте функции преобразования типов внутри вашей архитектуры. Пример ниже показывает это для Din и Dout:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in INTEGER;
Done : out BIT;
Dout : out INTEGER
);
end dct;
architecture behavioral of dct is
signal temp_din: std_logic_vector(7 downto 0);
signal temp_dout: std_logic_vector(11 downto 0);
begin
temp_din<=std_logic_Vector(to_unsigned(Din,8));
Dout<=to_integer(unsigned(temp_dout));
...
конечно, вы также можете использовать std_logic_vector непосредственно в вашей сущности:
entity dct is
port (
Clk : in BIT;
Start : in BIT;
Din : in std_logic_Vector(7 downto 0);
Done : out BIT;
Dout : out std_logic_vector(11 downto 0)
);
end dct;