Hi
i'm newer to the vhdl,
i wrote vhdl synthesize for the up down counter for the rotary encoder A phase and B phase input, use 50Mhz clock. here in code there is no problem while in simulation mode. but when input the actual A,B phase counter skip some state very rarely.(check output of LSB0)
are there any miss in my vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
Port ( clk,rst : in STD_LOGIC;
A,B : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (7 downto 0)
);
end Counter;
architecture rtl_Counter of Counter is
type state is (state_00, state_10, state_11, state_01); -- posible state of the rotary encoder A and B phase
signal next_state, present_state : state := state_00;
signal present_value : STD_LOGIC_VECTOR(7 downto 0) := (others=>'0'); --- for the counter value
begin
count <= present_value;
SetCounter : process(clk,rst)
begin
if(rst='0') then
present_value <= (others=> '0'); -- after reseting, start from A and B phase low state
present_state <= state_00;
elsif(clk'Event and clk ='1') then
case present_state is
when state_00 =>
if(next_state = state_10)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_01)then -- CW direction
present_value <= present_value - 1;
end if;
when state_10 =>
if(next_state = state_11)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_00)then -- CW direction
present_value <= present_value - 1;
end if;
when state_11 =>
if(next_state = state_01)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_01)then -- CW direction
present_value <= present_value - 1;
end if;
when state_01 =>
if(next_state = state_00)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_11)then -- CW direction
present_value <= present_value - 1;
end if;
end case;
present_state <= next_state;
end if;
end process SetCounter;
setDirection: process(present_state, A, B)
begin
case present_state is
when state_00 =>
if(A='1' and B ='0')then
next_state <= state_10;
elsif(A='0' and B ='1')then
next_state <= state_01;
else
next_state <= state_00;
end if;
when state_10 =>
if(A='1' and B ='1')then
next_state <= state_11;
elsif(A='0' and B ='0')then
next_state <= state_00;
else
next_state <= state_10;
end if;
when state_11 =>
if(A='0' and B ='1')then
next_state <= state_01;
elsif(A='1' and B ='0')then
next_state <= state_10;
else
next_state <= state_11;
end if;
when state_01 =>
if(A='0' and B ='0')then
next_state <= state_00;
elsif(A='1' and B ='1')then
next_state <= state_11;
else
next_state <= state_01;
end if;
end case;
end process setDirection;
end rtl_Counter;
i'm newer to the vhdl,
i wrote vhdl synthesize for the up down counter for the rotary encoder A phase and B phase input, use 50Mhz clock. here in code there is no problem while in simulation mode. but when input the actual A,B phase counter skip some state very rarely.(check output of LSB0)
are there any miss in my vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
Port ( clk,rst : in STD_LOGIC;
A,B : in STD_LOGIC;
count : out STD_LOGIC_VECTOR (7 downto 0)
);
end Counter;
architecture rtl_Counter of Counter is
type state is (state_00, state_10, state_11, state_01); -- posible state of the rotary encoder A and B phase
signal next_state, present_state : state := state_00;
signal present_value : STD_LOGIC_VECTOR(7 downto 0) := (others=>'0'); --- for the counter value
begin
count <= present_value;
SetCounter : process(clk,rst)
begin
if(rst='0') then
present_value <= (others=> '0'); -- after reseting, start from A and B phase low state
present_state <= state_00;
elsif(clk'Event and clk ='1') then
case present_state is
when state_00 =>
if(next_state = state_10)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_01)then -- CW direction
present_value <= present_value - 1;
end if;
when state_10 =>
if(next_state = state_11)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_00)then -- CW direction
present_value <= present_value - 1;
end if;
when state_11 =>
if(next_state = state_01)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_01)then -- CW direction
present_value <= present_value - 1;
end if;
when state_01 =>
if(next_state = state_00)then -- CCW direction
present_value <= present_value + 1;
elsif(next_state = state_11)then -- CW direction
present_value <= present_value - 1;
end if;
end case;
present_state <= next_state;
end if;
end process SetCounter;
setDirection: process(present_state, A, B)
begin
case present_state is
when state_00 =>
if(A='1' and B ='0')then
next_state <= state_10;
elsif(A='0' and B ='1')then
next_state <= state_01;
else
next_state <= state_00;
end if;
when state_10 =>
if(A='1' and B ='1')then
next_state <= state_11;
elsif(A='0' and B ='0')then
next_state <= state_00;
else
next_state <= state_10;
end if;
when state_11 =>
if(A='0' and B ='1')then
next_state <= state_01;
elsif(A='1' and B ='0')then
next_state <= state_10;
else
next_state <= state_11;
end if;
when state_01 =>
if(A='0' and B ='0')then
next_state <= state_00;
elsif(A='1' and B ='1')then
next_state <= state_11;
else
next_state <= state_01;
end if;
end case;
end process setDirection;
end rtl_Counter;