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

Subversion Repositories dct_idct

[/] [dct_idct/] [trunk/] [dct/] [RTL/] [DCT8AAN2.vhd] - Rev 2

Compare with Previous | Blame | View Log

---------------------------------------------------------------------
----                                                             ----
----  DCT IP core                                                ----
----                                                             ----
----  Authors: Anatoliy Sergienko, Volodya Lepeha                ----
----  Company: Unicore Systems http://unicore.co.ua              ----
----                                                             ----
----  Downloaded from: http://www.opencores.org                  ----
----                                                             ----
---------------------------------------------------------------------
----                                                             ----
---- Copyright (C) 2006-2010 Unicore Systems LTD                 ----
---- www.unicore.co.ua                                           ----
---- o.uzenkov@unicore.co.ua                                     ----
----                                                             ----
---- This source file may be used and distributed without        ----
---- restriction provided that this copyright statement is not   ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer.----
----                                                             ----
---- THIS SOFTWARE IS PROVIDED "AS IS"                           ----
---- AND ANY EXPRESSED OR IMPLIED WARRANTIES,                    ----
---- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED                  ----
---- WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT              ----
---- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.        ----
---- IN NO EVENT SHALL THE UNICORE SYSTEMS OR ITS                ----
---- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,            ----
---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL            ----
---- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT         ----
---- OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,               ----
---- DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                 ----
---- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,              ----
---- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT              ----
---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING                 ----
---- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                 ----
---- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.          ----
----                                                             ----
---------------------------------------------------------------------
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		
--		DESCRIPTION:
--
--	FUNCTION	 Discrete Cosine Transform of   8 samples using algorithm by
--							Arai, Agui, and Nakajama
--                       input data bit width: 10 bit ,	signed or unsigned
--			  output   data bit width: 12 bit   
--                       coefficient bit width: 11 bit         
--	                 Synthesable for  FPGAs of any vendor, preferably for Xilinx FPGA
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
library IEEE;
use IEEE.std_logic_1164.all;	 
use IEEE.std_logic_arith.all;
use IEEE.std_logic_signed.all;
 
entity DCT8AAN2 is 		
	generic( d_signed:integer:=1;	--1 input data signed; 0 - unsigned, and for compression 1/2 is subtracted
		scale_out:integer:=0); 		   -- 1 output data are scaled; 0 - genuine DCT 
	port (
		CLK: in STD_LOGIC;
		RST: in STD_LOGIC;		
		START: in STD_LOGIC;	     -- after this impulse the 0-th datum is sampled
		EN: in STD_LOGIC;		     -- operation enable to slow-down the calculations
		DATA_IN: in STD_LOGIC_VECTOR (9 downto 0);
		RDY: out   STD_LOGIC;	  -- delayed START impulse, after it the 0-th result is outpitted
		DATA_OUT: out STD_LOGIC_VECTOR (11 downto 0) --  output data
		);
end DCT8AAN2;
 
 
architecture STAGE of DCT8AAN2 is   
 
	type Tarr8 is array(0 to 7) of STD_LOGIC_VECTOR (10 downto 0);	
	type Tarr16 is array (0 to 15) of STD_LOGIC_VECTOR (9 downto 0);
	signal sr16:TARR16:=(others=>(others=>'0'));                                                --  SRL16
 
	constant S:Tarr8:=--(0.5/sqrt(2.0), 0.25/cos(pii*1.0),0.25/cos(pii*2.0),0.25/cos(pii*3.0),
	-- 0.25/cos(pii*4.0),0.25/cos(pii*5.0),0.25/cos(pii*6.0),0.25/cos(pii*7.0));
	(conv_std_logic_vector(integer(0.35355*2.0**9),11),
	conv_std_logic_vector(integer(0.2549*2.0**9),11),
	conv_std_logic_vector(integer(0.2706*2.0**9),11),			
	conv_std_logic_vector(integer(0.30067*2.0**9),11),	 
	conv_std_logic_vector(integer(0.35355*2.0**9),11),
	conv_std_logic_vector(integer(0.44999*2.0**9),11),
	conv_std_logic_vector(integer(0.65328*2.0**9),11),
	conv_std_logic_vector(integer(1.2815*2.0**9),11) );
 
	constant m1  : STD_LOGIC_VECTOR (10 downto 0) := conv_std_logic_vector(integer(0.70711*2.0**9),11); --cos(pii*4.0); -- 
	constant m2  : STD_LOGIC_VECTOR (10 downto 0) := conv_std_logic_vector(integer(0.38268*2.0**9),11);--cos(pii*6.0);  --
	constant m3  : STD_LOGIC_VECTOR (10 downto 0) := conv_std_logic_vector(integer(0.5412 *2.0**9),11);--(cos(pii*2.0) - cos(pii*6.0)); -- 
	constant m4  : STD_LOGIC_VECTOR (10 downto 0) := conv_std_logic_vector(integer(1.3066*2.0**9),11);--cos(pii*2.0) + cos(pii*6.0);  --
 
	constant zeros : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');	
	constant a1_2 : STD_LOGIC_VECTOR (9 downto 0) := "10"&zeros;	  
 
	signal sr: STD_LOGIC_VECTOR (10 downto 0) ;
 
	signal cycle,ad1,cycle6: integer range 0 to 7;	 
	signal cycles: integer range 0 to 16;	 
	signal di,a1,a2,a3,a4: STD_LOGIC_VECTOR (9 downto 0);	
	signal bp,bm,b1,b2,b3,b4,b6:STD_LOGIC_VECTOR (10  downto 0);  	
	signal cp,cm,c1,c2,c3,c4:STD_LOGIC_VECTOR (12 downto 0);		  
	signal dp,dm:STD_LOGIC_VECTOR (12 downto 0);	   
	signal rd:STD_LOGIC_VECTOR (12 downto 0);	   
 
	signal ep:STD_LOGIC_VECTOR (23 downto 0);  		  
	signal e27:STD_LOGIC_VECTOR (12 downto 0);	 	   
	signal m1_4:STD_LOGIC_VECTOR (10 downto 0);	 	   
	signal fp,fm,f45,s7,s07,spt:STD_LOGIC_VECTOR (13 downto 0);   
	signal SP : 	STD_LOGIC_VECTOR (24 downto 0);  
 
 
begin	   	 	 
	UU_COUN0:process(CLK,RST)
	begin
		if RST = '1' then	
			cycle <=0;	   
			cycle6 <=(-6) mod 8;	
			ad1<= ( - 5) mod 8;	  
			cycles <=16;				  
			RDY<='0';
		elsif CLK = '1' and CLK'event then 	
			if en = '1' then		
				RDY<='0';
				if START = '1' then	   
					cycle <=0;		
					cycle6 <=(-6) mod 8;	
					ad1<= ( - 5) mod 8;	  
					cycles <=0;	
				elsif en = '1' then	
					cycle<=(cycle +1) mod 8 ;	  
					cycle6<=(cycle6 +1) mod 8 ;	  
					ad1<=(ad1 +1) mod 8;  
					if cycles=15 then 
						RDY<='1';  
						end if;
					if cycles/=16	then
						cycles<=(cycles +1) ;	  
					end if;				
				end if;		  
			end if;
		end if;
	end process;	   			 
 
	SRL16_a:process(CLK)  begin                        --  SRL16
		if CLK'event and CLK='1' then 
			if en='1' and (cycle=1 or cycle=2 or cycle=3 or cycle=4) then	 
				sr16<=di & sr16(0 to 14);                  -- shift SRL16		  
			end if;
		end if;
	end process;	 
	a1<= sr16(ad1);                 -- output from SRL16
 
 
	SM_B:process(clk,rst)	
	begin
		if RST = '1' then	  
			di <= (others => '0');		  
			bp <= (others => '0');      
			bm <= (others => '0');
		elsif CLK = '1' and CLK'event then 	 
			if en = '1' then	  				  
				if 	d_signed =0 then
					di<=unsigned(DATA_IN) - unsigned( a1_2);
				else
					di<=DATA_IN;
				end if;	   
				bp<=SXT(di,11) + a1;
				bm<=a1 - SXT(di,11);
			end if;
		end if;
	end process;	   	
 
	SM_C:process(clk,rst)	
	begin
		if RST = '1' then	  
			b1 <= (others => '0');		  
			b2 <= (others => '0');      
			b3 <= (others => '0');
			b4 <= (others => '0');		  
			b6 <= (others => '0');      
			cp <= (others => '0');
			cm <= (others => '0');	
			c1 <= (others => '0');
 
		elsif CLK = '1' and CLK'event then 	 
			if en = '1' then	  	
				b1<=bp;
				b2<=b1;
				if cycle = 2 then 
					b3<=b4;
				else
					b3<=b2;
				end if;
				b4<=b3;
				b6<=bm;
				case cycle is
					when 0|1|7 =>cp<=SXT(bm,13)+b6;	
					when 2|3 =>cp<= SXT(b2,13)+b3;
					when others=> cp<=cp+c1;
				end case;
				c1<=cp;
 
				if 	cycle=2 or  cycle=3 then
					cm<=SXT(b2,13) - b3;
				else
					cm<=cp - c1;
				end if;	   
 
			end if;
		end if;
	end process;	  
 
 
	SM_D:process(clk,rst)	
	begin
		if RST = '1' then	  
			c2 <= (others => '0');      
			c3 <= (others => '0');
			c4 <= (others => '0');		  
			dp <= (others => '0');
			dm <= (others => '0');	
		elsif CLK = '1' and CLK'event then 	 
			if en = '1' then	  	
				if cycle=3 or  cycle=4 or cycle=5 then
					c2<=cm;											
				end if;
				if cycle = 1 then 
					c3<=c1;
				end if;						 
				if cycle = 2 then 
					c4<=SXT(b6,13);	
				elsif cycle=5 then
					c4<=c2;
				end if;		   
				if cycle = 4 then 
					dp<= SXT(cm, 13)+c2(12 downto 0); 
				else
					dp<= ep(21 downto 9)+c4(12 downto 0); 
				end if;	   
 
				if cycle = 2 then 
					dm<= c3(12 downto 0) - SXT(cp, 13); 
				elsif cycle=3  or cycle =7 then
					dm<= c4(12 downto 0) - ep(21 downto 9); 		
				end if;		   
 
			end if;
		end if;
	end process;	 	  
 
	MPU1:process(clk,rst)	
	begin
		if CLK = '1' and CLK'event then 	 
			if en = '1' then
				case cycle is
					when 1|5 => m1_4<=m1;
					when 2 => m1_4<=m4;
					when 3 => m1_4<=m2;
					when others => m1_4<=m3;
				end case ;	   
				case cycle is
					when 1|2 => rd<= SXT(cp,13);
					when 3 => rd<=dm;
					when 4 => rd<= SXT(c3,13);
					when others => rd<=dp;
				end case ;	   
				ep<=rd*m1_4;
				e27<= ep(21 downto 9);
			end if;
		end if;
	end process;	   
 
	SM_F:process(clk,rst)	
	begin
		if RST = '1' then	  
			fp <= (others => '0');		  
			fm <= (others => '0');      
			f45 <= (others => '0');		   
			s7 <= (others => '0');		   
		elsif CLK = '1' and CLK'event then 	 
			if en = '1' then	  				  
				case 	cycle is
					when 3 =>	fp<=ep(21 downto 9) + SXT(c4,14);
					when 5 =>		fp<=ep(21 downto 9) + SXT(e27,14);
					when 6|0 =>		fp<=fp + f45;				
					when 7 =>		fp<=e27 +f45; 	
					when others=> null;
				end case;	   
 
				if cycle=4 then
					f45<=fp;
				elsif cycle=6 then
					f45<=SXT(e27,14);	
				elsif cycle=7 or cycle=0 then
					f45<=SXT(dm,14);
				end if;
				fm<=f45 - fp;
				if cycle=7 then
					s7<=fm;
				end if;
			end if;
		end if;
	end process;	   
 
	MPU2:process(clk,rst)	
	begin
		if CLK = '1' and CLK'event then 	 
			if en = '1' then
				sr<=s(cycle6);
				case cycle is
					when 6 => s07<= SXT(c1,14);
					when 7|3 => s07<=fp;
					when 0 => s07<= SXT(dp,14);
					when 1 => s07<= SXT(fm,14);
					when 2 => s07<= SXT(c2,14);
					when 4 => s07<= SXT(f45,14);
					when others => s07<=s7;
				end case ;	   
				if 	scale_out =0 then
					sp<=s07*sr;	 
					DATA_OUT <=sp(20 downto 9);		  
				else	 
					spt<=s07;	 
					DATA_OUT <= spt(12 downto 1);	
				end if;
			end if;
		end if;
	end process;	 
 
 
end STAGE;
 

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.