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] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 eejlny
----------------------------------------------------------------------------
2
--  This file is a part of the LM VHDL IP LIBRARY
3
--  Copyright (C) 2009 Jose Nunez-Yanez
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  See the file COPYING for the full details of the license.
11
--
12
--  The license allows free and unlimited use of the library and tools for research and education purposes. 
13
--  The full LM core supports many more advanced motion estimation features and it is available under a 
14
--  low-cost commercial license. See the readme file to learn more or contact us at 
15
--  eejlny@byacom.co.uk or www.byacom.co.uk
16
-----------------------------------------------------------------------------
17
-- Entity:      register_file
18
-- File:        register_file.vhd
19
-- Author:      Jose Luis Nunez 
20
-- Description: register file that holds the command and the first mv
21
------------------------------------------------------------------------------
22
 
23
library IEEE;
24
use IEEE.std_logic_1164.all;
25
use IEEE.Numeric_STD.all;
26
use IEEE.std_logic_unsigned."-";
27
use IEEE.std_logic_unsigned."+";
28
use IEEE.std_logic_arith."abs";
29
use work.config.all;
30
 
31
 
32
entity distance_engine64 is
33
   generic( qp_mode : std_logic := '0');
34
        port(
35
        clk : in std_logic;
36
        clear : in std_logic;
37
        reset : in std_logic;
38
        enable : in std_logic;
39
        update : in std_logic;
40
        load_mv : in std_logic;
41
        mv_cost_on : in std_logic;
42
        mode_in : in mode_type;
43
      mv_cost_in : in std_logic_vector(15 downto 0);
44
        candidate_mvx : in std_logic_vector(7 downto 0);
45
        candidate_mvy : in std_logic_vector(7 downto 0);
46
        reference_data_in : in std_logic_vector(63 downto 0);
47
        residue_out : out std_logic_vector(63 downto 0);
48
        enable_fifo : out std_logic;
49
        reset_fifo : out std_logic;
50
        winner1 : out std_logic;
51
        calculate_sad_done : out std_logic;
52
        distance_engine_active : out std_logic;
53
        current_data_in : in std_logic_vector(63 downto 0);
54
   best_sad : out std_logic_vector(15 downto 0);
55
   best_mv : out std_logic_vector(15 downto 0));
56
end;
57
 
58
architecture behav of distance_engine64 is
59
 
60
 
61
type state_type is (idle,calculate_sad,select_mv,wait_for_sad); -- dist engine control unit states
62
 
63
type state_register_type is record
64
   enable_fifo : std_logic; -- enable the residue fifo
65
   winner1 : std_logic; -- winner flag controls residue store in block1 or 2
66
        state : state_type;
67
   current_sad : std_logic_vector(15 downto 0); -- stored partial and current sad
68
 --  current_mv : std_logic_vector(15 downto 0); -- stored the future motion vector to be evaluated
69
   current_mv2 : std_logic_vector(15 downto 0); -- stored the current motion vector being evaluated
70
   pipeline_cm : std_logic_vector(63 downto 0); -- pipeline for cm register directly from memory
71
   pipeline_rm : std_logic_vector(63 downto 0); -- pipeline for rm register directly from memory
72
   pipeline : std_logic_vector(63 downto 0); -- pipeline register
73
end record;
74
 
75
signal r, r_in: state_register_type; -- state register
76
 
77
 
78
--signal sad_value_out, sad_value_in : std_logic_vector(15 downto 0);
79
 
80
begin
81
 
82
 
83
residue_out <= r.pipeline; -- write the residue to FIFOs
84
r_in.enable_fifo <= '1' when r.state = calculate_sad else '0';
85
r_in.pipeline_cm <= current_data_in;
86
r_in.pipeline_rm <= reference_data_in;
87
enable_fifo <= r.enable_fifo;
88
--reset_fifo <= '1' when r.state = memory_read else '0'; -- empty the fifo before start writing to it
89
 
90
tree_process : process(r)
91
 
92
variable vpipeline : std_logic_vector(63 downto 0);
93
variable vsad_value : std_logic_vector(15 downto 0);
94
 
95
begin
96
 
97
   vpipeline := r.pipeline;
98
   vsad_value := r.current_sad;
99
 
100
   if (r.state = calculate_sad or r.state = wait_for_sad) then
101
   --if (r.state /= idle) then
102
 
103
      for i in 8 downto 1 loop
104
            vsad_value := vsad_value + (x"00" & vpipeline((8*i-1) downto (8*i-8)));
105
          end loop;
106
   elsif (qp_mode = '0') then
107
      vsad_value := (others => '0');
108
   elsif (r.state  = idle) then
109
      vsad_value := (others => '0');
110
   end if;
111
 
112
   r_in.current_sad <= vsad_value;
113
 
114
end process tree_process;
115
 
116
 
117
sad_process : process(r)
118
 
119
variable vpipeline : std_logic_vector(71 downto 0); -- 8 extra bits to accomodate signs
120
--variable vpipeline2 : std_logic_vector(63 downto 0);
121
 
122
 
123
begin
124
 
125
     if (r.state = idle) then
126
                vpipeline := (others => '0');
127
     elsif (r.state = select_mv and qp_mode = '1') then
128
                vpipeline := (others => '0');
129
        else
130
 
131
         for i in 8 downto 1 loop
132
            --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)));
133
            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))))));
134
            --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))))));
135
 
136
         end loop;
137
 
138
 
139
     end if;
140
 
141
   for i in 8 downto 1 loop
142
      r_in.pipeline((8*i-1) downto (8*i-8)) <= vpipeline((9*i-2) downto (9*i-9));
143
   end loop;
144
 
145
end process sad_process;
146
 
147
 
148
sad_control : process(r,enable,load_mv,update,candidate_mvx,candidate_mvy,mode_in)
149
variable vcalculate_sad_done,vdistance_engine_active : std_logic;
150
variable v : state_register_type;
151
begin
152
 
153
   vdistance_engine_active := '0';
154
   v.state := r.state;
155
   v.winner1 := r.winner1;
156
   vcalculate_sad_done := '0';
157
  -- v.current_mv := r.current_mv;
158
   v.current_mv2 := r.current_mv2;
159
 
160
 
161
 
162
   case v.state is
163
 
164
           when idle =>  -- first state, waiting for enable signal
165
                   if (enable = '1') then
166
                           v.state := calculate_sad;
167
                   end if;
168
        when calculate_sad => -- read and evaluate sad 
169
                  vdistance_engine_active := '1';
170
              if (enable = '0') then -- wait for sad
171
                        v.state := wait_for_sad;
172
                   end if;
173
       when wait_for_sad =>
174
                vdistance_engine_active := '1';
175
                v.state := select_mv;
176
        when select_mv => -- select best mv
177
                vdistance_engine_active := '1';
178
              --v.current_mv := (others => '0'); -- clear in preparation for new calculation
179
                if (qp_mode = '0') then
180
                        vcalculate_sad_done := '1';
181
              end if;
182
                if (enable = '0') then
183
                        if (qp_mode = '1') then
184
                                vcalculate_sad_done := '1';
185
                end if;
186
                        v.state := idle;
187
                else
188
                        --vcalculate_sad_done := '1';
189
                        v.state := calculate_sad;
190
            end if;
191
           when others => null;
192
        end case;
193
 
194
 --  if (enable = '1') then
195
--      v.current_mv2 := v.current_mv;
196
 --  end if;
197
 
198
   if (load_mv = '1') then
199
--      v.current_mv2 := v.current_mv;  
200
      v.current_mv2 := candidate_mvx & candidate_mvy;
201
   end if;
202
 
203
 
204
 
205
r_in.state <= v.state;
206
--r_in.current_mv <= v.current_mv;
207
r_in.current_mv2 <= v.current_mv2;
208
r_in.winner1 <= v.winner1;
209
calculate_sad_done <= vcalculate_sad_done;
210
distance_engine_active <= vdistance_engine_active;
211
 
212
end process sad_control;
213
 
214
 
215
best_sad <= (r.current_sad + mv_cost_in) when mv_cost_on = '1' else r.current_sad;
216
best_mv <= r.current_mv2;
217
winner1 <= r.winner1;
218
 
219
regs : process(clk,clear)
220
 
221
begin
222
 
223
 if (clear = '1') then
224
   r.enable_fifo <= '0';
225
   r.winner1 <= '0';
226
        r.state <= idle;
227
        r.current_sad <= (others => '0');
228
        r.pipeline <= (others => '0');
229
        r.pipeline_cm <= (others => '0');
230
        r.pipeline_rm <= (others => '0');
231
        --r.current_mv <= (others => '0');
232
        r.current_mv2 <= (others => '0');
233
 elsif rising_edge(clk) then
234
                if (reset = '1') then -- general enable
235
                      r.enable_fifo <= '0';
236
                      r.winner1 <= '0';
237
                                r.state <= idle;
238
                 r.current_sad <= (others => '0');
239
                 r.pipeline <= (others => '0');
240
                 r.pipeline_cm <= (others => '0');
241
                 r.pipeline_rm <= (others => '0');
242
                 --r.current_mv <= (others => '0');
243
                 r.current_mv2 <= (others => '0');
244
                else
245
                         r <= r_in;
246
                end if;
247
 end if;
248
 
249
 
250
end process regs;
251
 
252
 
253
end behav;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.