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

Subversion Repositories uart_fpga_slow_control_migrated

[/] [uart_fpga_slow_control/] [trunk/] [code/] [gh_fifo_async16_rcsr_wf.vhd] - Rev 27

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

---------------------------------------------------------------------
--	Filename:	gh_fifo_async16_rcsr_wf.vhd
--
--
--	Description:
--		a simple Asynchronous FIFO - uses FASM style Memory
--		16 word depth with UART level read flags
--		has "Style #2" gray code address compare
--              
--	Copyright (c) 2007 by Howard LeFevre 
--		an OpenCores.org Project
--		free to use, but see documentation for conditions 								 
--
--	Revision	History:
--	Revision	Date      	Author   	Comment
--	--------	----------	---------	-----------
--	1.0     	01/20/07  	h lefevre	Initial revision
--	
--------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;
 
entity gh_fifo_async16_rcsr_wf is
	GENERIC (data_width: INTEGER :=8 ); -- size of data bus
	port (					
		clk_WR  : in STD_LOGIC; -- write clock
		clk_RD  : in STD_LOGIC; -- read clock
		rst     : in STD_LOGIC; -- resets counters
		rc_srst : in STD_LOGIC:='0'; -- resets counters (sync with clk_RD!!!)
		WR      : in STD_LOGIC; -- write control 
		RD      : in STD_LOGIC; -- read control
		D       : in STD_LOGIC_VECTOR (data_width-1 downto 0);
		Q       : out STD_LOGIC_VECTOR (data_width-1 downto 0);
		empty   : out STD_LOGIC; -- sync with clk_RD!!!
		q_full  : out STD_LOGIC; -- sync with clk_RD!!!
		h_full  : out STD_LOGIC; -- sync with clk_RD!!!
		a_full  : out STD_LOGIC; -- sync with clk_RD!!!
		full    : out STD_LOGIC);
end entity;
 
architecture a of gh_fifo_async16_rcsr_wf is
 
component gh_binary2gray IS
	GENERIC (size: INTEGER := 8);
	PORT(	
		B   : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);
		G   : out STD_LOGIC_VECTOR(size-1 DOWNTO 0)
		);
end component;
 
component gh_gray2binary IS
	GENERIC (size: INTEGER := 8);
	PORT(	
		G   : IN STD_LOGIC_VECTOR(size-1 DOWNTO 0);	-- gray code in
		B   : out STD_LOGIC_VECTOR(size-1 DOWNTO 0) -- binary value out
		);
end component;
 
	type ram_mem_type is array (15 downto 0) 
	        of STD_LOGIC_VECTOR (data_width-1 downto 0);
	signal ram_mem : ram_mem_type; 
	signal iempty        : STD_LOGIC;
	signal diempty       : STD_LOGIC;
	signal ifull         : STD_LOGIC;
	signal add_WR_CE     : std_logic;
	signal add_WR        : std_logic_vector(4 downto 0); -- add_width -1 bits are used to address MEM
	signal add_WR_GC     : std_logic_vector(4 downto 0); -- add_width bits are used to compare
	signal iadd_WR_GC    : std_logic_vector(4 downto 0);
	signal n_add_WR      : std_logic_vector(4 downto 0); --   for empty, full flags
	signal add_WR_RS     : std_logic_vector(4 downto 0); -- synced to read clk
	signal add_RD_CE     : std_logic;
	signal add_RD        : std_logic_vector(4 downto 0);
	signal add_RD_GC     : std_logic_vector(4 downto 0);
	signal iadd_RD_GC    : std_logic_vector(4 downto 0);
	signal add_RD_GCwc   : std_logic_vector(4 downto 0);
	signal iadd_RD_GCwc  : std_logic_vector(4 downto 0);
	signal iiadd_RD_GCwc : std_logic_vector(4 downto 0);
	signal n_add_RD      : std_logic_vector(4 downto 0);
	signal add_RD_WS     : std_logic_vector(4 downto 0); -- synced to write clk
	signal srst_w        : STD_LOGIC;
	signal isrst_w       : STD_LOGIC;
	signal srst_r        : STD_LOGIC;
	signal isrst_r       : STD_LOGIC;
	signal c_add_RD      : std_logic_vector(4 downto 0);
	signal c_add_WR      : std_logic_vector(4 downto 0);
	signal c_add         : std_logic_vector(4 downto 0);
 
begin
 
--------------------------------------------
------- memory -----------------------------
--------------------------------------------
 
 
process (clk_WR)
begin			  
	if (rising_edge(clk_WR)) then
		if ((WR = '1') and (ifull = '0')) then
			ram_mem(CONV_INTEGER(add_WR(3 downto 0))) <= D;
		end if;
	end if;		
end process;
 
	Q <= ram_mem(CONV_INTEGER(add_RD(3 downto 0)));
 
-----------------------------------------
----- Write address counter -------------
-----------------------------------------
 
	add_WR_CE <= '0' when (ifull = '1') else
	             '0' when (WR = '0') else
	             '1';
 
	n_add_WR <= add_WR + "01";
 
U1 : gh_binary2gray
	generic map (size => 5)
	port map(
		B => n_add_WR,
		G => iadd_WR_GC
		);
 
process (clk_WR,rst)
begin 
	if (rst = '1') then
		add_WR <= (others => '0');
		add_RD_WS(4 downto 3) <= "11"; 
		add_RD_WS(2 downto 0) <= (others => '0');
		add_WR_GC <= (others => '0');
	elsif (rising_edge(clk_WR)) then
		add_RD_WS <= add_RD_GCwc;
		if (srst_w = '1') then
			add_WR <= (others => '0');
			add_WR_GC <= (others => '0');
		elsif (add_WR_CE = '1') then
			add_WR <= n_add_WR;
			add_WR_GC <= iadd_WR_GC;
		else
			add_WR <= add_WR;
			add_WR_GC <= add_WR_GC;
		end if;
	end if;
end process;
 
	full <= ifull;
 
	ifull <= '0' when (iempty = '1') else -- just in case add_RD_WS is reset to all zero's
	         '0' when (add_RD_WS /= add_WR_GC) else ---- instend of "11 zero's" 
	         '1';
 
 
-----------------------------------------
----- Read address counter --------------
-----------------------------------------
 
 
	add_RD_CE <= '0' when (iempty = '1') else
	             '0' when (RD = '0') else
	             '1';
 
	n_add_RD <= add_RD + "01";
 
U2 : gh_binary2gray
	generic map (size => 5)
	port map(
		B => n_add_RD,
		G => iadd_RD_GC -- to be used for empty flag
		);
 
	iiadd_RD_GCwc <= (not n_add_RD(4)) & n_add_RD(3 downto 0);
 
U3 : gh_binary2gray
	generic map (size => 5)
	port map(
		B => iiadd_RD_GCwc,
		G => iadd_RD_GCwc -- to be used for full flag
		);
 
process (clk_RD,rst)
begin 
	if (rst = '1') then
		add_RD <= (others => '0');	
		add_WR_RS <= (others => '0');
		add_RD_GC <= (others => '0');
		add_RD_GCwc(4 downto 3) <= "11";
		add_RD_GCwc(2 downto 0) <= (others => '0');
		diempty <= '1';
	elsif (rising_edge(clk_RD)) then
		add_WR_RS <= add_WR_GC;
		diempty <= iempty;
		if (srst_r = '1') then
			add_RD <= (others => '0');
			add_RD_GC <= (others => '0');
			add_RD_GCwc(4 downto 3) <= "11";
			add_RD_GCwc(2 downto 0) <= (others => '0');
		elsif (add_RD_CE = '1') then
			add_RD <= n_add_RD;
			add_RD_GC <= iadd_RD_GC;
			add_RD_GCwc <= iadd_RD_GCwc;
		else
			add_RD <= add_RD; 
			add_RD_GC <= add_RD_GC;
			add_RD_GCwc <= add_RD_GCwc;
		end if;
	end if;
end process;
 
	empty <= diempty;
 
	iempty <= '1' when (add_WR_RS = add_RD_GC) else
	          '0';
 
U4 : gh_gray2binary
	generic map (size => 5)
	port map(
		G => add_RD_GC,
		B => c_add_RD 
		);
 
U5 : gh_gray2binary
	generic map (size => 5)
	port map(
		G => add_WR_RS,
		B => c_add_WR 
		); 
 
	c_add <= (c_add_WR - c_add_RD);
 
	q_full <= '0' when (iempty = '1') else
	          '0' when (c_add(4 downto 2) = "000") else
	          '1';
 
	h_full <= '0' when (iempty = '1') else
	          '0' when (c_add(4 downto 3) = "00") else
	          '1'; 
 
	a_full <= '0' when (iempty = '1') else
	          '0' when (c_add(4 downto 1) < "0111") else
	          '1'; 
 
----------------------------------
--- sync rest stuff --------------
--- rc_srst is sync with clk_RD --
--- srst_w is sync with clk_WR ---
----------------------------------
 
process (clk_WR,rst)
begin 
	if (rst = '1') then
		srst_w <= '0';	
		isrst_r <= '0';	
	elsif (rising_edge(clk_WR)) then
		srst_w <= isrst_w;
		if (srst_w = '1') then
			isrst_r <= '1';
		elsif (srst_w = '0') then
			isrst_r <= '0';
		end if;
	end if;
end process;
 
process (clk_RD,rst)
begin 
	if (rst = '1') then
		srst_r <= '0';	
		isrst_w <= '0';
	elsif (rising_edge(clk_RD)) then
		srst_r <= rc_srst;
		if (rc_srst = '1') then
			isrst_w <= '1';
		elsif (isrst_r = '1') then
			isrst_w <= '0';
		end if;
	end if;
end process;
 
end architecture;
 

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.