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