0

I'm trying to create an accumulator to use in an NCO, but getting some strange errors. I'm fairly new to VHDL so any help is appreciated, here's my code:

library IEEE;
use IEEE.STD_LOGIC_1164.all;    -- for std_logic and std_logic_vector
use IEEE.NUMERIC_STD.all;       -- for unsigned type

---------------------------------------------------------------------
-- accumulator entity declaration
---------------------------------------------------------------------       

entity accumulator is

    port(CLK, Reset : in std_logic;
         S  : in std_logic_vector(11 downto 0);
           N : out std_logic_vector(7 downto 0));
end accumulator;

---------------------------------------------------------------------
-- accumulator architecture                                        
---------------------------------------------------------------------   

architecture accumulator_arch of accumulator is

begin   

process (CLK)
      variable ACC : unsigned(11 downto 0) := "000000000000";
      variable STEP : unsigned(11 downto 0) := "000000000000";
    begin
        -- use an "if" statement to synchronise to rising clock edge
        STEP := unsigned(S);
        if (Reset = '1') then
          ACC := "000000000000";

        elsif   rising_edge(clk) then

            ACC := ACC + S;
            --add step size to ACC
        end if;

        N <= std_logic_vector(ACC(11 downto 4));

end process;

end accumulator_arch;

The errors i'm getting are:

** Error: C:/Modeltech_pe_edu_10.4/Projects/NCO.vhd(34): No feasible entries for infix operator "+".
** Error: C:/Modeltech_pe_edu_10.4/Projects/NCO.vhd(34): Bad right hand side (infix expression) in variable assignment.
** Error: C:/Modeltech_pe_edu_10.4/Projects/NCO.vhd(42): VHDL Compiler exiting

I can't see why I'm getting errors, as its two unsigned variables I'm adding.

Thanks

1 Answers1

1

You are adding ACC (unsigned) with S (std_logic_vector). You probably meant to use STEP (unsigned) instead.

Also, since you used an asynchronous reset, you have to add Reset to the process sensitivity list or the simulation won't match the implementation.

I think you would want a synchronous reset in that case, since I expect reset to be driven by a top module instead of a global reset. You make the reset synchronous by moving it inside the rising_edge block:

if rising_edge(clk) then
    if (Reset = '1') then
        ACC := (others => '0');
    else
        ACC := ACC + STEP;
    end if;
end if;
Jonathan Drolet
  • 3,318
  • 1
  • 12
  • 23