I have a 3 bit counter that counts upwards from "000". Every time "101" is reached, I want the o_en signal to be HIGH.
I have the following VHDL file.
The behaviour is unfortunately different.
The o_en signal is HIGH, when "110" is reached (delayed by one clock cycle).
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity special_counter is
port(
i_clk : in std_logic;
i_en : in std_logic;
i_rst : in std_logic;
o_data : out std_logic_vector(2 downto 0);
o_en : out std_logic
);
end entity;
architecture behave of special_counter is
signal w_data : std_logic_vector(2 downto 0);
signal w_en : std_logic;
begin
process(i_clk, i_rst) begin
if i_rst = '1' then
w_data <= "000";
elsif rising_edge(i_clk) then
if i_en = '1' then
if w_data = "101" then
w_en <= '1';
w_data <= w_data + 1;
else
w_en <= '0';
w_data <= w_data + 1;
end if;
end if;
end if;
end process;
o_data <= w_data;
o_en <= w_en;
end architecture;
How can I change my program to perform the expected behaviour ?
That is exactly correct and that is what you have coded.
To put it into words:
"At the rising edge of the clock, when the counter has the value 101 then the w_en
will be set high."
Thus the w_en
signal from which o_en
is derived, will be high after the rising edge of the clock.
In the same time as the w_data
changes and after the rising clock becomes "110".
There are two solutions:
Test for "100" (so one cycle sooner)
Make w_en (and thus o_en) combinatorial.
For the latter you must move the assignment outside the 'clocked' section and use e.g.
w_en <= '1' when w_data = "101" else '0';