UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 11062

3.1i XST - VHDL counter synthesizes to incorrect logic

Description

Keywords: VHDL, synthesis, synthesize, logic, wrong, incorrect

Urgency: Standard

General Description:
When implementing a VHDL counter in the following manner, the counter does not operate correctly; it continually adds "1" to the sum, even when the loaded value to add is not equal to one, or is "0". This problem is illustrated in the following VHDL code:

(NOTE: This problem is fixed in the 4.1i software release.)

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.std_logic_unsigned.all;

entity accumulator_20 is
port (
RESET : in STD_LOGIC;
CLK : in STD_LOGIC;
AUDIO_IN : in STD_LOGIC_VECTOR (19 downto 0);
ACCU_LOAD : in std_logic;
ADD_EN : in STD_LOGIC;
AUDIO_OUT_A : out STD_LOGIC_VECTOR (19 downto 0);
AUDIO_OUT_B : out STD_LOGIC_VECTOR (19 downto 0)
);
end accumulator_20;

architecture accumulator_20_arch of accumulator_20 is

signal AUDIO_OUT_INT_A : std_logic_vector (19 downto 0);

begin
AUDIO_OUT_A <= AUDIO_OUT_INT_A;

process (CLK, RESET )
begin
if RESET = '1' then
AUDIO_OUT_INT_A <= ( others => '0' );
elsif rising_edge(CLK) then
if ACCU_LOAD = '1' then
AUDIO_OUT_INT_A <= AUDIO_IN;
elsif ADD_EN = '1' then
AUDIO_OUT_INT_A <= AUDIO_IN + AUDIO_OUT_INT_A;
end if;
end if;
end process;

end architecture;

Solution

This problem occurs because XST has difficulty with the counter declaration:

audio_out_int_a <= audio_in + audio_out_int_a

This line of code implements an inverter onto the LSB of the counter, thus causing the counter to increment by 1.

The solution is to use an intermediate signal to perform this operation, as illustrated below:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.std_logic_unsigned.all;

entity accumulator_20 is
port (
RESET : in STD_LOGIC;
CLK : in STD_LOGIC;
AUDIO_IN : in STD_LOGIC_VECTOR (19 downto 0);
ACCU_LOAD : in std_logic;
ADD_EN : in STD_LOGIC;
AUDIO_OUT_A : out STD_LOGIC_VECTOR (19 downto 0);
AUDIO_OUT_B : out STD_LOGIC_VECTOR (19 downto 0)
);
end accumulator_20;

architecture accumulator_20_arch of accumulator_20 is

signal AUDIO_OUT_INT_A : std_logic_vector (19 downto 0);
signal AUDIO_OUT_INT_B : std_logic_vector (19 downto 0);
signal ADD : std_logic_vector (19 downto 0);

begin

AUDIO_OUT_B <= AUDIO_OUT_INT_B;

ADD <= AUDIO_IN + AUDIO_OUT_INT_B;

process (CLK, RESET )
begin
if RESET = '1' then
AUDIO_OUT_INT_B <= ( others => '0' );
elsif rising_edge(CLK) then
if ACCU_LOAD = '1' then
AUDIO_OUT_INT_B <= AUDIO_IN;
elsif ADD_EN = '1' then
AUDIO_OUT_INT_B <= ADD;
end if;
end if;
end process;


end architecture;
AR# 11062
Date Created 02/26/2001
Last Updated 08/19/2002
Status Archive
Type General Article