📄 djv4.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0063)http://www.seattlerobotics.org/encoder/200601/article3/djv4.htm -->
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3243" name=GENERATOR></HEAD>
<BODY text=#000000 vLink=#000000 aLink=#0000ff link=#0000b0
bgColor=#008080><BASEFONT face=Arial color=#ffffff>
<CENTER>
<H2>A Color Vision System for Embedded Robotics Applications</H2></CENTER>
<CENTER>
<H2><A
href="http://www.seattlerobotics.org/encoder/200601/article3/index.php#djv"
target=main>Click here to return to article</CENTER></A>
<P>
<TABLE borderColor=#0080ff cellPadding=10 align=center
background=djv4.files/grid.gif border=10>
<TBODY>
<TR>
<TD><FONT color=black>
<CENTER>
<H4>Verilog FPGA Video Capture Code: </H4></CENTER>
<P><PRE>////////////////////////////////////////////////////
//
// Module Video Capture Written By: Kenneth Maxon
// On or about... March-2004 ...
//
////////////////////////////////////////////////////
module video_capture(
input wire sys_clock,
input wire force_reset,
input wire begin_capture,
output reg [17:0] video1_addr,
output wire [14:0] video1_data_filtered,
output reg video1_store_strb,
input wire video1_llc,
input wire video1_hsync,
input wire video1_vsync,
input wire [14:0] video1_raw,
output wire [23:0] blob1_x_out,
output wire [23:0] blob1_y_out,
output wire blob_capture_done,
input wire data_valid,
output reg [3:0] debug_state
);
reg video1_llc_reg;
reg video1_llc2_reg;
wire llc_edge_found;
reg video1_hsync_reg;
reg video1_hsync2_reg;
wire hsync_edge_found;
reg video1_vsync_reg;
reg video1_vsync2_reg;
wire vsync_edge_found;
reg [9:0] vid_cap_state_var;
reg [17:0] addr_index_count;
reg [14:0] video1_data;
reg [8:0] pixel_count;
reg [7:0] line_count;
reg end_of_screen_capture;
reg beginning_of_screen_capture;
always@(posedge sys_clock) // always double buffer across clock domains.
begin
video1_llc_reg <= #1 video1_llc;
video1_hsync_reg <= #1 video1_hsync;
video1_vsync_reg <= #1 video1_vsync;
video1_llc2_reg <= #1 video1_llc_reg;
video1_hsync2_reg <= #1 video1_hsync_reg;
video1_vsync2_reg <= #1 video1_vsync_reg;
end
assign #1 llc_edge_found = (~video1_llc2_reg & video1_llc_reg);
assign #1 hsync_edge_found = (~video1_hsync2_reg & video1_hsync_reg);
assign #1 vsync_edge_found = (~video1_vsync2_reg & video1_vsync_reg);
parameter[9:0]
DISPATCH_STATE = 10'b0000000001,
VID_CAP1_STATE = 10'b0000000010,
VID_CAP2_STATE = 10'b0000000100,
VID_CAP3_STATE = 10'b0000001000,
VID_CAP4_STATE = 10'b0000010000,
VID_CAP45_STATE = 10'b0000100000,
VID_CAP5_STATE = 10'b0001000000,
VID_CAP6_STATE = 10'b0010000000,
VID_CAP7_STATE = 10'b0100000000,
VID_CAP8_STATE = 10'b1000000000;
parameter[9:0]
DISPATCH_CASE = 10'bxxxxxxxxx1,
VID_CAP1_CASE = 10'bxxxxxxxx1x,
VID_CAP2_CASE = 10'bxxxxxxx1xx,
VID_CAP3_CASE = 10'bxxxxxx1xxx,
VID_CAP4_CASE = 10'bxxxxx1xxxx,
VID_CAP45_CASE = 10'bxxxx1xxxxx,
VID_CAP5_CASE = 10'bxxx1xxxxxx,
VID_CAP6_CASE = 10'bxx1xxxxxxx,
VID_CAP7_CASE = 10'bx1xxxxxxxx,
VID_CAP8_CASE = 10'b1xxxxxxxxx;
always @(posedge sys_clock or posedge force_reset)begin : vid_gen_state_fsm
if (force_reset)
vid_cap_state_var[9:0] <= #1 DISPATCH_STATE;
else begin
casex (vid_cap_state_var[9:0]) // synopsys parallel_case full_case
DISPATCH_CASE: // wait for processor to tell us to start
begin
if(begin_capture)
vid_cap_state_var[9:0] <= #1 VID_CAP1_STATE;
else
vid_cap_state_var[9:0] <= #1 DISPATCH_STATE;
end
VID_CAP1_CASE: // wait for vsync
begin
addr_index_count[17:0] <= #1 18'd01605;
line_count[7:0] <= #1 8'h00;
if(vsync_edge_found)
vid_cap_state_var[9:0] <= #1 VID_CAP2_STATE;
else
vid_cap_state_var[9:0] <= #1 VID_CAP1_STATE;
end
VID_CAP2_CASE: // wait for hsync
begin
pixel_count[8:0] <= #1 9'h000;
if(hsync_edge_found)
vid_cap_state_var[9:0] <= #1 VID_CAP3_STATE;
else
vid_cap_state_var[9:0] <= #1 VID_CAP2_STATE;
end
VID_CAP3_CASE: // wait for llc2 & latch in same state
begin
if(llc_edge_found)
begin
video1_addr[17:0] <= #1 addr_index_count[17:0];
video1_data[14:0] <= #1 video1_raw[14:0];
vid_cap_state_var[9:0] <= #1 VID_CAP4_STATE;
end
else
vid_cap_state_var[9:0] <= #1 VID_CAP3_STATE;
end
VID_CAP4_CASE: // send out data strobe to the RAM scheduler
begin
addr_index_count[17:0] <= addr_index_count[17:0] + 18'h00001;
pixel_count[8:0] <= #1 pixel_count[8:0] + 9'h001;
vid_cap_state_var[9:0] <= #1 VID_CAP45_STATE;
end
VID_CAP45_CASE: // skip every other pixel
begin
if(llc_edge_found)
vid_cap_state_var[9:0] <= #1 VID_CAP5_STATE;
else
vid_cap_state_var[9:0] <= #1 VID_CAP45_STATE;
end
VID_CAP5_CASE: // check to see if we are at the end of the line pixel wise
begin
if(pixel_count[8:0] < 9'd310)
vid_cap_state_var[9:0] <= #1 VID_CAP3_STATE;
else
vid_cap_state_var[9:0] <= #1 VID_CAP6_STATE;
end
VID_CAP6_CASE: // add the rest of the address to the address counter to make up for rest of the line
begin
addr_index_count[17:0] <= addr_index_count[17:0] + 18'd010;
line_count[7:0] <= line_count[7:0] + 8'd01;
vid_cap_state_var[9:0] <= #1 VID_CAP7_STATE;
end
VID_CAP7_CASE: // check to see if we're at the end of the screen
begin
if(line_count[7:0] < 8'd230)
vid_cap_state_var[9:0] <= #1 VID_CAP2_STATE;
else
vid_cap_state_var[9:0] <= #1 VID_CAP8_STATE;
end
VID_CAP8_CASE: // done
begin
vid_cap_state_var[9:0] <= #1 DISPATCH_STATE;
end
endcase
end
end // video_gen_state_fsm
always @(vid_cap_state_var[9:0])begin : vid_gen_state_assn
casex (vid_cap_state_var[9:0]) // synopsys parallel_case full_case
DISPATCH_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'ha;
beginning_of_screen_capture = 1'h1;
end_of_screen_capture = 1'b0;
end
VID_CAP1_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h2;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP2_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h3;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP3_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h4;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP4_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h5;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP45_CASE:
begin
video1_store_strb = 1'b1;
debug_state[3:0] = 4'h6;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP5_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h7;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP6_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h8;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP7_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'h9;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b0;
end
VID_CAP8_CASE:
begin
video1_store_strb = 1'b0;
debug_state[3:0] = 4'ha;
beginning_of_screen_capture = 1'h0;
end_of_screen_capture = 1'b1; // used to trigger blob calculation
end
endcase
end //video_gen_state_assn
assign #1 video1_data_filtered[14:0] = data_valid ?
video1_data[14:0] :
15'h0000;
blob_detection my_blob_detector(
.sys_clock(sys_clock),
.force_reset(force_reset),
.line_count(line_count[7:0]),
.pixel_count(pixel_count[8:0]),
.video1_out_strb(video1_store_strb),
.video_filter_data_valid(data_valid),
.end_of_screen_capture(end_of_screen_capture),
.beginning_of_screen_capture(beginning_of_screen_capture),
.x_output(blob1_x_out[23:0]),
.y_output(blob1_y_out[23:0]),
.blob_capture_done(blob_capture_done)
);
endmodule
</PRE></FONT></TR></TBODY></TABLE>
<P>
<CENTER>
<H2><A
href="http://www.seattlerobotics.org/encoder/200601/article3/index.php#djv"
target=main>Click here to return to
article</CENTER></A></H2></H2></BASEFONT></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -