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.storage/] [fifos/] [synch_fifos/] [1.0/] [vhd/] [fifo_mixed_clocks.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- File        : fifo_mixed_clocks.vhdl
-- Description : Mixed Clocks fifo buffer for hibi interface
-- Author      : Ari Kulmala
-- Date        : 19.06.2003
-- Modified    : 
--
-- _almost_ works. Empty signal isn't behaving as expected when 
-- concurrent read and write occurs. It's probably just a little
-- human err somewhere. Also has to check that full really works, even though
-- testbench says it does.
--
--
-- !NOTE!
-- * Output is rubbish when empty. (doesn't speed this up if otherwise).
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
 
entity mixed_clocks_fifo is
 
  generic (
    width : integer := 0;
    depth : integer := 0);
 
  port (
    Clk_In       : in  std_logic;
    Clk_Out      : in  std_logic;
    Rst_n        : in  std_logic;       -- Active low
    Data_In      : in  std_logic_vector (width-1 downto 0);
    Write_Enable : in  std_logic;
-- One_Place_Left : out std_logic;
    Full         : out std_logic;
    Data_Out     : out std_logic_vector (width-1 downto 0);
    Read_Enable  : in  std_logic;
    Empty        : out std_logic
-- One_Data_Left : out std_logic
    );
 
end mixed_clocks_fifo;
 
architecture behavioral of mixed_clocks_fifo is
  type reg is array (depth-1 downto 0) of std_logic_vector
    (width-1 downto 0);
  signal Input_Buffer : reg;
  signal Full_reg   : std_logic;
  signal Empty_reg  : std_logic;
--  signal Full_register   : std_logic register;
--  signal Empty_register  : std_logic register;
  signal Write_token  : integer range 0 to depth-1;
  signal Read_token   : integer range 0 to depth-1;
  --  if write catches read (full)
  signal Write_Turned : std_logic;
  signal Read_got : std_logic;
 
begin  -- behavioral
 
  -- Continious assignments
 Full <= Full_reg;
 Empty <=  Empty_reg;
 Data_Out <=  Input_Buffer(Read_token);
 
  -- purpose: Read from the FIFO
  Read : process (Clk_Out, Rst_n)
  begin  -- process Read
    if Rst_n = '0' then                 -- asynchronous reset (active low)
      Read_token <= 0;
--      Empty_reg <=  '1';
 
    elsif Clk_Out'event and Clk_Out = '1' then  -- rising clock edge
      if Read_Enable = '1' then
 
        if Empty_reg = '0' then
 --         Full_reg <=  '0';
          if Read_token = depth-1 then
            Read_token <= 0;
          else
            Read_token <= Read_token+1;
          end if;
 
--            if Read_token = Write_token then
--              Empty_reg = '1';
--            else
--              Empty_reg = '0';
--           end if;
 
        else
          Read_token <= Read_token;
        end if;
      end if;
 
    else
      Read_token <= Read_token;
    end if;
  end process Read;
 
  -- purpose: Write to the FIFO
  -- type   : sequential
  Write : process (Clk_In, Rst_n)
  begin  -- process Write
    if Rst_n = '0' then                 -- asynchronous reset (active low)
      Write_token <= 0;
--      Full_reg <= '0';
 
    elsif Clk_In'event and Clk_In = '1' then  -- rising clock edge
      if Write_Enable = '1' then
 
        if Full_reg = '0' then
          Input_Buffer(Write_token) <= Data_In;  -- Write_token < depth
--          Empty_reg <=  '0';
          if Write_token = depth-1 then
            Write_token <= 0;
          else
            Write_token <= Write_token+1;
          end if;
 
--            if Write_token = Read_token then
-- --             Full_reg <= '1'
--             Write_Turned <= '1';
--            else
-- --             Full_reg <= '0':
--              Write_Turned <= '0';
--            end if;
        else
--          Write_Turned   <= Write_Turned;
          Input_Buffer   <= Input_Buffer;
          Write_token    <= Write_token;
        end if;
      end if;
 
    else
--      Write_Turned <= Write_Turned;
      Input_Buffer <= Input_Buffer;
      Write_token  <= Write_token;
    end if;
 
  end process Write;
 
RESET: process (Clk_In, Clk_Out, Rst_n)
 
  -- ONLY READ CAN PUT EMPTY HIGH
begin  -- process RESET
  if Rst_n = '0' then                   -- asynchronous reset (active low)
    Full_reg  <= '0';
    Empty_reg <= '1';
    Write_Turned <=  '0';
  elsif Clk_Out'event and Clk_Out = '1' then    -- rising clock edge
 
-- READ
 
    if Write_token = Read_token then
      if Read_Enable = '1' and Write_Enable = '1' then
        if Full_reg = '1' then
          Full_reg <=  '0';
          Write_Turned <=  '0';
 --         Empty_reg <=  '0';
--        elsif Empty_reg = '1' then
--          Full_reg <=  '0';
--          Empty_reg <=  '0';
        else
          Full_reg <=  Full_reg;
          Empty_reg <=  Empty_reg;
        end if;
 
--      elsif Write_Enable = '1' and Write_Turned = '0' then
--        Empty_reg <=  '0';
--        Full_reg <=  '0';
      elsif Read_Enable = '1' and Write_Turned = '1' then
--        Empty_reg <=  '0';
        Full_reg <=  '0';
        Write_Turned <=  '0';              
      else
        Full_reg <=  Full_reg;
        Empty_reg <= Empty_reg;
        Write_Turned <=  Write_Turned;
 
      end if;
  -- getting empty
    elsif (Write_token - Read_token = 1 or Write_token - Read_token = -depth+1)
           and Read_Enable = '1' then
      Full_reg  <= '0';
      Empty_reg <= '1';
--    elsif (Write_token - Read_token = -1 or Write_token - Read_token = depth-1)             and Write_Enable = '1' then
--      Full_reg <= '1';
--      Empty_reg <=  '0';
--      Write_Turned <=  '1';              
 
    else
 
--   Full_reg  <= '0';
   Empty_reg <= '0';
 end if;
 
-- ONLY WRITE CAN PUT FULL HIGH
 
  elsif Clk_In'event and Clk_In = '1' then    -- rising clock edge
 
    if Write_token = Read_token then
      if Read_Enable = '1' and Write_Enable = '1' then
        if Full_reg = '1' then
          Full_reg <=  Full_reg;
--          Empty_reg <=  '0';
 --       elsif Empty_reg = '1' then
 --         Full_reg <=  '0';
 --         Empty_reg <=  '0';
        else
          Full_reg <=  Full_reg;
          Empty_reg <=  Empty_reg;
        end if;
 
      elsif Write_Enable = '1' and Write_Turned = '0' then
        Empty_reg <=  '0';
        Full_reg <=  '0';
 --     elsif Read_Enable = '1' and Write_Turned = '1' then
 --       Empty_reg <=  '0';
 --       Full_reg <=  '0';
 --       Write_Turned <=  '0';              
      else
        Full_reg <=  Full_reg;
        Empty_reg <= Empty_reg;
        Write_Turned <=  Write_Turned;
      end if;
 
--    elsif (Write_token - Read_token = 1 or Write_token - Read_token = -depth+1)
--           and Read_Enable = '1' then
 --     Full_reg  <= '0';
--      Empty_reg <= '1';
    elsif (Write_token - Read_token = -1 or Write_token - Read_token = depth-1)             and Write_Enable = '1' then
      Full_reg <= '1';
--      Empty_reg <=  '0';
      Write_Turned <=  '1';              
 
    else
 
   Full_reg  <= '0';
   Empty_reg <= '0';
 end if;
 
 
--  if Write_token = Read_token then
--    if Write_Turned = '1' then
--      Full_reg  <= '1';
--      Empty_reg <= '0';
--    else
 
 
--      Full_reg  <= '0';
--      Empty_reg <= '1';
--    end if;
 
--  else
 
--    Full_reg  <= '0';
--    Empty_reg <= '0';
--  end if;
 
  end if;
end process RESET;
 
 
 
 
--   if Rst_n = '0' then
--     Full_reg  <= '0';
--     Empty_reg <= '1';
--   else
--     Full_reg <=  Full_reg;
--     Empty_reg <= Empty_reg;
--   end if;
-- end process Reset;
 
--   end process FULL_AND_EMPTY;
 
end behavioral;
 
 
 
 
 

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.