2
\$\begingroup\$

I have created the following VHDL module, which is used as an up/down counter.

entity counter is
Port(clk        : in  STD_LOGIC;
     count_clk  : in  STD_LOGIC;
     reset      : in  STD_LOGIC;
     count_up   : in  STD_LOGIC;
     count_down : in  STD_LOGIC;
     counting   : out STD_LOGIC;
     value      : out signed(19 downto 0));
end counter;

architecture Behavioral of counter is
    signal temp_value   : signed(19 downto 0) := (others => '0');
    signal last_clk_val : STD_LOGIC           := '0';
begin
process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;
        end if;
    end if;
end process;
last_clk_val <= count_clk;
counting     <= count_up or count_down;
value        <= temp_value;
end Behavioral;

ISE presents me with the following warning (for each bit of temp_value):

WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch <ttl_top_inst/COUNTER_COMPONENT/temp_value_0> has a constant value of 0 in block <ttl_oneshot_inputs_top>. This FF/Latch will be trimmed during the optimization process.

Adding the Following lines to the code marked with --ADDED LINES removes the warning, but temp_value should not be altered at that point of the code.

entity counter is
Port(clk        : in  STD_LOGIC;
     count_clk  : in  STD_LOGIC;
     reset      : in  STD_LOGIC;
     count_up   : in  STD_LOGIC;
     count_down : in  STD_LOGIC;
     counting   : out STD_LOGIC;
     value      : out signed(19 downto 0));
end counter;

architecture Behavioral of counter is
    signal temp_value   : signed(19 downto 0) := (others => '0');
    signal last_clk_val : STD_LOGIC           := '0';
begin
process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;
        else --ADDED LINES
            temp_value <= temp_value - 1; --ADDED LINES
        end if;
    end if;
end process;
last_clk_val <= count_clk;
counting     <= count_up or count_down;
value        <= temp_value;
end Behavioral;

The code works without problems in the simulation, but I know that the simulation does not equal the actual implementation.

Could someone give me directions on how to fix this problem?
Thanks in advance!

\$\endgroup\$
7
\$\begingroup\$

Because this line:

last_clk_val <= count_clk;

is outside of the clocked process, both signals will have the same value in hardware (and also in simulation after a delta-cycle1). Thus, this condition within your process

if (last_clk_val = '0' and count_clk = '1') then

will never be true and the process will be equivalent to:

process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        null;
    end if;
end process;

Together with the signal initialization, this gives a constant value of all '0' for temp_value.

If you want to delay count_clk for one cycle to detect a rising-edge on this signal, you have to move the assignment of last_clk_val inside the process:

process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;

        last_clk_val <= count_clk;  -- moved here
    end if;
end process;

In simulation, all signal assignment are delayed. If no delay is given, then the signal assignment is delayed by a delta-cycle. Thus, if count_clk changes then count_clk will differ from last_clk_val for one delta-cycle in the original code. In hardware both signals are represented by the same wire.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.