Я не уверен, что мы можем подумать об оптимизации на этом небольшом примере кода
- Часто правила разработки компании вынуждают вас иметь асинхронное утверждение сброса и синхронное де-утверждение
- В 50% случаев у вас не будет сигнала «cond», синхронного с часами, так что вам все равно придется удвоить его выборку
Так что мы можем воспользоваться этими ограничениями, чтобы разработать несколькоправильное (imho) состояние сброса путем отмены внутреннего сброса через 3 такта, учитывая, что двойная выборка COND займет 2 такта.
Таким образом, мы можем извлечь выгоду из (почти) состояния стабильного сброса за один тактовый период.
Но вы наверняка можете сделать это на FPGA, где вы можете экспортировать сигнал данных (здесь внутренний сброспо сравнению с внешним RESET_N) в «сетку» распределения «часов».
Код приведен для информации ниже, и вы можете найти его в 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;