I am not sure that we can think about optimization on this small code sample
- Often company design rules will compel you to have an asynchronous reset assertion and synchronous de-assertion
- 50% of the time you will not have a 'cond' signal synchronous of the clock so that you will have to double sample it anyway
So we can take advantage of these constraints to elaborate a somewhat proper ( imho ) reset state by de-asserting the internal reset after 3 clock periods, taking into account that the double sampling of COND will take 2 clock periods.
By this way we may benefit from (almost) one clock period stable reset state.
But for sure you may do this on FPGA where you can export a data signal ( here the internal reset compared to the external RESET_N) to a "clock" distribution "grid".
The code is given for information below and and you may find it under EDA Playground
library IEEE;
use IEEE.std_logic_1164.all;
entity state_machine is
port ( CLOCK : in std_logic;
RESET_N : in std_logic;
COND : in std_logic;
OUTPUT : out std_logic_vector(7 downto 0));
end entity;
architecture rtl of state_machine is
type state_type is ( S1, S2, S3, S4);
signal state, next_state : state_type;
signal reset_state : state_type;
constant RSYNC_LENGTH : natural := 3;
signal reset : std_logic;
signal reset_v : std_logic_vector(RSYNC_LENGTH-1 downto 0);
signal scond : std_logic;
signal scond_q1 : std_logic;
signal outbuf : std_logic_vector(7 downto 0);
begin
reset_sync: process(CLOCK,RESET_N)
begin
if RESET_N = '0' then
reset_v <= (others => '1');
elsif rising_edge(CLOCK) then
reset_v(0) <= '0';
reset_v(RSYNC_LENGTH-1 downto 1) <= reset_v(RSYNC_LENGTH-2 downto 0);
end if;
end process reset_sync;
reset <= reset_v(RSYNC_LENGTH-1);
sync: process(CLOCK,RESET_N)
begin
if RESET_N = '0' then
scond <= '0';
scond_q1 <= '0';
elsif rising_edge(CLOCK) then
scond_q1 <= COND;
scond <= scond_q1;
end if;
end process sync;
reset_state <= S2 when scond='1' else S1;
SM : process(CLOCK,reset)
begin
if reset = '1' then
state <= reset_state;
elsif ( rising_edge(CLOCK) ) then
state <= next_state;
end if;
end process SM;
statedecoder: process(state)
begin
case ( state ) is
when S1 => next_state <= S2;
outbuf <= x"01";
when S2 => next_state <= S3;
outbuf <= x"02";
when S3 => next_state <= S4;
outbuf <= x"03";
when S4 => next_state <= S1;
outbuf <= x"04";
when others =>
next_state <= S1;
outbuf <= x"00";
end case;
end process statedecoder;
OUTPUT <= outbuf when reset = '0' else x"00";
end architecture rtl;