синхронизатор шин данных между частотными регионамиКод
library ieee;
use ieee.std_logic_1164.all;
entity indpClkDataBufferStd is
generic(
DW : natural := 32;
RST_ACTIVE_SRC : std_logic := '1';
RST_ACTIVE_DEST : std_logic := '1'
);
port(
clk_src : in std_logic;
clk_dest : in std_logic;
rst_src : in std_logic;
rst_dest : in std_logic;
src_rdy_i : in std_logic;
src_data_i : in std_logic_vector(DW - 1 downto 0);
dest_rdy_o : out std_logic;
src_rdy_o : out std_logic;
dest_data_o : out std_logic_vector(DW - 1 downto 0)
);
end indpClkDataBufferStd;
architecture rtl of indpClkDataBufferStd is
type state_src_t is (IDLE, WAIT_ACK, ACK);
signal state_src : state_src_t;
signal ack_b : std_logic; -- trigger for latching signal from dest_ctrl
signal ack_b2 : std_logic; -- trigger for latching signal from dest_ctrl
type state_dest_t is (IDLE, ACK);
signal state_dest : state_dest_t;
signal req_b : std_logic; -- trigger for latch signal from src_ctrl
signal req_b2 : std_logic; -- trigger for latch signal from src_ctrl
signal ack_dest_src : std_logic;
signal req_src_dest : std_logic;
signal data_src_dest : std_logic_vector(DW - 1 downto 0);
begin
src_ctrl_proc : process(clk_src, rst_src)
begin
if rst_src = RST_ACTIVE_SRC then
data_src_dest <= (others => '0');
req_src_dest <= '0';
src_rdy_o <= '0';
state_src <= IDLE;
ack_b <= '0';
elsif rising_edge(clk_src) then
ack_b <= ack_dest_src; -- base synchronize
ack_b2 <= ack_b;
case state_src is
when IDLE =>
src_rdy_o <= '0';
if (src_rdy_i = '1') then
state_src <= WAIT_ACK;
data_src_dest <= src_data_i; -- latching data bus from source to dest_ctrl
req_src_dest <= '1';
end if;
when WAIT_ACK =>
if (ack_b2 = '1') then -- when dest_ctrl get data, req_o = '0'
req_src_dest <= '0';
state_src <= ACK;
end if;
when ACK =>
if (ack_b2 = '0') then -- when dest_ctrl ack='0' go to IDLE
state_src <= IDLE;
src_rdy_o <= '1';
end if;
end case;
end if;
end process;
dest_ctrl_proc : process(clk_dest, rst_dest)
begin
if rst_dest = RST_ACTIVE_DEST then
ack_dest_src <= '0';
dest_data_o <= (others => '0');
state_dest <= IDLE;
req_b <= '0';
req_b2 <= '0';
dest_rdy_o <= '0';
elsif rising_edge(clk_dest) then
req_b <= req_src_dest;
req_b2 <= req_b;
case state_dest is
when IDLE =>
if (req_b2 = '1') then -- when request from src_cotrol, latch data bus, form acknowledge
dest_data_o <= data_src_dest;
dest_rdy_o <= '1';
ack_dest_src <= '1';
state_dest <= ACK;
end if;
when ACK =>
dest_rdy_o <= '0';
if (req_b2 = '0') then -- when req from src_ctrl is '0', ack_0 = '0', go to IDLE
ack_dest_src <= '0';
state_dest <= IDLE;
end if;
end case;
end if;
end process;
end rtl;
синхронизатор стробов между частотными регионамиКод
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
entity IndpClkStb is
generic(
RST_ACTIVE_SRC : std_logic := '1';
RST_ACTIVE_DEST : std_logic := '1'
);
port(
clk_src : in std_logic;
rst_src : in std_logic;
data_i : in std_logic;
clk_dest : in std_logic;
rst_dest : in std_logic;
data_o : out std_logic
);
end entity IndpClkStb;
architecture RTL of IndpClkStb is
type state_src_t is (IDLE, WAIT_ACK, ACK);
signal state_src : state_src_t;
type state_dest_t is (IDLE, ACK);
signal state_dest : state_dest_t;
signal hardshake_req : std_logic;
signal req_z : std_logic;
signal req_z2 : std_logic;
signal handshake_ack : std_logic;
signal ack_z : std_logic;
signal ack_z2 : std_logic;
begin
--================================================================================
====================================
--=========== автомат состояний входа
--================================================================================
====================================
proc_scr_ctrl : process(clk_src, rst_src)
begin
if (rst_src = RST_ACTIVE_SRC) then
hardshake_req <= '0';
state_src <= IDLE;
elsif rising_edge(clk_src) then
ack_z <= handshake_ack;
ack_z2 <= ack_z;
case state_src is
when IDLE =>
if (data_i = '1') then
state_src <= WAIT_ACK;
hardshake_req <= '1';
end if;
when WAIT_ACK =>
if (ack_z2 = '1') then
hardshake_req <= '0';
state_src <= ACK;
end if;
when ACK =>
if (ack_z2 = '0') then
state_src <= IDLE;
end if;
end case;
end if;
end process;
--================================================================================
====================================
--=========== автомат состояний выхода
--================================================================================
====================================
proc_dest_ctrl : process(clk_dest, rst_dest)
begin
if (rst_dest = RST_ACTIVE_DEST) then
handshake_ack <= '0';
state_dest <= IDLE;
data_o <= '0';
elsif rising_edge(clk_dest) then
req_z <= hardshake_req;
req_z2 <= req_z;
case state_dest is
when IDLE =>
if (req_z2 = '1') then
data_o <= '1';
handshake_ack <= '1';
state_dest <= ACK;
end if;
when ACK =>
data_o <= '0';
if (req_z2 = '0') then
handshake_ack <= '0';
state_dest <= IDLE;
end if;
end case;
end if;
end process;
end architecture RTL;