A Color Vision System for Embedded Robotics Applications

Click here to return to article

Verilog FPGA Top Level




//=========================================================
//
//  DJ's video FPGA
//
//  Written By: Kenneth Y. Maxon - 03/17/2004
//
//=========================================================

module dj_vid_top(
	input wire [17:0] proc_addr,
	inout wire [7:0] proc_data,
	input wire proc_rw,
	output wire proc_irq,
	input wire proc_cs,
	input wire sys_clock,
	output wire test_led,

	inout wire [14:0] ram_data_io,
	output wire [19:1] ram_addr,
	output wire ram_we,
	output wire ram_oe,
	output wire ram_ce,

	output wire [14:0] disp_data,
	output wire disp_hsync,
	output wire disp_vsync,
	output wire disp_enable,
	output wire disp_clk,

	input wire video1_llc,
	input wire video1_hsync,
	input wire video1_vsync,
	input wire [14:0] video1_raw
	);

parameter DISPLAY_TOP_ADDR = 18'd153600;
parameter LED_ADDRESS = DISPLAY_TOP_ADDR + 18'h00001;
parameter RESET_ADDRESS = DISPLAY_TOP_ADDR + 18'h00002;
parameter DISPLAY_READY = DISPLAY_TOP_ADDR + 18'h00003;
parameter DISPLAY_STATUS = DISPLAY_TOP_ADDR + 18'h00004;
parameter BEGIN_CAP = DISPLAY_TOP_ADDR + 18'h00005;
parameter CLEAR_FIFO_ERROR = DISPLAY_TOP_ADDR + 18'h00006;
parameter VIDEO1_RED_UPPER = DISPLAY_TOP_ADDR + 18'h00007;
parameter VIDEO1_RED_LOWER = DISPLAY_TOP_ADDR + 18'h00008;
parameter VIDEO1_GREEN_UPPER = DISPLAY_TOP_ADDR + 18'h00009;
parameter VIDEO1_GREEN_LOWER = DISPLAY_TOP_ADDR + 18'h0000A;
parameter VIDEO1_BLUE_UPPER = DISPLAY_TOP_ADDR + 18'h0000B;
parameter VIDEO1_BLUE_LOWER = DISPLAY_TOP_ADDR + 18'h0000C;
parameter BLOBX1 = DISPLAY_TOP_ADDR + 18'h0000D;
parameter BLOBX2 = DISPLAY_TOP_ADDR + 18'h0000E;
parameter BLOBX3 = DISPLAY_TOP_ADDR + 18'h0000F;
parameter BLOBY1 = DISPLAY_TOP_ADDR + 18'h00011;
parameter BLOBY2 = DISPLAY_TOP_ADDR + 18'h00012;
parameter BLOBY3 = DISPLAY_TOP_ADDR + 18'h00013;

//-------------- local vars
reg test_led_reg;
reg [1:0] qual_counter;
wire qual_data;
wire force_reset;
//-------------- display vars
reg [7:0] proc_data_lower;
wire enable_disp_irq;
wire [17:0] disp_data_get_addr;
//-------------- RAM Scheduler
wire disp_data_get_strb;
wire fifo_error;
reg disp_ping_pong;
//-------------- video1 variables
reg [4:0] video1_red_upper;
reg [4:0] video1_red_lower;
reg [4:0] video1_green_upper;
reg [4:0] video1_green_lower;
reg [4:0] video1_blue_upper;
reg [4:0] video1_blue_lower;

wire [17:0] video1_addr;
wire [14:0] video1_data;
wire video1_store_strb;
wire [3:0] debug_state;
//-------------- capture module variables
wire blob_capture_done;
wire [23:0] blob1_x_out;
wire [23:0] blob1_y_out;
reg vid_cap_done;
wire data_valid;
//-------------- processor data output module variables
wire d_path7,d_path6,d_path5,d_path4,d_path3,d_path2,d_path1,d_path0;

//==============================================================
//
//  Mains Section:
//
//==============================================================

assign #1 proc_irq = 1'b1;

assign #1 qual_data = ((qual_counter[1:0] == 2'b01) && (~proc_rw));

assign #1 force_reset = (qual_data && (proc_addr[17:0] == RESET_ADDRESS));

always @(posedge sys_clock)
begin
	if(proc_cs)
		qual_counter[1:0] <= #1 2'b00;
	else
		qual_counter[1:0] <= qual_counter[1:0] + 2'b01;
end

assign #1 test_led = test_led_reg;

always @(posedge sys_clock)
	if((qual_data) && (proc_addr[17:0] == LED_ADDRESS))
		test_led_reg <= #1 proc_data[0];

//==============================================================
//
//  RAM Scheduler
//
//==============================================================

ram_scheduler my_sched(
			.sys_clock(sys_clock),
			.force_reset(force_reset),

			.proc_data_w({proc_data[6:0],proc_data_lower[7:0]}),  //defines 15 not 16 bits
			.qual2_data(qual_data && (proc_addr[17:0] < DISPLAY_TOP_ADDR) && ~proc_addr[0]),
			.proc_addr(proc_addr[17:1]),

			.disp_data_get_addr(disp_data_get_addr[17:0]),
			.disp_data_get_strb(disp_data_get_strb),
			.disp_data(disp_data[14:0]),

			.video1_addr(video1_addr[17:0]),
			.video1_data(video1_data[14:0]),
			.video1_store_strb(video1_store_strb),

			.disp_ping_pong(disp_ping_pong),

			.ram_we(ram_we),
			.ram_oe(ram_oe),
			.ram_ce(ram_ce),
			.ram_addr(ram_addr[19:1]),
			.ram_data_io(ram_data_io[14:0]),
			
			.fifo_error(fifo_error),
			.clear_fifo_error((qual_data) && (proc_addr[17:0] == CLEAR_FIFO_ERROR))
			);

always @(posedge sys_clock)
	if (force_reset)
		disp_ping_pong <= #1 1'b0;
	else if ((qual_data) && (proc_addr[17:0] == DISPLAY_READY) && (proc_data[0]))
     	disp_ping_pong <= #1 ~disp_ping_pong;

//==============================================================
//
//  Display interfaces
//
//==============================================================

always @(posedge sys_clock)
begin
	if(force_reset)
		proc_data_lower[7:0] <= 8'h00;
	else if(qual_data && (proc_addr[17:0] < DISPLAY_TOP_ADDR) && proc_addr[0])
		proc_data_lower[7:0] <= #1 proc_data[7:0];
end

disp_driver my_disp_driver(
			.proc_clock(sys_clock),
			.force_reset(force_reset),
			.disp_irq(enable_disp_irq),

			.addr_index_count(disp_data_get_addr[17:0]),
			
			.disp_hsync(disp_hsync),
			.disp_vsync(disp_vsync),
			.disp_enable(disp_enable),
			.disp_clk(disp_clk),
			.disp_data_get_strb(disp_data_get_strb)
			);

//==============================================================
//
//  Video Cap Interface
//
//==============================================================

always @(posedge sys_clock)
begin
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_RED_UPPER))
		video1_red_upper[4:0] <= #1 proc_data[4:0];
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_RED_LOWER))
		video1_red_lower[4:0] <= #1 proc_data[4:0];
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_GREEN_UPPER))
		video1_green_upper[4:0] <= #1 proc_data[4:0];
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_GREEN_LOWER))
		video1_green_lower[4:0] <= #1 proc_data[4:0];
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_BLUE_UPPER))
		video1_blue_upper[4:0] <= #1 proc_data[4:0];
	if ((qual_data) && (proc_addr[17:0] == VIDEO1_BLUE_LOWER))
		video1_blue_lower[4:0] <= #1 proc_data[4:0];
end

assign #1 data_valid = (
			(video1_raw[14:10] <= video1_red_upper[4:0]) &&
			(video1_raw[14:10] >= video1_red_lower[4:0]) &&
			(video1_raw[9:5] <= video1_green_upper[4:0]) &&
			(video1_raw[9:5] >= video1_green_lower[4:0]) &&
			(video1_raw[4:0] <= video1_blue_upper[4:0]) &&
			(video1_raw[4:0] >= video1_blue_lower[4:0]));

video_capture my_vid_cap1(
			.sys_clock(sys_clock),
			.force_reset(force_reset || ((qual_data) && (proc_addr[17:0] == CLEAR_FIFO_ERROR))),

			.begin_capture((qual_data) && (proc_addr[17:0] == BEGIN_CAP)),

			.video1_addr(video1_addr[17:0]),
			.video1_data_filtered(video1_data[14:0]),
			.video1_store_strb(video1_store_strb),

			.video1_llc(video1_llc),
			.video1_hsync(video1_hsync),
			.video1_vsync(video1_vsync),
			.video1_raw(video1_raw[14:0]),

			.blob1_x_out(blob1_x_out[23:0]),
			.blob1_y_out(blob1_y_out[23:0]),
			.blob_capture_done(blob_capture_done),
			.data_valid(data_valid),

			.debug_state(debug_state[3:0])
			);

always @(posedge sys_clock)
	if((qual_data) && (proc_addr[17:0] == BEGIN_CAP))
		vid_cap_done <= #1 1'b0;
	else if(blob_capture_done)
		vid_cap_done <= #1 1'b1;

//==============================================================
//
//  Processor Data Buss Output Section
//
//==============================================================

assign #1 d_path7 =
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[7])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[15])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[23])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[7])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[15])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[23])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (debug_state[3])));
			
assign #1 d_path6 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[6])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[14])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[22])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[6])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[14])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[22])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (debug_state[2])));
			
assign #1 d_path5 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[5])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[13])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[21])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[5])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[13])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[21])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (debug_state[1])));
			
assign #1 d_path4 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[4])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[12])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[20])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[4])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[12])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[20])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (debug_state[0])));
			
assign #1 d_path3 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[3])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[11])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[19])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[3])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[11])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[19])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (fifo_error)));
			
assign #1 d_path2 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[2])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[10])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[18])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[2])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[10])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[18])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (disp_ping_pong)));
			
assign #1 d_path1 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[1])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[9])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[17])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[1])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[9])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[17])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (enable_disp_irq)));
			
assign #1 d_path0 = 
			(((proc_addr[17:0] == BLOBX1) && (blob1_x_out[0])) ||
			((proc_addr[17:0] == BLOBX2) && (blob1_x_out[8])) ||
			((proc_addr[17:0] == BLOBX3) && (blob1_x_out[16])) ||
			((proc_addr[17:0] == BLOBY1) && (blob1_y_out[0])) ||
			((proc_addr[17:0] == BLOBY2) && (blob1_y_out[8])) ||
			((proc_addr[17:0] == BLOBY3) && (blob1_y_out[16])) ||
			((proc_addr[17:0] == DISPLAY_STATUS) && (vid_cap_done)));
			
assign #1	proc_data[7:0] = 
			((~proc_cs) && (proc_rw) &&
			((proc_addr[17:0] == DISPLAY_STATUS) ||
			(proc_addr[17:0] == BLOBX1) ||
			(proc_addr[17:0] == BLOBX2) ||
			(proc_addr[17:0] == BLOBX3) ||
			(proc_addr[17:0] == BLOBY1) ||
			(proc_addr[17:0] == BLOBY2) ||
			(proc_addr[17:0] == BLOBY3))) ? 
			{d_path7,d_path6,d_path5,d_path4,d_path3,d_path2,d_path1,d_path0} :
			8'bZZZZZZZZ;

endmodule

Click here to return to article