OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [pkt_codec_mk2/] [1.0/] [vhd/] [cdc.vhd] - Rev 145

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : CDC (Clock Domain Crossing)
-- Project    : 
-------------------------------------------------------------------------------
-- File       : cdc.vhd
-- Author     : Lasse Lehtonen
-- Company    : 
-- Created    : 2011-10-12
-- Last update: 2011-10-24
-- Platform   : 
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description:
--
-- Generics:
-- 
-- clock_mode_g 0 : single clock
-- clock_mode_g 1 : two asynchronous clocks
--
-------------------------------------------------------------------------------
-- Copyright (c) 2011 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-10-12  1.0      lehton87        Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity cdc is
 
  generic (
    cmd_width_g  : positive;
    data_width_g : positive;
    clock_mode_g : natural);
 
  port (
    clk_ip  : in std_logic;
    clk_net : in std_logic;
    rst_n   : in std_logic;
 
    ip_cmd_out  : out std_logic_vector(cmd_width_g-1 downto 0);
    ip_data_out : out std_logic_vector(data_width_g-1 downto 0);
    ip_stall_in : in  std_logic;
 
    ip_cmd_in    : in  std_logic_vector(cmd_width_g-1 downto 0);
    ip_data_in   : in  std_logic_vector(data_width_g-1 downto 0);
    ip_stall_out : out std_logic;
 
    net_cmd_out  : out std_logic_vector(cmd_width_g-1 downto 0);
    net_data_out : out std_logic_vector(data_width_g-1 downto 0);
    net_stall_in : in  std_logic;
 
    net_cmd_in    : in  std_logic_vector(cmd_width_g-1 downto 0);
    net_data_in   : in  std_logic_vector(data_width_g-1 downto 0);
    net_stall_out : out std_logic);
 
end cdc;
 
 
architecture rtl of cdc is
 
  signal ip_in_cd     : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal net_in_cd    : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal ip_out_cd    : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal net_out_cd   : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal ip_out_cd_r  : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal net_out_cd_r : std_logic_vector(cmd_width_g+data_width_g-1 downto 0);
  signal ip_we        : std_logic;
  signal net_we       : std_logic;
  signal ip_re        : std_logic;
  signal net_re       : std_logic;
  signal ip_empty     : std_logic;
  signal net_empty    : std_logic;
 
 
begin  -- rtl
 
  -----------------------------------------------------------------------------
  -- ONE CLOCK
  --
  -- Just a direct combinatorial connection
  -----------------------------------------------------------------------------
  clock_mode_0 : if clock_mode_g = 0 generate
 
    ip_cmd_out    <= net_cmd_in;
    ip_data_out   <= net_data_in;
    net_stall_out <= ip_stall_in;
 
    net_cmd_out  <= ip_cmd_in;
    net_data_out <= ip_data_in;
    ip_stall_out <= net_stall_in;
 
  end generate clock_mode_0;
 
  -----------------------------------------------------------------------------
  -- TWO ASYNCHRONOUS CLOCKS
  -----------------------------------------------------------------------------
  clock_mode_1 : if clock_mode_g = 1 generate
 
    ---------------------------------------------------------------------------
    -- FROM IP TO NET
    ---------------------------------------------------------------------------
    ip_in_cd <= ip_cmd_in & ip_data_in;
    net_re   <= not net_stall_in;
 
    ip_we_p : process (ip_cmd_in)
    begin  -- process ip_we_p
      if ip_cmd_in /= "00" then
        ip_we <= '1';
      else
        ip_we <= '0';
      end if;
    end process ip_we_p;
 
    fifo_ip2net : entity work.fifo_2clk
      generic map (
        data_width_g => cmd_width_g+data_width_g,
        depth_g      => 4)
      port map (
        rst_n => rst_n,
 
        clk_wr   => clk_ip,
        we_in    => ip_we,
        data_in  => ip_in_cd,
        full_out => ip_stall_out,
 
        clk_rd    => clk_net,
        re_in     => net_re,
        data_out  => net_out_cd,
        empty_out => net_empty);
 
    sto1_p: process (clk_net, rst_n)
    begin  -- process sto1_p
      if rst_n = '0' then               -- asynchronous reset (active low)
        net_out_cd_r <= (others => '0');
      elsif clk_net'event and clk_net = '1' then  -- rising clock edge
        if net_stall_in = '0' and net_empty = '0' then
          net_out_cd_r <= net_out_cd;
        end if;        
      end if;
    end process sto1_p;
 
    net_outs_p: process (net_stall_in, net_empty, net_out_cd, net_out_cd_r)
    begin  -- process net_outs_p
      if net_stall_in = '1' then
        net_cmd_out <= net_out_cd_r(cmd_width_g+data_width_g-1 downto
                                    data_width_g);
        net_data_out <= net_out_cd_r(data_width_g-1 downto 0);
      elsif net_empty = '1' then
        net_cmd_out <= (others => '0');
        net_data_out <= (others => '0');
      else
        net_cmd_out <= net_out_cd(cmd_width_g+data_width_g-1 downto
                                  data_width_g);
        net_data_out <= net_out_cd(data_width_g-1 downto 0);
      end if;
    end process net_outs_p;
 
    ---------------------------------------------------------------------------
    -- FROM NET TO IP
    ---------------------------------------------------------------------------
    net_in_cd <= net_cmd_in & net_data_in;
    ip_re     <= not ip_stall_in;
 
    net_we_p : process (net_cmd_in)
    begin  -- process ip_we_p
      if net_cmd_in /= "00" then
        net_we <= '1';
      else
        net_we <= '0';
      end if;
    end process net_we_p;
 
    fifo_net2ip : entity work.fifo_2clk
      generic map (
        data_width_g => cmd_width_g+data_width_g,
        depth_g      => 4)
      port map (
        rst_n => rst_n,
 
        clk_wr   => clk_net,
        we_in    => net_we,
        data_in  => net_in_cd,
        full_out => net_stall_out,
 
        clk_rd    => clk_ip,
        re_in     => ip_re,
        data_out  => ip_out_cd,
        empty_out => ip_empty);
 
    sto2_p: process (clk_ip, rst_n)
    begin  -- process sto1_p
      if rst_n = '0' then               -- asynchronous reset (active low)
        ip_out_cd_r <= (others => '0');
      elsif clk_ip'event and clk_ip = '1' then  -- rising clock edge
        if ip_stall_in = '0' and ip_empty = '0' then
          ip_out_cd_r <= ip_out_cd;
        end if;        
      end if;
    end process sto2_p;
 
    ip_outs_p: process (ip_stall_in, ip_empty, ip_out_cd, ip_out_cd_r)
    begin  -- process net_outs_p
      if ip_stall_in = '1' then
        ip_cmd_out <= ip_out_cd_r(cmd_width_g+data_width_g-1 downto
                                  data_width_g);
        ip_data_out <= ip_out_cd_r(data_width_g-1 downto 0);
      elsif ip_empty = '1' then
        ip_cmd_out <= (others => '0');
        ip_data_out <= (others => '0');
      else
        ip_cmd_out <= ip_out_cd(cmd_width_g+data_width_g-1 downto
                                  data_width_g);
        ip_data_out <= ip_out_cd(data_width_g-1 downto 0);
      end if;
    end process ip_outs_p;
 
  end generate clock_mode_1;
 
end rtl;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.