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 15 to Rev 16
    Reverse comparison

Rev 15 → Rev 16

/trunk/macroblock_motion_detection/MotionDetection.v
1,11 → 1,11
/////////////////////////////////////////////////////////////////////
//// ////
//// MotionDetection.v ////
//// ////
//// Performs motion estimation for one 16 x 16 macroblock ////
//// in a 48 x 48 pixel window every 512 clock cycles. ////
//// ////
//// ////
//// ////
//// 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 ////
//// ////
32,824 → 32,824
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//// 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
//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;
507: 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/MotionTest.v
1,260 → 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
 
/////////////////////////////////////////////////////////////////////
//// ////
//// 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/FrametoMacroBlock/motion_detection_top.v Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/macroblock_motion_detection/FrametoMacroBlock/motion_detection_top.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/macroblock_motion_detection/timescale.v =================================================================== --- trunk/macroblock_motion_detection/timescale.v (revision 15) +++ trunk/macroblock_motion_detection/timescale.v (revision 16) @@ -1,2 +1,2 @@ -`timescale 1ns/10ps - +`timescale 1ns/10ps + Index: trunk/macroblock_motion_detection/HalfPel/HalfPel.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/macroblock_motion_detection/HalfPel/HalfPel.v =================================================================== --- trunk/macroblock_motion_detection/HalfPel/HalfPel.v (nonexistent) +++ trunk/macroblock_motion_detection/HalfPel/HalfPel.v (revision 16)
trunk/macroblock_motion_detection/HalfPel/HalfPel.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/macroblock_motion_detection/HalfPel/HP_Block_Ram.v =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/macroblock_motion_detection/HalfPel/HP_Block_Ram.v =================================================================== --- trunk/macroblock_motion_detection/HalfPel/HP_Block_Ram.v (nonexistent) +++ trunk/macroblock_motion_detection/HalfPel/HP_Block_Ram.v (revision 16)
trunk/macroblock_motion_detection/HalfPel/HP_Block_Ram.v Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/macroblock_motion_detection/MD_Block_Ram.v =================================================================== --- trunk/macroblock_motion_detection/MD_Block_Ram.v (revision 15) +++ trunk/macroblock_motion_detection/MD_Block_Ram.v (revision 16) @@ -1,411 +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 +///////////////////////////////////////////////////////////////////// +//// //// +//// 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.