问题
I am trying to create a phase accumulator using VHDL that has the following characteristics.
Inputs:
- D (Input signal)
- RESET
- CE
- CLK
Outputs:
- Q (output signal - feedback)
Source code:
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;
I get an error with the line trying to merge together the 2 signals for feedback...
Q <= ("000000000000" & D) + Q;
Cannot read output "Q".
回答1:
You can't read the value of an out
in VHDL revisions prior to VHDL-2008. The usual way to get around this is to have an internal copy of your output, and use that internal copy when you need to get its value:
[...]
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;
回答2:
I suggest to use numeric_std library instead of STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED. I also suggest to make some minor optimizations regarding the vector size specification.
Also the sensitivity list has two many entries. You have to remove D and CE to describe a valid clocked process with asynchronous reset. See your Synthesis tool manual for details.
This makes the code above to
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;
来源:https://stackoverflow.com/questions/54541371/vhdl-phase-accumulator-with-feedback