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

Subversion Repositories motion_estimation_processor

[/] [motion_estimation_processor/] [trunk/] [src_me/] [distance_engine64.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------
--  This file is a part of the LM VHDL IP LIBRARY
--  Copyright (C) 2009 Jose Nunez-Yanez
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  See the file COPYING for the full details of the license.
--
--  The license allows free and unlimited use of the library and tools for research and education purposes. 
--  The full LM core supports many more advanced motion estimation features and it is available under a 
--  low-cost commercial license. See the readme file to learn more or contact us at 
--  eejlny@byacom.co.uk or www.byacom.co.uk
-----------------------------------------------------------------------------
-- Entity: 	register_file
-- File:	register_file.vhd
-- Author:	Jose Luis Nunez 
-- Description:	register file that holds the command and the first mv
------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.Numeric_STD.all;
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_arith."abs";
use work.config.all;
 
 
entity distance_engine64 is
   generic( qp_mode : std_logic := '0');
	port(
	clk : in std_logic;
	clear : in std_logic;
	reset : in std_logic;
	enable : in std_logic;
	update : in std_logic;
	load_mv : in std_logic;
	mv_cost_on : in std_logic;
	mode_in : in mode_type;
      mv_cost_in : in std_logic_vector(15 downto 0);
	candidate_mvx : in std_logic_vector(7 downto 0);
	candidate_mvy : in std_logic_vector(7 downto 0);
	reference_data_in : in std_logic_vector(63 downto 0);
	residue_out : out std_logic_vector(63 downto 0);
	enable_fifo : out std_logic;
	reset_fifo : out std_logic;
	winner1 : out std_logic;
	calculate_sad_done : out std_logic; 
	distance_engine_active : out std_logic;
	current_data_in : in std_logic_vector(63 downto 0);
   best_sad : out std_logic_vector(15 downto 0);
   best_mv : out std_logic_vector(15 downto 0));
end;
 
architecture behav of distance_engine64 is
 
 
type state_type is (idle,calculate_sad,select_mv,wait_for_sad); -- dist engine control unit states
 
type state_register_type is record
   enable_fifo : std_logic; -- enable the residue fifo
   winner1 : std_logic; -- winner flag controls residue store in block1 or 2
	state : state_type;
   current_sad : std_logic_vector(15 downto 0); -- stored partial and current sad
 --  current_mv : std_logic_vector(15 downto 0); -- stored the future motion vector to be evaluated
   current_mv2 : std_logic_vector(15 downto 0); -- stored the current motion vector being evaluated
   pipeline_cm : std_logic_vector(63 downto 0); -- pipeline for cm register directly from memory
   pipeline_rm : std_logic_vector(63 downto 0); -- pipeline for rm register directly from memory
   pipeline : std_logic_vector(63 downto 0); -- pipeline register
end record;
 
signal r, r_in: state_register_type; -- state register
 
 
--signal sad_value_out, sad_value_in : std_logic_vector(15 downto 0);
 
begin
 
 
residue_out <= r.pipeline; -- write the residue to FIFOs
r_in.enable_fifo <= '1' when r.state = calculate_sad else '0';
r_in.pipeline_cm <= current_data_in;
r_in.pipeline_rm <= reference_data_in;
enable_fifo <= r.enable_fifo;
--reset_fifo <= '1' when r.state = memory_read else '0'; -- empty the fifo before start writing to it
 
tree_process : process(r)
 
variable vpipeline : std_logic_vector(63 downto 0);
variable vsad_value : std_logic_vector(15 downto 0);
 
begin
 
   vpipeline := r.pipeline;
   vsad_value := r.current_sad;
 
   if (r.state = calculate_sad or r.state = wait_for_sad) then
   --if (r.state /= idle) then
 
      for i in 8 downto 1 loop
            vsad_value := vsad_value + (x"00" & vpipeline((8*i-1) downto (8*i-8)));
   	  end loop;
   elsif (qp_mode = '0') then
      vsad_value := (others => '0');
   elsif (r.state  = idle) then
      vsad_value := (others => '0');
   end if;
 
   r_in.current_sad <= vsad_value;
 
end process tree_process;
 
 
sad_process : process(r)
 
variable vpipeline : std_logic_vector(71 downto 0); -- 8 extra bits to accomodate signs
--variable vpipeline2 : std_logic_vector(63 downto 0);
 
 
begin
 
     if (r.state = idle) then
		vpipeline := (others => '0');
     elsif (r.state = select_mv and qp_mode = '1') then
		vpipeline := (others => '0');
	else
 
         for i in 8 downto 1 loop
            --vpipeline1((8*i-1) downto (8*i-8)) := signed(reference_data_in((8*i-1) downto (8*i-8)) - current_data_in((8*i-1) downto (8*i-8)));
            vpipeline((9*i-1) downto (9*i-9)) := std_logic_vector(ABS(signed(("0" & r.pipeline_rm((8*i-1) downto (8*i-8))) - ("0" & r.pipeline_cm((8*i-1) downto (8*i-8))))));
            --vpipeline((9*i-1) downto (9*i-9)) := std_logic_vector(ABS(signed(("0" & reference_data_in((8*i-1) downto (8*i-8))) - ("0" & current_data_in((8*i-1) downto (8*i-8))))));
 
         end loop;
 
 
     end if;
 
   for i in 8 downto 1 loop
      r_in.pipeline((8*i-1) downto (8*i-8)) <= vpipeline((9*i-2) downto (9*i-9));
   end loop;
 
end process sad_process;
 
 
sad_control : process(r,enable,load_mv,update,candidate_mvx,candidate_mvy,mode_in)
variable vcalculate_sad_done,vdistance_engine_active : std_logic;
variable v : state_register_type;
begin
 
   vdistance_engine_active := '0';
   v.state := r.state;
   v.winner1 := r.winner1;
   vcalculate_sad_done := '0';
  -- v.current_mv := r.current_mv;
   v.current_mv2 := r.current_mv2;
 
 
 
   case v.state is
 
	   when idle =>  -- first state, waiting for enable signal
		   if (enable = '1') then
			   v.state := calculate_sad;
		   end if;	
	when calculate_sad => -- read and evaluate sad 
		  vdistance_engine_active := '1';
              if (enable = '0') then -- wait for sad
		      	v.state := wait_for_sad;	
		   end if;
       when wait_for_sad => 
		vdistance_engine_active := '1';
		v.state := select_mv;
	when select_mv => -- select best mv
		vdistance_engine_active := '1';
	      --v.current_mv := (others => '0'); -- clear in preparation for new calculation
		if (qp_mode = '0') then
			vcalculate_sad_done := '1';
	      end if;
		if (enable = '0') then 
			if (qp_mode = '1') then
				vcalculate_sad_done := '1';
	      	end if;
			v.state := idle;
		else
			--vcalculate_sad_done := '1';
			v.state := calculate_sad;
            end if;
	   when others => null;
	end case;
 
 --  if (enable = '1') then
--	v.current_mv2 := v.current_mv;
 --  end if;
 
   if (load_mv = '1') then    
--	v.current_mv2 := v.current_mv;  
      v.current_mv2 := candidate_mvx & candidate_mvy;
   end if;	
 
 
 
r_in.state <= v.state;
--r_in.current_mv <= v.current_mv;
r_in.current_mv2 <= v.current_mv2;
r_in.winner1 <= v.winner1;
calculate_sad_done <= vcalculate_sad_done;
distance_engine_active <= vdistance_engine_active;
 
end process sad_control;
 
 
best_sad <= (r.current_sad + mv_cost_in) when mv_cost_on = '1' else r.current_sad;
best_mv <= r.current_mv2;
winner1 <= r.winner1;
 
regs : process(clk,clear)
 
begin
 
 if (clear = '1') then
   r.enable_fifo <= '0';
   r.winner1 <= '0';
	r.state <= idle;
	r.current_sad <= (others => '0');
	r.pipeline <= (others => '0');
	r.pipeline_cm <= (others => '0');
	r.pipeline_rm <= (others => '0');
	--r.current_mv <= (others => '0');
	r.current_mv2 <= (others => '0');
 elsif rising_edge(clk) then 
		if (reset = '1') then -- general enable
		      r.enable_fifo <= '0';
		      r.winner1 <= '0';
			 	r.state <= idle;
	         r.current_sad <= (others => '0');
	         r.pipeline <= (others => '0');
	         r.pipeline_cm <= (others => '0');
	         r.pipeline_rm <= (others => '0');
	         --r.current_mv <= (others => '0');
	         r.current_mv2 <= (others => '0');
		else
			 r <= r_in;
		end if;
 end if;
 
 
end process regs; 
 
 
end behav;
 

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.