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

📄 h264intra4x4.vhd

📁 VHDL语言实现H.264的opencore
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-------------------------------------------------------------------------
-- H264 intra 4x4 luma prediction - VHDL
-- 
-- Written by Andy Henson
-- Copyright (c) 2008 Zexia Access Ltd
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--    * Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--    * Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in the
--      documentation and/or other materials provided with the distribution.
--    * Neither the name of the Zexia Access Ltd nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY ZEXIA ACCESS LTD ``AS IS'' AND ANY
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL ZEXIA ACCESS LTD OR ANDY HENSON 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.
-------------------------------------------------------------------------

-- Converts a macroblock to residuals for transform, using the block
-- immediately above and to the left as basis for prediction
-- Predicts one of type:
-- (0) Vertical
-- (1) Horizontal
-- (2) DC
-- (3) (NOT USED)
-- (4) Diagonal down right (45deg) (NOT CURRENTLY)
-- (5) Vertical right (22deg) (NOT CURRENTLY)
-- (6) Horizonal down (22deg) (NOT CURRENTLY)
-- (7) (NOT USED)
-- (8) Horizonal up (22deg) (NOT CURRENTLY)

-- Input: DATAI(8bit)x4, STROBEI, NEWLINE, TOPI
-- Output: DATAO(9bit)x4, STROBEO, MODEO

-- There are 256 pixels in a macroblock (16x16), transfered
-- four at a time on the wide bus (lsbits = first pixel)

-- Data in/out is in raster scan order...
-- 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 
-- 5.....5 6.....6 7.....7 8.....8
--                ...
-- 61...61 62...62 63...63 64...64 

-- Before the first macroblock in a line NEWLINE is set
-- this initialises all pointers and resets the prediction mode to
-- no adjacent blocks.  NEWLINE should be set for at least 1 CLK before
-- STROBEI goes high.
-- If this is the first in a slice, NEWSLICE should be set at the same
-- time as newline.

-- Data is clocked in by STROBEI; because of lag between READYI and
-- data from (possibly external) ram, then a limited amount of data
-- may be clocked in even after READYI falls (up to 16 words).

-- Note the pixels from the previous line are NOT stored by this module
-- but input via TOPI.  Those on the left are stored internally,
-- For this reason, an entire line of macroblocks must be encoded at once.
-- External to this module is a simple storage interface which stores TOP
-- pixels and block types.  TOPMI is the top blocks's mode.
-- (these are ignored if first line in slice).
-- XXO indicates which TOPI should be read but also which to latch the
-- FEEDB data into when it appears.

-- FEEDBI provides the pixel feedback to the left column, and FBSTROBE
-- when it is valid.  This comes from the transform/quantise/dequant/detransform
-- loop and gives the pixels as seen by the decoder.

-- XST: 387 slices+1BRAM; 116 MHz; XPower: 8mW

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.ALL;

entity h264intra4x4 is
	port (
		CLK : in std_logic;					--pixel clock
		--
		-- in interface:
		NEWSLICE : in std_logic;			--indication this is the first in a slice
		NEWLINE : in std_logic;				--indication this is the first on a line
		STROBEI : in std_logic;				--data here
		DATAI : in std_logic_vector(31 downto 0);
		READYI : out std_logic := '0';
		--
		-- top interface:
		TOPI : in std_logic_vector(31 downto 0);	--top pixels (to predict against)
		TOPMI : in std_logic_vector(3 downto 0);	--top block's mode (for P/RMODEO)
		XXO : out std_logic_vector(1 downto 0) := b"00";		--which macroblock X
		XXINC : out std_logic := '0';				--when to increment XX macroblock
		--
		-- feedback interface:
		FEEDBI : in std_logic_vector(7 downto 0);	--feedback for pixcol
		FBSTROBE : in std_logic;					--feedback valid
		--
		-- out interface:
		STROBEO : out std_logic := '0';				--data here
		DATAO : out std_logic_vector(35 downto 0) := (others => '0');
		BASEO : out std_logic_vector(31 downto 0) := (others => '0');	--base for reconstruct
		READYO : in std_logic := '1';
		MSTROBEO : out std_logic := '0';			--modeo here
		MODEO : out std_logic_vector(3 downto 0) := (others => '0');	--0..8 prediction type
		PMODEO : out std_logic := '0';				--prev_i4x4_pred_mode_flag
		RMODEO : out std_logic_vector(2 downto 0) := (others => '0');	--rem_i4x4_pred_mode_flag
		--
		CHREADY :  out std_logic := '0'				--ready line to chroma
	);
end h264intra4x4;

architecture hw of h264intra4x4 is
	--pixels on left
	type Tpix is array(63 downto 0) of std_logic_vector(31 downto 0);
	signal pix : Tpix := (others => (others => '0'));	--macroblock data
	type Tpixcol is array(15 downto 0) of std_logic_vector(7 downto 0);
	signal pixleft : Tpixcol := (others => x"00");		--previous col
	signal pixlefttop : std_logic_vector(7 downto 0);	--previous top col
	signal lvalid : std_logic := '0';					--set if pixels on left are valid
	signal tvalid : std_logic := '0';					--set if TOP valid (not first line)
	signal dconly : std_logic := '0';					--dconly as per std
	signal topih : std_logic_vector(31 downto 0) := (others=>'0');
	signal topii : std_logic_vector(31 downto 0) := (others=>'0');
	--
	--input states	
	signal statei : std_logic_vector(5 downto 0) := b"000000";	--state(rowcol) for input
	--processing states	
	constant IDLE : std_logic_vector(4 downto 0) := b"00000";
	signal state : std_logic_vector(4 downto 0) := IDLE;	--state/row for processing
	--output state
	signal outf1 : std_logic := '0';						--output flag
	signal outf : std_logic := '0';							--output flag
	signal chreadyi : std_logic := '0';						--chready anticipated
	signal chreadyii : std_logic := '0';					--chready anticipated 2
	signal readyod : std_logic := '0';						--delayed READYO in
	--
	--position of sub macroblock in macroblock
	signal submb : std_logic_vector(3 downto 0) := x"0";	--which of 16 submb in mb
	signal xx : std_logic_vector(1 downto 0) := b"00";
	signal yy : std_logic_vector(1 downto 0) := b"00";
	signal yyfull : std_logic_vector(3 downto 0) := x"0";
	signal oldxx : std_logic_vector(1 downto 0) := b"00";
	signal fbptr : std_logic_vector(3 downto 0) := x"0";
	signal fbpending : std_logic := '0';
	--type out
	signal modeoi : std_logic_vector(3 downto 0) := x"0";
	signal prevmode : std_logic_vector(3 downto 0) := x"0";
	type Tlmode is array(3 downto 0) of std_logic_vector(3 downto 0);
	signal lmode : Tlmode := (others => x"9");
	--data path
	signal dat0 : std_logic_vector(31 downto 0) := (others=>'0');
	--data channels
	alias datai0 : std_logic_vector(7 downto 0) is dat0(7 downto 0);
	alias datai1 : std_logic_vector(7 downto 0) is dat0(15 downto 8);
	alias datai2 : std_logic_vector(7 downto 0) is dat0(23 downto 16);
	alias datai3 : std_logic_vector(7 downto 0) is dat0(31 downto 24);
	--top channels
	alias topi0 : std_logic_vector(7 downto 0) is TOPI(7 downto 0);
	alias topi1 : std_logic_vector(7 downto 0) is TOPI(15 downto 8);
	alias topi2 : std_logic_vector(7 downto 0) is TOPI(23 downto 16);
	alias topi3 : std_logic_vector(7 downto 0) is TOPI(31 downto 24);
	alias topii0 : std_logic_vector(7 downto 0) is topii(7 downto 0);
	alias topii1 : std_logic_vector(7 downto 0) is topii(15 downto 8);
	alias topii2 : std_logic_vector(7 downto 0) is topii(23 downto 16);
	alias topii3 : std_logic_vector(7 downto 0) is topii(31 downto 24);
	--diffs for mode 0 vertical
	signal vdif0 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal vdif1 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal vdif2 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal vdif3 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal vabsdif0 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal vabsdif1 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal vabsdif2 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal vabsdif3 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal vtotdif : std_logic_vector(11 downto 0) :=  (others=>'0');
	--diffs for mode 1 horizontal
	signal leftp : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal leftpd : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal hdif0 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal hdif1 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal hdif2 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal hdif3 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal habsdif0 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal habsdif1 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal habsdif2 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal habsdif3 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal htotdif : std_logic_vector(11 downto 0) :=  (others=>'0');
	--diffs for mode 2 dc
	signal left0 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal left1 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal left2 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal left3 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal ddif0 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal ddif1 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal ddif2 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal ddif3 : std_logic_vector(8 downto 0) :=  (others=>'0');
	signal dabsdif0 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal dabsdif1 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal dabsdif2 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal dabsdif3 : std_logic_vector(7 downto 0) :=  (others=>'0');
	signal dtotdif : std_logic_vector(11 downto 0) :=  (others=>'0');
	--averages for mode 2 dc
	signal sumt : std_logic_vector(9 downto 0) :=  (others=>'0');
	signal suml : std_logic_vector(9 downto 0) :=  (others=>'0');
	signal sumtl : std_logic_vector(10 downto 0) :=  (others=>'0');
	alias avg  : std_logic_vector(7 downto 0) is sumtl(10 downto 3);
	--
begin
	--
	xx <= submb(2)&submb(0);
	yy <= submb(3)&submb(1);
	--
	XXO <= xx when state=2 or state=16 else oldxx;
	XXINC <= '1' when state=20 else '0';
	READYI <= '1' when statei(5 downto 4) /= yy-2 and statei(5 downto 4) /= yy-1 else '0';
	--
	yyfull <= yy & state(1 downto 0);
	left0 <= pixleft(conv_integer(yy & b"00"));
	left1 <= pixleft(conv_integer(yy & b"01"));
	left2 <= pixleft(conv_integer(yy & b"10"));
	left3 <= pixleft(conv_integer(yy & b"11"));
	--
	MODEO <= modeoi;
	--
	CHREADY <= chreadyii and READYO;
	--
process(CLK)
	variable xi: integer;
	variable yi: integer;
begin
	if rising_edge(CLK) then
		--
		if STROBEI='1' then
			pix(conv_integer(statei)) <= DATAI;
			statei <= statei + 1;
		elsif NEWLINE='1' then
			statei <= b"000000";

⌨️ 快捷键说明

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