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

Subversion Repositories macroblock_motion_detection

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/macroblock_motion_detection/macroblock_motion_detection/MotionDetection.v
0,0 → 1,855
/////////////////////////////////////////////////////////////////////
//// ////
//// MotionDetection.v ////
//// ////
//// Performs motion estimation for one 16 x 16 macroblock ////
//// in a 48 x 48 pixel window every 512 clock cycles. ////
//// ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MotionDetection(clk, ena, rst, din1, din2, dout, state, count);
// runs at 1/2 clock speed?
reg clk2;
parameter COMP = 0;
 
input [31:0] din1, din2;
input clk, ena, rst;
input [3:0] state;
output [31:0] dout;
input [8:0] count;
 
reg [31:0] dout;
 
integer i, j, k, l, m, n, o;
 
// Motion Estimation Registers
reg [8:0] diff[0:2][0:15];
reg [7:0] diffp[0:15];
reg [7:0] diffpd[0:15];
reg [7:0] diffm[0:2][0:15];
reg [7:0] diffpp[0:2][0:15];
reg [7:0] diffmm[0:2][0:15];
reg [7:0] diffmd[0:2][0:15];
reg [10:0] difft[0:2][0:3];
 
reg [3:0] offset;
wire [7:0] curt[0:15];
wire [7:0] searcht [0:47];
 
reg [15:0] sums [0:2][0:11];
reg [15:0] lowsum[0:1];
reg lowflag;
reg [5:0] minxt,minyt;
reg [5:0] oldminx,oldminy;
reg [3:0] cursum;
reg sumflag;
reg [5:0] minx;
reg [5:0] miny;
 
wire [31:0] DOUTC0;
wire [31:0] DOUTC1;
wire [31:0] DOUTC2;
wire [31:0] DOUTC3;
wire [31:0] DOUT0;
wire [31:0] DOUT1;
wire [31:0] DOUT2;
wire [31:0] DOUT3;
wire [31:0] DOUT4;
wire [31:0] DOUT5;
wire [31:0] DOUT6;
wire [31:0] DOUT7;
wire [31:0] DOUT8;
wire [31:0] DOUT9;
wire [31:0] DOUT10;
wire [31:0] DOUT11;
 
assign {curt[0],curt[1],curt[2],curt[3]} = DOUTC0;
assign {curt[4],curt[5],curt[6],curt[7]} = DOUTC1;
assign {curt[8],curt[9],curt[10],curt[11]} = DOUTC2;
assign {curt[12],curt[13],curt[14],curt[15]} = DOUTC3;
 
assign {searcht[0],searcht[1],searcht[2],searcht[3]} = DOUT0;
assign {searcht[4],searcht[5],searcht[6],searcht[7]} = DOUT1;
assign {searcht[8],searcht[9],searcht[10],searcht[11]} = DOUT2;
assign {searcht[12],searcht[13],searcht[14],searcht[15]} = DOUT3;
assign {searcht[16],searcht[17],searcht[18],searcht[19]} = DOUT4;
assign {searcht[20],searcht[21],searcht[22],searcht[23]} = DOUT5;
assign {searcht[24],searcht[25],searcht[26],searcht[27]} = DOUT6;
assign {searcht[28],searcht[29],searcht[30],searcht[31]} = DOUT7;
assign {searcht[32],searcht[33],searcht[34],searcht[35]} = DOUT8;
assign {searcht[36],searcht[37],searcht[38],searcht[39]} = DOUT9;
assign {searcht[40],searcht[41],searcht[42],searcht[43]} = DOUT10;
assign {searcht[44],searcht[45],searcht[46],searcht[47]} = DOUT11;
 
// Instantiate MD_Block_Ram
MD_Block_Ram MD_Block_Ram (
.clk(clk2),
.ena(ena),
.rst(rst),
.din1(din1),
.din2(din2),
.DOUTC0(DOUTC0),
.DOUTC1(DOUTC1),
.DOUTC2(DOUTC2),
.DOUTC3(DOUTC3),
.DOUT0(DOUT0),
.DOUT1(DOUT1),
.DOUT2(DOUT2),
.DOUT3(DOUT3),
.DOUT4(DOUT4),
.DOUT5(DOUT5),
.DOUT6(DOUT6),
.DOUT7(DOUT7),
.DOUT8(DOUT8),
.DOUT9(DOUT9),
.DOUT10(DOUT10),
.DOUT11(DOUT11),
.count(count),
.minx(minx),
.miny(miny)
);
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
i = 0;
o = 0;
for (i = 0; i < 12; i=i+1)
begin
sums[0][i] <= 0;
sums[1][i] <= 0;
sums[2][i] <= 0;
end
end
else
begin
if (ena)
begin
case (state)
COMP:
begin
// delay curt 1 cycle to match diffm selection below
for (i=0; i < 16; i=i+1)
begin
diffp[i] <= curt[i];
end
for (i=0; i < 16; i=i+1)
begin
diffpd[i] <= diffp[i];
end
// find differences for this row at three places
 
case (offset)
8: begin // 1 and 3 offset by 16
for (i=0; i < 16; i=i+1)
begin
diffm[0][i] <= searcht[i+8];
diffm[2][i] <= searcht[i+24];
end
end
4: begin // 1 and 3 offset by 8
for (i=0; i < 16; i=i+1)
begin
case (minx)
8: begin
diffm[0][i] <= searcht[i+4];
end
16: begin
diffm[0][i] <= searcht[i+12];
end
24: begin
diffm[0][i] <= searcht[i+20];
end
endcase
end
for (i=8; i < 16; i=i+1)
begin
case (minx)
8: begin
diffm[2][i] <= searcht[i+12];
end
16: begin
diffm[2][i] <= searcht[i+20];
end
24: begin
diffm[2][i] <= searcht[i+28];
end
endcase
end
end
2: begin // 1 and 3 offset by 4
for (i=0; i < 16; i=i+1)
begin
case (minx)
4: begin
diffm[0][i] <= searcht[i+2];
end
8: begin
diffm[0][i] <= searcht[i+6];
end
12: begin
diffm[0][i] <= searcht[i+10];
end
16: begin
diffm[0][i] <= searcht[i+14];
end
20: begin
diffm[0][i] <= searcht[i+18];
end
24: begin
diffm[0][i] <= searcht[i+22];
end
28: begin
diffm[0][i] <= searcht[i+26];
end
endcase
end
for (i=12; i < 16; i=i+1)
begin
case (minx)
4: begin
diffm[2][i] <= searcht[i+6];
end
8: begin
diffm[2][i] <= searcht[i+10];
end
12: begin
diffm[2][i] <= searcht[i+14];
end
16: begin
diffm[2][i] <= searcht[i+18];
end
20: begin
diffm[2][i] <= searcht[i+22];
end
24: begin
diffm[2][i] <= searcht[i+26];
end
28: begin
diffm[2][i] <= searcht[i+30];
end
endcase
end
end
1: begin // 1 and 3 offset by 2
for (i=0; i < 16; i=i+1)
begin
case (minx)
2: begin
diffm[0][i] <= searcht[i+1];
end
4: begin
diffm[0][i] <= searcht[i+3];
end
6: begin
diffm[0][i] <= searcht[i+5];
end
8: begin
diffm[0][i] <= searcht[i+7];
end
10: begin
diffm[0][i] <= searcht[i+9];
end
12: begin
diffm[0][i] <= searcht[i+11];
end
14: begin
diffm[0][i] <= searcht[i+13];
end
16: begin
diffm[0][i] <= searcht[i+15];
end
18: begin
diffm[0][i] <= searcht[i+17];
end
20: begin
diffm[0][i] <= searcht[i+19];
end
22: begin
diffm[0][i] <= searcht[i+21];
end
24: begin
diffm[0][i] <= searcht[i+23];
end
26: begin
diffm[0][i] <= searcht[i+25];
end
28: begin
diffm[0][i] <= searcht[i+27];
end
30: begin
diffm[0][i] <= searcht[i+29];
end
endcase
end
for (i=14; i < 16; i=i+1)
begin
case (minx)
2: begin
diffm[2][i] <= searcht[i+3];
end
4: begin
diffm[2][i] <= searcht[i+5];
end
6: begin
diffm[2][i] <= searcht[i+7];
end
8: begin
diffm[2][i] <= searcht[i+9];
end
10: begin
diffm[2][i] <= searcht[i+11];
end
12: begin
diffm[2][i] <= searcht[i+13];
end
14: begin
diffm[2][i] <= searcht[i+15];
end
16: begin
diffm[2][i] <= searcht[i+17];
end
18: begin
diffm[2][i] <= searcht[i+19];
end
20: begin
diffm[2][i] <= searcht[i+21];
end
22: begin
diffm[2][i] <= searcht[i+23];
end
24: begin
diffm[2][i] <= searcht[i+25];
end
26: begin
diffm[2][i] <= searcht[i+27];
end
28: begin
diffm[2][i] <= searcht[i+29];
end
30: begin
diffm[2][i] <= searcht[i+31];
end
endcase
end
end
endcase
// copy from 1 and 3 to 1 2 and 3
// 1 is the same
for (i=0; i < 16; i=i+1)
begin
diffmd[0][i] <= diffm[0][i];
end
// 2 is combination of 1 and 3
case (offset)
8: begin
for (i=0; i < 8; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+8];
diffmd[1][i+8] <= diffm[2][i];
end
end
4: begin
for (i=0; i < 12; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+4];
end
for (i=12; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-4];
end
end
2: begin
for (i=0; i < 14; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+2];
end
for (i=14; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-2];
end
end
1: begin
for (i=0; i < 15; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+1];
end
for (i=15; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-1];
end
end
endcase
// 3 is combination of 1 and 3
case (offset)
8: begin
for (i=0; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
4: begin
for (i=0; i < 8; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+8];
end
for (i=8; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
2: begin
for (i=0; i < 12; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+4];
end
for (i=12; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
1: begin
for (i=0; i < 14; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+2];
end
for (i=14; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
endcase
 
 
for (o = 0; o < 3; o = o + 1)
begin
for (i=0; i < 16; i=i+1)
begin
if (diffpd[i] > diffmd[o][i])
begin
diffpp[o][i] <= diffpd[i];
diffmm[o][i] <= diffmd[o][i];
end
else
begin
diffpp[o][i] <= diffmd[o][i];
diffmm[o][i] <= diffpd[i];
end
diff[o][i] <= diffpp[o][i] - diffmm[o][i];
end // for i 0 to 15
end // for o 0 to 3
 
// partial sums three times for three tests per row
for (o = 0; o < 3; o = o + 1)
begin
for(i=0; i < 4; i = i + 1)
begin
k = {i,2'b0};
l = k + 1;
m = k + 2;
n = k + 3;
difft[o][i] <= diff[o][k]+diff[o][l]+diff[o][m]+diff[o][n];
end
end // o loop
 
// final sums at proper delay repeat three times for three tests per row
if (sumflag)
begin
for (i =0; i < 3; i = i + 1)
begin
sums[i][cursum] <= sums[i][cursum] + difft[i][0] + difft[i][1] + difft[i][2] + difft[i][3];
end
end
else
if (count == 511)
begin
for (i =0; i < 3; i = i + 1)
begin
for (j =0; j < 12; j = j + 1)
begin
sums[i][j] <= 0;
end
end
end
end // COMP state
endcase // state
 
end // if ena
end // if ~rst else
end // always
 
// control for cursum and sumflag , minx, & miny control
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
cursum <= 0;
sumflag <= 0;
minxt <= 0;
minyt <= 0;
oldminx <= 0;
oldminy <= 0;
lowsum[1] <= 0;
lowflag <= 0;
dout <= 0;
end
else
if (ena)
begin
i = 5;
case (count) // 16 adds for each offset i from beginning
0+i: begin sumflag <=1; cursum <= 0; end //0
16+i: begin sumflag <=1; cursum <= 1; end //16
32+i: begin sumflag <=1; cursum <= 2; end //32
48+i: sumflag <=0;
 
49+i: begin
lowflag <=1;
lowsum[1] <= sums[0][0];
minxt <= 8;
minyt <= 8;
end
50+i: begin
lowsum[1] <= sums[1][0];
minxt <= 16;
minyt <= 8;
end
51+i: begin
lowsum[1] <= sums[2][0];
minxt <= 24;
minyt <= 8;
end
 
52+i: begin
lowsum[1] <= sums[0][1];
minxt <= 8;
minyt <= 16;
end
53+i: begin
lowsum[1] <= sums[1][1];
minxt <= 16;
minyt <= 16;
end
54+i: begin
lowsum[1] <= sums[2][1];
minxt <= 24;
minyt <= 16;
end
 
55+i: begin
lowsum[1] <= sums[0][2];
minxt <= 8;
minyt <= 24;
end
56+i: begin
lowsum[1] <= sums[1][2];
minxt <= 16;
minyt <= 24;
end
57+i: begin
lowsum[1] <= sums[2][2];
minxt <= 24;
minyt <= 24;
end
58+i: lowflag <=0;
 
112+i: begin sumflag <=1; cursum <= 3; end //112
128+i: begin sumflag <=1; cursum <= 4; end //128
144+i: begin sumflag <=1; cursum <= 5; end //144
160+i: sumflag <=0;
161+i: begin
oldminx <= minx;
oldminy <= miny;
end
 
162+i: begin
lowflag <=1;
lowsum[1] <= sums[0][3];
minxt <= oldminx - 4;
minyt <= oldminy - 4;
end
163+i: begin
lowsum[1] <= sums[1][3];
minxt <= oldminx - 0;
minyt <= oldminy - 4;
end
164+i: begin
lowsum[1] <= sums[2][3];
minxt <= oldminx + 4;
minyt <= oldminy - 4;
end
 
165+i: begin
lowsum[1] <= sums[0][4];
minxt <= oldminx - 4;
minyt <= oldminy;
end
166+i: begin
lowsum[1] <= sums[1][4];
minxt <= oldminx;
minyt <= oldminy;
end
167+i: begin
lowsum[1] <= sums[2][4];
minxt <= oldminx + 4;
minyt <= oldminy;
end
 
168+i: begin
lowsum[1] <= sums[0][5];
minxt <= oldminx - 4;
minyt <= oldminy + 4;
end
169+i: begin
lowsum[1] <= sums[1][5];
minxt <= oldminx;
minyt <= oldminy + 4;
end
170+i: begin
lowsum[1] <= sums[2][5];
minxt <= oldminx + 4;
minyt <= oldminy + 4;
end
171+i: lowflag <=0;
 
224+i: begin sumflag <=1; cursum <= 6; end //224
240+i: begin sumflag <=1; cursum <= 7; end //240
256+i: begin sumflag <=1; cursum <= 8; end //256
272+i: sumflag <=0;
273+i: begin
oldminx <= minx;
oldminy <= miny;
end
274+i: begin
lowflag <=1;
lowsum[1] <= sums[0][6];
minxt <= oldminx - 2;
minyt <= oldminy - 2;
end
275+i: begin
lowsum[1] <= sums[1][6];
minxt <= oldminx;
minyt <= oldminy - 2;
end
276+i: begin
lowsum[1] <= sums[2][6];
minxt <= oldminx + 2;
minyt <= oldminy - 2;
end
 
277+i: begin
lowsum[1] <= sums[0][7];
minxt <= oldminx - 2;
minyt <= oldminy;
end
278+i: begin
lowsum[1] <= sums[1][7];
minxt <= oldminx;
minyt <= oldminy;
end
279+i: begin
lowsum[1] <= sums[2][7];
minxt <= oldminx + 2;
minyt <= oldminy;
end
 
280+i: begin
lowsum[1] <= sums[0][8];
minxt <= oldminx - 2;
minyt <= oldminy + 2;
end
281+i: begin
lowsum[1] <= sums[1][8];
minxt <= oldminx;
minyt <= oldminy + 2;
end
282+i: begin
lowsum[1] <= sums[2][8];
minxt <= oldminx + 2;
minyt <= oldminy + 2;
end
283+i: lowflag <=0;
 
 
336+i: begin sumflag <=1; cursum <= 9; end //336
352+i: begin sumflag <=1; cursum <= 10; end //352
368+i: begin sumflag <=1; cursum <= 11; end //368
384+i: sumflag <=0;
385+i: begin
oldminx <= minx;
oldminy <= miny;
end
 
386+i: begin
lowflag <=1;
lowsum[1] <= sums[0][9];
minxt <= oldminx - 1;
minyt <= oldminy - 1;
end
387+i: begin
lowsum[1] <= sums[1][9];
minxt <= oldminx;
minyt <= oldminy - 1;
end
388+i: begin
lowsum[1] <= sums[2][9];
minxt <= oldminx + 1;
minyt <= oldminy - 1;
end
 
389+i: begin
lowsum[1] <= sums[0][10];
minxt <= oldminx - 1;
minyt <= oldminy;
end
390+i: begin
lowsum[1] <= sums[1][10];
minxt <= oldminx;
minyt <= oldminy;
end
391+i: begin
lowsum[1] <= sums[2][10];
minxt <= oldminx + 1;
minyt <= oldminy;
end
 
392+i: begin
lowsum[1] <= sums[0][11];
minxt <= oldminx - 1;
minyt <= oldminy + 1;
end
393+i: begin
lowsum[1] <= sums[1][11];
minxt <= oldminx;
minyt <= oldminy + 1;
end
394+i: begin
lowsum[1] <= sums[2][11];
minxt <= oldminx + 1;
minyt <= oldminy + 1;
end
500: lowflag <=0;
508: dout <= {10'b0,minx,10'b0,miny};
510: begin minxt <= 16; minyt <= 16; lowsum[1] <= 0; lowflag <=1; end
// Upper Left Corner of Center Block
511: lowflag <= 0;
 
default: cursum <= cursum;
endcase
end // if (ena)
end //always loop
 
// control for minx miny lowsum[0] calc
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
lowsum[0] <= 16'b1111111111111111;
minx <= 0;
miny <= 0;
end
else
if (ena)
begin
if (lowflag)
begin
if (lowsum[1] < lowsum[0])
begin
lowsum[0] <= lowsum[1];
minx <= minxt;
miny <= minyt;
end
end
else
begin
lowsum[0] <= 16'b1111111111111111;
minx <= minx;
miny <= miny;
end
end
end
 
// control for offset
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
offset <= 0;
end
else
if (ena)
begin
case (count)
111: offset <= 4;
223: offset <= 2;
335: offset <= 1;
511: offset <= 8;
default: offset <= offset;
endcase
end
end
 
// control for clk2
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
clk2 <= 0;
end
else
if (ena)
begin
clk2 <= ~clk2;
end
end
endmodule
/trunk/macroblock_motion_detection/macroblock_motion_detection/MotionTest.v
0,0 → 1,260
/////////////////////////////////////////////////////////////////////
//// ////
//// MotionTest.v ////
//// ////
//// Test Bench for MotionDetection.v ////
//// This file inputs a current macroblock and nine ////
//// test macroblocks to be searched for the best match ////
//// every 512 cycles to be tested in the next 521 cycles. ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MotionDetection_MotionTest_v_tf();
// DATE: 22:50:06 09/11/2004
// MODULE: MotionDetection
// DESIGN: MotionDetection
// FILENAME: MotionTest.v
// PROJECT: NTSCtoMacroblock
// VERSION:
 
integer i,j;
reg clk2; //half speed clock
// Inputs
reg clk;
reg ena;
reg rst;
reg [31:0] din1, din2;
reg [3:0] state;
reg [8:0] count;
reg [31:0] curinput;
reg [3:0] curcount;
 
 
// Outputs
wire [31:0] dout;
 
 
// Bidirs
 
// Instantiate the UUT
MotionDetection uut (
.clk(clk),
.ena(ena),
.rst(rst),
.din1(din1),
.din2(din2),
.dout(dout),
.state(state),
.count(count)
);
 
 
initial begin
clk <= 0;
ena <= 0;
rst <= 0;
@(posedge clk);
ena <= 1;
rst <= 1;
@(posedge clk);
state = 0;
for (j = 0; j < 10; j = j + 1) // Initilization + 9 tests
begin
for (i = 0; i < 512; i = i + 1) // 512 counts per test
begin
@(posedge clk); // Two clocks per count
@(posedge clk);
end
end
$stop;
end
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
count <= 0;
end
else
if (ena)
begin
count <= count + 1;
end
end
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
curcount <= 0;
curinput <= {8'd1,8'd1,8'd1,8'd1};
end
else
if (ena)
begin
if (count == 511)
begin
curcount <= curcount + 1;
case (curcount)
0: curinput <= {8'd2,8'd2,8'd2,8'd2};
1: curinput <= {8'd3,8'd3,8'd3,8'd3};
2: curinput <= {8'd4,8'd4,8'd4,8'd4};
3: curinput <= {8'd5,8'd5,8'd5,8'd5};
4: curinput <= {8'd6,8'd6,8'd6,8'd6};
5: curinput <= {8'd7,8'd7,8'd7,8'd7};
6: curinput <= {8'd8,8'd8,8'd8,8'd8};
7: curinput <= {8'd9,8'd9,8'd9,8'd9};
endcase
end
end
end
 
 
// address control for block memories control
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
din1 <= 0;
din2 <= 0;
end
else
if (ena)
begin
case (count)
47: // Writes for CUR and 1 for next macroblock
begin
din1 <= curinput;
din2 <= {8'd1,8'd1,8'd1,8'd1};
end
159: // Writes for 2 and 3 for next macroblock
begin
din1 <= {8'd2,8'd2,8'd2,8'd2};
din2 <= {8'd3,8'd3,8'd3,8'd3};
end
271: // Writes for 4 and 5 for next macroblock
begin
din2 <= {8'd4,8'd4,8'd4,8'd4};
din1 <= {8'd5,8'd5,8'd5,8'd5};
end
383: // Writes for 6 and 7 for next macroblock
begin
din1 <= {8'd6,8'd6,8'd6,8'd6};
din2 <= {8'd7,8'd7,8'd7,8'd7};
end
447: // Writes for 8 and 9 for next macroblock
begin
din1 <= {8'd8,8'd8,8'd8,8'd8};
din2 <= {8'd9,8'd9,8'd9,8'd9};
end
default:
begin
din1 <= din1;
din2 <= din2;
end
endcase
end // if(ena)
end // always
 
// generate clock
always #2.5 clk <= ~clk;
 
 
// control for clk2
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
clk2 <= 0;
end
else
if (ena)
begin
clk2 <= ~clk2;
end
end
 
// Display changes to the signals
always @(posedge clk2)
begin
if (ena)
begin
if (count == 511)
begin
if (dout) // eliminates 0 0 from initialization cycle
begin
$display("X offset is %d Y offset is %d", dout[31:16], dout[15:0]);
case (curcount)
3: begin
$display(" Note this search failed to find the block ");
$display(" in the upper right corrner since a log search ");
$display(" was used and on the first pass there was a tie");
$display(" between the upper left and upper right blocks");
$display(" at (8,8) and (24,8) and the first was selected");
$display(" then a local minima was found.");
end
7: begin
$display(" Note this search failed to find the block ");
$display(" in the lower left corrner since a log search ");
$display(" was used and on the first pass there was a tie ");
$display(" between the lower left and lower right blocks ");
$display(" at (8,24) and (24,24) and the second was selected");
$display(" then a local minima was found.");
$display(" ");
$display(" ");
$display(" ");
end
endcase
end
end
end
end
endmodule
 
/trunk/macroblock_motion_detection/macroblock_motion_detection/MD_Block_Ram.v
0,0 → 1,411
/////////////////////////////////////////////////////////////////////
//// ////
//// MD_Block_Ram.v ////
//// ////
//// Manages Block Ram Resources for Motion.v ////
//// ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MD_Block_Ram(clk, ena, rst, din1, din2,
DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11,
count, minx, miny);
 
input [31:0] din1, din2;
input clk, ena, rst;
output [31:0] DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11;
 
wire [31:0] DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11;
 
input [8:0] count;
 
 
 
input [5:0] minx;
input [5:0] miny;
 
integer i;
reg PAGE;
reg ioflag; // used for address control
 
reg WE[0:11];
reg [5:0] ADDR[0:2];
wire [7:0] ADDRA[0:2];
wire [7:0] ADDRB[0:2];
 
assign ADDRA[0][7:1] = {PAGE,ADDR[0]};
assign ADDRB[0][7:1] = {PAGE,ADDR[0]};
assign ADDRA[0][0:0] = 0;
assign ADDRB[0][0:0] = 1;
assign ADDRA[1][7:1] = {PAGE,ADDR[1]};
assign ADDRB[1][7:1] = {PAGE,ADDR[1]};
assign ADDRA[1][0:0] = 0;
assign ADDRB[1][0:0] = 1;
assign ADDRA[2][7:1] = {PAGE,ADDR[2]};
assign ADDRB[2][7:1] = {PAGE,ADDR[2]};
assign ADDRA[2][0:0] = 0;
assign ADDRB[2][0:0] = 1;
wire [15:0] DINA[0:11], DINB[0:11];
 
assign {DINA[0],DINB[0]} = din2;
assign {DINA[1],DINB[1]} = din2;
assign {DINA[2],DINB[2]} = din2;
assign {DINA[3],DINB[3]} = din2;
assign {DINA[4],DINB[4]} = din1;
assign {DINA[5],DINB[5]} = din1;
assign {DINA[6],DINB[6]} = din1;
assign {DINA[7],DINB[7]} = din1;
assign {DINA[8],DINB[8]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[9],DINB[9]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[10],DINB[10]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[11],DINB[11]} = (ADDR[2][4:4]) ? din1 : din2;
wire [15:0] DOUTA[0:11];
wire [15:0] DOUTB[0:11];
 
genvar t;
//
generate
for (t=0; t<12; t=t+1)
begin:searchram
RAMB4_S16_S16 mem(.WEA(WE[t]), .WEB(WE[t]), .ENA(1'b1), .ENB(1'b1), .RSTA(1'b0), .RSTB(1'b0), .CLKA(clk), .CLKB(clk),
.ADDRA(ADDRA[t >> 2]), .ADDRB(ADDRB[t >> 2]), .DIA(DINA[t]), .DIB(DINB[t]), .DOA(DOUTA[t]), .DOB(DOUTB[t]));
end
endgenerate
 
reg WEC[0:3];
reg [5:0] ADDRC;
wire [7:0] ADDRAC, ADDRBC;
assign ADDRAC[7:1] = {PAGE,ADDRC};
assign ADDRBC[7:1] = {PAGE,ADDRC};
assign ADDRAC[0:0] = 0;
assign ADDRBC[0:0] = 1;
wire [15:0] DINAC[0:3], DINBC[0:3];
assign {DINAC[0],DINBC[0]} = din1;
assign {DINAC[1],DINBC[1]} = din1;
assign {DINAC[2],DINBC[2]} = din1;
assign {DINAC[3],DINBC[3]} = din1;
wire [15:0] DOUTAC[0:3];
wire [15:0] DOUTBC[0:3];
 
//
generate
for (t=0; t<4; t=t+1)
begin:curram
RAMB4_S16_S16 mem(.WEA(WEC[t]), .WEB(WEC[t]), .ENA(1'b1), .ENB(1'b1), .RSTA(1'b0), .RSTB(1'b0), .CLKA(clk), .CLKB(clk),
.ADDRA(ADDRAC), .ADDRB(ADDRBC), .DIA(DINAC[t]), .DIB(DINBC[t]), .DOA(DOUTAC[t]), .DOB(DOUTBC[t]));
end
endgenerate
 
assign DOUTC0 = {DOUTAC[0],DOUTBC[0]};
assign DOUTC1 = {DOUTAC[1],DOUTBC[1]};
assign DOUTC2 = {DOUTAC[2],DOUTBC[2]};
assign DOUTC3 = {DOUTAC[3],DOUTBC[3]};
 
assign DOUT0 = {DOUTA[0],DOUTB[0]};
assign DOUT1 = {DOUTA[1],DOUTB[1]};
assign DOUT2 = {DOUTA[2],DOUTB[2]};
assign DOUT3 = {DOUTA[3],DOUTB[3]};
 
assign DOUT4 = {DOUTA[4],DOUTB[4]};
assign DOUT5 = {DOUTA[5],DOUTB[5]};
assign DOUT6 = {DOUTA[6],DOUTB[6]};
assign DOUT7 = {DOUTA[7],DOUTB[7]};
 
assign DOUT8 = {DOUTA[8],DOUTB[8]};
assign DOUT9 = {DOUTA[9],DOUTB[9]};
assign DOUT10 = {DOUTA[10],DOUTB[10]};
assign DOUT11 = {DOUTA[11],DOUTB[11]};
 
// address control for block memories control
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
ADDR[0] <= 0; // Block Memories
ADDR[1] <= 0; // 0 1 2 3 4 5 6 7 8 9 10 11
ADDR[2] <= 0; // MacroBlocks Addresses
ADDRC <= 0; //
ioflag <= 1; // 1 1 1 1 2 2 2 2 3 3 3 3 0 - 15
PAGE <= 0; //
end // 4 4 4 4 5 5 5 5 6 6 6 6 16 - 23
else //
if (ena) // 7 7 7 7 8 8 8 8 9 9 9 9 24 - 47
begin //
case (count) // Addr[0] Addr[1] Addr[2]
15:
begin
PAGE <= PAGE;
ADDR[0] <= 16; // Next 16 clocks read rows 16 - 31 of Search Block
ADDR[1] <= 16; // For first 3 checks
ADDR[2] <= 16;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
31:
begin
PAGE <= PAGE;
ADDR[0] <= 24; // Next 16 clocks read rows 24 - 39 of Search Block
ADDR[1] <= 24; // For first 3 checks
ADDR[2] <= 24;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
47: // Writes for CUR and 1 for next macroblock
begin
WEC[0] <= 1;
WE[0] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 0;
ADDR[1] <= 0;
ADDR[2] <= 0;
ADDRC <= 0;
ioflag <= 0;
end
111:
begin
WEC[3] <= 0;
WE[3] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 4; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 4; // For second 3 checks
ADDR[2] <= miny - 4;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
127:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For second 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
143:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 4; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 4; // For second 3 checks
ADDR[2] <= miny + 4;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
159: // Writes for 2 and 3 for next macroblock
begin
WE[4] <= 1;
WE[8] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 0;
ADDR[1] <= 0;
ADDR[2] <= 0;
ADDRC <= 0;
ioflag <= 0;
end
223:
begin
WE[7] <= 0;
WE[11] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 2; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 2; // For third 3 checks
ADDR[2] <= miny - 2;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
239:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For third 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
255:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 2; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 2; // For third 3 checks
ADDR[2] <= miny + 2;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
271: // Writes for 4 and 5 for next macroblock
begin
WE[0] <= 1;
WE[4] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 16;
ADDR[1] <= 16;
ADDR[2] <= 16;
ADDRC <= 0;
ioflag <= 0;
end
335:
begin
WE[3] <= 0;
WE[7] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 1; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 1; // For fourth 3 checks
ADDR[2] <= miny - 1;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
351:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For fourth 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
367:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 1; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 1; // For fourth 3 checks
ADDR[2] <= miny + 1;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
383: // Writes for 6 and 7 for next macroblock
begin
WE[8] <= 1; // for block 6
WE[0] <= 1; // for block 7
PAGE <= ~PAGE;
ADDR[0] <= 32; // for block 7
ADDR[1] <= 0; // doesn't matter
ADDR[2] <= 16; // for block 6
ADDRC <= 0;
ioflag <= 0;
end
447: // Writes for 8 and 9 for next macroblock
begin
WE[11] <= 0;
WE[3] <= 0;
WE[4] <= 1;
WE[8] <= 1;
PAGE <= PAGE;
ADDR[0] <= 0;
ADDR[1] <= 32;
ADDR[2] <= 32;
ADDRC <= 0;
ioflag <= 0;
end
511:
begin
WE[7] <= 0;
WE[11] <= 0;
PAGE <= PAGE; // Dont switch here -- Read starts on page that was just written
ADDR[0] <= 8; // Next 16 clocks read rows 8 - 23 of Search Block
ADDR[1] <= 8; // For first 3 checks
ADDR[2] <= 8;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
default:
begin
for (i = 0; i < 4; i = i + 1)
begin
if (WEC[i])
begin
WEC[i] <= 0;
if (i == 3)
WEC[0] <= 1;
else
WEC[i+1] <= 1;
end
end
for (i = 0; i < 12; i = i + 1)
begin
if (WE[i])
begin
WE[i] <= 0;
if (i[1:0] == 3)
WE[i-3] <= 1;
else
WE[i+1] <= 1;
end
end
PAGE <= PAGE;
if (ioflag)
begin
ADDR[0] <= ADDR[0] + 1;
ADDR[1] <= ADDR[1] + 1;
ADDR[2] <= ADDR[2] + 1;
ADDRC <= ADDRC + 1;
end
else
if (count[1:0] == 3)
begin
ADDR[0] <= ADDR[0] + 1;
ADDR[1] <= ADDR[1] + 1;
ADDR[2] <= ADDR[2] + 1;
ADDRC <= ADDRC + 1;
end
end
endcase
end
 
end
 
 
endmodule
/branches/avendor/macroblock_motion_detection/MotionDetection.v
0,0 → 1,855
/////////////////////////////////////////////////////////////////////
//// ////
//// MotionDetection.v ////
//// ////
//// Performs motion estimation for one 16 x 16 macroblock ////
//// in a 48 x 48 pixel window every 512 clock cycles. ////
//// ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MotionDetection(clk, ena, rst, din1, din2, dout, state, count);
// runs at 1/2 clock speed?
reg clk2;
parameter COMP = 0;
 
input [31:0] din1, din2;
input clk, ena, rst;
input [3:0] state;
output [31:0] dout;
input [8:0] count;
 
reg [31:0] dout;
 
integer i, j, k, l, m, n, o;
 
// Motion Estimation Registers
reg [8:0] diff[0:2][0:15];
reg [7:0] diffp[0:15];
reg [7:0] diffpd[0:15];
reg [7:0] diffm[0:2][0:15];
reg [7:0] diffpp[0:2][0:15];
reg [7:0] diffmm[0:2][0:15];
reg [7:0] diffmd[0:2][0:15];
reg [10:0] difft[0:2][0:3];
 
reg [3:0] offset;
wire [7:0] curt[0:15];
wire [7:0] searcht [0:47];
 
reg [15:0] sums [0:2][0:11];
reg [15:0] lowsum[0:1];
reg lowflag;
reg [5:0] minxt,minyt;
reg [5:0] oldminx,oldminy;
reg [3:0] cursum;
reg sumflag;
reg [5:0] minx;
reg [5:0] miny;
 
wire [31:0] DOUTC0;
wire [31:0] DOUTC1;
wire [31:0] DOUTC2;
wire [31:0] DOUTC3;
wire [31:0] DOUT0;
wire [31:0] DOUT1;
wire [31:0] DOUT2;
wire [31:0] DOUT3;
wire [31:0] DOUT4;
wire [31:0] DOUT5;
wire [31:0] DOUT6;
wire [31:0] DOUT7;
wire [31:0] DOUT8;
wire [31:0] DOUT9;
wire [31:0] DOUT10;
wire [31:0] DOUT11;
 
assign {curt[0],curt[1],curt[2],curt[3]} = DOUTC0;
assign {curt[4],curt[5],curt[6],curt[7]} = DOUTC1;
assign {curt[8],curt[9],curt[10],curt[11]} = DOUTC2;
assign {curt[12],curt[13],curt[14],curt[15]} = DOUTC3;
 
assign {searcht[0],searcht[1],searcht[2],searcht[3]} = DOUT0;
assign {searcht[4],searcht[5],searcht[6],searcht[7]} = DOUT1;
assign {searcht[8],searcht[9],searcht[10],searcht[11]} = DOUT2;
assign {searcht[12],searcht[13],searcht[14],searcht[15]} = DOUT3;
assign {searcht[16],searcht[17],searcht[18],searcht[19]} = DOUT4;
assign {searcht[20],searcht[21],searcht[22],searcht[23]} = DOUT5;
assign {searcht[24],searcht[25],searcht[26],searcht[27]} = DOUT6;
assign {searcht[28],searcht[29],searcht[30],searcht[31]} = DOUT7;
assign {searcht[32],searcht[33],searcht[34],searcht[35]} = DOUT8;
assign {searcht[36],searcht[37],searcht[38],searcht[39]} = DOUT9;
assign {searcht[40],searcht[41],searcht[42],searcht[43]} = DOUT10;
assign {searcht[44],searcht[45],searcht[46],searcht[47]} = DOUT11;
 
// Instantiate MD_Block_Ram
MD_Block_Ram MD_Block_Ram (
.clk(clk2),
.ena(ena),
.rst(rst),
.din1(din1),
.din2(din2),
.DOUTC0(DOUTC0),
.DOUTC1(DOUTC1),
.DOUTC2(DOUTC2),
.DOUTC3(DOUTC3),
.DOUT0(DOUT0),
.DOUT1(DOUT1),
.DOUT2(DOUT2),
.DOUT3(DOUT3),
.DOUT4(DOUT4),
.DOUT5(DOUT5),
.DOUT6(DOUT6),
.DOUT7(DOUT7),
.DOUT8(DOUT8),
.DOUT9(DOUT9),
.DOUT10(DOUT10),
.DOUT11(DOUT11),
.count(count),
.minx(minx),
.miny(miny)
);
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
i = 0;
o = 0;
for (i = 0; i < 12; i=i+1)
begin
sums[0][i] <= 0;
sums[1][i] <= 0;
sums[2][i] <= 0;
end
end
else
begin
if (ena)
begin
case (state)
COMP:
begin
// delay curt 1 cycle to match diffm selection below
for (i=0; i < 16; i=i+1)
begin
diffp[i] <= curt[i];
end
for (i=0; i < 16; i=i+1)
begin
diffpd[i] <= diffp[i];
end
// find differences for this row at three places
 
case (offset)
8: begin // 1 and 3 offset by 16
for (i=0; i < 16; i=i+1)
begin
diffm[0][i] <= searcht[i+8];
diffm[2][i] <= searcht[i+24];
end
end
4: begin // 1 and 3 offset by 8
for (i=0; i < 16; i=i+1)
begin
case (minx)
8: begin
diffm[0][i] <= searcht[i+4];
end
16: begin
diffm[0][i] <= searcht[i+12];
end
24: begin
diffm[0][i] <= searcht[i+20];
end
endcase
end
for (i=8; i < 16; i=i+1)
begin
case (minx)
8: begin
diffm[2][i] <= searcht[i+12];
end
16: begin
diffm[2][i] <= searcht[i+20];
end
24: begin
diffm[2][i] <= searcht[i+28];
end
endcase
end
end
2: begin // 1 and 3 offset by 4
for (i=0; i < 16; i=i+1)
begin
case (minx)
4: begin
diffm[0][i] <= searcht[i+2];
end
8: begin
diffm[0][i] <= searcht[i+6];
end
12: begin
diffm[0][i] <= searcht[i+10];
end
16: begin
diffm[0][i] <= searcht[i+14];
end
20: begin
diffm[0][i] <= searcht[i+18];
end
24: begin
diffm[0][i] <= searcht[i+22];
end
28: begin
diffm[0][i] <= searcht[i+26];
end
endcase
end
for (i=12; i < 16; i=i+1)
begin
case (minx)
4: begin
diffm[2][i] <= searcht[i+6];
end
8: begin
diffm[2][i] <= searcht[i+10];
end
12: begin
diffm[2][i] <= searcht[i+14];
end
16: begin
diffm[2][i] <= searcht[i+18];
end
20: begin
diffm[2][i] <= searcht[i+22];
end
24: begin
diffm[2][i] <= searcht[i+26];
end
28: begin
diffm[2][i] <= searcht[i+30];
end
endcase
end
end
1: begin // 1 and 3 offset by 2
for (i=0; i < 16; i=i+1)
begin
case (minx)
2: begin
diffm[0][i] <= searcht[i+1];
end
4: begin
diffm[0][i] <= searcht[i+3];
end
6: begin
diffm[0][i] <= searcht[i+5];
end
8: begin
diffm[0][i] <= searcht[i+7];
end
10: begin
diffm[0][i] <= searcht[i+9];
end
12: begin
diffm[0][i] <= searcht[i+11];
end
14: begin
diffm[0][i] <= searcht[i+13];
end
16: begin
diffm[0][i] <= searcht[i+15];
end
18: begin
diffm[0][i] <= searcht[i+17];
end
20: begin
diffm[0][i] <= searcht[i+19];
end
22: begin
diffm[0][i] <= searcht[i+21];
end
24: begin
diffm[0][i] <= searcht[i+23];
end
26: begin
diffm[0][i] <= searcht[i+25];
end
28: begin
diffm[0][i] <= searcht[i+27];
end
30: begin
diffm[0][i] <= searcht[i+29];
end
endcase
end
for (i=14; i < 16; i=i+1)
begin
case (minx)
2: begin
diffm[2][i] <= searcht[i+3];
end
4: begin
diffm[2][i] <= searcht[i+5];
end
6: begin
diffm[2][i] <= searcht[i+7];
end
8: begin
diffm[2][i] <= searcht[i+9];
end
10: begin
diffm[2][i] <= searcht[i+11];
end
12: begin
diffm[2][i] <= searcht[i+13];
end
14: begin
diffm[2][i] <= searcht[i+15];
end
16: begin
diffm[2][i] <= searcht[i+17];
end
18: begin
diffm[2][i] <= searcht[i+19];
end
20: begin
diffm[2][i] <= searcht[i+21];
end
22: begin
diffm[2][i] <= searcht[i+23];
end
24: begin
diffm[2][i] <= searcht[i+25];
end
26: begin
diffm[2][i] <= searcht[i+27];
end
28: begin
diffm[2][i] <= searcht[i+29];
end
30: begin
diffm[2][i] <= searcht[i+31];
end
endcase
end
end
endcase
// copy from 1 and 3 to 1 2 and 3
// 1 is the same
for (i=0; i < 16; i=i+1)
begin
diffmd[0][i] <= diffm[0][i];
end
// 2 is combination of 1 and 3
case (offset)
8: begin
for (i=0; i < 8; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+8];
diffmd[1][i+8] <= diffm[2][i];
end
end
4: begin
for (i=0; i < 12; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+4];
end
for (i=12; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-4];
end
end
2: begin
for (i=0; i < 14; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+2];
end
for (i=14; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-2];
end
end
1: begin
for (i=0; i < 15; i=i+1)
begin
diffmd[1][i] <= diffm[0][i+1];
end
for (i=15; i < 16; i=i+1)
begin
diffmd[1][i] <= diffm[2][i-1];
end
end
endcase
// 3 is combination of 1 and 3
case (offset)
8: begin
for (i=0; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
4: begin
for (i=0; i < 8; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+8];
end
for (i=8; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
2: begin
for (i=0; i < 12; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+4];
end
for (i=12; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
1: begin
for (i=0; i < 14; i=i+1)
begin
diffmd[2][i] <= diffm[0][i+2];
end
for (i=14; i < 16; i=i+1)
begin
diffmd[2][i] <= diffm[2][i];
end
end
endcase
 
 
for (o = 0; o < 3; o = o + 1)
begin
for (i=0; i < 16; i=i+1)
begin
if (diffpd[i] > diffmd[o][i])
begin
diffpp[o][i] <= diffpd[i];
diffmm[o][i] <= diffmd[o][i];
end
else
begin
diffpp[o][i] <= diffmd[o][i];
diffmm[o][i] <= diffpd[i];
end
diff[o][i] <= diffpp[o][i] - diffmm[o][i];
end // for i 0 to 15
end // for o 0 to 3
 
// partial sums three times for three tests per row
for (o = 0; o < 3; o = o + 1)
begin
for(i=0; i < 4; i = i + 1)
begin
k = {i,2'b0};
l = k + 1;
m = k + 2;
n = k + 3;
difft[o][i] <= diff[o][k]+diff[o][l]+diff[o][m]+diff[o][n];
end
end // o loop
 
// final sums at proper delay repeat three times for three tests per row
if (sumflag)
begin
for (i =0; i < 3; i = i + 1)
begin
sums[i][cursum] <= sums[i][cursum] + difft[i][0] + difft[i][1] + difft[i][2] + difft[i][3];
end
end
else
if (count == 511)
begin
for (i =0; i < 3; i = i + 1)
begin
for (j =0; j < 12; j = j + 1)
begin
sums[i][j] <= 0;
end
end
end
end // COMP state
endcase // state
 
end // if ena
end // if ~rst else
end // always
 
// control for cursum and sumflag , minx, & miny control
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
cursum <= 0;
sumflag <= 0;
minxt <= 0;
minyt <= 0;
oldminx <= 0;
oldminy <= 0;
lowsum[1] <= 0;
lowflag <= 0;
dout <= 0;
end
else
if (ena)
begin
i = 5;
case (count) // 16 adds for each offset i from beginning
0+i: begin sumflag <=1; cursum <= 0; end //0
16+i: begin sumflag <=1; cursum <= 1; end //16
32+i: begin sumflag <=1; cursum <= 2; end //32
48+i: sumflag <=0;
 
49+i: begin
lowflag <=1;
lowsum[1] <= sums[0][0];
minxt <= 8;
minyt <= 8;
end
50+i: begin
lowsum[1] <= sums[1][0];
minxt <= 16;
minyt <= 8;
end
51+i: begin
lowsum[1] <= sums[2][0];
minxt <= 24;
minyt <= 8;
end
 
52+i: begin
lowsum[1] <= sums[0][1];
minxt <= 8;
minyt <= 16;
end
53+i: begin
lowsum[1] <= sums[1][1];
minxt <= 16;
minyt <= 16;
end
54+i: begin
lowsum[1] <= sums[2][1];
minxt <= 24;
minyt <= 16;
end
 
55+i: begin
lowsum[1] <= sums[0][2];
minxt <= 8;
minyt <= 24;
end
56+i: begin
lowsum[1] <= sums[1][2];
minxt <= 16;
minyt <= 24;
end
57+i: begin
lowsum[1] <= sums[2][2];
minxt <= 24;
minyt <= 24;
end
58+i: lowflag <=0;
 
112+i: begin sumflag <=1; cursum <= 3; end //112
128+i: begin sumflag <=1; cursum <= 4; end //128
144+i: begin sumflag <=1; cursum <= 5; end //144
160+i: sumflag <=0;
161+i: begin
oldminx <= minx;
oldminy <= miny;
end
 
162+i: begin
lowflag <=1;
lowsum[1] <= sums[0][3];
minxt <= oldminx - 4;
minyt <= oldminy - 4;
end
163+i: begin
lowsum[1] <= sums[1][3];
minxt <= oldminx - 0;
minyt <= oldminy - 4;
end
164+i: begin
lowsum[1] <= sums[2][3];
minxt <= oldminx + 4;
minyt <= oldminy - 4;
end
 
165+i: begin
lowsum[1] <= sums[0][4];
minxt <= oldminx - 4;
minyt <= oldminy;
end
166+i: begin
lowsum[1] <= sums[1][4];
minxt <= oldminx;
minyt <= oldminy;
end
167+i: begin
lowsum[1] <= sums[2][4];
minxt <= oldminx + 4;
minyt <= oldminy;
end
 
168+i: begin
lowsum[1] <= sums[0][5];
minxt <= oldminx - 4;
minyt <= oldminy + 4;
end
169+i: begin
lowsum[1] <= sums[1][5];
minxt <= oldminx;
minyt <= oldminy + 4;
end
170+i: begin
lowsum[1] <= sums[2][5];
minxt <= oldminx + 4;
minyt <= oldminy + 4;
end
171+i: lowflag <=0;
 
224+i: begin sumflag <=1; cursum <= 6; end //224
240+i: begin sumflag <=1; cursum <= 7; end //240
256+i: begin sumflag <=1; cursum <= 8; end //256
272+i: sumflag <=0;
273+i: begin
oldminx <= minx;
oldminy <= miny;
end
274+i: begin
lowflag <=1;
lowsum[1] <= sums[0][6];
minxt <= oldminx - 2;
minyt <= oldminy - 2;
end
275+i: begin
lowsum[1] <= sums[1][6];
minxt <= oldminx;
minyt <= oldminy - 2;
end
276+i: begin
lowsum[1] <= sums[2][6];
minxt <= oldminx + 2;
minyt <= oldminy - 2;
end
 
277+i: begin
lowsum[1] <= sums[0][7];
minxt <= oldminx - 2;
minyt <= oldminy;
end
278+i: begin
lowsum[1] <= sums[1][7];
minxt <= oldminx;
minyt <= oldminy;
end
279+i: begin
lowsum[1] <= sums[2][7];
minxt <= oldminx + 2;
minyt <= oldminy;
end
 
280+i: begin
lowsum[1] <= sums[0][8];
minxt <= oldminx - 2;
minyt <= oldminy + 2;
end
281+i: begin
lowsum[1] <= sums[1][8];
minxt <= oldminx;
minyt <= oldminy + 2;
end
282+i: begin
lowsum[1] <= sums[2][8];
minxt <= oldminx + 2;
minyt <= oldminy + 2;
end
283+i: lowflag <=0;
 
 
336+i: begin sumflag <=1; cursum <= 9; end //336
352+i: begin sumflag <=1; cursum <= 10; end //352
368+i: begin sumflag <=1; cursum <= 11; end //368
384+i: sumflag <=0;
385+i: begin
oldminx <= minx;
oldminy <= miny;
end
 
386+i: begin
lowflag <=1;
lowsum[1] <= sums[0][9];
minxt <= oldminx - 1;
minyt <= oldminy - 1;
end
387+i: begin
lowsum[1] <= sums[1][9];
minxt <= oldminx;
minyt <= oldminy - 1;
end
388+i: begin
lowsum[1] <= sums[2][9];
minxt <= oldminx + 1;
minyt <= oldminy - 1;
end
 
389+i: begin
lowsum[1] <= sums[0][10];
minxt <= oldminx - 1;
minyt <= oldminy;
end
390+i: begin
lowsum[1] <= sums[1][10];
minxt <= oldminx;
minyt <= oldminy;
end
391+i: begin
lowsum[1] <= sums[2][10];
minxt <= oldminx + 1;
minyt <= oldminy;
end
 
392+i: begin
lowsum[1] <= sums[0][11];
minxt <= oldminx - 1;
minyt <= oldminy + 1;
end
393+i: begin
lowsum[1] <= sums[1][11];
minxt <= oldminx;
minyt <= oldminy + 1;
end
394+i: begin
lowsum[1] <= sums[2][11];
minxt <= oldminx + 1;
minyt <= oldminy + 1;
end
500: lowflag <=0;
508: dout <= {10'b0,minx,10'b0,miny};
510: begin minxt <= 16; minyt <= 16; lowsum[1] <= 0; lowflag <=1; end
// Upper Left Corner of Center Block
511: lowflag <= 0;
 
default: cursum <= cursum;
endcase
end // if (ena)
end //always loop
 
// control for minx miny lowsum[0] calc
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
lowsum[0] <= 16'b1111111111111111;
minx <= 0;
miny <= 0;
end
else
if (ena)
begin
if (lowflag)
begin
if (lowsum[1] < lowsum[0])
begin
lowsum[0] <= lowsum[1];
minx <= minxt;
miny <= minyt;
end
end
else
begin
lowsum[0] <= 16'b1111111111111111;
minx <= minx;
miny <= miny;
end
end
end
 
// control for offset
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
offset <= 0;
end
else
if (ena)
begin
case (count)
111: offset <= 4;
223: offset <= 2;
335: offset <= 1;
511: offset <= 8;
default: offset <= offset;
endcase
end
end
 
// control for clk2
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
clk2 <= 0;
end
else
if (ena)
begin
clk2 <= ~clk2;
end
end
endmodule
/branches/avendor/macroblock_motion_detection/MotionTest.v
0,0 → 1,260
/////////////////////////////////////////////////////////////////////
//// ////
//// MotionTest.v ////
//// ////
//// Test Bench for MotionDetection.v ////
//// This file inputs a current macroblock and nine ////
//// test macroblocks to be searched for the best match ////
//// every 512 cycles to be tested in the next 521 cycles. ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MotionDetection_MotionTest_v_tf();
// DATE: 22:50:06 09/11/2004
// MODULE: MotionDetection
// DESIGN: MotionDetection
// FILENAME: MotionTest.v
// PROJECT: NTSCtoMacroblock
// VERSION:
 
integer i,j;
reg clk2; //half speed clock
// Inputs
reg clk;
reg ena;
reg rst;
reg [31:0] din1, din2;
reg [3:0] state;
reg [8:0] count;
reg [31:0] curinput;
reg [3:0] curcount;
 
 
// Outputs
wire [31:0] dout;
 
 
// Bidirs
 
// Instantiate the UUT
MotionDetection uut (
.clk(clk),
.ena(ena),
.rst(rst),
.din1(din1),
.din2(din2),
.dout(dout),
.state(state),
.count(count)
);
 
 
initial begin
clk <= 0;
ena <= 0;
rst <= 0;
@(posedge clk);
ena <= 1;
rst <= 1;
@(posedge clk);
state = 0;
for (j = 0; j < 10; j = j + 1) // Initilization + 9 tests
begin
for (i = 0; i < 512; i = i + 1) // 512 counts per test
begin
@(posedge clk); // Two clocks per count
@(posedge clk);
end
end
$stop;
end
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
count <= 0;
end
else
if (ena)
begin
count <= count + 1;
end
end
 
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
curcount <= 0;
curinput <= {8'd1,8'd1,8'd1,8'd1};
end
else
if (ena)
begin
if (count == 511)
begin
curcount <= curcount + 1;
case (curcount)
0: curinput <= {8'd2,8'd2,8'd2,8'd2};
1: curinput <= {8'd3,8'd3,8'd3,8'd3};
2: curinput <= {8'd4,8'd4,8'd4,8'd4};
3: curinput <= {8'd5,8'd5,8'd5,8'd5};
4: curinput <= {8'd6,8'd6,8'd6,8'd6};
5: curinput <= {8'd7,8'd7,8'd7,8'd7};
6: curinput <= {8'd8,8'd8,8'd8,8'd8};
7: curinput <= {8'd9,8'd9,8'd9,8'd9};
endcase
end
end
end
 
 
// address control for block memories control
always @(posedge clk2 or negedge rst)
begin
if (~rst)
begin
din1 <= 0;
din2 <= 0;
end
else
if (ena)
begin
case (count)
47: // Writes for CUR and 1 for next macroblock
begin
din1 <= curinput;
din2 <= {8'd1,8'd1,8'd1,8'd1};
end
159: // Writes for 2 and 3 for next macroblock
begin
din1 <= {8'd2,8'd2,8'd2,8'd2};
din2 <= {8'd3,8'd3,8'd3,8'd3};
end
271: // Writes for 4 and 5 for next macroblock
begin
din2 <= {8'd4,8'd4,8'd4,8'd4};
din1 <= {8'd5,8'd5,8'd5,8'd5};
end
383: // Writes for 6 and 7 for next macroblock
begin
din1 <= {8'd6,8'd6,8'd6,8'd6};
din2 <= {8'd7,8'd7,8'd7,8'd7};
end
447: // Writes for 8 and 9 for next macroblock
begin
din1 <= {8'd8,8'd8,8'd8,8'd8};
din2 <= {8'd9,8'd9,8'd9,8'd9};
end
default:
begin
din1 <= din1;
din2 <= din2;
end
endcase
end // if(ena)
end // always
 
// generate clock
always #2.5 clk <= ~clk;
 
 
// control for clk2
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
clk2 <= 0;
end
else
if (ena)
begin
clk2 <= ~clk2;
end
end
 
// Display changes to the signals
always @(posedge clk2)
begin
if (ena)
begin
if (count == 511)
begin
if (dout) // eliminates 0 0 from initialization cycle
begin
$display("X offset is %d Y offset is %d", dout[31:16], dout[15:0]);
case (curcount)
3: begin
$display(" Note this search failed to find the block ");
$display(" in the upper right corrner since a log search ");
$display(" was used and on the first pass there was a tie");
$display(" between the upper left and upper right blocks");
$display(" at (8,8) and (24,8) and the first was selected");
$display(" then a local minima was found.");
end
7: begin
$display(" Note this search failed to find the block ");
$display(" in the lower left corrner since a log search ");
$display(" was used and on the first pass there was a tie ");
$display(" between the lower left and lower right blocks ");
$display(" at (8,24) and (24,24) and the second was selected");
$display(" then a local minima was found.");
$display(" ");
$display(" ");
$display(" ");
end
endcase
end
end
end
end
endmodule
 
/branches/avendor/macroblock_motion_detection/MD_Block_Ram.v
0,0 → 1,411
/////////////////////////////////////////////////////////////////////
//// ////
//// MD_Block_Ram.v ////
//// ////
//// Manages Block Ram Resources for Motion.v ////
//// ////
//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2004 James Edgar ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// This disclaimer of warranty extends to the user of these ////
//// programs and user's customers, employees, agents, ////
//// transferees, successors, and assigns. ////
//// ////
//// The author does not represent or warrant that the programs ////
//// furnished hereunder are free of infringement of any ////
//// third-party patents. ////
//// ////
//// Commercial implementations of MPEG like video encoders ////
//// including shareware, are subject to royalty fees to patent ////
//// holders. Many of these patents are general enough such ////
//// that they are unavoidable regardless of implementation ////
//// design. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//synopsys translate_off
`include "timescale.v"
//synopsys translate_on
module MD_Block_Ram(clk, ena, rst, din1, din2,
DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11,
count, minx, miny);
 
input [31:0] din1, din2;
input clk, ena, rst;
output [31:0] DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11;
 
wire [31:0] DOUTC0, DOUTC1, DOUTC2, DOUTC3,
DOUT0, DOUT1, DOUT2, DOUT3,
DOUT4, DOUT5, DOUT6, DOUT7,
DOUT8, DOUT9, DOUT10, DOUT11;
 
input [8:0] count;
 
 
 
input [5:0] minx;
input [5:0] miny;
 
integer i;
reg PAGE;
reg ioflag; // used for address control
 
reg WE[0:11];
reg [5:0] ADDR[0:2];
wire [7:0] ADDRA[0:2];
wire [7:0] ADDRB[0:2];
 
assign ADDRA[0][7:1] = {PAGE,ADDR[0]};
assign ADDRB[0][7:1] = {PAGE,ADDR[0]};
assign ADDRA[0][0:0] = 0;
assign ADDRB[0][0:0] = 1;
assign ADDRA[1][7:1] = {PAGE,ADDR[1]};
assign ADDRB[1][7:1] = {PAGE,ADDR[1]};
assign ADDRA[1][0:0] = 0;
assign ADDRB[1][0:0] = 1;
assign ADDRA[2][7:1] = {PAGE,ADDR[2]};
assign ADDRB[2][7:1] = {PAGE,ADDR[2]};
assign ADDRA[2][0:0] = 0;
assign ADDRB[2][0:0] = 1;
wire [15:0] DINA[0:11], DINB[0:11];
 
assign {DINA[0],DINB[0]} = din2;
assign {DINA[1],DINB[1]} = din2;
assign {DINA[2],DINB[2]} = din2;
assign {DINA[3],DINB[3]} = din2;
assign {DINA[4],DINB[4]} = din1;
assign {DINA[5],DINB[5]} = din1;
assign {DINA[6],DINB[6]} = din1;
assign {DINA[7],DINB[7]} = din1;
assign {DINA[8],DINB[8]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[9],DINB[9]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[10],DINB[10]} = (ADDR[2][4:4]) ? din1 : din2;
assign {DINA[11],DINB[11]} = (ADDR[2][4:4]) ? din1 : din2;
wire [15:0] DOUTA[0:11];
wire [15:0] DOUTB[0:11];
 
genvar t;
//
generate
for (t=0; t<12; t=t+1)
begin:searchram
RAMB4_S16_S16 mem(.WEA(WE[t]), .WEB(WE[t]), .ENA(1'b1), .ENB(1'b1), .RSTA(1'b0), .RSTB(1'b0), .CLKA(clk), .CLKB(clk),
.ADDRA(ADDRA[t >> 2]), .ADDRB(ADDRB[t >> 2]), .DIA(DINA[t]), .DIB(DINB[t]), .DOA(DOUTA[t]), .DOB(DOUTB[t]));
end
endgenerate
 
reg WEC[0:3];
reg [5:0] ADDRC;
wire [7:0] ADDRAC, ADDRBC;
assign ADDRAC[7:1] = {PAGE,ADDRC};
assign ADDRBC[7:1] = {PAGE,ADDRC};
assign ADDRAC[0:0] = 0;
assign ADDRBC[0:0] = 1;
wire [15:0] DINAC[0:3], DINBC[0:3];
assign {DINAC[0],DINBC[0]} = din1;
assign {DINAC[1],DINBC[1]} = din1;
assign {DINAC[2],DINBC[2]} = din1;
assign {DINAC[3],DINBC[3]} = din1;
wire [15:0] DOUTAC[0:3];
wire [15:0] DOUTBC[0:3];
 
//
generate
for (t=0; t<4; t=t+1)
begin:curram
RAMB4_S16_S16 mem(.WEA(WEC[t]), .WEB(WEC[t]), .ENA(1'b1), .ENB(1'b1), .RSTA(1'b0), .RSTB(1'b0), .CLKA(clk), .CLKB(clk),
.ADDRA(ADDRAC), .ADDRB(ADDRBC), .DIA(DINAC[t]), .DIB(DINBC[t]), .DOA(DOUTAC[t]), .DOB(DOUTBC[t]));
end
endgenerate
 
assign DOUTC0 = {DOUTAC[0],DOUTBC[0]};
assign DOUTC1 = {DOUTAC[1],DOUTBC[1]};
assign DOUTC2 = {DOUTAC[2],DOUTBC[2]};
assign DOUTC3 = {DOUTAC[3],DOUTBC[3]};
 
assign DOUT0 = {DOUTA[0],DOUTB[0]};
assign DOUT1 = {DOUTA[1],DOUTB[1]};
assign DOUT2 = {DOUTA[2],DOUTB[2]};
assign DOUT3 = {DOUTA[3],DOUTB[3]};
 
assign DOUT4 = {DOUTA[4],DOUTB[4]};
assign DOUT5 = {DOUTA[5],DOUTB[5]};
assign DOUT6 = {DOUTA[6],DOUTB[6]};
assign DOUT7 = {DOUTA[7],DOUTB[7]};
 
assign DOUT8 = {DOUTA[8],DOUTB[8]};
assign DOUT9 = {DOUTA[9],DOUTB[9]};
assign DOUT10 = {DOUTA[10],DOUTB[10]};
assign DOUT11 = {DOUTA[11],DOUTB[11]};
 
// address control for block memories control
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
ADDR[0] <= 0; // Block Memories
ADDR[1] <= 0; // 0 1 2 3 4 5 6 7 8 9 10 11
ADDR[2] <= 0; // MacroBlocks Addresses
ADDRC <= 0; //
ioflag <= 1; // 1 1 1 1 2 2 2 2 3 3 3 3 0 - 15
PAGE <= 0; //
end // 4 4 4 4 5 5 5 5 6 6 6 6 16 - 23
else //
if (ena) // 7 7 7 7 8 8 8 8 9 9 9 9 24 - 47
begin //
case (count) // Addr[0] Addr[1] Addr[2]
15:
begin
PAGE <= PAGE;
ADDR[0] <= 16; // Next 16 clocks read rows 16 - 31 of Search Block
ADDR[1] <= 16; // For first 3 checks
ADDR[2] <= 16;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
31:
begin
PAGE <= PAGE;
ADDR[0] <= 24; // Next 16 clocks read rows 24 - 39 of Search Block
ADDR[1] <= 24; // For first 3 checks
ADDR[2] <= 24;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
47: // Writes for CUR and 1 for next macroblock
begin
WEC[0] <= 1;
WE[0] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 0;
ADDR[1] <= 0;
ADDR[2] <= 0;
ADDRC <= 0;
ioflag <= 0;
end
111:
begin
WEC[3] <= 0;
WE[3] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 4; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 4; // For second 3 checks
ADDR[2] <= miny - 4;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
127:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For second 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
143:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 4; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 4; // For second 3 checks
ADDR[2] <= miny + 4;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
159: // Writes for 2 and 3 for next macroblock
begin
WE[4] <= 1;
WE[8] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 0;
ADDR[1] <= 0;
ADDR[2] <= 0;
ADDRC <= 0;
ioflag <= 0;
end
223:
begin
WE[7] <= 0;
WE[11] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 2; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 2; // For third 3 checks
ADDR[2] <= miny - 2;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
239:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For third 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
255:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 2; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 2; // For third 3 checks
ADDR[2] <= miny + 2;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
271: // Writes for 4 and 5 for next macroblock
begin
WE[0] <= 1;
WE[4] <= 1;
PAGE <= ~PAGE;
ADDR[0] <= 16;
ADDR[1] <= 16;
ADDR[2] <= 16;
ADDRC <= 0;
ioflag <= 0;
end
335:
begin
WE[3] <= 0;
WE[7] <= 0;
PAGE <= ~PAGE;
ADDR[0] <= miny - 1; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny - 1; // For fourth 3 checks
ADDR[2] <= miny - 1;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
351:
begin
PAGE <= PAGE;
ADDR[0] <= miny; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny; // For fourth 3 checks
ADDR[2] <= miny;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
367:
begin
PAGE <= PAGE;
ADDR[0] <= miny + 1; // Next 16 clocks read 16 rows of Search Block
ADDR[1] <= miny + 1; // For fourth 3 checks
ADDR[2] <= miny + 1;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
383: // Writes for 6 and 7 for next macroblock
begin
WE[8] <= 1; // for block 6
WE[0] <= 1; // for block 7
PAGE <= ~PAGE;
ADDR[0] <= 32; // for block 7
ADDR[1] <= 0; // doesn't matter
ADDR[2] <= 16; // for block 6
ADDRC <= 0;
ioflag <= 0;
end
447: // Writes for 8 and 9 for next macroblock
begin
WE[11] <= 0;
WE[3] <= 0;
WE[4] <= 1;
WE[8] <= 1;
PAGE <= PAGE;
ADDR[0] <= 0;
ADDR[1] <= 32;
ADDR[2] <= 32;
ADDRC <= 0;
ioflag <= 0;
end
511:
begin
WE[7] <= 0;
WE[11] <= 0;
PAGE <= PAGE; // Dont switch here -- Read starts on page that was just written
ADDR[0] <= 8; // Next 16 clocks read rows 8 - 23 of Search Block
ADDR[1] <= 8; // For first 3 checks
ADDR[2] <= 8;
ADDRC <= 0; // Next 16 clocks read 16 rows of Current Block
ioflag <= 1;
end
default:
begin
for (i = 0; i < 4; i = i + 1)
begin
if (WEC[i])
begin
WEC[i] <= 0;
if (i == 3)
WEC[0] <= 1;
else
WEC[i+1] <= 1;
end
end
for (i = 0; i < 12; i = i + 1)
begin
if (WE[i])
begin
WE[i] <= 0;
if (i[1:0] == 3)
WE[i-3] <= 1;
else
WE[i+1] <= 1;
end
end
PAGE <= PAGE;
if (ioflag)
begin
ADDR[0] <= ADDR[0] + 1;
ADDR[1] <= ADDR[1] + 1;
ADDR[2] <= ADDR[2] + 1;
ADDRC <= ADDRC + 1;
end
else
if (count[1:0] == 3)
begin
ADDR[0] <= ADDR[0] + 1;
ADDR[1] <= ADDR[1] + 1;
ADDR[2] <= ADDR[2] + 1;
ADDRC <= ADDRC + 1;
end
end
endcase
end
 
end
 
 
endmodule

powered by: WebSVN 2.1.0

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