VHDL - Фазовый аккумулятор с обратной связью - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь создать фазовый аккумулятор, используя VHDL, который имеет следующие характеристики:

Входы:

  • D (входной сигнал)
  • RESET
  • CE
  • CLK

Выходы:

  • Q (выходной сигнал - обратная связь)

Исходный код:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Phase_accu is
port (
    D       : in std_logic_vector(3 downto 0);
    CE      : in std_logic;
    CLK     : in std_logic;
    RESET   : in std_logic;
    Q       : out std_logic_vector(15 downto 0)
);
end Phase_accu;

architecture Behavioral of Phase_accu is
begin

process(D, CE, CLK, RESET)
    begin
        if RESET = '1' then
            Q <= "0000000000000000";
        elsif rising_edge(CLK) then
            if CE = '1' then
                Q <= ("000000000000" & D) + Q;
            end if;
        end if;
end process;

end Behavioral;

Я получаю сообщение об ошибке, когда линия пытается объединить 2 сигнала для обратной связи ...

Q <= ("000000000000" & D) + Q;

Невозможно прочитать вывод "Q".

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Я предлагаю использовать библиотеку numeric_std вместо STD_LOGIC_ARITH и STD_LOGIC_UNSIGNED.Я также предлагаю сделать несколько небольших оптимизаций в отношении спецификации размера вектора.

Также в списке чувствительности есть две записи.Вы должны удалить D и CE, чтобы описать действительный синхронизированный процесс с асинхронным сбросом.Подробности см. В руководстве к инструменту для синтеза.

Код выше

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Phase_accu is
port (
    D       : in std_logic_vector(3 downto 0);
    CE      : in std_logic;
    CLK     : in std_logic;
    RESET   : in std_logic;
    Q       : out std_logic_vector(15 downto 0)
);
end Phase_accu;

architecture Behavioral of Phase_accu is
    signal Q_reg : unsigned(Q'range);
begin

process(CLK, RES)
begin

        if RES = '1' then
            Q_reg <= (others => '0');
        elsif rising_edge(CLK) then
            if CE = '1' then
                Q_reg <= resize(unsigned(D), Q_reg'length) + Q_reg;
            end if;
        end if;

end process;

Q <= std_logic_vector(Q_reg);

end Behavioral;
.
0 голосов
/ 05 февраля 2019

Вы не можете прочитать значение out в версиях VHDL до VHDL-2008.Обычный способ обойти это - иметь внутреннюю копию выходных данных и использовать эту внутреннюю копию, когда вам нужно получить ее значение:

[...]
Q : out std_logic_vector(15 downto 0);
[...]
signal Q_reg : std_logic_vector(15 downto 0);

process(D, CE, CLK, RES)
    begin

        if RES = '1' then
            Q_reg <= "0000000000000000";
        elsif rising_edge(CLK) then
            if CE = '1' then
                Q_reg <= ("000000000000" & D) + Q_reg;
            end if;
        end if;
end process;

Q <= Q_reg;
...