VHDL ile Clock Domain Crossing İşlemi
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;