⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gh_tvfd_filter_w.vhd

📁 VHDL Library for 8254 timer/counter core
💻 VHD
字号:
---------------------------------------------------------------------
--	Filename:	gh_TVFD_filter_w.vhd
--			
--	Description:
--		Time Varying Fractional Delay Filter 
--		with wide range output (will work past 100%)
--
--	Copyright (c) 2007, 2008 by George Huber 
--		an OpenCores.org Project
--		free to use, but see documentation for conditions 
--
--	Revision 	History:
--	Revision 	Date      	Author   	Comment
--	-------- 	----------	---------	-----------
--	1.0      	08/12/07  	S A Dodd 	Initial revision
--	2.0     	12/24/07  	h lefevre	fixed increased range issues
--	2.1     	09/20/08  	hlefevre 	add simulation init
--	        	          	          	  (to '0') to ram data  
--
------------------------------------------------------------------
library IEEE;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;


entity gh_TVFD_filter_w is  
	GENERIC(
		modulo_bits : INTEGER := 7; -- must have bits to hold modulo_count
		modulo_count : INTEGER := 100;
		x : INTEGER := 3; -- filter order = 2^x
		d_size : INTEGER := 16;	-- size of data path
		c_size : INTEGER := 16	-- size of filter coeff 
		);
	port(
		CLK : in STD_LOGIC;
		rst : in STD_LOGIC;
		START : in STD_LOGIC;
		RATE : in STD_LOGIC_VECTOR(modulo_bits downto 0);
		L_IN : in STD_LOGIC_VECTOR(d_size-1 downto 0);
		R_IN : in STD_LOGIC_VECTOR(d_size-1 downto 0);
		coef_data : in STD_LOGIC_VECTOR(c_size-1 downto 0);
		ND : out STD_LOGIC;
		ROM_ADD : out STD_LOGIC_VECTOR((modulo_bits + x -1) downto 0); 
		L_OUT : out STD_LOGIC_VECTOR(d_size-1 downto 0);
		R_OUT : out STD_LOGIC_VECTOR(d_size-1 downto 0)
		);
end entity;

architecture a of gh_TVFD_filter_w is

function conv_std_logic_vector(i : integer; w : integer) return std_logic_vector is
	variable tmp : std_logic_vector(w-1 downto 0);
	begin
		tmp := STD_LOGIC_VECTOR(conv_unsigned(i, w));
	return(tmp);
end;

---- Component declarations -----

component gh_MAC_ld
	generic(size_A : INTEGER :=16;
	        size_B : INTEGER :=16;
	        xbits : INTEGER :=0);
	port(
		clk  : in STD_LOGIC;
		rst  : in STD_LOGIC;
		LOAD : in STD_LOGIC; -- "clears" old data/starts a new accumulation
		ce   : in STD_LOGIC; --  clock enable
		DA   : in STD_LOGIC_VECTOR(size_A-1 downto 0);
		DB   : in STD_LOGIC_VECTOR(size_B-1 downto 0);
		Q    : out STD_LOGIC_VECTOR(size_A+size_B+xbits-1 downto 0)
		);
end component;

	type ram_mem_type is array (((2**(x+1))-1) downto 0) 
	        of STD_LOGIC_VECTOR (d_size-1 downto 0);
	signal L_mem    : ram_mem_type := (others => (others => '0')); 
	signal R_mem    : ram_mem_type := (others => (others => '0'));
	signal mem_WR   : STD_LOGIC;
	signal emem_WR  : STD_LOGIC; -- added 12/24/07
	signal mem_Wadd : STD_LOGIC_VECTOR(x downto 0);
	signal mem_Radd : STD_LOGIC_VECTOR(x downto 0);
	signal mem_LD   : STD_LOGIC_VECTOR(d_size-1 downto 0);
	signal mem_RD   : STD_LOGIC_VECTOR(d_size-1 downto 0);

	constant ORDER  : INTEGER := 2**x;
	constant S_OFFSET : INTEGER := 8;
	constant max_coef_count : STD_LOGIC_VECTOR(x downto 1) := (others => '1');

	signal oRATE        : STD_LOGIC;
	signal iND          : STD_LOGIC;
	signal diND         : STD_LOGIC_VECTOR(1 downto 0);	-- added 12/24/07
	signal iiND         : STD_LOGIC;
	signal i_L_DATA     : STD_LOGIC_VECTOR(d_size-1 downto 0);
	signal i_R_DATA     : STD_LOGIC_VECTOR(d_size-1 downto 0);
	signal L_ACC        : STD_LOGIC_VECTOR(d_size+c_size-1 downto 0);
	signal R_ACC        : STD_LOGIC_VECTOR(d_size+c_size-1 downto 0);
	signal CE           : STD_LOGIC;
	signal R_ADD        : STD_LOGIC_VECTOR(x-1 downto 0);
	signal buff_wr_ADD  : STD_LOGIC_VECTOR(x downto 0);
	signal ibuff_rd_ADD : STD_LOGIC_VECTOR(x downto 0);
	signal buff_rd_ADD  : STD_LOGIC_VECTOR(x downto 0);
	signal WINDOW       : STD_LOGIC;
	signal Delay        : STD_LOGIC_VECTOR(3 downto 1);
	signal iSTART       : STD_LOGIC_VECTOR(order+S_OFFSET+1 downto 1); -- 12/24/07
	signal iRATE        : STD_LOGIC_VECTOR(modulo_bits downto 0);
	signal iTC          : STD_LOGIC;
	signal filter       : STD_LOGIC_VECTOR(modulo_bits+1 downto 0);
	signal mod_c        : STD_LOGIC_VECTOR(modulo_bits+1 downto 0);
	signal iNQ          : STD_LOGIC_VECTOR(modulo_bits+1 downto 0);
	signal NQ           : STD_LOGIC_VECTOR(modulo_bits+2 downto 0);

begin

	ND <= iND;

-----------------------------------------------------
-- mem for data buffer ------------------------------
-----------------------------------------------------
process (clk)
begin
	if (rising_edge(clk)) then
		emem_WR <= iND;	  -- added 12/24/07
		mem_WR <= emem_WR; -- 12/24/07
		mem_Wadd <= buff_wr_ADD;
		mem_Radd <= buff_rd_ADD;
		mem_LD <= L_IN;
		mem_RD <= R_IN;
		i_L_DATA <= L_mem(CONV_INTEGER(mem_Radd));
		i_R_DATA <= R_mem(CONV_INTEGER(mem_Radd));
		if (mem_WR = '1') then
			L_mem(CONV_INTEGER(mem_Wadd)) <= mem_LD;
			R_mem(CONV_INTEGER(mem_Wadd)) <= mem_RD;
		end if;
	end if;		
end process;

process(CLK,rst)
begin
	if (rst = '1') then
		buff_wr_ADD <= (others => '0');
		ibuff_rd_ADD <= (others => '0');
		diND <= (others => '0'); -- added 12/24/07
	elsif (rising_edge(CLK)) then
		diND <= (diND(0) & iND);  -- added 12/24/07	
		if (iND = '1') then
			buff_wr_ADD <= buff_wr_ADD + "01";
		end if;
		if ((iND = '1') and (diND = "00")) then	-- added 12/24/07
			ibuff_rd_ADD <= buff_wr_ADD; 
		end if;
	end if;
end process;
		
	buff_rd_ADD <= ibuff_rd_ADD - R_ADD;
	
---------------------------------------------

U1 : gh_MAC_ld
	generic map (
		size_A => d_size,
		size_B => c_size
		)	
	port map(
		clk => CLK,
		rst => rst,
		LOAD => iSTART(S_OFFSET-1), 
		CE => WINDOW,
		DA => i_L_DATA,
		DB => coef_data,
		Q => L_ACC
		);

U2 : gh_MAC_ld
	generic map (
		size_A => d_size,
		size_B => c_size
		)
	port map(
		clk => CLK,
		rst => rst,
		LOAD => iSTART(S_OFFSET-1),
		CE => WINDOW,
		DA => i_R_DATA,
		DB => coef_data,
		Q => R_ACC
		);

process(CLK,rst)
begin
	if (rst = '1') then
		iSTART <= (others => '0');
	elsif (rising_edge(CLK)) then
		iSTART(1) <= START;
		iSTART(order+S_OFFSET+1 downto 2) <= iSTART(order+S_OFFSET downto 1); -- 12/24/07
	end if;
end process;

-------------------------------------------------
-- hold the output of the MAC's ----------------- 
------ (output of filter)  ----------------------
-------------------------------------------------

process(CLK,rst)
begin
	if (rst = '1') then
		L_OUT <= (others => '0');
		R_OUT <= (others => '0');
	elsif (rising_edge(CLK)) then
		if (iSTART(order+S_OFFSET+1) = '1') then
			L_OUT <= L_ACC(d_size+c_size-2 downto c_size-1);
			R_OUT <= R_ACC(d_size+c_size-2 downto c_size-1);
		end if;
	end if;
end process;
		
----------------------------------------------------------
------- control the fractional delay --------------------- 
-------- filter -> Fractional Delay  ---------------------
----------------------------------------------------------

	mod_c <= conv_std_logic_vector(modulo_count, modulo_bits+2);
	
	oRATE <= '1' when (("00" & iNQ) >= ('0' & mod_c & '0')) else -- 12/24/07
	         '0';

	iTC <= '0' when (START = '0') else 
	       '0' when (('0' & iNQ) < ('0' & mod_c)) else
	       '1';
	      
	iNQ <= (filter + ("0" & iRATE));

	NQ <= (('0' & iNQ) - (mod_c & '0')) when (('0' & iNQ) >= (mod_c & '0')) else -- 12/24/07
	      ('0' & iNQ) when (('0' & iNQ) < ('0' & mod_c)) else
	      (('0' & iNQ) - ('0' & mod_c));
 		  
PROCESS (CLK,rst)
BEGIN			 
	if (rst = '1') then
		filter <= (others => '0');
		iiND <= '0';
		iRATE <= (others => '0');
	elsif (rising_edge(CLK)) then
		iiND <= iTC;
		if (START = '1') then
			filter <= NQ(modulo_bits+1 downto 0);
		end if;	
		if (('0' & RATE) >  ('0' & mod_c & '0')) then
			iRATE <= (mod_c(modulo_bits-1 downto 0) & '0') - "01";
		else   
			iRATE <= RATE;
		end if;
	end if;
END PROCESS;
		
	iND <= iiND when (oRATE = '0') else
	       (iiND or iSTART(3));	 -- if rate is over 100%, 
	                             -- may need to read two data samples 
		
	ROM_ADD <= (filter(modulo_bits-1 downto 0) & R_ADD);
	
----------------------------------------------------------
------- cycle through the 8 data samples and prom coef  -- 
-------- R_ADD -> coef/data sample address  --------------
----------------------------------------------------------
	
	CE <= '0' when (R_ADD = max_coef_count) else
	      '1';

process(CLK,rst)
begin
	if (rst = '1') then
		DELAY <= (others => '0');
		R_ADD <= (others => '0');
	elsif (rising_edge(CLK)) then
		DELAY(1) <= CE;
		DELAY(3 downto 2) <= DELAY(2 downto 1);
		if (iSTART(S_OFFSET-4) = '1') then
			R_ADD <= (others => '0');
		elsif (CE = '1') then
			R_ADD <= R_ADD + "01";
		end if;
	end if;
end process;
		
	WINDOW <= DELAY(2) or DELAY(3);		

--------------------------------------------------

end a;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -