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

Subversion Repositories motion_estimation_processor

[/] [motion_estimation_processor/] [trunk/] [src_me/] [register_file.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.std_logic_unsigned."+";
26
use IEEE.std_logic_unsigned."-";
27
use work.config.all;
28
 
29
entity register_file is
30
generic (integer_pipeline_count : integer);
31
        port(
32
        clk : in std_logic;
33
        clear : in std_logic;
34
        reset : in std_logic;
35
        addr : in std_logic_vector(4 downto 0);
36
        write : in std_logic;
37
        data_in : in std_logic_vector(31 downto 0);
38
   data_out : out std_logic_vector(31 downto 0);
39
        start : out std_logic;
40
        start_row : out std_logic;
41
   all_done_qp : in std_logic; -- program completes
42
      mvc_done : out std_logic; -- all motion vector candidates evaluated
43
        mvc_to_do : out std_logic_vector(3 downto 0); --mvcs left to do
44
        all_done_fp : in std_logic; -- fp part completes
45
        instruction_zero : in std_logic;
46
        partition_done_fp : in std_logic; -- fp partition terminates
47
        partition_done_qp : in std_logic; -- qp partition terminates
48
        done_interrupt : out std_logic;
49
        mv_cost_on : out std_logic; -- activate the costing of mvs
50
      mode_out : out mode_type;
51
        update_fp : in std_logic; -- update mv and sad
52
      load_mv : in std_logic; -- force the mvc to move foward
53
        best_sad_fp : in std_logic_vector(15 downto 0);
54
   best_mv_fp : in std_logic_vector(15 downto 0);
55
   first_mv_fp : out std_logic_vector(15 downto 0);
56
        rest_first_mv_fp : out rest_type_displacement;
57
        mbx_coordinate : out std_logic_vector(7 downto 0);
58
        mby_coordinate : out std_logic_vector(7 downto 0);
59
        mvp_x : out std_logic_vector(7 downto 0);
60
        mvp_y : out std_logic_vector(7 downto 0);
61
      quant_parameter : out std_logic_vector(5 downto 0);
62
frame_dimension_x : out std_logic_vector(7 downto 0);
63
frame_dimension_y : out std_logic_vector(7 downto 0);
64
partition_count : in std_logic_vector(3 downto 0); --identify the subpartition active
65
        update_qp : in std_logic;
66
        best_sad_qp : in std_logic_vector(15 downto 0);
67
   best_mv_qp : in std_logic_vector(15 downto 0);
68
   first_mv_qp : out std_logic_vector(15 downto 0));
69
end;
70
 
71
architecture behav of register_file is
72
 
73
component reg_memory_dp
74
        port (
75
        addra: in std_logic_vector(4 downto 0);
76
        addrb: in std_logic_vector(4 downto 0);
77
        clka: in std_logic;
78
        clkb: in std_logic;
79
        dina: in std_logic_vector(31 downto 0);
80
        doutb: out std_logic_vector(31 downto 0);
81
        wea: in std_logic);
82
end component;
83
 
84
type type_register_file is array(4 downto 0) of std_logic_vector(31 downto 0);
85
type type_register_file_mvc is array(7 downto 0) of std_logic_vector(15 downto 0);
86
type type_working_register_file is array(1 downto 0) of std_logic_vector(31 downto 0); --one fp wr and one qp wr
87
 
88
signal r,r_in : type_register_file;
89
signal mvc_r, mvc_r_in : type_register_file_mvc;
90
signal w_r,w_r_in : type_working_register_file; -- mv and sad change here
91
signal count_enable_fp,count_enable_fp_in,count_enable_qp,count_enable_qp_in,mem_we,mvc_done_r,mvc_done_r_in : std_logic; -- to enable the profiling counter
92
signal mem_data_in,mem_data_out : std_logic_vector(31 downto 0);
93
signal mem_address_a, mem_address_b : std_logic_vector(4 downto 0);
94
signal mvc_to_do_r, mvc_to_do_r_in, mvc_next, mvc_next_in : std_logic_vector(3 downto 0); -- how many mvcs
95
 
96
 
97
begin
98
 
99
mbx_coordinate <= (others => '0');
100
mby_coordinate <= (others => '0');
101
 
102
 
103
frame_dimension_x <= r(1)(15 downto 8);
104
frame_dimension_y <= r(1)(7 downto 0);
105
mvp_x <= mvc_r(0)(15 downto 8);
106
mvp_y <= mvc_r(0)(7 downto 0);
107
 
108
mode_process : process(r(0))
109
 
110
begin
111
 
112
case r(0)(19 downto 16) is
113
 
114
        when "0000" => mode_out <= m16x16;
115
        when "0001" => mode_out <= m8x8;
116
        when "0010" => mode_out <= m8x16;
117
        when "0011" => mode_out <= m16x8;
118
        when others => mode_out <= m16x16;
119
 
120
end case;
121
 
122
end process;
123
 
124
quant_parameter <= r(0)(26 downto 21);
125
mv_cost_on <= r(0)(20); -- activate the costing of mv
126
 
127
reg_memory_dp1 : reg_memory_dp
128
        port map(
129
        addra => mem_address_a,
130
        addrb => mem_address_b,
131
        clka => clk,
132
        clkb => clk,
133
        dina => mem_data_in,
134
        doutb => mem_data_out,
135
        wea => mem_we
136
);
137
 
138
 
139
read_process: process(addr,w_r,r,mem_data_out,mvc_next)
140
variable vmem_address_b : std_logic_vector(4 downto 0);
141
variable vfirst_mv_fp : std_logic_vector(15 downto 0); -- search initial MV
142
variable vrest_first_mv_fp : rest_type_displacement; -- other initial MV for the rest of the pipelines
143
 
144
begin
145
 
146
vfirst_mv_fp := w_r(0)(31 downto 16); -- normal mode
147
vmem_address_b := addr;
148
 
149
case mvc_next is -- next_mvc
150
        when "0000" => vfirst_mv_fp := w_r(0)(31 downto 16); -- normal mode
151
                           for i in 1 to (integer_pipeline_count-1) loop
152
                                vrest_first_mv_fp(i) := w_r(0)(31 downto 16); -- normal mode
153
                           end loop;
154
        when others => null;
155
end case;
156
 
157
 
158
 
159
case addr is
160
 
161
when "00000" =>   data_out <= r(0);  --command register r(0)
162
when "00001" =>   data_out <= r(1);  -- frame dimensions    
163
when "00010" =>   data_out <= r(2);  -- profiling register  fp
164
when "00011" =>
165
        if  (CFG_PIPELINE_COUNT_QP = 0) then
166
                data_out <= (others => '0');
167
        else
168
                data_out <= r(3);  -- profiling register  qp
169
        end if;
170
when "00100" =>   data_out <= r(4);  -- configuration register: frame number and mv candidate configuration
171
when others =>   data_out <= mem_data_out;  -- result registers and SAD
172
end case;
173
 
174
mem_address_b <= vmem_address_b;
175
first_mv_fp <= vfirst_mv_fp;
176
rest_first_mv_fp <= vrest_first_mv_fp;
177
 
178
end process;
179
 
180
write_process : process(load_mv,mvc_done_r,mvc_next,partition_done_fp,partition_count,count_enable_fp,addr,write,r,data_in,update_fp,best_mv_fp,best_sad_fp,instruction_zero,all_done_fp,update_qp,best_mv_qp,best_sad_qp,all_done_qp)
181
 
182
variable v : type_register_file;
183
variable mvc_v : type_register_file_mvc;
184
variable w_v : type_working_register_file;
185
variable vimproved_sad,vcount_enable_fp,vcount_enable_qp,vmem_we,vmvc_done : std_logic;
186
variable vmvc_next,vmvc_to_do : std_logic_vector(3 downto 0);
187
variable vmem_data_in : std_logic_vector(31 downto 0);
188
variable vmem_address_a : std_logic_vector(4 downto 0);
189
 
190
begin
191
 
192
vimproved_sad := '0';
193
vcount_enable_fp := count_enable_fp;
194
vcount_enable_qp := count_enable_qp;
195
vmem_data_in := data_in;
196
vmem_address_a := addr;
197
vmem_we := '0';
198
vmvc_next := mvc_next;
199
vmvc_done := mvc_done_r;
200
 
201
for i in 7 downto 0 loop
202
                        mvc_v(i) := mvc_r(i);
203
end loop;
204
 
205
for i in 4 downto 0 loop
206
                        v(i) := r(i);
207
end loop;
208
 
209
for i in 1 downto 0 loop
210
        w_v(i) := w_r(i);
211
end loop;
212
 
213
case addr is
214
 
215
when "00000" => if (write = '1') then -- command register
216
                        v(0) := data_in;
217
                end if;
218
when "00001" => if (write = '1') then  -- frame dimensions
219
                        v(1) := data_in;
220
                end if;
221
when "00010" => if (write = '1') then -- profiling register  fp
222
                        v(2) := data_in;
223
                        end if;
224
when "00011" => if (write = '1') then    -- profiling register qp
225
                        v(3) := data_in;
226
                        end if;
227
when "00100" => if (write = '1') then -- configuration register
228
                        v(4) := data_in;
229
                end if;
230
when others => null;
231
 
232
end case;
233
 
234
if (r(0)(30) = '1') then --reset row start only last one cycle
235
    v(0)(30) := '0';
236
end if;
237
 
238
 
239
if (r(0)(31) = '1') then --reset start only last one cycle
240
        vcount_enable_fp := '1';
241
        vmvc_done := '0';
242
        vmvc_next := "0001"; -- pointing to first mvc
243
        v(2) := (others => '0'); -- reset fp profile register
244
      v(0)(31) := '0';
245
    -- mv candidates to working registers
246
      w_v(0) := (others => '0'); -- reset working register
247
  --  v(1)(15 downto 0) := x"FFFF"; -- reset result register at the start of each macroblock processing
248
end if;
249
 
250
if (load_mv = '1') then
251
                vmvc_next := (others => '0');
252
end if;
253
 
254
if (update_fp = '1')  then -- update is used after each instruciton to update mv and sad
255
          w_v(0) := best_mv_fp & best_sad_fp;
256
 
257
end if;
258
 
259
 
260
vmvc_done := '1';
261
vmvc_to_do := r(0)(3 downto 0) - (vmvc_next - 1);
262
 
263
if (partition_done_fp = '1') then
264
          vmem_data_in := w_v(0); --results register
265
          vmem_we := '1';
266
          case partition_count is --update results register
267
                when "0000" =>   vmem_address_a := "01110";  -- register 14 result 16x16 (8x8 up-left result) (8x16 left result) (16x8 up result)fp
268
                when "0010" =>   vmem_address_a := "01111";  -- register 15 result 16x16 (8x8 up-right result) (8x16 right result) fp
269
                when "1000" =>   vmem_address_a := "10000";  -- register 16 result 16x16 (8x8 down-left result) (16x8 down result) fp
270
                when "1010" =>   vmem_address_a := "10001";  -- register 17 result 16x16 (8x8 down-right result) fp
271
                when others => null;
272
          end case;
273
          w_v(0) := (others => '0'); -- reset working register for the next subpartition
274
end if;
275
 
276
if  (CFG_PIPELINE_COUNT_QP = 1) then
277
if (update_qp = '1') then
278
     w_v(1) := best_mv_qp & best_sad_qp;
279
end if;
280
end if;
281
 
282
if(instruction_zero = '1') then
283
    v(0)(27) := '1';
284
end if;
285
 
286
if(all_done_fp = '1') then
287
    v(0)(29) := '1';
288
    w_v(1) := (others => '0'); -- search should start center at zero for qp w_r(0); --move the fp mv,sad to the qp working register
289
        v(3) := (others => '0'); -- reset qp profile register
290
    vcount_enable_fp := '0';
291
    if (instruction_zero = '0') then
292
        vcount_enable_qp := '1';
293
    end if;
294
end if;
295
 
296
if(all_done_qp = '1') then
297
    v(0)(28) := '1';
298
    -- temporal until partition_done_qp is available
299
    vmem_data_in := w_v(1); --results register
300
    vmem_we := '1';
301
    vmem_address_a := "10110"; --register 22 stores qp result  
302
    vcount_enable_qp := '0';
303
end if;
304
 
305
if (vcount_enable_fp = '1') then
306
    v(2):= v(2) + 1;
307
end if;
308
 
309
if  (CFG_PIPELINE_COUNT_QP = 1) then
310
        if (vcount_enable_qp = '1') then
311
        v(3):= v(3) + 1;
312
        end if;
313
end if;
314
 
315
if (CFG_USE_MVC = 1) then
316
        for i in 7 downto 0 loop
317
                        mvc_r_in(i) <= mvc_v(i);
318
        end loop;
319
        mvc_to_do <= vmvc_to_do; -- how many mvcs still to do
320
        mvc_done_r_in <= vmvc_done;
321
        mvc_next_in <= vmvc_next;
322
 
323
else
324
        for i in 7 downto 0 loop
325
                        mvc_r_in(i) <= (others => '0'); --disable
326
        end loop;
327
        mvc_to_do <= (others => '0'); -- how many mvcs still to do
328
        mvc_done_r_in <= '1';
329
        mvc_next_in <= (others => '0');
330
end if;
331
 
332
for i in 4 downto 0 loop
333
                        r_in(i) <= v(i);
334
end loop;
335
 
336
for i in 1 downto 0 loop
337
                        w_r_in(i) <= w_v(i);
338
end loop;
339
 
340
 
341
mem_data_in <= vmem_data_in;
342
count_enable_fp_in <= vcount_enable_fp;
343
count_enable_qp_in <= vcount_enable_qp;
344
mem_address_a <= vmem_address_a;
345
mem_we <= vmem_we;
346
 
347
 
348
 
349
end process;
350
 
351
 
352
start <= r(0)(31); -- bit 31 activates the me
353
start_row <= r(0)(30); -- bit 30 indicates starting the row. reset the memory map
354
 
355
first_mv_qp <= w_r(1)(31 downto 16); -- first motion vector for qp
356
mvc_done <= mvc_done_r_in;
357
 
358
 
359
-- the control processor should read the register to know what has happen
360
--done_interrupt <= r(0)(29) or r(0)(28); -- bit 29 high when fp process completes  or bit 28 high when qp process completes
361
 
362
done0 : if CFG_PIPELINE_COUNT_QP = 1 generate
363
done_interrupt <= r(0)(28) or (r(0)(29) and r(0)(27)); --instruction zero hit then interrupt high with only fp part 
364
end generate;
365
 
366
done1 : if CFG_PIPELINE_COUNT_QP = 0 generate
367
done_interrupt <= r(0)(29);
368
end generate;
369
 
370
regs : process(clk,clear)
371
 
372
begin
373
 
374
 if (clear = '1') then
375
        for i in 4 downto 0 loop
376
                        r(i) <= (others => '0');
377
        end loop;
378
        for i in 7 downto 0 loop
379
                        mvc_r(i) <= (others => '0');
380
        end loop;
381
        for i in 1 downto 0 loop
382
                        w_r(i) <= (others => '0');
383
        end loop;
384
        count_enable_fp <= '0';
385
        count_enable_qp <= '0';
386
        mvc_done_r <= '0';
387
      mvc_next <= (others => '0');
388
 elsif rising_edge(clk) then
389
                if (reset = '1') then -- general enable
390
                              for i in 4 downto 0 loop
391
                                                r(i) <= (others => '0');
392
                                end loop;
393
                                for i in 7 downto 0 loop
394
                                        mvc_r(i) <= (others => '0');
395
                                end loop;
396
                                for i in 1 downto 0 loop
397
                                                w_r(i) <= (others => '0');
398
                                end loop;
399
                                count_enable_fp <= '0';
400
                                count_enable_qp <= '0';
401
                                mvc_done_r <= '0'; --remember when you have finish with mvc
402
                              mvc_next <= (others => '0');
403
                else
404
                                for i in 4 downto 0 loop
405
                                                r(i) <= r_in(i);
406
                                end loop;
407
                                for i in 7 downto 0 loop
408
                                        mvc_r(i) <= mvc_r_in(i);
409
                                end loop;
410
                                for i in 1 downto 0 loop
411
                                                w_r(i) <= w_r_in(i);
412
                                end loop;
413
                                mvc_done_r <= mvc_done_r_in;
414
                                count_enable_fp <= count_enable_fp_in;
415
                                count_enable_qp <= count_enable_qp_in;
416
                              mvc_next <= mvc_next_in;
417
                end if;
418
 end if;
419
 
420
end process regs;
421
 
422
end behav;

powered by: WebSVN 2.1.0

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