OpenCores
URL https://opencores.org/ocsvn/mjpeg-decoder/mjpeg-decoder/trunk

Subversion Repositories mjpeg-decoder

[/] [mjpeg-decoder/] [trunk/] [mjpeg/] [pcores/] [myipif/] [hdl/] [vhdl/] [jpeg_upsampling.vhd] - Rev 4

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------------------------
-- Two address ranges (indicated by the address-MSB) are used alternately as input and output buffer.
-- When the input buffer is full and the output buffer is empty, 'do_copy' toggles the address-MSB.
-------------------------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity jpeg_upsampling is
	port(
		Clk			: in  std_logic;
		reset_i		: in  std_logic;
		context_i	: in  std_logic_vector(3 downto 0);
		data_i		: in  std_logic_vector(8 downto 0);
		sampling_i	: in  std_logic_vector(3 downto 0);
		context_o	: out std_logic_vector(3 downto 0);
		Y_o			: out std_logic_vector(8 downto 0);
		Cb_o			: out std_logic_vector(8 downto 0);
		Cr_o			: out std_logic_vector(8 downto 0);
		datavalid_i	: in  std_logic;
		datavalid_o	: out std_logic;
		ready_i		: in  std_logic;
		ready_o		: out std_logic
	);
end entity;
 
 
architecture IMP of jpeg_upsampling is
 
	component jpeg_upsampling_buffer
	port (
		clka	: IN  std_logic;
		dina	: IN  std_logic_VECTOR(8 downto 0);
		addra	: IN  std_logic_VECTOR(10 downto 0);
		wea	: IN  std_logic_VECTOR(0 downto 0);
		clkb	: IN  std_logic;
		addrb	: IN  std_logic_VECTOR(10 downto 0);
		doutb	: OUT std_logic_VECTOR(8 downto 0)
	);
	end component;
 
	signal doutb_Y, doutb_Cb, doutb_Cr : std_logic_vector(8 downto 0) :=(others=>'0');
 
	signal addra_Y, addra_Cb, addra_Cr : std_logic_vector(10 downto 0) :=(others=>'0');
	signal addrb_Y, addrb_Cb, addrb_Cr : std_logic_vector(10 downto 0) :=(others=>'0');
	signal addrb_Y_short, addrb_Y_short_D : std_logic_vector(7 downto 0) :=(others=>'0');
	signal addrb_Cb_short, addrb_Cr_short, addrb_Cb_short_D, addrb_Cr_short_D : std_logic_vector(5 downto 0) :=(others=>'0');
	signal address_msb, address_msb_D : std_logic :='0';
 
	signal wea_Y   : std_logic_vector(0 downto 0) :=(others=>'1');
	signal wea_Y_D, wea_Y_rem : std_logic_vector(0 downto 0) :=(others=>'1');
	signal wea_Cb,   wea_Cr   : std_logic_vector(0 downto 0) :=(others=>'0');
	signal wea_Cb_D, wea_Cr_D, wea_Cb_rem, wea_Cr_rem : std_logic_vector(0 downto 0) :=(others=>'0');
 
	signal ce_in  : std_logic :='0';
	signal ce_out : std_logic :='0';
	signal counter_in, counter_in_D,  counter_in_hold  : std_logic_vector(8 downto 0) :=(others=>'0');
	signal counter_out,counter_out_D, counter_out_hold : std_logic_vector(7 downto 0) :=(others=>'1');
	signal counter_in_Y_max,  counter_in_Y_D_max  : std_logic_vector(8 downto 0) :=(others=>'0');
	signal counter_in_Cb_max, counter_in_Cb_D_max : std_logic_vector(8 downto 0) :=(others=>'0');
	signal counter_in_Cr_max, counter_in_Cr_D_max : std_logic_vector(8 downto 0) :=(others=>'0');
	signal do_copy,  do_copy_D, do_copy_delayed  : std_logic :='0';
	signal stop_in,  stop_in_D  : std_logic :='0';
	signal stop_out, stop_out_D : std_logic :='1';
	signal stop_eoi_out, stop_eoi_out_D : std_logic := '1';
	signal context_in, context_in_D, context_out, context_out_D : std_logic_vector(3 downto 0) :=(others=>'0');
	signal eoi, eoi_D	: std_logic :='0'; 
	signal eoi_hold, eoi_hold_D : std_logic :='0'; 
	signal ready, ready_D : std_logic :='1';
	signal datavalid : std_logic :='0';
 
	-- "00"->gray, "01"->4:2:0, "10"->4:2:2, "11"->4:4:4
	signal sampling_in, sampling_in_D, sampling_out, sampling_out_D : std_logic_vector(1 downto 0) :=(others=>'0');
 
 
begin
 
 
Y_buffer : jpeg_upsampling_buffer
		port map (
			clka => Clk,
			dina => data_i, 
			addra => addra_Y,
			wea => wea_Y,
			clkb => Clk,
			addrb => addrb_Y,
			doutb => doutb_Y 
		);
Cb_buffer : jpeg_upsampling_buffer
		port map (
			clka => Clk,
			dina => data_i, 
			addra => addra_Cb,
			wea => wea_Cb,
			clkb => Clk,
			addrb => addrb_Cb,
			doutb => doutb_Cb
		);
Cr_buffer : jpeg_upsampling_buffer
		port map (
			clka => Clk,
			dina => data_i, 
			addra => addra_Cr,
			wea => wea_Cr,
			clkb => Clk,
			addrb => addrb_Cr,
			doutb => doutb_Cr
		);
addra_Y  <=     address_msb & "00"   & counter_in(7  downto 0);
addra_Cb <=     address_msb & "0000" & counter_in(5  downto 0);
addra_Cr <=     address_msb & "0000" & counter_in(5  downto 0);
addrb_Y  <= not address_msb & "00"   & addrb_Y_short;
addrb_Cb <= not address_msb & "0000" & addrb_Cb_short;
addrb_Cr <= not address_msb & "0000" & addrb_Cr_short;
wea_Y(0)  <= wea_Y_rem(0)  and ce_in;
wea_Cb(0) <= wea_Cb_rem(0) and ce_in;
wea_Cr(0) <= wea_Cr_rem(0) and ce_in;
 
 
 
 
-- connect signals to the outside
process(Clk)
begin
	if rising_edge(Clk) then
		ready_o		<= ready;
		datavalid	<= ce_out;
		datavalid_o	<= datavalid;
		Y_o 			<= doutb_Y;	
		Cb_o 			<= doutb_Cb;	
		Cr_o 			<= doutb_Cr;		
		context_o	<= context_out;
	end if;
end process;
 
 
 
process(sampling_in, sampling_out)
begin
	case sampling_in is
		when "00" =>								-- gray 1 in (8x8 blocks)
			counter_in_hold   <= "000111111";
			counter_in_Y_max  <= "111111111";
			counter_in_Cb_max <= "111111111";
			counter_in_Cr_max <= "111111111";
		when "01" => 								-- 4:2:0 6 in
			counter_in_hold   <= "101111111";
			counter_in_Y_max  <= "011111111";
			counter_in_Cb_max <= "100111111";
			counter_in_Cr_max <= "101111111";
		when "10" => 								-- 4:2:2 4 in 
			counter_in_hold   <= "011111111";
			counter_in_Y_max  <= "001111111";
			counter_in_Cb_max <= "010111111";
			counter_in_Cr_max <= "011111111";
		when others => 							-- 4:4:4 3 in
			counter_in_hold   <= "010111111";
			counter_in_Y_max  <= "000111111";
			counter_in_Cb_max <= "001111111";
			counter_in_Cr_max <= "010111111";
	end case;
	case sampling_out is
		when "00" =>								-- gray  1 out
			counter_out_hold   <= "00111111";
		when "01" => 								-- 4:2:0  4 out
			counter_out_hold   <= "11111111";
		when "10" =>								-- 4:2:2  2 out
			counter_out_hold   <= "01111111"; 
		when others => 							-- 4:4:4  1 out
			counter_out_hold   <= "00111111";	
	end case;
end process;
 
 
 
 
 
 
 
 
 
----------------------------------------------------------
-- handle the write-enable
process(wea_Y_rem, wea_Cb_rem, wea_Cr_rem, counter_in, counter_in_Y_max, counter_in_Cb_max,
        counter_in_Cr_max, reset_i, do_copy)
begin
	wea_Y_D  <= wea_Y_rem;
	wea_Cb_D <= wea_Cb_rem;
	wea_Cr_D <= wea_Cr_rem;
	if (counter_in=counter_in_Y_max) then
		wea_Y_D  <= "0";
		wea_Cb_D <= "1";
	end if;
	if (counter_in=counter_in_Cb_max) then
		wea_Cb_D <= "0";
		wea_Cr_D <= "1";
	end if;
	if (counter_in=counter_in_Cr_max) then
		wea_Cr_D <= "0";
		wea_Y_D  <= "1";
	end if;
 
	if reset_i='1' or do_copy='1' then
		wea_Y_D  <= "1";
		wea_Cb_D <= "0";
		wea_Cr_D <= "0";
	end if;
 
end process;
 
process(Clk)
begin
	if rising_edge(Clk) then
		wea_Y_rem  <= wea_Y_D;
		wea_Cb_rem <= wea_Cb_D;
		wea_Cr_rem <= wea_Cr_D;
	end if;
end process;
----------------------------------------------------------
 
 
process(counter_out, addrb_Y_short, addrb_Cb_short, addrb_Cr_short, sampling_out)
begin
 
	case sampling_out is
	when "01" =>					-- 4:2:0
		addrb_Y_short 	<= counter_out(7) & counter_out(3) & counter_out(6 downto 4) & counter_out(2 downto 0);
		addrb_Cb_short	<= counter_out(7 downto 5) & counter_out(3 downto 1);
		addrb_Cr_short	<= counter_out(7 downto 5) & counter_out(3 downto 1);
	when "10" =>					-- 4:2:2
		addrb_Y_short 	<= '0' & counter_out(3) & counter_out(6 downto 4) & counter_out(2 downto 0);
		addrb_Cb_short	<= counter_out(6 downto 1);
		addrb_Cr_short	<= counter_out(6 downto 1);
	when others =>					-- gray and 4:4:4
		addrb_Y_short 	<= "00" & counter_out(5 downto 0);
		addrb_Cb_short	<= counter_out(5 downto 0);
		addrb_Cr_short	<= counter_out(5 downto 0);
	end case;
 
end process;
----------------------------------------------------------
 
 
 
 
----------------------------------------------------------
-- switch read and write memory
 
do_copy_D <= stop_in and stop_out;
 
process(do_copy, do_copy_delayed, address_msb)
begin
	address_msb_D <= address_msb;
	if do_copy='1' and do_copy_delayed='0' then
		address_msb_D <= not address_msb;
	end if;
end process;
 
 
process(ready, counter_in, counter_in_hold, do_copy)
begin
	ready_D <= ready;	
 
	if counter_in=(counter_in_hold-62) then
		ready_D <='0';
	end if;
	if do_copy='1' then
		ready_D <='1';
	end if;
end process;
 
process(Clk)
begin
	if rising_edge(Clk) then
		if reset_i='1' then
			ready <= '1';
			do_copy <= '0';
			do_copy_delayed <= '0';
			address_msb <= '0';
		else
			ready <= ready_D;
			do_copy <= do_copy_D;
			do_copy_delayed <= do_copy;
			address_msb <= address_msb_D;
		end if;
	end if;
end process;
----------------------------------------------------------
 
 
 
 
 
 
 
process(stop_eoi_out, counter_in, do_copy)
begin
	stop_eoi_out_D <= stop_eoi_out;
	if (counter_in=1) then
		stop_eoi_out_D <='1';
	elsif(do_copy='1') then 
		stop_eoi_out_D<='0';
	end if;
end process;
process(Clk, reset_i)
begin
	if rising_edge(Clk) then
		if(reset_i='1') then
			stop_eoi_out <='1';
		elsif ce_in='1' then
			stop_eoi_out <= stop_eoi_out_D;
		end if;
	end if;
end process;
 
 
 
-- handle the context
process(eoi, eoi_hold, context_i, counter_out, do_copy, stop_eoi_out)
begin
	eoi_D <= eoi;
	eoi_hold_D <= eoi_hold;
	if (context_i(3)='1' and do_copy='0' and stop_eoi_out='1') then
		eoi_hold_D <= '1';
	elsif(context_i(3)='1' and (do_copy='1' and stop_eoi_out='1')) then
		eoi_D <= '1';
		eoi_hold_D <= '0';
	elsif(context_i(3)='1' and stop_eoi_out='0') then
		eoi_D <= '1';
		eoi_hold_D <= '0';
	elsif(eoi_hold='1' and do_copy='1') then
		eoi_D <= '1';
		eoi_hold_D <= '0';
	end if;
	if (counter_out=counter_out_hold and eoi='1') then
		eoi_D <= '0';
	end if;
end process;
 
process(context_i, sampling_i)
begin
	context_in_D <= '0' & context_i(2 downto 0);
	if context_i(1)='0' then
		sampling_in_D <= sampling_i(1 downto 0);
	else
		sampling_in_D <= sampling_i(3 downto 2);
	end if;
end process;
 
 
process(Clk)
begin
	if rising_edge(Clk) then
		eoi		<= eoi_D;
		eoi_hold <= eoi_hold_D;
		context_out	<= '0' & '0' & context_out(1 downto 0);		
		if counter_out=counter_out_hold and ce_out='1' then  
			context_out(3)	<= eoi;
		end if;
 
		if(ce_in='1') then
			sampling_in <= sampling_in_D;
			context_in  <= context_in_D;
		end if;
		if do_copy='1' then
			sampling_out <= sampling_in;
			context_out(2 downto 0)  <= context_in(2 downto 0);
		end if;
 
		if reset_i='1' then
			context_out <= (others=>'0');
			context_in  <= (others=>'0');
			eoi <='0';
			eoi_hold <='0';
			sampling_out <= "00";
			sampling_in  <= "00";
		end if;
 
	end if;
end process;
 
 
 
 
 
-------------------------------------------------------------------------
-- shift in
 
ce_in <= datavalid_i and not stop_in;
 
process(counter_in_hold, stop_in, counter_in)
begin
		if counter_in = counter_in_hold then
			stop_in_D <= '1';
		elsif do_copy ='1' then
			stop_in_D <= '0';
		else
			stop_in_D <= stop_in;
		end if;
end process;
 
process(Clk)
begin
	if rising_edge(Clk) then
	if reset_i='1' or do_copy ='1' then
		counter_in <= (others=>'0');
		stop_in <= '0';
	elsif ce_in='1' then
		counter_in <= counter_in+1;
		stop_in <= stop_in_D;
	end if;
	end if;
end process;
-------------------------------------------------------------------------
 
 
-------------------------------------------------------------------------
-- shift out 
ce_out <= ready_i and not stop_out and not do_copy;
 
process(counter_out_hold, do_copy, stop_out, counter_out)
begin
	if counter_out = counter_out_hold then
		stop_out_D <= '1';
	elsif do_copy ='1' then
		stop_out_D <= '0';
	else
		stop_out_D <= stop_out;
	end if;
end process;
 
process(counter_out, do_copy, ready_i, stop_out)
begin
	counter_out_D	<= counter_out;
	if ready_i='1' and stop_out='0' then
		counter_out_D	<= counter_out+1;
	end if;
 
	if (do_copy='1') then
		counter_out_D	<=(others=>'0');
	end if;
end process;
 
process(Clk)
begin
	if rising_edge(Clk) then
		stop_out <= stop_out_D;
		if reset_i='1' then
			counter_out	<= (others=>'1');
			stop_out		<= '1';
		elsif ce_out='1' or do_copy='1' then
			counter_out	<= counter_out_D;
		end if;
	end if;
end process;
 
-------------------------------------------------------------------------
 
end IMP;
 

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.