Professional Documents
Culture Documents
//author :
//date
:
motion_estimation.v
Ray Luo
2007.12.25
module motion_estimation(
clk_sys,
rst_n,
frm_start,
frm_cf_d,
frm_pf_da,
frm_pf_db,
frm_cf_addr,
frm_cf_rd,
frm_pf_addra,
frm_pf_rda,
frm_pf_addrb,
frm_pf_rdb,
vect_row,
vect_col
);
input
input
input
input
input
input
output
output
output
output
output
output
output
output
clk_sys;
rst_n;
frm_start;
[7:0] frm_cf_d;
[7:0] frm_pf_da;
[7:0] frm_pf_db;
[15:0] frm_cf_addr;
frm_cf_rd;
[15:0] frm_pf_addra;
frm_pf_rda;
[15:0] frm_pf_addrb;
frm_pf_rdb;
[2:0] vect_row;
[2:0] vect_col;
wire
wire
wire
wire
[7:0]
wire
[7:0]
wire
[7:0]
reg
[15:0]
ram
reg
[15:0]
sram
reg
[15:0]
sram
reg
[2:0]
or transmit
reg
[2:0]
for transmit
reg
[15:0]
lock
reg
[8:0]
t blok
reg
reg
reg
clk_sys;
rst_n;
frm_start;
frm_cf_d;
frm_pf_da;
frm_pf_db;
frm_cf_addr;
frm_pf_addra;
frm_pf_addrb;
vect_row;
vect_col;
blk_row;
blk_col;
frm_cf_rd;
frm_pf_rda;
frm_pf_rdb;
reg
[8:0]
previous frame
reg
[8:0]
previous frame
reg
[8:0]
current frame
reg
[8:0]
e
reg
[2:0]
reg
reg
blk_i_starta;
a
blk_i_startb;
b
blk_i_startc;
blk_j_start;
blk_i_cnt8;
[11:0] srh_l_addr_cnta;
[11:0] srh_l_addr_cntb;
reg
window
srh_win_en;
reg
srh_win_enda;
calculate a
reg
srh_win_endb;
calculate b
reg
[11:0] srh_blkaddr_lstarta;
n the search window a
reg
[11:0] srh_blkaddr_lstartb;
n the search window b
reg
[2:0] srh_blk_lstarta;
earch window a
reg
[2:0] srh_blk_lstartb;
earch window a
reg
[2:0] srh_lstartb_ff;
n the search window b
reg
reg
[15:0]
previous frame
reg
[15:0]
previous frame
reg
[15:0]
rrent frame
frm_start_ff ;
blk_jaddr_starta;
blk_jaddr_startb;
blk_jaddr_startc;
reg
[11:0] blk_jaddr_cnt8;
reg
[2:0] srh_lblk_cnt;
ch window
reg
pf_da_sam_en;
reg
pf_db_sam_en;
pf_da0;
pf_da1;
pf_da2;
pf_da3;
pf_da4;
pf_da5;
pf_da6;
reg
read
reg
read
reg
read
reg
read
reg
read
reg
read
reg
[7:0]
a address
[7:0]
a address
[7:0]
a address
[7:0]
a address
[7:0]
a address
[7:0]
a address
[7:0]
read
reg
read
reg
read
reg
read
reg
read
reg
read
reg
read
reg
read
reg
a address
[7:0]
b address
[7:0]
b address
[7:0]
b address
[7:0]
b address
[7:0]
b address
[7:0]
b address
[7:0]
b address
[7:0]
reg
ame
reg
ame
reg
ame
reg
ame
reg
ame
reg
ame
reg
ame
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
reg
b
reg
b
reg
b
reg
b
pf_db0;
pf_db1;
pf_db2;
pf_db3;
pf_db4;
pf_db5;
pf_db6;
cf_d;
[7:0]
pf_d0;
[7:0]
pf_d1;
[7:0]
pf_d2;
[7:0]
pf_d3;
[7:0]
pf_d4;
[7:0]
pf_d5;
[7:0]
pf_d6;
[8:0]
[8:0]
[8:0]
[8:0]
[8:0]
[8:0]
[8:0]
[7:0]
[7:0]
[7:0]
[7:0]
[7:0]
[7:0]
[7:0]
[13:0]
[13:0]
[13:0]
[13:0]
[13:0]
[13:0]
[13:0]
[13:0]
cf_sub_pf0;
cf_sub_pf1;
cf_sub_pf2;
cf_sub_pf3;
cf_sub_pf4;
cf_sub_pf5;
cf_sub_pf6;
abs_sub0;
abs_sub1;
abs_sub2;
abs_sub3;
abs_sub4;
abs_sub5;
abs_sub6;
acc_abs_sub0;
acc_abs_sub1;
acc_abs_sub2;
acc_abs_sub3;
acc_abs_sub4;
acc_abs_sub5;
acc_abs_sub6;
acc_abs_sub_ff0;
[13:0] acc_abs_sub_ff1;
[13:0] acc_abs_sub_ff2;
[13:0] acc_abs_sub_ff3;
reg
[13:0]
b
reg
[13:0]
b
reg
[13:0]
b
reg
[13:0]
reg
[13:0]
reg
reg
[3:0]
in the window
reg
[3:0]
in the window
reg
reg
acc_abs_sub_ff4;
acc_abs_sub_ff5;
acc_abs_sub_ff6;
comp_acc_op;
comp_acc_abs;
comp_acc_en ;
srh_ka_cnt;
srh_kb_cnt;
srh_kb_cnt_en;
srh_kb_cnt_en_ff;
reg
b_cnt
reg
[2:0]
srh_k_sel;
comp_cnt;
reg
reg
reg
reg
reg
[15:0]
[15:0]
[7:0]
[7:0]
srh_win_laddra;
srh_win_laddrb;
srh_win_kaddra;
srh_win_kaddrb;
srh_array_end;
reg
reg
[2:0]
srh_win_end_cnt;
srh_win_end_cnt_en;
blk_i_cnt8_en;
i;
reg
integer
if (!rst_n)
blk_jaddr_cnt8 <= 12'd0;
else if ((blk_jaddr_cnt8 ==12'd2464)&(blk_i_cnt8==3'b111))
blk_jaddr_cnt8 <= 12'd0;
else if (blk_i_cnt8==3'b111)
blk_jaddr_cnt8 <= blk_jaddr_cnt8 +9'd352;
end
//generate the address of current frame
always @(posedge clk_sys)
begin
if (!rst_n)
frm_cf_addr <= 16'h00000;
else
frm_cf_addr <= blk_jaddr_startc + blk_jaddr_cnt8 + blk_i_cnt8 + blk_i_star
tc;
end
//******************************************************************************
*****************//
//******************************************************************************
*****************//
//******************************************************************************
*****************//
//******************************************************************************
*****************//
_l_addr_cnta;
end
always @(blk_jaddr_startb or srh_blkaddr_lstartb or srh_l_addr_cntb)
begin
if ((blk_jaddr_startb + srh_blkaddr_lstartb + srh_l_addr_cntb) < 11'd1056)
srh_win_laddrb = 16'd0;
else if ((blk_jaddr_startb+srh_blkaddr_lstartb+srh_l_addr_cntb)>16'd98560)
srh_win_laddrb = 16'd98560;
else
srh_win_laddrb = blk_jaddr_startb - 11'd1056 + srh_blkaddr_lstartb + srh
_l_addr_cntb;
end
//generate search window row address
always @(blk_i_starta or srh_ka_cnt)
begin
if ((blk_i_starta + srh_ka_cnt ) < 2'd3)
srh_win_kaddra = 9'd0;
else if ((blk_i_starta + srh_ka_cnt ) > 9'd351)
srh_win_kaddra = 9'd351;
else
srh_win_kaddra = blk_i_starta + srh_ka_cnt -2'd3;
end
always @(blk_i_startb or srh_kb_cnt)
begin
if ((blk_i_startb + srh_kb_cnt ) < 2'd3)
srh_win_kaddrb = 9'd10;
else if ((blk_i_startb + srh_kb_cnt ) > 9'd351)
srh_win_kaddrb = 9'd351;
else
srh_win_kaddrb = blk_i_startb + srh_kb_cnt -2'd3;
end
//generate the addressa of previous frame
always @(posedge clk_sys)
begin
if (!rst_n)
frm_pf_addra <= 16'h00000;
else
frm_pf_addra <= srh_win_laddra + srh_win_kaddra;
end
always @(posedge clk_sys)
begin
if (!rst_n)
frm_pf_addrb <= 16'd352;
else
frm_pf_addrb <= srh_win_laddrb + srh_win_kaddrb;
end
//generate the first row address increment of each block in the window
always @(posedge clk_sys)
begin
if (!rst_n)
begin
srh_blkaddr_lstarta <= 12'd0;
srh_blk_lstarta <= 3'd0;
end
else if (srh_win_enda)
begin
srh_blkaddr_lstarta <= 12'd0;
srh_blk_lstarta <= 3'd0;
end
else if ((srh_win_en)&(srh_ka_cnt==4'b1111))
begin
if (srh_lblk_cnt==3'b110)
begin
srh_blkaddr_lstarta <= srh_blkaddr_lstarta +9'd352;
srh_blk_lstarta <= srh_blk_lstarta + 1'b1;
end
end
end
always @(posedge clk_sys)
begin
if (!rst_n)
begin
srh_blkaddr_lstartb <= 12'd0;
srh_blk_lstartb <= 3'd0;
end
else if ((srh_win_en)&(srh_ka_cnt==4'b0111))
begin
srh_blkaddr_lstartb <= srh_blkaddr_lstarta;
srh_blk_lstartb <= srh_blk_lstarta;
end
end
//gernerate the search window end signal
always @(srh_lblk_cnt or srh_ka_cnt or srh_win_en or srh_blkaddr_lstarta)
begin
srh_win_enda = ((srh_win_en)&(srh_lblk_cnt==3'b110)&(srh_ka_cnt==4'b1111)&(s
rh_blkaddr_lstarta==12'd2112));
end
always @(srh_lblk_cnt or srh_kb_cnt or srh_win_en or srh_blkaddr_lstartb)
begin
srh_win_endb = ((srh_win_en)&(srh_lblk_cnt==3'b111)&(srh_kb_cnt==4'b1111)&(s
rh_blkaddr_lstartb==12'd2112));
end
//generate the one array block end signal
always @(srh_win_en or srh_lblk_cnt or srh_kb_cnt)
begin
srh_array_end = ((srh_win_en)&(srh_lblk_cnt==3'b111)&(srh_kb_cnt==4'b1111));
end
//******************************************************************************
*****************//
//******************************************************************************
*****************//
//******************************************************************************
*****************//
//******************************************************************************
*****************//
pf_d0;
pf_d1;
pf_d2;
pf_d3;
pf_d4;
pf_d5;
pf_d6;
//absolute
always @(cf_sub_pf0 or cf_sub_pf1 or cf_sub_pf2 or cf_sub_pf3 or cf_sub_pf4 or c
f_sub_pf5 or cf_sub_pf6)
begin
abs_sub0 =cf_sub_pf0[8] ? (~cf_sub_pf0[7:0]+1'b1) : cf_sub_pf0[7:0];
abs_sub1 =cf_sub_pf1[8] ? (~cf_sub_pf1[7:0]+1'b1) : cf_sub_pf1[7:0];
abs_sub2 =cf_sub_pf2[8] ? (~cf_sub_pf2[7:0]+1'b1) : cf_sub_pf2[7:0];
abs_sub3 =cf_sub_pf3[8] ? (~cf_sub_pf3[7:0]+1'b1) : cf_sub_pf3[7:0];
abs_sub4 =cf_sub_pf4[8] ? (~cf_sub_pf4[7:0]+1'b1) : cf_sub_pf4[7:0];
abs_sub5 =cf_sub_pf5[8] ? (~cf_sub_pf5[7:0]+1'b1) : cf_sub_pf5[7:0];
abs_sub6 =cf_sub_pf6[8] ? (~cf_sub_pf6[7:0]+1'b1) : cf_sub_pf6[7:0];
end
//accumulation
always @(posedge clk_sys)
begin
if (!rst_n)
begin
acc_abs_sub0 <= 14'h0000;
acc_abs_sub1 <= 14'h0000;
acc_abs_sub2 <= 14'h0000;
acc_abs_sub3 <= 14'h0000;
acc_abs_sub4 <= 14'h0000;
acc_abs_sub5 <= 14'h0000;
acc_abs_sub6 <= 14'h0000;
end
else if (srh_kb_cnt_en_ff)
begin
if (srh_array_end)
begin
acc_abs_sub0 <=
acc_abs_sub1 <=
acc_abs_sub2 <=
acc_abs_sub3 <=
acc_abs_sub4 <=
acc_abs_sub5 <=
acc_abs_sub6 <=
end
else
begin
acc_abs_sub0 <=
acc_abs_sub1 <=
acc_abs_sub2 <=
acc_abs_sub3 <=
acc_abs_sub4 <=
acc_abs_sub5 <=
acc_abs_sub6 <=
end
14'h0000;
14'h0000;
14'h0000;
14'h0000;
14'h0000;
14'h0000;
14'h0000;
acc_abs_sub0
acc_abs_sub1
acc_abs_sub2
acc_abs_sub3
acc_abs_sub4
acc_abs_sub5
acc_abs_sub6
end
+
+
+
+
+
+
+
end
//register the accumulation
always @(posedge clk_sys)
begin
if (!rst_n)
begin
acc_abs_sub_ff0 <= 14'h0000;
acc_abs_sub_ff1 <= 14'h0000;
acc_abs_sub_ff2 <= 14'h0000;
acc_abs_sub_ff3 <= 14'h0000;
acc_abs_sub_ff4 <= 14'h0000;
acc_abs_sub_ff5 <= 14'h0000;
acc_abs_sub_ff6 <= 14'h0000;
end
else if (srh_array_end)
begin
acc_abs_sub_ff0 <= acc_abs_sub0;
acc_abs_sub_ff1 <= acc_abs_sub1;
acc_abs_sub_ff2 <= acc_abs_sub2;
acc_abs_sub_ff3 <= acc_abs_sub3;
acc_abs_sub_ff4 <= acc_abs_sub4;
acc_abs_sub_ff5 <= acc_abs_sub5;
acc_abs_sub_ff6 <= acc_abs_sub6;
end
end
//generate the enable signal for comp_acc
always @(posedge clk_sys)
begin
if (!rst_n)
comp_acc_en <= 1'b0;
else if (srh_array_end)
comp_acc_en <= 1'b1;
else if (comp_cnt==3'b110)
comp_acc_en <= 1'b0;
end
always @(posedge clk_sys)
abs_sub0;
abs_sub1;
abs_sub2;
abs_sub3;
abs_sub4;
abs_sub5;
abs_sub6;
begin
if (!rst_n)
comp_cnt <= 3'b000;
else if (comp_acc_en)
begin
if (comp_cnt==3'b110)
comp_cnt <= 3'b000;
else
comp_cnt <= comp_cnt + 1'b1;
end
end
always @(comp_cnt or acc_abs_sub_ff0 or acc_abs_sub_ff1 or acc_abs_sub_ff2 or ac
c_abs_sub_ff3 or acc_abs_sub_ff4 or acc_abs_sub_ff5 or acc_abs_sub_ff6)
begin
case(comp_cnt)
3'b000 :
comp_acc_op = acc_abs_sub_ff0;
3'b001 :
comp_acc_op = acc_abs_sub_ff1;
3'b010 :
comp_acc_op = acc_abs_sub_ff2;
3'b011 :
comp_acc_op = acc_abs_sub_ff3;
3'b100 :
comp_acc_op = acc_abs_sub_ff4;
3'b101 :
comp_acc_op = acc_abs_sub_ff5;
3'b100 :
comp_acc_op = acc_abs_sub_ff6;
default :
comp_acc_op = acc_abs_sub_ff0;
endcase
end
always @(posedge clk_sys)
begin
if (!rst_n)
comp_acc_abs <= 14'h3fff;
else if (comp_acc_en)
begin
if (comp_acc_abs >comp_acc_op)
comp_acc_abs <= comp_acc_op;
end
else if (srh_win_end_cnt==3'b111)
comp_acc_abs <= 14'h3fff;
end
//generate the enable signal for srh_win_end_cnt
always @(posedge clk_sys)
begin
if (!rst_n)
srh_win_end_cnt_en <= 1'b0;
else if (srh_win_endb)
srh_win_end_cnt_en <= 1'b1;
else if (srh_win_end_cnt==3'b111)
srh_win_end_cnt_en <= 1'b0;
end
always @(posedge clk_sys)
begin
if (!rst_n)
srh_win_end_cnt <= 3'b000;
else if (srh_win_end_cnt_en)
srh_win_end_cnt <= srh_win_end_cnt + 1'b1;
end