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 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/branches/avendor/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 |
/branches/avendor/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 |
|
/branches/avendor/macroblock_motion_detection/FrametoMacroBlock/ram_dp_sr_sw.v
1,118 → 1,118
/////////////////////////////////////////////////////////////////////////// |
// Function : Synchronous read write RAM // |
// Coder : Deepak Kumar Tala // |
// Date : 18-April-2002 // |
/////////////////////////////////////////////////////////////////////////// |
// // |
// Synchronous read write RAM from www.asic-world.com // |
// // |
// The following disclaimer from website applies to this code: // |
// // |
// I don't makes any claims, promises or guarantees about the // |
// accuracy, completeness, or adequacy of the contents of this // |
// website and expressly disclaims liability for errors and // |
// omissions in the contents of this website. No warranty of // |
// any kind, implied, expressed or statutory, including but not // |
// limited to the warranties of non-infringement of third // |
// party rights, title, merchantability, fitness for a particular // |
// purpose and freedom from computer virus, is given with respect // |
// to the contents of this website or its hyperlinks to other // |
// Internet resources. Reference in this website to any specific // |
// commercial products, processes, or services, or the use of // |
// any trade, firm or corporation name is for the information, and // |
// does not constitute endorsement, recommendation, or favoring by // |
// me. All the source code and Tutorials are to be used on your own // |
// risk. All the ideas and views in this site are my own and are // |
// not by any means related to my employer. // |
// // |
/////////////////////////////////////////////////////////////////////////// |
// // |
// Bus width adjusted for use with Motion Detection Core and timescale // |
// directive added for simulation. // |
// // |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Function : Synchronous read write RAM // |
// Coder : Deepak Kumar Tala // |
// Date : 18-April-2002 // |
/////////////////////////////////////////////////////////////////////////// |
// // |
// Synchronous read write RAM from www.asic-world.com // |
// // |
// The following disclaimer from website applies to this code: // |
// // |
// I don't makes any claims, promises or guarantees about the // |
// accuracy, completeness, or adequacy of the contents of this // |
// website and expressly disclaims liability for errors and // |
// omissions in the contents of this website. No warranty of // |
// any kind, implied, expressed or statutory, including but not // |
// limited to the warranties of non-infringement of third // |
// party rights, title, merchantability, fitness for a particular // |
// purpose and freedom from computer virus, is given with respect // |
// to the contents of this website or its hyperlinks to other // |
// Internet resources. Reference in this website to any specific // |
// commercial products, processes, or services, or the use of // |
// any trade, firm or corporation name is for the information, and // |
// does not constitute endorsement, recommendation, or favoring by // |
// me. All the source code and Tutorials are to be used on your own // |
// risk. All the ideas and views in this site are my own and are // |
// not by any means related to my employer. // |
// // |
/////////////////////////////////////////////////////////////////////////// |
// // |
// Bus width adjusted for use with Motion Detection Core and timescale // |
// directive added for simulation. // |
// // |
/////////////////////////////////////////////////////////////////////////// |
|
//synopsys translate_off |
`include "timescale.v" |
//synopsys translate_on |
module ram_dp_sr_sw ( |
|
clk , // Clock Input |
address_0 , // address_0 Input |
data_0 , // data_0 bi-directional |
cs_0 , // Chip Select |
we_0 , // Write Enable/Read Enable |
oe_0 , // Output Enable |
address_1 , // address_1 Input |
data_1 , // data_1 bi-directional |
cs_1 , // Chip Select |
we_1 , // Write Enable/Read Enable |
oe_1 // Output Enable |
); |
|
parameter data_0_WIDTH = 32 ; |
parameter ADDR_WIDTH = 17 ; |
parameter RAM_DEPTH = 1 << ADDR_WIDTH; |
|
//--------------Input Ports----------------------- |
input clk; |
input [ADDR_WIDTH-1:0] address_0 ; |
input cs_0 ; |
input we_0 ; |
input oe_0 ; |
input [ADDR_WIDTH-1:0] address_1 ; |
input cs_1 ; |
input we_1 ; |
input oe_1 ; |
|
//--------------Inout Ports----------------------- |
inout [data_0_WIDTH-1:0] data_0 ; |
inout [data_0_WIDTH-1:0] data_1 ; |
|
//--------------Internal variables---------------- |
reg [data_0_WIDTH-1:0] data_0_out ; |
reg [data_0_WIDTH-1:0] data_1_out ; |
reg [data_0_WIDTH-1:0] mem [0:RAM_DEPTH-1]; |
|
//--------------Code Starts Here------------------ |
// Memory Write Block |
// Write Operation : When we_0 = 1, cs_0 = 1 |
always @ (posedge clk) |
begin : MEM_WRITE |
if ( cs_0 && we_0 ) |
mem[address_0] <= data_0; |
if (cs_1 && we_1) |
mem[address_1] <= data_1; |
end |
|
|
|
// Tri-State Buffer control |
// output : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
assign data_0 = (cs_0 && oe_0 && !we_0) ? data_0_out : 32'bz; |
|
// Memory Read Block |
// Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
always @ (posedge clk) |
begin : MEM_READ_0 |
if (cs_0 && !we_0 && oe_0) |
data_0_out <= mem[address_0]; |
else |
data_0_out <= 0; |
end |
|
//Second Port of RAM |
// Tri-State Buffer control |
// output : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
assign data_1 = (cs_1 && oe_1 && !we_1) ? data_1_out : 32'bz; |
// Memory Read Block 1 |
// Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1 |
always @ (posedge clk) |
begin : MEM_READ_1 |
if (cs_1 && !we_1 && oe_1) |
data_1_out <= mem[address_1]; |
else |
data_1_out <= 0; |
end |
|
endmodule // End of Module ram_dp_sr_sw |
//synopsys translate_on |
module ram_dp_sr_sw ( |
|
clk , // Clock Input |
address_0 , // address_0 Input |
data_0 , // data_0 bi-directional |
cs_0 , // Chip Select |
we_0 , // Write Enable/Read Enable |
oe_0 , // Output Enable |
address_1 , // address_1 Input |
data_1 , // data_1 bi-directional |
cs_1 , // Chip Select |
we_1 , // Write Enable/Read Enable |
oe_1 // Output Enable |
); |
|
parameter data_0_WIDTH = 32 ; |
parameter ADDR_WIDTH = 17 ; |
parameter RAM_DEPTH = 1 << ADDR_WIDTH; |
|
//--------------Input Ports----------------------- |
input clk; |
input [ADDR_WIDTH-1:0] address_0 ; |
input cs_0 ; |
input we_0 ; |
input oe_0 ; |
input [ADDR_WIDTH-1:0] address_1 ; |
input cs_1 ; |
input we_1 ; |
input oe_1 ; |
|
//--------------Inout Ports----------------------- |
inout [data_0_WIDTH-1:0] data_0 ; |
inout [data_0_WIDTH-1:0] data_1 ; |
|
//--------------Internal variables---------------- |
reg [data_0_WIDTH-1:0] data_0_out ; |
reg [data_0_WIDTH-1:0] data_1_out ; |
reg [data_0_WIDTH-1:0] mem [0:RAM_DEPTH-1]; |
|
//--------------Code Starts Here------------------ |
// Memory Write Block |
// Write Operation : When we_0 = 1, cs_0 = 1 |
always @ (posedge clk) |
begin : MEM_WRITE |
if ( cs_0 && we_0 ) |
mem[address_0] <= data_0; |
if (cs_1 && we_1) |
mem[address_1] <= data_1; |
end |
|
|
|
// Tri-State Buffer control |
// output : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
assign data_0 = (cs_0 && oe_0 && !we_0) ? data_0_out : 32'bz; |
|
// Memory Read Block |
// Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
always @ (posedge clk) |
begin : MEM_READ_0 |
if (cs_0 && !we_0 && oe_0) |
data_0_out <= mem[address_0]; |
else |
data_0_out <= 0; |
end |
|
//Second Port of RAM |
// Tri-State Buffer control |
// output : When we_0 = 0, oe_0 = 1, cs_0 = 1 |
assign data_1 = (cs_1 && oe_1 && !we_1) ? data_1_out : 32'bz; |
// Memory Read Block 1 |
// Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1 |
always @ (posedge clk) |
begin : MEM_READ_1 |
if (cs_1 && !we_1 && oe_1) |
data_1_out <= mem[address_1]; |
else |
data_1_out <= 0; |
end |
|
endmodule // End of Module ram_dp_sr_sw |
/branches/avendor/macroblock_motion_detection/FrametoMacroBlock/motion_detection_top.v
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
branches/avendor/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: branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlock.v
===================================================================
--- branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlock.v (revision 14)
+++ branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlock.v (revision 15)
@@ -1,27 +1,27 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// FrametoMacroBlock.v ////
-//// ////
-//// Buffers data from frames to Motion.v for motion ////
-//// estimation. Data is assumed to arrive in 4:2:2 ////
-//// format in YUYV order. Data is separated by component ////
-//// (presumably in off chip ram.) U and V data is down ////
-//// sampled to 4:2:0 by discarding every other row for ////
-//// use in MPEG like system. Currently, U and V data ////
-//// are ignored since program outputs motion vectors ////
-//// for macroblocks, but does not yet do half pel motion ////
-//// estimation or output differences between macroblock ////
-//// and best match for furthur processing. ////
-//// ////
-//// Memory access is assumed to run at 54MHz, but most ////
-//// other processing occurs based on clk2 which runs at ////
-//// half speed (including 8 bit inputs of YUV data) ////
-//// to match digital NTSC/PAL like data rates. ////
-//// ////
-//// ////
-//// ////
-//// ////
-//// ////
+//// ////
+//// Buffers data from frames to Motion.v for motion ////
+//// estimation. Data is assumed to arrive in 4:2:2 ////
+//// format in YUYV order. Data is separated by component ////
+//// (presumably in off chip ram.) U and V data is down ////
+//// sampled to 4:2:0 by discarding every other row for ////
+//// use in MPEG like system. Currently, U and V data ////
+//// are ignored since program outputs motion vectors ////
+//// for macroblocks, but does not yet do half pel motion ////
+//// estimation or output differences between macroblock ////
+//// and best match for furthur processing. ////
+//// ////
+//// Memory access is assumed to run at 54MHz, but most ////
+//// other processing occurs based on clk2 which runs at ////
+//// half speed (including 8 bit inputs of YUV data) ////
+//// to match digital NTSC/PAL like data rates. ////
+//// ////
+//// ////
+//// ////
+//// ////
+//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
@@ -48,570 +48,866 @@
//// 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 FrametoMacroBlock(clk, ena, rst, dstrb, dclr, din1,dout1,douten,
- MD_ena, MD_rst, MD_din1, MD_din2, MD_state, MD_dout, MD_count,
- address_0, data_0, cs_0, we_0, oe_0, address_1, data_1, cs_1, we_1, oe_1);
-reg clk2; //1/2 speed clk for data input
-
- // parameters
- parameter frame_width = 352; //720;
- parameter frame_height = 200; //480;
- parameter xmblocks = frame_width >> 4;
- parameter ymblocks = frame_height >> 4;
- parameter uoffset = frame_width*frame_height - (frame_width >> 4);
- parameter voffset = frame_width*frame_height;
- parameter frameoffset = frame_width*frame_height+((frame_width*frame_height)>>1);
- parameter yblkoffset = frame_width * 4; // number of mem locs for 1 line of macroblocks
- parameter ylinoffset = frame_width >> 2;
- parameter addr_cur_start = yblkoffset * (ymblocks - 1);
-
- parameter clk_match = 1; // used to adjust clock cycles to match MotionDetection.v
-
+//synopsys translate_on
+module FrametoMacroBlock(clk, ena, rst, dstrb, dclr, din1,dout1,douten,
+ MD_ena, MD_rst, MD_din1, MD_din2, MD_state, MD_dout, MD_count,
+ HP_ena, HP_rst, HP_din1, HP_din2, HP_state, HP_dout, HP_count,
+ HP_xoffset, HP_yoffset,
+ address_0, data_0, cs_0, we_0, oe_0, address_1, data_1, cs_1, we_1, oe_1);
+ reg clk2; //1/2 speed clk for data input
+ reg [8:0] count; // 512 cycle counter to synch with Motion block inputs
+ // parameters
+ parameter frame_width = 352; //720;
+ parameter frame_height = 200; //480;
+ parameter xmblocks = frame_width >> 4;
+ parameter ymblocks = frame_height >> 4;
+ parameter uoffset = frame_width*frame_height - (frame_width >> 4);
+ parameter voffset = frame_width*frame_height;
+ parameter frameoffset = frame_width*frame_height+((frame_width*frame_height)>>1);
+ parameter yblkoffset = frame_width * 4; // number of mem locs for 1 line of macroblocks
+ parameter ylinoffset = frame_width >> 2;
+ parameter addr_cur_start = yblkoffset * (ymblocks - 1);
+
+ integer clk_match; // used to adjust clock cycles to match MotionDetection.v
+
input clk;
input ena;
- input rst;
- input dstrb;
- input dclr;
- input [7:0] din1;
- output [7:0] dout1;
- reg [7:0] dout1;
- reg [31:0] ybuffer;
- reg [31:0] ubuffer;
- reg [31:0] vbuffer;
- reg uvflag;
+ input rst;
+ input dstrb;
+ input dclr;
+ input [7:0] din1;
+ output [7:0] dout1;
+ reg [7:0] dout1;
+ reg [31:0] ybuffer;
+ reg [31:0] ubuffer;
+ reg [31:0] vbuffer;
+ reg uvflag;
output douten; // data-out enable
- reg douten;
-
- reg [3:0] state;
- reg frame;
- reg [20:0] input_cnt;
- reg [9:0] inx_cnt;
- reg [9:0] iny_cnt;
-
- // Motion Detection connections
- output MD_ena;
- output MD_rst;
- output [31:0] MD_din1,MD_din2;
- output [3:0] MD_state;
- output [8:0] MD_count;
-
- reg MD_ena;
- reg MD_rst;
- reg [31:0] MD_din1, MD_din2;
- wire [3:0] MD_state;
- assign MD_state = state;
- wire [8:0] MD_count;
-
-// Outputs
- input [31:0] MD_dout;
- wire [31:0] MD_dout;
-
-
- // RAM Connections
- // RAM Inputs
- output [16:0] address_0;
- output cs_0;
- output we_0;
- output oe_0;
- output [16:0] address_1;
- output cs_1;
- output we_1;
- output oe_1;
-
- reg [16:0] address_0;
- reg cs_0;
- reg we_0;
- reg oe_0;
- reg [16:0] address_1;
- reg cs_1;
- reg we_1;
- reg oe_1;
-
-// Outputs
-
-
-// Bidirs
- reg [31:0] data_0_t;
- reg [31:0] data_1_t;
-
- inout [31:0] data_0;
- inout [31:0] data_1;
-
- assign data_0 = (we_0) ? data_0_t : 32'bz;
- assign data_1 = (we_1) ? data_1_t : 32'bz;
-
-
-// Motion Estimation Registers
- reg [15:0] cur [0:15];
- reg [7:0] mblx; // current macro block x
- reg [7:0] mbly; // current macro block y
- reg mfr; // current frame
- reg [3:0] mbln; // 0 for curr, 1 - 9 for search blocks
-
- reg [6:0] mecount; // 128 counts for 2 macroblocks * 64 mems per
- reg me_datain_flag;
- reg [8:0] count; // 512 cycle counter to synch with Motion block inputs
- reg [15:0] addr_cur; // address of data in current block
- reg [15:0] addr_search1;
- reg [15:0] addr_search2;
-
- assign MD_count = count;
+ reg douten;
+
+ reg [3:0] state;
+ reg frame;
+ reg [20:0] input_cnt;
+ reg [9:0] inx_cnt;
+ reg [9:0] iny_cnt;
+
+ // Motion Detection connections
+ output MD_ena;
+ output MD_rst;
+ output [31:0] MD_din1,MD_din2;
+ output [3:0] MD_state;
+ output [8:0] MD_count;
+
+ reg MD_ena;
+ reg MD_rst;
+ reg [31:0] MD_din1, MD_din2;
+ reg [31:0] MD_din1_hold;
+ wire [3:0] MD_state;
+ assign MD_state = state;
+ wire [8:0] MD_count;
+ assign MD_count = count;
+ input [31:0] MD_dout;
+ wire [31:0] MD_dout;
+
+ // Half Pel Connections
+// Inputs
+
+ output HP_ena;
+ output HP_rst;
+ output [31:0] HP_din1;
+ output [31:0] HP_din2;
+ output [3:0] HP_state;
+ output [8:0] HP_count;
+ output [5:0] HP_xoffset;
+ output [5:0] HP_yoffset; // minx, miny from full pixel unit
+
+ reg HP_ena;
+ reg HP_rst;
+ reg [31:0] HP_din1;
+ reg [31:0] HP_din1_hold;
+ reg [31:0] HP_din1_ee;
+ reg [31:0] HP_din1_e;
+ reg [31:0] HP_din2;
+ reg [31:0] HP_din2_ee;
+ reg [31:0] HP_din2_e;
+ wire [3:0] HP_state;
+ assign HP_state = state;
+ wire [8:0] HP_count;
+ assign HP_count = count;
+ reg [5:0] HP_xoffset;
+ reg [5:0] HP_yoffset; // minx, miny from full pixel unit
+
+// Outputs
+ input [31:0] HP_dout;
+ wire [31:0] HP_dout;
+
+
+
+
+// Outputs
+
+
+
+ // RAM Connections
+ // RAM Inputs
+ output [16:0] address_0;
+ output cs_0;
+ output we_0;
+ output oe_0;
+ output [16:0] address_1;
+ output cs_1;
+ output we_1;
+ output oe_1;
+
+ reg [16:0] address_0;
+ reg cs_0;
+ reg we_0;
+ reg oe_0;
+ reg [16:0] address_1;
+ reg cs_1;
+ reg we_1;
+ reg oe_1;
+
+// Outputs
+
+
+// Bidirs
+ reg [31:0] data_0_t;
+ reg [31:0] data_1_t;
+
+ inout [31:0] data_0;
+ inout [31:0] data_1;
+
+ assign data_0 = (we_0) ? data_0_t : 32'bz;
+ assign data_1 = (we_1) ? data_1_t : 32'bz;
+
+
+// Motion Estimation Registers
+ reg [7:0] mblx; // current macro block x
+ reg [7:0] mbly; // current macro block y
+ reg [7:0] mblxd; // delayed for hp
+ reg [7:0] mblyd; // delayed for hp
+ reg [3:0] mbln; // 0 - 4 tracks which macroblocks are being
+ reg [3:0] mblnd; // sent to Motiondetection Unit
+ reg [3:0] mblndd; // 0 = cur and 1 1 = 2 and 3
+ // 2 = 4 and 5 3 = 6 and 7
+ // 4 = 8 and 9
+
+ reg [6:0] mecount; // 128 counts for 2 macroblocks * 64 mems per
+ reg me_datain_flag;
+ reg [15:0] addr_cur; // address of data in current block
+ reg frame_cur;
+
+// Half Pel Registers
+ reg [7:0] hblx; // current macro block x
+ reg [7:0] hbly; // current macro block y
+ reg [2:0] hp_xcnt; // 0 - 5 for 18 input/row (4/mem)
+ reg [4:0] hp_ycnt; // 0 - 17 for row input count
+ reg [15:0] hp_addr_cur;
+ reg [15:0] hp_addr_cur_hold;
+ reg [15:0] hp_addr_srch;
+ reg [15:0] hp_addr_srch_d;
+ reg hp_datain_flag; //
+ reg hp_frame_cur;
+ reg hp_frame_cur_hold;
+
+
// x y input counter and frame control
always @(posedge clk2 or negedge rst)
- if (~rst)
+ if (~rst)
begin
- input_cnt <= 5'h0;
- inx_cnt <= 0;
- iny_cnt <= 0;
- frame <= 0;
+ input_cnt <= 5'h0; // 21 bit
+ inx_cnt <= 0;
+ iny_cnt <= 0;
+ frame <= 0;
end
- else
+ else
if (ena)
- if(input_cnt == frame_height * frame_width * 2 - 1)
- begin
- frame <= ~frame;
- input_cnt <=0;
- inx_cnt <= 0;
- iny_cnt <= 0;
- end
- else
- begin
- if (inx_cnt == frame_width * 2 - 1)
- begin
- inx_cnt <= 0;
- iny_cnt <= iny_cnt + 1;
+ if(input_cnt == frame_height * frame_width * 2 - 1)
+ begin
+ frame <= ~frame;
+ input_cnt <=0;
+ inx_cnt <= 0;
+ iny_cnt <= 0;
+ end
+ else
+ begin
+ if (inx_cnt == frame_width * 2 - 1)
+ begin
+ inx_cnt <= 0;
+ iny_cnt <= iny_cnt + 1;
+ end
+ else
+ begin
+ inx_cnt <= inx_cnt + 1;
+ iny_cnt <= iny_cnt;
end
- else
- begin
- inx_cnt <= inx_cnt + 1;
- iny_cnt <= iny_cnt;
- end
- input_cnt <= input_cnt + 1;
- end
-
-// input buffer and save
+ input_cnt <= input_cnt + 1;
+ end
+
+// input buffer and save
always @(posedge clk2 or negedge rst)
if (~rst)
begin
douten <= 1'b0;
- state <= 0;
+ state <= 0;
end
else if (ena)
- begin
- // Pixels are assumed to be coming from a camera in
- // 4:2:2 format 8-bits at a time in Y U Y V order
- // Pixel info is stored 4 bits at a time
- // Separating Y U V components
-
- // Buffer input for storage
- if (state==0)
- begin
- if (input_cnt[0:0] == 0)
- begin
- case (input_cnt[2:1])
- 0: ybuffer[31:24] <= din1;
- 1: ybuffer[23:16] <= din1;
- 2: ybuffer[15:8] <= din1;
- 3: ybuffer[7:0] <= din1;
- endcase
- end
- else
- begin
- case (input_cnt[3:1])
- 0: ubuffer[31:24] <= din1;
- 1: vbuffer[31:24] <= din1;
- 2: ubuffer[23:16] <= din1;
- 3: vbuffer[23:16] <= din1;
- 4: ubuffer[15:8] <= din1;
- 5: vbuffer[15:8] <= din1;
- 6: ubuffer[7:0] <= din1;
- 7: vbuffer[7:0] <= din1;
- endcase
- end
-
- // Save buffered data to memory
- // Case statement takes last digit of line count to downsample
- // U and V data. Last four bits of input_cnt track input
- // data groups YUYV YUYV YUYV YUYV
- // ^ save Y ^ save Y
- // ^ save U (odd lines)
- // ^ save V (saves on odd lines, first data will
- // be last V from previous line)
- address_0[16:16] <= frame; // alternates each frame
- casez({iny_cnt[0:0],input_cnt[3:0]})
- 5'b10000: // save V at 0 after 3 7 9 16
- begin // every other line
- we_0 <= 1;
- cs_0 <= 1;
- if (inx_cnt == 0) // note takes last from first line
- address_0[15:0] <= voffset - 1 + (frame_width >> 4) + input_cnt[19:4];
- else // others from second line
- address_0 <= voffset - 1 + input_cnt[19:4];
- data_0_t <= vbuffer;
- end
- 5'b??111 : // save Y every 8 after 0 2 4 6
- begin
- we_0 <= 1;
- cs_0 <= 1;
- address_0[15:0] <= {input_cnt[19:3]};
- data_0_t <= ybuffer;
- end
- 5'b11110: // save u at 14 after 1 5 9 13
- begin // every other line
- we_0 <= 1;
- cs_0 <= 1;
- address_0[15:0] <= uoffset + input_cnt[19:4];
- data_0_t <= ubuffer;
- end
- default:
- begin
- we_0 <= 0;
- cs_0 <= 0;
- end
- endcase
- end // if state = 0 (always true now)
- end // (ena)
-
-// Motion Detection
-// Note Write enables for blocks are timed in MD_Block_Ram
-always @(posedge clk or negedge rst)
- begin
- we_1 <= 0;
- oe_1 <= 1;
- cs_1 <= 1;
- if (~rst)
- begin
- MD_din1 <=0;
- MD_din2 <=0;
- end
- else
- if (ena)
- if (mecount[0:0])
- case (mbln)
- 0: begin
- MD_din1 <= data_1; // current always valid
- end
- 1: begin
- if (mbly >0)
- MD_din1 <= data_1; //block 2 valid on rows > 0
- else
- MD_din1 <= 32'b10000000100000001000000010000000;
- end
- 2: begin
- MD_din1 <= data_1; // block 5 always valid
- end
- 3: begin
- if (mblx < xmblocks - 1)
- MD_din1 <= data_1; // block 6 valid except last col
- else
- MD_din1 <= 32'b10000000100000001000000010000000;
- end
- 4: begin
- if (mbly < ymblocks - 1)
- MD_din1 <= data_1; // block 8 valid except bottom row
- else
- MD_din1 <= 32'b10000000100000001000000010000000;
- end
- endcase
- else
- case (mbln)
- 0: begin
- if ((mblx > 0) & (mbly >0))
- MD_din2 <= data_1; // block 1 valid if row,col > 1
- else
- MD_din2 <= 32'b10000000100000001000000010000000;
- end
- 1: begin
- if ((mblx < xmblocks - 1) & (mbly >0))
- MD_din2 <= data_1; // block 3 valid row>1 col < max
- else
- MD_din2 <= 32'b10000000100000001000000010000000;
- end
- 2: begin
- if (mblx > 0) // block 4 valid if col > 1
- MD_din2 <= data_1;
- else
- MD_din2 <= 32'b10000000100000001000000010000000;
- end
- 3: begin
- if ((mblx > 0) & (mbly < ymblocks - 1))
- MD_din2 <= data_1; // block 7 valid row < max col > 1
- else
- MD_din2 <= 32'b10000000100000001000000010000000;
- end
- 4: begin
- if ((mblx < xmblocks - 1) & (mbly < ymblocks - 1))
- MD_din2 <= data_1; // block 9 valid row < max col < max
- else
- MD_din2 <= 32'b10000000100000001000000010000000;
- end
- endcase
+ begin
+ // Pixels are assumed to be coming from a camera in
+ // 4:2:2 format 8-bits at a time in Y U Y V order
+ // Pixel info is stored 4 bits at a time
+ // Separating Y U V components
+
+ // Buffer input for storage
+ if (state==0)
+ begin
+ if (input_cnt[0:0] == 0)
+ begin
+ case (input_cnt[2:1])
+ 0: ybuffer[31:24] <= din1;
+ 1: ybuffer[23:16] <= din1;
+ 2: ybuffer[15:8] <= din1;
+ 3: ybuffer[7:0] <= din1;
+ endcase
+ end
+ else
+ begin
+ case (input_cnt[3:1])
+ 0: ubuffer[31:24] <= din1;
+ 1: vbuffer[31:24] <= din1;
+ 2: ubuffer[23:16] <= din1;
+ 3: vbuffer[23:16] <= din1;
+ 4: ubuffer[15:8] <= din1;
+ 5: vbuffer[15:8] <= din1;
+ 6: ubuffer[7:0] <= din1;
+ 7: vbuffer[7:0] <= din1;
+ endcase
+ end
+
+ // Save buffered data to memory
+ // Case statement takes last digit of line count to downsample
+ // U and V data. Last four bits of input_cnt track input
+ // data groups YUYV YUYV YUYV YUYV
+ // ^ save Y ^ save Y
+ // ^ save U (odd lines)
+ // ^ save V (saves on odd lines, first data will
+ // be last V from previous line)
+ address_0[16:16] <= frame; // alternates each frame
+ casez({iny_cnt[0:0],input_cnt[3:0]})
+ 5'b10000: // save V at 0 after 3 7 9 16
+ begin // every other line
+ we_0 <= 1;
+ cs_0 <= 1;
+ if (inx_cnt == 0) // note takes last from first line
+ address_0[15:0] <= voffset - 1 + (frame_width >> 4) + input_cnt[19:4];
+ else // others from second line
+ address_0 <= voffset - 1 + input_cnt[19:4];
+ data_0_t <= vbuffer;
+ end
+ 5'b??111 : // save Y every 8 after 0 2 4 6
+ begin
+ we_0 <= 1;
+ cs_0 <= 1;
+ address_0[15:0] <= {input_cnt[19:3]};
+ data_0_t <= ybuffer;
+ end
+ 5'b11110: // save u at 14 after 1 5 9 13
+ begin // every other line
+ we_0 <= 1;
+ cs_0 <= 1;
+ address_0[15:0] <= uoffset + input_cnt[19:4];
+ data_0_t <= ubuffer;
+ end
+ default:
+ begin
+ we_0 <= 0;
+ cs_0 <= 0;
+ end
+ endcase
+ end // if state = 0 (always true now)
+ end // (ena)
+
+// Motion Detection
+// Note Write enables for blocks are timed in MD_Block_Ram
+always @(posedge clk or negedge rst)
+ begin
+ we_1 <= 0;
+ oe_1 <= 1;
+ cs_1 <= 1;
+ if (~rst)
+ begin
+ MD_din1 <=0;
+ MD_din1_hold <= 0;
+ MD_din2 <=0;
+ end
+ else
+ if (ena)
+ if (mecount[0:0])
+ case (mblndd)
+ 0: begin
+ MD_din1_hold <= data_1; // current always valid
+ end
+ 1: begin
+ if (mbly >0)
+ MD_din1_hold <= data_1; //block 2 valid on rows > 0
+ else
+ MD_din1_hold <= 32'b10000000100000001000000010000000;
+ end
+ 2: begin
+ MD_din1_hold <= data_1; // block 5 always valid
+ end
+ 3: begin
+ if (mblx < xmblocks - 1)
+ MD_din1_hold <= data_1; // block 6 valid except last col
+ else
+ MD_din1_hold <= 32'b10000000100000001000000010000000;
+ end
+ 4: begin
+ if (mbly < ymblocks - 1)
+ MD_din1_hold <= data_1; // block 8 valid except bottom row
+ else
+ MD_din1_hold <= 32'b10000000100000001000000010000000;
+ end
+ default: MD_din1_hold <= 0;
+ endcase
+ else
+ begin
+ MD_din1 <= MD_din1_hold;
+ case (mblndd)
+ 0: begin
+ if ((mblx > 0) & (mbly >0))
+ MD_din2 <= data_1; // block 1 valid if row,col > 1
+ else
+ MD_din2 <= 32'b10000000100000001000000010000000;
+ end
+ 1: begin
+ if ((mblx < xmblocks - 1) & (mbly >0))
+ MD_din2 <= data_1; // block 3 valid row>1 col < max
+ else
+ MD_din2 <= 32'b10000000100000001000000010000000;
+ end
+ 2: begin
+ if (mblx > 0) // block 4 valid if col > 1
+ MD_din2 <= data_1;
+ else
+ MD_din2 <= 32'b10000000100000001000000010000000;
+ end
+ 3: begin
+ if ((mblx > 0) & (mbly < ymblocks - 1))
+ MD_din2 <= data_1; // block 7 valid row < max col > 1
+ else
+ MD_din2 <= 32'b10000000100000001000000010000000;
+ end
+ 4: begin
+ if ((mblx < xmblocks - 1) & (mbly < ymblocks - 1))
+ MD_din2 <= data_1; // block 9 valid row < max col < max
+ else
+ MD_din2 <= 32'b10000000100000001000000010000000;
+ end
+ default: MD_din2 <= 0;
+ endcase
+ end
end // always
-
-// Control for Motion Estimation Data
-always @(posedge clk or negedge rst)
- if (~rst)
- begin
+
+// Half Pel data in
+// Note Write enables for blocks are timed in MD_Block_Ram
+// ensures data from valid position otherwise uses 128
+always @(posedge clk or negedge rst)
+ begin
+ if (~rst)
+ begin
+ HP_din1 <=0;
+ HP_din1 <=0;
+ HP_din2 <=0;
+ end
+ else
+ if (ena)
+ if (~clk2)
+ begin
+ if (mblndd == 5)
+ HP_din1 <= data_1;
+ else
+ HP_din1 <= 0;
+ end
+ else
+ begin
+ //HP_din1 <= HP_din1_hold;
+ if (mblndd == 5)
+ // test for block in col 0 offset to left of frame
+ if (({hblx,2'b0} + HP_xoffset[5:2] + hp_xcnt) < 4)
+ HP_din2 <= 32'b10000000100000001000000010000000;
+ else // test for block in last col offset to right
+ if (({hblx,2'b0} + HP_xoffset[5:2] + hp_xcnt) > ({xmblocks,2'b0} + 7))
+ HP_din2 <= 32'b10000000100000001000000010000000;
+ else // test for blocks on top row
+ if ({hbly,4'b0} + HP_yoffset + hp_ycnt < 16)
+ HP_din2 <= 32'b10000000100000001000000010000000;
+ else // test for blocks on bottom row
+ if ({hbly,4'b0} + HP_yoffset + hp_ycnt > 95)
+ HP_din2_ee <= 32'b10000000100000001000000010000000;
+ else
+ HP_din2 <= data_1;
+ else
+ HP_din2 <= 0;
+ //HP_din1_e <= HP_din1_ee;
+ //HP_din1 <= HP_din1_e;
+ //HP_din2_e <= HP_din2_ee;
+ //HP_din2 <= HP_din2_e;
+ end
+ end // always
+
+// Control for hp_xcnt hp_ycnt
+always @(posedge clk2 or negedge rst)
+ if (~rst)
+ begin
+ hp_xcnt <= 0;
+ hp_ycnt <= 0;
+ end
+ else
+ if (ena)
+ begin
+ case (count)
+ 508:
+ begin
+ hp_xcnt <= 0;
+ hp_ycnt <= 0;
+ end
+ default:
+ begin
+ if (hp_datain_flag)
+ begin
+ if (hp_xcnt == 5) // last byte of row
+ begin
+ hp_xcnt <= 0;
+ hp_ycnt <= hp_ycnt + 1;
+ end
+ else
+ hp_xcnt <= hp_xcnt + 1;
+ end
+ end // case default
+ endcase
+ end
+// Control for hp_datain_flag
+always @(posedge clk2 or negedge rst)
+ if (~rst)
+ begin
+ hp_datain_flag <= 0;
+ end
+ else
+ if (ena)
+ begin
+ case (count)
+ 45: hp_datain_flag <= 0;
+ 109: hp_datain_flag <= 1; // address increases again at 110
+ 157: hp_datain_flag <= 0;
+ 221: hp_datain_flag <= 1; // address increases again at 222
+ 233: hp_datain_flag <= 0;
+ 509: hp_datain_flag <= 1;
+ endcase
+ end
+
+
+// Control for hp_addr_cur hp_addr_srch
+// Writes to Half Pel Unit
+// 2 - 49
+// 114 - 161
+// 226 - 237
+always @(posedge clk2 or negedge rst)
+ if (~rst)
+ begin
+ hp_addr_cur <= 0;
+ hp_addr_cur_hold <= 0;
+ hp_addr_srch <= 0;
+ hp_addr_srch_d <= 0;
+ hp_frame_cur <= 0;
+ hp_frame_cur_hold <= 0;
+ end
+ else
+ if (ena)
+ begin
+ hp_addr_srch_d <= hp_addr_srch;
+ case (count)
+ 509:
+ begin // addr_curr reset at
+ hp_frame_cur_hold <= ~address_1[16:16]; // at 508 this should be in search frame
+ hp_frame_cur <= hp_frame_cur_hold;
+ hp_addr_cur_hold <= addr_cur;
+ hp_addr_cur <= hp_addr_cur_hold;
+ // Search address starts one pixel up and to the left
+ // of best match from motion detection.
+ // Multiplier could be eliminated by adding register and
+ // adding in steps while decrementing counter
+ // during earlier counts
+ hp_addr_srch <= hp_addr_cur_hold - 4 + HP_xoffset[5:2]
+ + HP_yoffset * ylinoffset - {ylinoffset,4'b0};
+ end
+ default:
+ begin
+ if (hp_datain_flag)
+ begin
+ // cur rows of 4
+ if (hp_addr_cur[1:0] == 3)
+ hp_addr_cur <= hp_addr_cur + ylinoffset - 3;
+ else
+ hp_addr_cur <= hp_addr_cur + 1;
+ // search rows of 6
+ if(hp_xcnt == 5)
+ hp_addr_srch <= hp_addr_srch + ylinoffset - 5;
+ else
+ hp_addr_srch <= hp_addr_srch + 1;
+ end
+ end
+ endcase
+ end
+// Control for Motion Estimation Data
+always @(posedge clk or negedge rst)
+ if (~rst)
+ begin
me_datain_flag <= 0;
end
- else
- if (ena)
- begin
- if (iny_cnt[3:0] == 15) // last row of macroblock
- begin
- if (inx_cnt == frame_width*2 - 1) // last byte of row
- begin
- me_datain_flag <= 1;
- end
- 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
-
- // control for mfr (motion block frame)
-always @(posedge clk or negedge rst)
- begin
- if (~rst)
- begin
- mfr <= 0;
- end
- else
- if (ena)
- if (iny_cnt == 15) // last row of first macroblock
- begin
- if (inx_cnt == frame_width*2 - 1) // last byte of row
- begin
- mfr <= frame;
- end
- end
- end // always
-
- // control for mblx mbly (current macroblock being processed)
-always @(posedge clk2 or negedge rst)
- begin
- if (~rst)
- begin
- mblx <= 0;
- mbly <= ymblocks - 1; // Start on last row
- addr_cur <= addr_cur_start; // address for first macroblock on last row
- end
- else
- if (ena)
- if (count == 511) // new macroblock every 512 counts
- begin
- if (mblx == xmblocks - 1)
- begin
- if (mbly == ymblocks - 1)
- begin
- mbly <= 0;
- addr_cur <=0;
- end
- else
- begin
- mbly <= mbly + 1;
- addr_cur <= addr_cur + yblkoffset - ylinoffset + 4;
- end
- mblx <= 0;
- end
- else
- begin
- mblx <= mblx + 1;
- addr_cur <= addr_cur + 4;
- end
- end
- end // always
-
-// control for count
-always @(posedge clk2 or negedge rst)
- begin
- if (~rst)
- begin
- count <= 0;
- end
- else
- if (ena)
- begin
- count <= count + 1;
- end
- end
-
-// control for Motion Detection Enable and rst
-always @(posedge clk2 or negedge rst)
- begin
- if (~rst)
- begin
- MD_ena <= 0;
- MD_rst <= 0;
- end
- else
- if (ena)
- begin
- MD_ena <= 1;
- MD_rst <= 1;
- end
- end
-
- // control for dout1
-always @(posedge clk2 or negedge rst)
- begin
- if (~rst)
- begin
- dout1 <= 0;
- end
- else
- if (ena)
- begin
- case (count[1:0])
- 3: dout1 <= MD_dout[31:24];
- 0: dout1 <= MD_dout[23:16];
- 1: dout1 <= MD_dout[15:8];
- 2: dout1 <= MD_dout[7:0];
- endcase
- end
- end
-
-// address control for block memories control
-always @(posedge clk or negedge rst)
- begin
- if (~rst)
- begin
- address_1 <= 0;
- mbln <=0;
- mecount <= 0;
- addr_search1 <= 0;
- addr_search2 <= 0;
- end
- else
- if (ena)
- begin
- if (~clk2)
- begin
- case (count)
- 47-clk_match: // Writes for CUR and 1 for next macroblock
- begin
- if(iny_cnt > 15)
- address_1[16:16] <= frame; // first read for cur
- else // uses frame currently
- address_1[16:16] <= ~frame; // loading unless last
- address_1[15:0] <= addr_cur; // row
- mecount <=0;
- mbln <= 0;
- end
- 159-clk_match: // Writes for 2 and 3 for next macroblock
- begin
- if(iny_cnt > 15)
- address_1[16:16] <= ~frame; // all others use previous
- else // frame unless last row
- address_1[16:16] <= frame;
- address_1[15:0] <= addr_cur - yblkoffset; // Block 2
- mecount <=0;
- mbln <= 1;
- end
- 271-clk_match: // Writes for 4 and 5 for next macroblock
- begin
- address_1[15:0] <= addr_cur; // Block 5 is MD_din1
- mecount <=0;
- mbln <= 2;
- end
- 383-clk_match: // Writes for 6 and 7 for next macroblock
- begin
- address_1[15:0] <= addr_cur + 4; // Block 6
- mecount <=0;
- mbln <= 3;
- end
- 447-clk_match: // Writes for 8 and 9 for next macroblock
- begin
- address_1[15:0] <= addr_cur + yblkoffset; // Block 8
- mecount <=0;
- mbln <= 4;
- end
- default:
- begin
- mecount <= mecount +1;
- case (mbln)
- 0: begin
- address_1[16:16] <= ~address_1[16:16]; // cur and 1 of search in different frames
- if (address_1[1:0] == 3)
- address_1[15:0] <= address_1[15:0] + yblkoffset + ylinoffset + 1;
- else // block 1 to cur
- address_1[15:0] <= address_1[15:0] + yblkoffset + 5;
- end
- 1: begin
- if (address_1[1:0] == 3)
- address_1[15:0] <= address_1[15:0] + ylinoffset - 7;
- else // block 3 to 2
- address_1[15:0] <= address_1[15:0] - 3;
- end
- 2: begin
- if (address_1[1:0] == 3)
- address_1[15:0] <= address_1[15:0] + ylinoffset + 1;
- else // block 4 to 5
- address_1[15:0] <= address_1[15:0] + 5;
- end
- 3: begin
- if (address_1[1:0] == 3)
- address_1[15:0] <= address_1[15:0] - yblkoffset + ylinoffset + 5;
- else // block 7 to 6
- address_1[15:0] <= address_1[15:0] - yblkoffset + 9;
- end
- 4: begin
- if (address_1[1:0] == 3)
- address_1[15:0] <= address_1[15:0] + ylinoffset - 7;
- else // block 9 to 8
- address_1[15:0] <= address_1[15:0] - 3;
- end
- endcase
- end
- endcase
- end // if(clk2)
- else
- begin
- mecount <= mecount +1;
- case (mbln)
- 0: begin
- address_1[16:16] <= ~address_1[16:16]; // cur and 1 of search in different frames
- address_1[15:0] <= address_1[15:0] - yblkoffset - 4;
- end
- 1: address_1[15:0] <= address_1[15:0] + 4;
- 2: address_1[15:0] <= address_1[15:0] - 4;
- 3: address_1[15:0] <= address_1[15:0] + yblkoffset - 8;
- 4: address_1[15:0] <= address_1[15:0] + 4;
- endcase
- end
- end // if(ena)
- end // always
-
-endmodule
+ else
+ if (ena)
+ begin
+ if (iny_cnt[3:0] == 15) // last row of macroblock
+ begin
+ if (inx_cnt == frame_width*2 - 1) // last byte of row
+ begin
+ me_datain_flag <= 1;
+ end
+ 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
+
+ // control for mblx mbly (current macroblock being processed)
+ // hblx hbly current macroblock for half pel unit
+always @(posedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ mblx <= 0;
+ mbly <= ymblocks - 1; // Start on last row
+ mblxd <= 0;
+ mblyd <= 0;
+ hblx <= 0; // 2 blocks behind mblx
+ hbly <= 0;
+ addr_cur <= addr_cur_start; // address for first macroblock on last row
+ end
+ else
+ if (ena)
+ if (count == 511) // new macroblock every 512 counts
+ begin
+ mblxd <= mblx;
+ mblyd <= mbly;
+ hblx <= mblxd; // half pel runs one macroblock
+ hbly <= mblyd; // behind motion detection unit
+ if (mblx == xmblocks - 1)
+ begin
+ if (mbly == ymblocks - 1)
+ begin
+ mbly <= 0;
+ addr_cur <=0;
+ end
+ else
+ begin
+ mbly <= mbly + 1;
+ addr_cur <= addr_cur + yblkoffset - ylinoffset + 4;
+ end
+ mblx <= 0;
+ end
+ else
+ begin
+ mblx <= mblx + 1;
+ addr_cur <= addr_cur + 4;
+ end
+ end
+ end // always
+
+// control for count
+always @(posedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ count <= 0;
+ end
+ else
+ if (ena)
+ begin
+ count <= count + 1;
+ end
+ end
+
+// control for Motion Detection Enable and rst
+always @(negedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ MD_ena <= 0;
+ MD_rst <= 0;
+ end
+ else
+ if (ena)
+ begin
+ MD_ena <= 1;
+ MD_rst <= 1;
+ end
+ end
+
+// control for Half Pel Enable and rst
+// Should be changed to not operate during I frames
+always @(negedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ HP_ena <= 0;
+ HP_rst <= 0;
+ end
+ else
+ if (ena)
+ begin
+ HP_ena <= 1;
+ HP_rst <= 1;
+ end
+ end
+
+ // control for dout1
+always @(posedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ dout1 <= 0;
+ end
+ else
+ if (ena)
+ begin
+ case (count[1:0])
+ 3: dout1 <= MD_dout[31:24];
+ 0: dout1 <= MD_dout[23:16];
+ 1: dout1 <= MD_dout[15:8];
+ 2: dout1 <= MD_dout[7:0];
+ endcase
+ end
+ end
+
+ // control for HP_xoffset HP_yoffset
+always @(posedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ HP_xoffset <= 16; // default to no motion
+ HP_yoffset <= 16; // minx, miny from full pixel unit
+ end
+ else
+ if (ena)
+ begin
+ if (count == 508) // check value
+ begin
+ HP_xoffset <= MD_dout[21:16] - 1; // -1 to get search block
+ HP_yoffset <= MD_dout[5:0] - 1; // starting up and over 1
+ end
+ end
+ end
+
+ // control for mbln, mblnd
+always @(posedge clk or negedge rst) // check edge
+ begin
+ if (~rst)
+ begin
+ mbln <= 0;
+ mblnd <= 0;
+ mblndd <= 0;
+ end
+ else
+ if (ena)
+ begin // need if ~clk2?
+ if (clk2)
+ begin
+ clk_match = 1;
+ mblndd <= mblnd;
+ // mblnd <= mbln; din1 00s at 511
+ case (count)
+ 47-clk_match: mbln <= 0; // Cur and 1
+ 111-clk_match: mbln <= 5; // hp writes
+ 159-clk_match: mbln <= 1; // 2 and 3
+ 223-clk_match: mbln <= 5; // hp writes
+ 271-clk_match: mbln <= 2; // 4 and 5
+ 335-clk_match: mbln <= 5; // hp writes
+ 383-clk_match: mbln <= 3; // 6 and 7
+ 447-clk_match: mbln <= 4; // 8 and 9
+ 511-clk_match: mbln <= 5; // hp writes
+ endcase
+ end
+ else
+ begin
+ mblnd <= mbln; // mblnd <= mbln din2 00s at
+ end
+ end
+ end
+
+ // control for frame_cur
+always @(posedge clk or negedge rst) // check edge
+ begin
+ if (~rst)
+ begin
+ frame_cur <= 0;
+ end
+ else
+ if (ena)
+ begin // need if ~clk2?
+ if (~clk2)
+ begin
+ case (count)
+ 45:
+ begin
+ if(iny_cnt > 15)
+ frame_cur <= frame; // first read for cur
+ else // uses frame currently
+ frame_cur <= ~frame; // loading unless last
+ end // row
+ endcase
+ end
+ end
+ end
+
+// address control for off chip memories control
+always @(posedge clk or negedge rst)
+ begin
+ if (~rst)
+ begin
+ address_1 <= 0;
+ mecount <= 0;
+ end
+ else
+ if (ena)
+ begin
+ clk_match = 1;
+ if (~clk2)
+ begin
+ case (count)
+ 47-clk_match: // Writes for CUR and 1 for next macroblock
+ begin
+ address_1[16:16] <= frame_cur;
+ address_1[15:0] <= addr_cur;
+ mecount <=0;
+ end
+ 159-clk_match: // Writes for 2 and 3 for next macroblock
+ begin
+ address_1[16:16] <= ~frame_cur;
+ address_1[15:0] <= addr_cur - yblkoffset; // Block 2
+ mecount <=0;
+ end
+ 271-clk_match: // Writes for 4 and 5 for next macroblock
+ begin
+ address_1[16:16] <= ~frame_cur;
+ address_1[15:0] <= addr_cur; // Block 5 is MD_din1
+ mecount <=0;
+ end
+ 383-clk_match: // Writes for 6 and 7 for next macroblock
+ begin
+ address_1[16:16] <= ~frame_cur;
+ address_1[15:0] <= addr_cur + 4; // Block 6
+ mecount <=0;
+ end
+ 447-clk_match: // Writes for 8 and 9 for next macroblock
+ begin
+ address_1[16:16] <= ~frame_cur;
+ address_1[15:0] <= addr_cur + yblkoffset; // Block 8
+ mecount <=0;
+ end
+ default:
+ begin
+ mecount <= mecount +1;
+ case (mbln)
+ 0: address_1[16:16] <= frame_cur;
+ 5: address_1[16:16] <= hp_frame_cur;
+ default: address_1[16:16] <= ~frame_cur;
+ endcase
+ case (mbln)
+ 0: begin // block 1 to cur
+ if (address_1[1:0] == 3)
+ address_1[15:0] <= address_1[15:0] + yblkoffset + ylinoffset + 1;
+ else
+ address_1[15:0] <= address_1[15:0] + yblkoffset + 5;
+ end
+ 1: begin // block 3 to 2
+ if (address_1[1:0] == 3)
+ address_1[15:0] <= address_1[15:0] + ylinoffset - 7;
+ else
+ address_1[15:0] <= address_1[15:0] - 3;
+ end
+ 2: begin // block 4 to 5
+ if (address_1[1:0] == 3)
+ address_1[15:0] <= address_1[15:0] + ylinoffset + 1;
+ else
+ address_1[15:0] <= address_1[15:0] + 5;
+ end
+ 3: begin // block 7 to 6
+ if (address_1[1:0] == 3)
+ address_1[15:0] <= address_1[15:0] - yblkoffset + ylinoffset + 5;
+ else
+ address_1[15:0] <= address_1[15:0] - yblkoffset + 9;
+ end
+ 4: begin // block 9 to 8
+ if (address_1[1:0] == 3)
+ address_1[15:0] <= address_1[15:0] + ylinoffset - 7;
+ else
+ address_1[15:0] <= address_1[15:0] - 3;
+ end
+ 5: address_1[15:0] <= hp_addr_cur;
+ endcase
+ end
+ endcase
+ end // if(~clk2)
+ else
+ begin
+ mecount <= mecount +1;
+ case (mbln)
+ 5: address_1[16:16] <= ~hp_frame_cur;
+ default: address_1[16:16] <= ~frame_cur; // search blocks 1 3 5 7 9
+ endcase
+ case (mbln)
+ 0: address_1[15:0] <= address_1[15:0] - yblkoffset - 4;
+ 1: address_1[15:0] <= address_1[15:0] + 4;
+ 2: address_1[15:0] <= address_1[15:0] - 4;
+ 3: address_1[15:0] <= address_1[15:0] + yblkoffset - 8;
+ 4: address_1[15:0] <= address_1[15:0] + 4;
+ 5: address_1[15:0] <= hp_addr_srch_d;
+ endcase
+ end
+ end // if(ena)
+ end // always
+
+endmodule
Index: branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlockTest.v
===================================================================
--- branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlockTest.v (revision 14)
+++ branches/avendor/macroblock_motion_detection/FrametoMacroBlock/FrametoMacroBlockTest.v (revision 15)
@@ -1,37 +1,37 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// FrametoMacroblockTest.v ////
-//// ////
-//// Test bench for FrametoMacroBlock.v ////
-//// ////
-//// This file reads data from files and feeds data to ////
-//// FrametoMacroBlock.v The test files were generated ////
-//// using an MPEG decode program. The files are separated ////
-//// by component (YUV) and the U and V components are 1/4 ////
-//// the size of the Y files. U and V data is upsampled to ////
-//// simulate high end 4:2:2 camera output and sent to the ////
-//// frame management module one component (8-bits) at a time. ////
-//// ////
-//// Simulation time in Modelsim Xilinx Starter Edition on ////
-//// a Pentium 1.4 is about an 1 1/2 hours for 5 9x5 ////
-//// macroblock frames. ////
-//// ////
-//// Note that outputs for the first frame are not valid ////
-//// since there is no previous frame in memory. Valid ////
-//// processing begins after the full 0 row of the second ////
-//// frame has been loaded. The motion vectors are ////
-//// offset in a 9x9 Macroblock area. Macroblocks with best ////
-//// match at current location will generate motion vector ////
-//// (16,16) -- the upper left corner of the center block. ////
-//// ////
-//// Timing is meant to match up with CCIR601 27MHz clock. ////
-//// 9x5 macroblock frame (1/29.33 of 704x480) takes up ////
-//// 853uS. With horizontal and vertical synch time, size ////
-//// of NTSC is 858x525. ////
-//// 853uS * 29.33 * 858/704 * 525/480 * 29.97 f/s = 1.0001s ////
-//// ////
-//// The first valid output is (17,16) ////
-//// ////
+//// ////
+//// Test bench for FrametoMacroBlock.v ////
+//// ////
+//// This file reads data from files and feeds data to ////
+//// FrametoMacroBlock.v The test files were generated ////
+//// using an MPEG decode program. The files are separated ////
+//// by component (YUV) and the U and V components are 1/4 ////
+//// the size of the Y files. U and V data is upsampled to ////
+//// simulate high end 4:2:2 camera output and sent to the ////
+//// frame management module one component (8-bits) at a time. ////
+//// ////
+//// Simulation time in Modelsim Xilinx Starter Edition on ////
+//// a Pentium 1.4 is about an 1 1/2 hours for 5 9x5 ////
+//// macroblock frames. ////
+//// ////
+//// Note that outputs for the first frame are not valid ////
+//// since there is no previous frame in memory. Valid ////
+//// processing begins after the full 0 row of the second ////
+//// frame has been loaded. The motion vectors are ////
+//// offset in a 9x9 Macroblock area. Macroblocks with best ////
+//// match at current location will generate motion vector ////
+//// (16,16) -- the upper left corner of the center block. ////
+//// ////
+//// Timing is meant to match up with CCIR601 27MHz clock. ////
+//// 9x5 macroblock frame (1/29.33 of 704x480) takes up ////
+//// 853uS. With horizontal and vertical synch time, size ////
+//// of NTSC is 858x525. ////
+//// 853uS * 29.33 * 858/704 * 525/480 * 29.97 f/s = 1.0001s ////
+//// ////
+//// The first valid output is (17,16) ////
+//// ////
//// Author: James Edgar ////
//// JamesSEDgar@Hotmail.com ////
//// ////
@@ -58,197 +58,168 @@
//// 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
-
-// Defines for file access for test frames
+//synopsys translate_on
+
+// Defines for file access for test frames
`define EOF 32'hFFFF_FFFF
`define NULL 0
-`define MAX_LINE_LENGTH 1000
-
-module FrametoMacroBlock_Test_v_tf();
-
-// DATE: 00:27:37 09/04/2004
-// MODULE: FrametoMacroBlock
-// DESIGN: FrametoMacroBlock
-// FILENAME: FrametoMacroBlockTest.v
-// PROJECT: Macroblock_Motion_Detection
-// VERSION:
-
-// parameters
-
-parameter frame_width = 144; //352; // currently must be multiple of 16 720
-parameter frame_height = 80; //196; // currently must be multiple of 16 480
-
- reg clk2; // half speed clock
- reg [8:0] count; // this is just to keep track of when motion vectors are available
-// Inputs
- reg clk;
- reg ena;
- reg rst;
- reg dstrb;
- reg dclr;
- reg [7:0] din1;
-
-// Outputs
- wire [7:0] dout1;
- wire douten;
-
-
-// Bidirs
-
-
-wire [16:0] address_0;
-wire [31:0] data_0;
-wire cs_0,we_0,oe_0;
-wire [16:0] address_1;
-wire [31:0] data_1;
-wire cs_1,we_1,oe_1;
-
-// Motion Detect wires
- wire MD_ena;
- wire MD_rst;
- wire [31:0] MD_din1, MD_din2;
- wire [3:0] MD_state;
- wire [8:0] MD_count;
-
-
-// Outputs
- wire [31:0] MD_dout;
-
-// Instantiate the UUT
- FrametoMacroBlock #(frame_width, frame_height)
- FrametoMacroBlock1 (
- .clk(clk),
- .ena(ena),
- .rst(rst),
- .dstrb(dstrb),
- .dclr(dclr),
- .din1(din1),
- .dout1(dout1),
- .douten(douten),
- .MD_ena(MD_ena),
- .MD_rst(MD_rst),
- .MD_din1(MD_din1),
- .MD_din2(MD_din2),
- .MD_dout(MD_dout),
- .MD_state(MD_state),
- .MD_count(MD_count),
-
- .address_0(address_0),
- .data_0(data_0),
- .cs_0(cs_0),
- .we_0(we_0),
- .oe_0(oe_0),
- .address_1(address_1),
- .data_1(data_1),
- .cs_1(cs_1),
- .we_1(we_1),
- .oe_1(oe_1)
-
- );
-
- // Instantiate the ram (Outside of FPGA, but all pins will connect to FPGA)
- ram_dp_sr_sw ram (
- .clk(clk),
- .address_0(address_0),
- .data_0(data_0),
- .cs_0(cs_0),
- .we_0(we_0),
- .oe_0(oe_0),
- .address_1(address_1),
- .data_1(data_1),
- .cs_1(cs_1),
- .we_1(we_1),
- .oe_1(oe_1)
- );
-
- // Instantiate Motion Detection Module
-
- MotionDetection MD (
- .clk(clk),
- .ena(MD_ena),
- .rst(MD_rst),
- .din1(MD_din1),
- .din2(MD_din2),
- .dout(MD_dout),
- .state(MD_state),
- .count(MD_count)
- );
-
-// Registers for file input
-
+`define MAX_LINE_LENGTH 1000
+
+module FrametoMacroBlock_Test_v_tf();
+
+// DATE: 00:27:37 09/04/2004
+// MODULE: FrametoMacroBlock
+// DESIGN: FrametoMacroBlock
+// FILENAME: FrametoMacroBlockTest.v
+// PROJECT: Macroblock_Motion_Detection
+// VERSION:
+
+// parameters
+
+parameter frame_width = 144; //352; // currently must be multiple of 16 720
+parameter frame_height = 80; //196; // currently must be multiple of 16 480
+
+ reg clk2; // half speed clock
+ reg [8:0] count; // this is just to keep track of when motion vectors are available
+// Inputs
+ reg clk;
+ reg ena;
+ reg rst;
+ reg dstrb;
+ reg dclr;
+ reg [7:0] din1;
+
+// Outputs
+ wire [7:0] dout1;
+ wire douten;
+ wire [31:0] HP_dout;
+
+// Bidirs
+
+
+wire [16:0] address_0;
+wire [31:0] data_0;
+wire cs_0,we_0,oe_0;
+wire [16:0] address_1;
+wire [31:0] data_1;
+wire cs_1,we_1,oe_1;
+
+
+ // Instantiate the ram (Outside of FPGA, but all pins will connect to FPGA)
+ ram_dp_sr_sw ram (
+ .clk(clk),
+ .address_0(address_0),
+ .data_0(data_0),
+ .cs_0(cs_0),
+ .we_0(we_0),
+ .oe_0(oe_0),
+ .address_1(address_1),
+ .data_1(data_1),
+ .cs_1(cs_1),
+ .we_1(we_1),
+ .oe_1(oe_1)
+ );
+
+// Instantiate the UUT
+ motion_detection_top #(frame_width, frame_height)
+ motion_detection_top (
+ .clk(clk),
+ .ena(ena),
+ .rst(rst),
+ .dstrb(dstrb),
+ .dclr(dclr),
+ .din1(din1),
+ .dout1(dout1),
+ .douten(douten),
+
+ .address_0(address_0),
+ .data_0(data_0),
+ .cs_0(cs_0),
+ .we_0(we_0),
+ .oe_0(oe_0),
+ .address_1(address_1),
+ .data_1(data_1),
+ .cs_1(cs_1),
+ .we_1(we_1),
+ .oe_1(oe_1),
+ .HP_dout(HP_dout)
+
+ );
+
+// Registers for file input
+
integer file, fileu, filev;
reg [3:0] bin;
- reg [31:0] dec, hex, uv;
- reg [9:0] countx, county;
+ reg [31:0] dec, hex, uv;
+ reg [9:0] countx, county;
reg uvflag,fill420flag;
real real_time;
reg [8*`MAX_LINE_LENGTH-1:0] line; /* Line of text read from file */
integer c, r, i;
- reg [8*7:1] name;
- reg [8*7:1] nameu;
- reg [8*7:1] namev;
- reg [8*72:1] dir;
- reg [8*79:1] full;
-
-// Initialize Inputs
-
-initial begin
- clk = 0;
- ena = 0;
- rst = 0;
- dstrb = 0;
- dclr = 0;
- din1 = 0;
- countx = 0;
- county = 0;
- @(posedge clk);
- rst <= 1;
- ena <= 1;
- // Read Frames from YUV files
- begin : file_block
- dir = "C:\\Documents and Settings\\user\\Desktop\\MPEG\\mpeg2v12\\src\\mpeg2dec\\Test2\\";
- name = "Vac10.Y";
- nameu = "Vac10.U";
- namev = "Vac10.V";
- while (name[23:17] < 53)
- begin
- $display("name[3]",name[24:17]);
- full = {dir,name};
- file = $fopen(full,"r");
- full = {dir,nameu};
- fileu = $fopen(full,"r");
- full = {dir,namev};
+ reg [8*7:1] name;
+ reg [8*7:1] nameu;
+ reg [8*7:1] namev;
+ reg [8*17:1] dir;
+ reg [8*79:1] full;
+
+// Initialize Inputs
+
+initial begin
+ clk = 0;
+ ena = 0;
+ rst = 0;
+ dstrb = 0;
+ dclr = 0;
+ din1 = 0;
+ countx = 0;
+ county = 0;
+ @(posedge clk);
+ rst <= 1;
+ ena <= 1;
+ // Read Frames from YUV files
+ begin : file_block
+ dir = ".\\SampleFrames\\"; //17
+ name = "Vac10.Y";
+ nameu = "Vac10.U";
+ namev = "Vac10.V";
+ while (name[23:17] < 50) // 50 = hex 32 -- process two frames
+ begin
+ $display("name[3]",name[24:17]);
+ full = {dir,name};
+ file = $fopen(full,"r");
+ full = {dir,nameu};
+ fileu = $fopen(full,"r");
+ full = {dir,namev};
filev = $fopen(full,"r");
if (file == `NULL)
- disable file_block;
- countx = 0;
- county = 0;
- uvflag <= 0;
+ disable file_block;
+ countx = 0;
+ county = 0;
+ uvflag <= 0;
fill420flag = 0;
c = $fgetc(file);
while (c != `EOF)
- begin
+ begin
/* Check the first character for comment */
if (c == "/")
r = $fgets(line, file);
@@ -256,112 +227,112 @@
begin // Read Y
// Push the character back to the file then read the next time
r = $ungetc(c, file);
- hex = $fgetc(file);
- end // if c else
- din1 <= hex;
- @(posedge clk); // two system clocks per input data
+ hex = $fgetc(file);
+ end // if c else
+ din1 <= hex;
+ @(posedge clk); // two system clocks per input data
+ @(posedge clk);
+
+ // read U or V
+ if (uvflag == 0)
+ begin
+ uv = $fgetc(fileu);
+ end
+ else
+ begin
+ uv = $fgetc(filev);
+ end
+ uvflag <= ~uvflag;
+ din1 <= uv;
+ if (countx == frame_width-1)
+ begin
+ countx <= 0;
+ county <= county+1;
+ if (county[0:0] == 1)
+ begin // read u and v lines twice to simulate 4:2:2
+ for (i=0; i < (frame_width >> 1); i=i+1)
+ begin
+ r = $ungetc(c, fileu);
+ r = $ungetc(c, filev);
+ end
+ end
+ end
+ else
+ begin
+ countx <= countx+1;
+ end
+ @(posedge clk);
@(posedge clk);
-
- // read U or V
- if (uvflag == 0)
- begin
- uv = $fgetc(fileu);
- end
- else
- begin
- uv = $fgetc(filev);
- end
- uvflag <= ~uvflag;
- din1 <= uv;
- if (countx == frame_width-1)
- begin
- countx <= 0;
- county <= county+1;
- if (county[0:0] == 1)
- begin // read u and v lines twice to simulate 4:2:2
- for (i=0; i < (frame_width >> 1); i=i+1)
- begin
- r = $ungetc(c, fileu);
- r = $ungetc(c, filev);
- end
- end
- end
- else
- begin
- countx <= countx+1;
- end
- @(posedge clk);
- @(posedge clk);
c = $fgetc(file);
end // while not EOF
- $fclose(file);
- $fclose(fileu);
- $fclose(filev);
- name[23:17] = name[23:17]+1;
- nameu[23:17] = nameu[23:17]+1;
- namev[23:17] = namev[23:17]+1;
- $display("full[3]",full[24:17]);
+ $fclose(file);
+ $fclose(fileu);
+ $fclose(filev);
+ name[23:17] = name[23:17]+1;
+ nameu[23:17] = nameu[23:17]+1;
+ namev[23:17] = namev[23:17]+1;
+ $display("full[3]",full[24:17]);
end
-
-
- end // frame loop
- $stop;
-end
+
+
+ end // frame loop
+ $stop;
+end
// Display changes to input signals
// always @(hex)
- // $display("This is one %h", hex, " U or V = %h " , uv);
-
+ // $display("This is one %h", hex, " U or V = %h " , uv);
+
// Display Y Macroblock input #
always @(county[4:4])
- $display("Y MacroBlock Input Row = %d ", county[9:4]);
-
+ $display("Y MacroBlock Input Row = %d ", county[9:4]);
+
// Display the motion vectors
- always @(posedge clk2)
- begin
- if (ena)
- begin
- if (count > 507) // motion vector output at 509 511
- begin
- if (dout1) // eliminates 0 0 from initialization cycle
- begin
- case (count)
- 509: $display("X offset is %d ", dout1);
- 511: $display("Y offset is %d ", dout1);
- endcase
- end
- end
- end
- end
-
+ always @(posedge clk2)
+ begin
+ if (ena)
+ begin
+ if (count > 507) // motion vector output at 509 511
+ begin
+ if (dout1) // eliminates 0 0 from initialization cycle
+ begin
+ case (count)
+ 509: $display("X offset is %d ", dout1);
+ 511: $display("Y offset is %d ", dout1);
+ endcase
+ end
+ end
+ end
+ end
+
// generate clock (54MHz)
- always #9.25926 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
-
-always @(posedge clk2 or negedge rst)
- begin
- if (~rst)
- begin
- count <= 0;
- end
- else
- if (ena)
- begin
- count <= count + 1;
- end
- end
-
-endmodule
-
+ always #9.25926 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
+
+always @(posedge clk2 or negedge rst)
+ begin
+ if (~rst)
+ begin
+ count <= 0;
+ end
+ else
+ if (ena)
+ begin
+ count <= count + 1;
+ end
+ end
+
+endmodule
+
Index: branches/avendor/macroblock_motion_detection/timescale.v
===================================================================
--- branches/avendor/macroblock_motion_detection/timescale.v (revision 14)
+++ branches/avendor/macroblock_motion_detection/timescale.v (revision 15)
@@ -1,2 +1,2 @@
-`timescale 1ns/10ps
-
+`timescale 1ns/10ps
+
Index: branches/avendor/macroblock_motion_detection/HalfPel/HalfPel.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: branches/avendor/macroblock_motion_detection/HalfPel/HalfPel.v
===================================================================
--- branches/avendor/macroblock_motion_detection/HalfPel/HalfPel.v (nonexistent)
+++ branches/avendor/macroblock_motion_detection/HalfPel/HalfPel.v (revision 15)
branches/avendor/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: branches/avendor/macroblock_motion_detection/HalfPel/HP_Block_Ram.v
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: branches/avendor/macroblock_motion_detection/HalfPel/HP_Block_Ram.v
===================================================================
--- branches/avendor/macroblock_motion_detection/HalfPel/HP_Block_Ram.v (nonexistent)
+++ branches/avendor/macroblock_motion_detection/HalfPel/HP_Block_Ram.v (revision 15)
branches/avendor/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: branches/avendor/macroblock_motion_detection/MD_Block_Ram.v
===================================================================
--- branches/avendor/macroblock_motion_detection/MD_Block_Ram.v (revision 14)
+++ branches/avendor/macroblock_motion_detection/MD_Block_Ram.v (revision 15)
@@ -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