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.

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3.  
  4.  
  5. entity clk_bridge is
  6.   Generic(
  7.     CLK_COMPARE : integer range 0 to 1 := 0;
  8. --if in_clk_A > in_clk_B; 0 else 1;
  9.     DATA_WIDTH : integer := 8
  10.    
  11.   );
  12.   Port (
  13.     in_rst : in std_logic;
  14.     in_clk_A : in std_logic;
  15.     in_clk_B : in std_logic;
  16.     in_data_A_vld : in std_logic;
  17.     in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  18.     out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  19.     out_data_B_vld : out std_logic  
  20.    
  21.   );
  22. end clk_bridge;
  23.  
  24. architecture Behavioral of clk_bridge is
  25.  
  26.     component cdc_down
  27.         generic(
  28.             DATA_WIDTH : integer := 8
  29.         );
  30.         Port (
  31.             in_rst : in std_logic;
  32.             in_clk_A : in std_logic;
  33.             in_clk_B : in std_logic;
  34.             in_data_A_vld : in std_logic;
  35.             in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  36.             out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  37.             out_data_B_vld : out std_logic
  38.                    
  39.         );    
  40.     end component;
  41.    
  42.     component cdc_up
  43.         generic(
  44.             DATA_WIDTH : integer := 8
  45.         );
  46.         Port (
  47.             in_rst : in std_logic;
  48.             in_clk_A : in std_logic;
  49.             in_clk_B : in std_logic;
  50.             in_data_A_vld : in std_logic;
  51.             in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  52.             out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  53.             out_data_B_vld : out std_logic            
  54.         );    
  55.     end component;
  56. begin
  57.  
  58.     cdc_down_if : if CLK_COMPARE = 0 generate
  59.         cdc_down_map : cdc_down
  60.         generic map(
  61.             DATA_WIDTH => DATA_WIDTH
  62.         )
  63.         Port map(
  64.             in_rst => in_rst,
  65.             in_clk_A => in_clk_A,
  66.             in_clk_B => in_clk_B,
  67.             in_data_A_vld => in_data_A_vld,
  68.             in_data_A => in_data_A,
  69.             out_data_B => out_data_B,
  70.             out_data_B_vld =>  out_data_B_vld                    
  71.         );          
  72.     end generate cdc_down_if;
  73.     cdc_up_if : if CLK_COMPARE = 1 generate
  74.         cdc_up_map : cdc_up
  75.         generic map(
  76.             DATA_WIDTH => DATA_WIDTH
  77.         )
  78.         Port map(
  79.             in_rst => in_rst,
  80.             in_clk_A => in_clk_A,
  81.             in_clk_B => in_clk_B,
  82.             in_data_A_vld => in_data_A_vld,
  83.             in_data_A => in_data_A,
  84.             out_data_B => out_data_B,
  85.             out_data_B_vld =>  out_data_B_vld                    
  86.         );
  87.     end generate cdc_up_if;
  88.  
  89. end Behavioral;
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3.  
  4. entity cdc_down is
  5.     generic(
  6.         DATA_WIDTH : integer := 8
  7.     );
  8.     Port (
  9.         in_rst : in std_logic;
  10.         in_clk_A : in std_logic;
  11.         in_clk_B : in std_logic;
  12.         in_data_A_vld : in std_logic;
  13.         in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  14.         out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  15.         out_data_B_vld : out std_logic
  16.                
  17.     );
  18. end cdc_down;
  19.  
  20. architecture Behavioral of cdc_down is
  21.    
  22.     signal r_data_A : std_logic_vector(DATA_WIDTH - 1 downto 0)
  23.      := (others => '0');
  24.     signal r_data_B : std_logic_vector(DATA_WIDTH - 1 downto 0)
  25.      := (others => '0');
  26.     signal r_handshake_A : std_logic := '0';
  27.     signal r_handshake_B : std_logic := '0';
  28.  
  29. begin
  30.  
  31.     out_data_B <= r_data_B;
  32.     out_data_B_vld <= r_handshake_B;
  33.  
  34.     process(in_clk_A, in_rst)
  35.     begin
  36.         if in_rst = '1' then
  37.             r_handshake_A <= '0';  
  38.             r_data_A <= (others => '0');
  39.  
  40.         elsif rising_edge(in_clk_A) then
  41.             if in_data_A_vld = '1' and r_handshake_A = '0' then
  42.                 r_data_A <= in_data_A;
  43.                 r_handshake_A <= '1';
  44.             else
  45.                 if r_handshake_B = '1' then
  46.                     r_handshake_A <= '0';
  47.                  end if;
  48.             end if;
  49.         end if;
  50.     end process;
  51.  
  52.     process(in_clk_B, in_rst)
  53.     begin
  54.         if in_rst = '1' then
  55.             r_handshake_B <= '0';
  56.             r_data_B <= (others => '0');
  57.         elsif rising_edge(in_clk_B) then
  58.             if r_handshake_B = '0' and r_handshake_A = '1'  then
  59.                 r_handshake_B <= '1';
  60.                 r_data_B <= r_data_A;          
  61.             elsif r_handshake_A = '0' then
  62.                 r_handshake_B <= '0';      
  63.             end if;
  64.         end if;    
  65.     end process;
  66.  
  67. end Behavioral;
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3.  
  4. entity cdc_up is
  5.     generic(
  6.         DATA_WIDTH : integer := 8
  7.     );
  8.     Port (
  9.         in_rst : in std_logic;
  10.         in_clk_A : in std_logic;
  11.         in_clk_B : in std_logic;
  12.         in_data_A_vld : in std_logic;
  13.         in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  14.         out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  15.         out_data_B_vld : out std_logic            
  16.     );
  17. end cdc_up;
  18.  
  19. architecture Behavioral of cdc_up is
  20.     signal r_data_cnt : std_logic_vector(3 downto 0) := (others => '0');
  21. begin
  22.    
  23.     out_data_B <= in_data_A when r_data_cnt(3 downto 2) = "01"
  24.      else (others => '0');
  25.     out_data_B_vld <= '1' when r_data_cnt(3 downto 2) = "01"
  26.      else '0';
  27.    
  28.     process(in_clk_B, in_rst)
  29.     begin
  30.         if in_rst = '1' then
  31.             r_data_cnt <= (others => '0');
  32.         elsif rising_edge(in_clk_B) then
  33.             r_data_cnt <= r_data_cnt(2 downto 0) & in_data_A_vld;
  34.         end if;
  35.     end process;
  36. end Behavioral;
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  4.  
  5. entity tb_clk_bridge is
  6. end tb_clk_bridge;
  7.  
  8. architecture Behavioral of tb_clk_bridge is
  9.  
  10. component clk_bridge
  11. Generic(
  12. CLK_COMPARE : integer range 0 to 1 := 0;
  13. DATA_WIDTH : integer := 8
  14.  
  15. );
  16. Port (
  17. in_rst : in std_logic;
  18. in_clk_A : in std_logic;
  19. in_clk_B : in std_logic;
  20. in_data_A_vld : in std_logic;
  21. in_data_A : in std_logic_vector(DATA_WIDTH - 1 downto 0);
  22. out_data_B : out std_logic_vector(DATA_WIDTH - 1 downto 0);
  23. out_data_B_vld : out std_logic
  24. );
  25. end component;
  26.  
  27. constant DATA_WIDTH : integer := 8;
  28. constant PERIOD_CLK_A :time := 10 us;
  29. constant PERIOD_CLK_B :time := 1 us;
  30. signal in_clk_A : std_logic := '0';
  31. signal in_clk_B : std_logic := '0';
  32. signal in_data_A_vld : std_logic := '0';
  33. signal in_data_A : std_logic_vector(DATA_WIDTH - 1 downto 0)
  34. := (others => '0');
  35. signal out_data_B : std_logic_vector(DATA_WIDTH - 1 downto 0)
  36. := (others => '0');
  37. signal out_data_B_vld : std_logic := '0';
  38.  
  39. begin
  40. process
  41. begin
  42. in_clk_A <= '1';
  43. wait for PERIOD_CLK_A / 2;
  44. in_clk_A <= '0';
  45. wait for PERIOD_CLK_A / 2;
  46. end process;
  47.  
  48. process
  49. begin
  50. in_clk_B <= '1';
  51. wait for PERIOD_CLK_B / 2;
  52. in_clk_B <= '0';
  53. wait for PERIOD_CLK_B / 2;
  54. end process;
  55.  
  56. process
  57. begin
  58. in_data_A_vld <= '0';
  59. wait for PERIOD_CLK_A * 19;
  60. in_data_A_vld <= '1';
  61. wait for PERIOD_CLK_A;
  62. end process;
  63.  
  64. process(in_data_A_vld)
  65. begin
  66. if in_data_A_vld = '1' then
  67. in_data_A <= in_data_A + 1;
  68. end if;
  69. end process;
  70.  
  71.  
  72. clk_bridge_map : clk_bridge
  73. Generic map(
  74. CLK_COMPARE => 1, --f_clk_a <= f_clk_b
  75. DATA_WIDTH => DATA_WIDTH
  76. )
  77. Port map(
  78. in_rst => '0',
  79. in_clk_A => in_clk_A,
  80. in_clk_B => in_clk_B,
  81. in_data_A_vld => in_data_A_vld,
  82. in_data_A => in_data_A,
  83. out_data_B => out_data_B,
  84. out_data_B_vld => out_data_B_vld
  85. );
  86.  
  87. end Behavioral;