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

Subversion Repositories macroblock_motion_detection

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 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

powered by: WebSVN 2.1.0

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