📄 sync.vhd
字号:
--
-- Sychronizer circuit, and read control, as well as stall generation. Assumes that read port
-- cannot keep up with the write circuit, and hence generates a stall signal that disables the
-- write port. The source of the data must stop inputing data until the stall goes away.
-- Signalling between the read and write circuits is double buffered to prevent metastability.
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
library WORK1;
use WORK1.SER_PAR_LIB.all;
entity SYNC is
generic(
ENABLE_READ_STALL:INTEGER;
ENABLE_WRITE_STALL:INTEGER
);
port (
RESET: in STD_LOGIC;
RD_CLK: in STD_LOGIC;
WR_CLK: in STD_LOGIC;
DECREMENT_BCOUNT: in STD_LOGIC;
INCREMENT_BCOUNT: in STD_LOGIC;
ENABLE_IN: in STD_LOGIC;
WRITE_ENABLE: out STD_LOGIC;
READ_ENABLE: out STD_LOGIC
);
end SYNC;
architecture SYNC_arch of SYNC is
signal INCREMENT_BCOUNT_CAPTURED: STD_LOGIC;
signal INCREMENT_BCOUNT_METASTABLE: STD_LOGIC;
signal INCREMENT: STD_LOGIC;
signal BUFFER_COUNT: INTEGER range 0 to 3;
signal EMPTY: STD_LOGIC;
signal FULL: STD_LOGIC;
signal FULL_METASTABLE: STD_LOGIC;
signal FULL_SYNCED: STD_LOGIC;
begin
--
-- CAPTURE RISING EDGE OF INCREMENT BUFFER COUNT
--
process (INCREMENT_BCOUNT, RESET, INCREMENT)
begin
if (RESET='1' or INCREMENT='1')then
INCREMENT_BCOUNT_CAPTURED <= '0';
elsif INCREMENT_BCOUNT='1' and INCREMENT_BCOUNT'event then
INCREMENT_BCOUNT_CAPTURED <= '1';
end if;
end process;
--
-- Synchronize the INCREMENT_BUFFER_COUNT signal to the READ clock and one shot it
--
process (RD_CLK, RESET)
begin
if RESET='1' then
INCREMENT_BCOUNT_METASTABLE <= '0';
INCREMENT <= '0';
elsif RD_CLK='1' and RD_CLK'event then
INCREMENT_BCOUNT_METASTABLE <= (INCREMENT_BCOUNT_CAPTURED and (not INCREMENT));
INCREMENT <= (INCREMENT_BCOUNT_METASTABLE and (not INCREMENT));
end if;
end process;
--
-- Set flag to begin reading data, control BUFFER COUNTER, AND EMPTY/FULL FLAGS
--
-- Begine
--
process (RD_CLK, RESET)
begin
if RESET='1' then
BUFFER_COUNT <= 0;
EMPTY <= '1' ;
FULL <= '0';
elsif RD_CLK='1' and RD_CLK'event then
if (DECREMENT_BCOUNT='1' and INCREMENT='0') then
BUFFER_COUNT <= BUFFER_COUNT - 1;
elsif (DECREMENT_BCOUNT='0' and INCREMENT='1') then
BUFFER_COUNT <= BUFFER_COUNT + 1;
end if;
if BUFFER_COUNT = 0 then
EMPTY <= '1' ;
FULL <= '0';
elsif BUFFER_COUNT = 2 then
EMPTY <= '0' ;
FULL <= '1';
else
EMPTY <= '0';
FULL <= '0';
end if;
end if;
end process;
--
-- READ ENABLE GENERATION
--
process (RD_CLK, RESET)
begin
if RESET='1' then
READ_ENABLE <= '0';
elsif RD_CLK='1' and RD_CLK'event then
if (ENABLE_READ_STALL=1 and EMPTY='1') then
READ_ENABLE <= '0';
else
READ_ENABLE <= '1';
end if;
end if;
end process;
--
-- Synchronize Full flag to write clock
--
process (WR_CLK, RESET)
begin
if RESET='1' then
FULL_METASTABLE <= '0';
FULL_SYNCED <= '0';
elsif WR_CLK='1' and WR_CLK'event then
FULL_METASTABLE <= FULL;
FULL_SYNCED <= FULL_METASTABLE;
end if;
end process;
--
-- WRITE ENABLE GENERATION
--
process (WR_CLK, RESET)
begin
if RESET='1' then
WRITE_ENABLE <= '0';
elsif WR_CLK='1' and WR_CLK'event then
if (ENABLE_IN = '0' or (ENABLE_WRITE_STALL=1 and FULL_SYNCED='1')) then
WRITE_ENABLE <= '0';
else
WRITE_ENABLE <= '1';
end if;
end if;
end process;
end SYNC_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -