Aşağıda A saat darbesi frekansında mevcut bir sinyalin B saat darbesi frekansında oluşturulmasını sağlayan VHDL kodları aşağıda verilmiştir.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity clk_bridge is
Generic(
CLK_COMPARE : integer range 0 to 1 := 0;
--if in_clk_A > in_clk_B; 0 else 1;
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end clk_bridge;
architecture Behavioral of clk_bridge is
component cdc_down
generic(
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end component;
component cdc_up
generic(
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end component;
begin
cdc_down_if : if CLK_COMPARE = 0 generate
cdc_down_map : cdc_down
generic map(
DATA_WIDTH => DATA_WIDTH
)
Port map(
in_rst => in_rst,
in_clk_A => in_clk_A,
in_clk_B => in_clk_B,
in_data_A_vld => in_data_A_vld,
in_data_A => in_data_A,
out_data_B => out_data_B,
out_data_B_vld => out_data_B_vld
);
end generate cdc_down_if;
cdc_up_if : if CLK_COMPARE = 1 generate
cdc_up_map : cdc_up
generic map(
DATA_WIDTH => DATA_WIDTH
)
Port map(
in_rst => in_rst,
in_clk_A => in_clk_A,
in_clk_B => in_clk_B,
in_data_A_vld => in_data_A_vld,
in_data_A => in_data_A,
out_data_B => out_data_B,
out_data_B_vld => out_data_B_vld
);
end generate cdc_up_if;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity cdc_down is
generic(
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end cdc_down;
architecture Behavioral of cdc_down is
signal r_data_A : std_logic_vector(DATA_WIDTH - 1 downto 0)
:= (others => '0');
signal r_data_B : std_logic_vector(DATA_WIDTH - 1 downto 0)
:= (others => '0');
signal r_handshake_A : std_logic := '0';
signal r_handshake_B : std_logic := '0';
begin
out_data_B <= r_data_B;
out_data_B_vld <= r_handshake_B;
process(in_clk_A, in_rst)
begin
if in_rst = '1' then
r_handshake_A <= '0';
r_data_A <= (others => '0');
elsif rising_edge(in_clk_A) then
if in_data_A_vld = '1' and r_handshake_A = '0' then
r_data_A <= in_data_A;
r_handshake_A <= '1';
else
if r_handshake_B = '1' then
r_handshake_A <= '0';
end if;
end if;
end if;
end process;
process(in_clk_B, in_rst)
begin
if in_rst = '1' then
r_handshake_B <= '0';
r_data_B <= (others => '0');
elsif rising_edge(in_clk_B) then
if r_handshake_B = '0' and r_handshake_A = '1' then
r_handshake_B <= '1';
r_data_B <= r_data_A;
elsif r_handshake_A = '0' then
r_handshake_B <= '0';
end if;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity cdc_up is
generic(
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end cdc_up;
architecture Behavioral of cdc_up is
signal r_data_cnt : std_logic_vector(3 downto 0) := (others => '0');
begin
out_data_B <= in_data_A when r_data_cnt(3 downto 2) = "01"
else (others => '0');
out_data_B_vld <= '1' when r_data_cnt(3 downto 2) = "01"
else '0';
process(in_clk_B, in_rst)
begin
if in_rst = '1' then
r_data_cnt <= (others => '0');
elsif rising_edge(in_clk_B) then
r_data_cnt <= r_data_cnt(2 downto 0) & in_data_A_vld;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tb_clk_bridge is
end tb_clk_bridge;
architecture Behavioral of tb_clk_bridge is
component clk_bridge
Generic(
CLK_COMPARE : integer range 0 to 1 := 0;
DATA_WIDTH : integer := 8
);
Port (
in_rst : in std_logic;
in_clk_A : in std_logic;
in_clk_B : in std_logic;
in_data_A_vld : in std_logic;
in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
out_data_B_vld : out std_logic
);
end component;
constant DATA_WIDTH : integer := 8;
constant PERIOD_CLK_A :time := 10 us;
constant PERIOD_CLK_B :time := 1 us;
signal in_clk_A : std_logic := '0';
signal in_clk_B : std_logic := '0';
signal in_data_A_vld : std_logic := '0';
signal in_data_A : std_logic_vector(DATA_WIDTH - 1 downto 0)
:= (others => '0');
signal out_data_B : std_logic_vector(DATA_WIDTH - 1 downto 0)
:= (others => '0');
signal out_data_B_vld : std_logic := '0';
begin
process
begin
in_clk_A <= '1';
wait for PERIOD_CLK_A / 2;
in_clk_A <= '0';
wait for PERIOD_CLK_A / 2;
end process;
process
begin
in_clk_B <= '1';
wait for PERIOD_CLK_B / 2;
in_clk_B <= '0';
wait for PERIOD_CLK_B / 2;
end process;
process
begin
in_data_A_vld <= '0';
wait for PERIOD_CLK_A * 19;
in_data_A_vld <= '1';
wait for PERIOD_CLK_A;
end process;
process(in_data_A_vld)
begin
if in_data_A_vld = '1' then
in_data_A <= in_data_A + 1;
end if;
end process;
clk_bridge_map : clk_bridge
Generic map(
CLK_COMPARE => 1, --f_clk_a <= f_clk_b
DATA_WIDTH => DATA_WIDTH
)
Port map(
in_rst => '0',
in_clk_A => in_clk_A,
in_clk_B => in_clk_B,
in_data_A_vld => in_data_A_vld,
in_data_A => in_data_A,
out_data_B => out_data_B,
out_data_B_vld => out_data_B_vld
);
end Behavioral;