Стараюсь писать как можно понятнее. И самому легче и ошибок меньше.
Мне понятнее так:
CODE
entity sig is
Port ( CLK : in STD_LOGIC;
reset : in std_logic; -- sync reset
btn : in STD_LOGIC;
vix : out STD_LOGIC);
end sig;
architecture Behavioral of sig is
type state_t is (st_idle, st_button_pressed, st_wait_depress);
signal state_reg : state_t;
begin
process (CLK, reset)
if rising_edge(CLK) then
if reset='1' then
button_reg1 <= '0';
button_reg <= '0';
else
button_reg1 <= btn;
button_reg <= button_reg1;
end if;
end process;
process (CLK, reset)
begin
if rising_edge(CLK) then
viz <= '0'; -- by default
if reset='1' then
state_reg <= st_idle;
else
case state_reg is
when st_idle =>
if button_reg='1' then
state_reg <= st_button_pressed;
end if; -- else keep state_reg
when st_button_pressed =>
viz <= '1'; -- 1 cycle pulse
if button_reg='1' then
state_reg <= st_wait_depress;
else
state_reg <= st_idle;
end if;
when st_wait_depress =>
if button_reg='0' then
state_reg <= st_idle;
end if;
end case;
end if;
end if;
end process;
end Behavioral;
Сразить метастабильность можно еще так (версия для xilinx):
CODE
-- reduce probability of metastable effect
library IEEE;
use IEEE.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
entity sync is
generic (
LENGTH : natural := 2;
PATH_COUNT : natural := 3
);
port (
clk : in std_logic;
d : in std_logic;
q : out std_logic
);
end sync;
architecture v2p of sync is
function majority(a : std_logic_vector) return std_logic is
variable c0, c1 : natural;
begin
c0 := 0; c1 := 0;
for i in a'range loop
if a(i)='1' then c1:=c1+1; end if;
if a(i)='0' then c0:=c0+1; end if;
end loop;
if c0>c1 then return '0'; else return '1'; end if;
end;
subtype path_t is std_logic_vector(0 to PATH_COUNT-1);
type path_vector is array (natural range <>) of path_t;
signal x : path_vector(0 to LENGTH);
attribute syn_keep : boolean;
attribute syn_keep of x : signal is true;
begin
-- generate chains of ff, prevent shift register instantiation
path_gen : for path in 0 to PATH_COUNT-1 generate
x(0)(path) <= d;
chain_gen : for stage in 0 to LENGTH-1 generate
fd_inst : FD port map(C=>clk, D=>x(stage)(path), Q=>x(stage+1)(path));
end generate;
end generate;
-- registered majority output
process(clk)
begin
if rising_edge(clk) then
q <= majority(x(LENGTH));
end if;
end process;
end v2p;
Причина редактирования: Уменьшение видимого размера цитаты исходника.