Based on FPGA: moving target detection (LCD display + serial port output, pure Verilog project)

foreword

      The earliest FPGA-based : moving target detection (VGA display, schematic diagram + source code + hardware selection) , some netizens responded that VGA has a large screen, it is very inconvenient to do, and the function is too single.
     Therefore, on the basis of the previous project, it is modified to TFT-LCD screen detection, and the detection results are output to the computer host computer through the serial port, so that everyone can do extended development.

First, look at the effect

      Not much to say, first watch the video to see the effect.

FPGA-based moving target detection (LCD display-serial port output)

2. Hardware selection

Development board Altera: EP4CE6F17C8 (compatible with E10)
Camera: OV5640
Screen: TFT-LCD
cache data: SDRAM
board is self-made

3. System framework

      Before the image acquisition of this system, because the frequency of the onboard crystal oscillator is inconsistent with that of the camera module and the TFT-LCD module, it is necessary to design the phase-locked loop module to output a clock signal consistent with that of the OV5640 camera before the system works. After the clock is input, configure the registers according to the manual of OV5640, so that the working mode of OV5640 meets the design requirements of this system. The image collected by the CMOS sensor enters the image processing module, and outputs the grayscale of the current frame for writing into SDRAM. At the same time, read out the gray level of the previous frame from SDRAM (one clock cycle difference from the current output) and re-enter the image processing module for frame difference image processing (that is, processing related to moving target detection).
      In this system, when the selection function is satisfied, the real-time performance is required, so only one video stream is selected to be input. And according to the different clock domains, an asynchronous FIFO is designed to complete the data transmission buffer. Finally, the processing result is displayed on the screen through the ILI9488 driver module, and the detection information is output to the host computer through the serial port.

insert image description here

4. Program module

      Code framework: This design basically uses pure Verilog design, using less IP, such as: PLL, FIFO. The code is accompanied by comments, which is highly readable and easy for everyone to transplant, participate in competitions, and complete the project.

insert image description here
      Some module simulations:

insert image description hereinsert image description here

1. Top-level module of the system

module dmk_photo_uart(
	input                       clk,
	input                       rst_n,             //KEY4(o) 即OK按键作为复位

	//CMOS Port
	inout                       cmos_scl,          //cmos i2c clock
	inout                       cmos_sda,          //cmos i2c data
	input                       cmos_vsync,        //cmos vsync
	input                       cmos_href,         //cmos hsync refrence,data valid
	input                       cmos_pclk,         //cmos pxiel clock
	output                      cmos_xclk,         //cmos externl clock
	input   [7:0]               cmos_db,           //cmos data
	output                      cmos_rst_n,        //cmos reset
	output                      cmos_pwdn,         //cmos power down
    
	//LCD ILI9488 Port
	output             			WR,
	output             			RD, 
	output             			CS,
	output             			RS,
	output             			BL_cnt,
	output [15:0]      			data,
	output             			RESET,
    
	//LED
	output  [3:0]               led,
	
	//uart
	input                       uart_rxd,          //uart 串行数据接收
	output                      uart_txd,          //uart 串行数据发送	
    
	//SDRAM Port
	output                      sdram_clk,         //sdram clock
	output                      sdram_cke,         //sdram clock enable
	output                      sdram_cs_n,        //sdram chip select
	output                      sdram_we_n,        //sdram write enable
	output                      sdram_cas_n,       //sdram column address strobe
	output                      sdram_ras_n,       //sdram row address strobe
	output[1:0]                 sdram_dqm,         //sdram data enable
	output[1:0]                 sdram_ba,          //sdram bank address
	output[12:0]                sdram_addr,        //sdram address
	inout[15:0]                 sdram_dq           //sdram data
);

// parameter  CMOS_H_PIXEL = 24'd640    ;  //CMOS水平方向像素个数,用于设置SDRAM缓存大小
// parameter  CMOS_V_PIXEL = 24'd480     ;  //CMOS垂直方向像素个数,用于设置SDRAM缓存大小

parameter  CMOS_H_PIXEL = 24'd480    ;  //CMOS水平方向像素个数,用于设置SDRAM缓存大小
parameter  CMOS_V_PIXEL = 24'd320     ;  //CMOS垂直方向像素个数,用于设置SDRAM缓存大小

parameter  Diff_Threshold = 8'd40	  ;  //帧差检测阈值	

assign cmos_rst_n = 1'b1;
assign cmos_pwdn  = 1'b0;

wire clk_ref;
wire clk_refout;//sdram控制器100M工作时钟、给SDRAM芯片的100M时钟
wire clk_lcd_w; //LCD驱动模块工作时钟,12.5MHz
wire pll_lock_w;
wire sys_rst_n;
wire lcd_init_done;

//PLL模块
sys_pll u_sys_pll_0(
	.areset         (!rst_n),
	.inclk0         (clk),
    
	.c0             (clk_ref   ),//sdram控制器100M 工作时钟
	.c1             (clk_refout),//SDRAM芯片 100M 时钟
	.c2             (cmos_xclk),//CMOS XCLK 24M 时钟
	.c3             (clk_lcd_w),//LCD驱动模块工作时钟,12.5MHz
	.locked         (pll_lock_w)
	);
    
//延迟复位模块
delay_reset u_delay_reset_0(
    .clk            (clk),
	.rst_n          (rst_n && pll_lock_w && lcd_init_done),
    
	.reset_n        (sys_rst_n)
);

//摄像头I2C配置模块
ov5640_config    #(
     .CMOS_H_PIXEL      (CMOS_H_PIXEL),
     .CMOS_V_PIXEL      (CMOS_V_PIXEL)
    )  u_ov5640_config_0(
	.rst_n          (sys_rst_n),
	.clk            (clk),
    
	.i2c_scl        (cmos_scl),
	.i2c_sda        (cmos_sda)
	);
    
    
wire			cmos_frame_vsync;	 
wire			cmos_frame_href;	 
wire			cmos_frame_clken;	 
wire	[15:0]	cmos_frame_data;	 
                                     
//CMOS图像数据采集模块
cmos_capture_data u_cmos_capture_data(  //系统初始化完成之后再开始采集数据 
    .rst_n              (sys_rst_n && sdram_init_done), 
        
    .cam_pclk           (cmos_pclk),   
    .cam_vsync          (cmos_vsync),  
    .cam_href           (cmos_href),   
    .cam_data           (cmos_db),     
        
    .cmos_frame_vsync   (cmos_frame_vsync   ),
    .cmos_frame_href    (cmos_frame_href    ),
    .cmos_frame_valid   (cmos_frame_clken   ),       //数据有效使能信号
    .cmos_frame_data    (cmos_frame_data    )      //有效数据 
    );


//----------------------------------------------------
//Video Image processor module.
wire			per_frame_vsync	=	cmos_frame_vsync;	                                 
wire			per_frame_href	=	cmos_frame_href;	                                 
wire			per_frame_clken	=	cmos_frame_clken;

wire	[7:0]	per_img_red		=	{
    
    cmos_frame_data[15:11], cmos_frame_data[15:13]};	 
wire	[7:0]	per_img_green	=	{
    
    cmos_frame_data[10:5], cmos_frame_data[10:9]};		 
wire	[7:0]	per_img_blue	=	{
    
    cmos_frame_data[4:0], cmos_frame_data[4:2]};		 

wire			post_frame_vsync;	 
wire			post_frame_href;	 
wire			post_frame_clken;	 

wire			post_img_Bit;		 
wire [7:0]	    post_img_red;		 
wire [7:0]	    post_img_green;	     
wire [7:0]	    post_img_blue;		 
wire [15:0]	    post_frame_data ;

assign post_frame_data  =  {
    
    post_img_red[7:3],post_img_green[7:2],post_img_blue[7:3]} ;	

wire 			YCbCr_frame_vsync ;
wire 			YCbCr_frame_href  ;
wire 			YCbCr_frame_clken ;
wire [7:0]	    YCbCr_img_Y_current;	//当前帧灰度
wire [15:0]	    YCbCr_img_Y_pre;		//前一帧灰度

wire target_detect;

Video_Image_Processor     #(
     .IMG_HDISP      (CMOS_H_PIXEL),
     .IMG_VDISP      (CMOS_V_PIXEL)
    )  	u_Video_Image_Processor
(
	//global clock
	.clk					(cmos_pclk),  			         
	.rst_n					(sys_rst_n && sdram_init_done),  

	//Image data prepred to be processd
	.per_frame_vsync		(per_frame_vsync),		 
	.per_frame_href		    (per_frame_href),		 
	.per_frame_clken		(per_frame_clken),		 
	.per_img_red			(per_img_red),			 
	.per_img_green			(per_img_green),		 
	.per_img_blue			(per_img_blue),			 
	
	//RGB2YCbCr output 
	.YCbCr_frame_vsync	    (YCbCr_frame_vsync),						
	.YCbCr_frame_href		(YCbCr_frame_href ),						
	.YCbCr_frame_clken	    (YCbCr_frame_clken),	
	.YCbCr_img_Y_current	(YCbCr_img_Y_current),			
	.YCbCr_img_Y_pre		(YCbCr_img_Y_pre[7:0]),

	//Image data has been processd
	.post_frame_vsync		(post_frame_vsync),		 
	.post_frame_href		(post_frame_href),		 
	.post_frame_clken		(post_frame_clken),		 
	.post_img_red			(post_img_red	),		 
	.post_img_green		    (post_img_green),		 
	.post_img_blue			(post_img_blue	),		 
                                                     
	//User interface                                 
	.Diff_Threshold		    (Diff_Threshold),
    .target_detect          (target_detect)
    );

//sdram read & write
wire        wr1_wrreq;
wire [15:0] wr1_data;
wire        rd1_rdreq;
wire [15:0] rd1_data;

assign wr1_wrreq    = YCbCr_frame_clken;
assign wr1_data     = {
    
    8'd0,YCbCr_img_Y_current};

assign rd1_rdreq        = YCbCr_frame_clken;
assign YCbCr_img_Y_pre  = rd1_data;

//摄像头采集模块,dvp转avalon-st裸流
wire [15:0] data_w0;
wire valid_w0,ready_w0,sop_w0,eop_w0;	

cmos_to_st_top     #(
     .WIDTH         (CMOS_H_PIXEL),
     .HEIGHT        (CMOS_V_PIXEL),
     .DWIDTH        (16)
    )  u_cmos_to_st_top( 
	.clk            (clk),
	.rst_n          (sys_rst_n && sdram_init_done),
    
    .cmos_pclk      (cmos_pclk),
    
	.cmos_vsync		(post_frame_vsync   ),		 
	.cmos_href 	    (post_frame_href    ),		 
	.cmos_clken		(post_frame_clken   ),		 
	.cmos_data 		(post_frame_data    ),		 
    
	// .cmos_vsync		(YCbCr_frame_vsync  ),		 
	// .cmos_href 	    (YCbCr_frame_href   ),		 
	// .cmos_clken		(YCbCr_frame_clken  ),		 
	// .cmos_data 		( {YCbCr_img_Y_current[7:3],YCbCr_img_Y_current[7:2],YCbCr_img_Y_current[7:3]}    ),		

	.source_sop     (sop_w0),
	.source_valid   (valid_w0),
	.source_data    (data_w0),
	.source_eop     (eop_w0),
	.source_ready   (ready_w0)
);


//TFTLCD模块
vip_ILI9488 u_vip_ILI9488_0(
	.clk            (clk),
	.clk12p5M       (clk_lcd_w),                      
	.rst_n          (rst_n),
    
	//Avalon-ST Sink
    .sink_sop       (sop_w0),
    .sink_valid     (valid_w0),
    .sink_data      (data_w0),
    .sink_eop       (eop_w0),
    .sink_ready     (ready_w0),
    
    .lcd_intdone    (lcd_init_done),
    
	//TFTLCD interface
	.WR             (WR),             
	.RD             (RD),             
	.CS             (CS),             
	.RS             (RS),             
	.BL_cnt         (BL_cnt),         
	.data           (data),           
	.RESET          (RESET)           
);	

wire wr_full_1/*synthesis keep*/;
wire wr_full_2;
wire rd_empty_1;
wire rd_empty_2/*synthesis keep*/;

//assign led = {wr_full_1,1'b0,1'b0,rd_empty_1};

//4port SDRAM控制器模块
Sdram_Control_4Port Sdram_Control_4Port(
	.REF_CLK        (clk_ref),
	.OUT_CLK        (clk_refout),
	.RESET_N        (sys_rst_n),	                //复位输入,低电平复位
                
	.WR1_DATA       (wr1_data),		                //写入端口1的数据输入端,16bit
	.WR1            (wr1_wrreq),	                //写入端口1的写使能端,高电平写入
	.WR1_ADDR       (0),			                //写入端口1的写起始地址
	.WR1_MAX_ADDR   (CMOS_H_PIXEL*CMOS_V_PIXEL),    		            //写入端口1的写入最大地址
	.WR1_LENGTH     (256),			                //一次性写入数据长度
	.WR1_LOAD       (~sys_rst_n),	                //写入端口1清零请求,高电平清零写入地址和fifo
	.WR1_CLK        (cmos_pclk ),			                //写入端口1 fifo写入时钟
	.WR1_FULL       (wr_full_1),			                    //写入端口1 fifo写满信号
	.WR1_USE        (),				                //写入端口1 fifo已经写入的数据长度
            
            
	.WR2_DATA       ( ),	                        //写入端口2的数据输入端,16bit
	.WR2            (0),	                        //写入端口2的写使能端,高电平写入
	.WR2_ADDR       (CMOS_H_PIXEL*CMOS_V_PIXEL),    //写入端口2的写起始地址
	.WR2_MAX_ADDR   (CMOS_H_PIXEL*CMOS_V_PIXEL*2),  //写入端口2的写入最大地址
	.WR2_LENGTH     (256),			                //一次性写入数据长度
	.WR2_LOAD       (~sys_rst_n),	                //写入端口2清零请求,高电平清零写入地址和fifo
	.WR2_CLK        (clk),			                //写入端口2 fifo写入时钟
	.WR2_FULL       (wr_full_2),			                    //写入端口2 fifo写满信号
	.WR2_USE        (),				                //写入端口2 fifo已经写入的数据长度
                
                
	.RD1_DATA       (rd1_data),		                //读出端口1的数据输出端,16bit
	.RD1            (rd1_rdreq),	                //读出端口1的读使能端,高电平读出
	.RD1_ADDR       (0),			                //读出端口1的读起始地址
	.RD1_MAX_ADDR   (CMOS_H_PIXEL*CMOS_V_PIXEL),    //读出端口1的读出最大地址
	.RD1_LENGTH     (256),			                //一次性读出数据长度
	.RD1_LOAD       (~sys_rst_n),	                //读出端口1 清零请求,高电平清零读出地址和fifo
	.RD1_CLK        (cmos_pclk),			                //读出端口1 fifo读取时钟
	.RD1_EMPTY      (rd_empty_1),	                //读出端口1 fifo读空信号
	.RD1_USE        (),				                //读出端口1 fifo已经还可以读取的数据长度
                
	.RD2_DATA       (),			                    //读出端口2的数据输出端,16bit
	.RD2            (0),                            //读出端口2的读使能端,高电平读出
	.RD2_ADDR       (CMOS_H_PIXEL*CMOS_V_PIXEL),    //读出端口2的读起始地址
	.RD2_MAX_ADDR   (CMOS_H_PIXEL*CMOS_V_PIXEL*2),  //读出端口2的读出最大地址
	.RD2_LENGTH     (256),			                //一次性读出数据长度
	.RD2_LOAD       (~sys_rst_n),	                //读出端口2清零请求,高电平清零读出地址和fifo
	.RD2_CLK        (clk),			                //读出端口2 fifo读取时钟
	.RD2_EMPTY      (rd_empty_2),	                //读出端口2 fifo读空信号
	.RD2_USE        (),				                //读出端口2 fifo已经还可以读取的数据长度
       
           
	.SA             (sdram_addr),		            //SDRAM 地址线,
	.BA             (sdram_ba),		                //SDRAM bank地址线
	.CS_N           (sdram_cs_n),		            //SDRAM 片选信号
	.CKE            (sdram_cke),		            //SDRAM 时钟使能
	.RAS_N          (sdram_ras_n),	                //SDRAM 行选中信号
	.CAS_N          (sdram_cas_n),	                //SDRAM 列选中信号
	.WE_N           (sdram_we_n),		            //SDRAM 写请求信号
	.DQ             (sdram_dq),		                //SDRAM 双向数据总线
	.SDR_CLK        (sdram_clk),       
	.DQM            (),		                        //SDRAM 数据总线高低字节屏蔽信号
    
	.Sdram_Init_Done(sdram_init_done)
	);

assign sdram_dqm = 2'b00;



///串口波特率

parameter  CLK_FREQ = 50000000;      
parameter  UART_BPS = 9600;
    
    
wire [7:0] uart_tx_data  ; 
wire       uart_tx_en    ; 
wire       uart_tx_done  ; 

    
uart_tx_ctrl uart_tx_ctrl(
	.clk                (clk),
	.rst_n              (rst_n),

	.target_detect      (target_detect),

	.uart_tx_en         (uart_tx_en),
	.uart_tx_data       (uart_tx_data),

    .uart_tx_done       (uart_tx_done)
);

// 串口 发送
uart_send #(
    .CLK_FREQ                       (CLK_FREQ),        
    .UART_BPS                       (UART_BPS)
    )        
rj45_1_send_mode1(                                 
    .sys_clk                        (clk),
    .sys_rst_n                      (rst_n),

    .uart_din                       (uart_tx_data  ),
    .uart_en                        (uart_tx_en    ),
 
    .uart_txd                       (uart_txd),
    .tx_flag                        (),
    
    .tx_done                        (uart_tx_done)
    );

// 串口 接收
uart_recv #(                           
    .CLK_FREQ                       (CLK_FREQ),        
    .UART_BPS                       (UART_BPS)
    )        
rs485_1_recv(                                         
    .sys_clk                        (clk),         
    .sys_rst_n                      (rst_n),           
                                                    
    .uart_rxd                       (uart_rxd),      
                                                    
    .uart_done                      ( ),     
    .uart_data                      ( ),
    
    .uart_valid                     ( )   
    );  

assign led[0] = target_detect;
assign led[1] = target_detect;

assign led[3] = uart_txd ;

    
endmodule 

2. Image processing top-level module

`timescale 1ns/1ns
module Video_Image_Processor #(
	parameter	[9:0]	IMG_HDISP = 10'd480,	//640*480
	parameter	[9:0]	IMG_VDISP = 10'd320
)
(
	//global clock
	input					clk,  				//cmos video pixel clock
	input					rst_n,				//global reset

	//Image data prepred to be processd
	input					per_frame_vsync,	//Prepared Image data vsync valid signal
	input					per_frame_href,		//Prepared Image data href vaild  signal
	input					per_frame_clken,	//Prepared Image data output/capture enable clock
	input		[7:0]		per_img_red,		//Prepared Image red data to be processed
	input		[7:0]		per_img_green,		//Prepared Image green data to be processed
	input		[7:0]		per_img_blue,		//Prepared Image blue data to be processed

	output				YCbCr_frame_vsync,	
	output				YCbCr_frame_href,		
	output				YCbCr_frame_clken,	
	output	[7:0]		YCbCr_img_Y_current,	//输出当前帧的灰度,用于写入SDRAM
	input 	[7:0]		YCbCr_img_Y_pre,		//同时从SDRAM中读出前一帧的灰度,与当前输出相差一个时钟周期
	
	//Image data has been processd
	output				post_frame_vsync,	//Processed Image data vsync valid signal
	output				post_frame_href,	//Processed Image data href vaild  signal
	output				post_frame_clken,	//Processed Image data output/capture enable clock
	output	[7:0]		post_img_red,		//Processed Image red data to be processed
	output	[7:0]		post_img_green,	//Processed Image green data to be processed
	output	[7:0]		post_img_blue,		//Processed Image blue data to be processed
	
	//user interface
	input		[7:0]		Diff_Threshold,		//Frame Difference Threshold for move detect	
    output                  target_detect
   );

assign YCbCr_frame_vsync 	= post0_frame_vsync;
assign YCbCr_frame_href	 	= post0_frame_href ;	
assign YCbCr_frame_clken 	= post0_frame_clken;
assign YCbCr_img_Y_current	= post0_img_Y      ;		

//-------------------------------------
//Convert the RGB888 format to YCbCr444 format.
wire 			post0_frame_vsync;   
wire 			post0_frame_href ;   
wire 			post0_frame_clken;    
wire [7:0]	post0_img_Y      ;   
wire [7:0]	post0_img_Cb     ;   
wire [7:0]	post0_img_Cr     ;   

VIP_RGB888_YCbCr444	u_VIP_RGB888_YCbCr444
(
	//global clock
	.clk				(clk),					//cmos video pixel clock
	.rst_n				(rst_n),				//system reset

	//Image data prepred to be processd
	.per_frame_vsync	(per_frame_vsync),		//Prepared Image data vsync valid signal
	.per_frame_href	(per_frame_href),		//Prepared Image data href vaild  signal
	.per_frame_clken	(per_frame_clken),		//Prepared Image data output/capture enable clock
	.per_img_red		(per_img_red),			//Prepared Image red data input
	.per_img_green		(per_img_green),		//Prepared Image green data input
	.per_img_blue		(per_img_blue),			//Prepared Image blue data input
	
	//Image data has been processd
	.post_frame_vsync	(post0_frame_vsync),		//Processed Image frame data valid signal
	.post_frame_href	(post0_frame_href),		//Processed Image hsync data valid signal
	.post_frame_clken	(post0_frame_clken),		//Processed Image data output/capture enable clock
	.post_img_Y			(post0_img_Y),			//Processed Image brightness output
	.post_img_Cb		(post0_img_Cb),			//Processed Image blue shading output
	.post_img_Cr		(post0_img_Cr)			//Processed Image red shading output
);

//--------------------------------------
//frame difference 
wire			post1_frame_vsync;	//Processed Image data vsync valid signal
wire			post1_frame_href;		//Processed Image data href vaild  signal
wire			post1_frame_clken;	//Processed Image data output/capture enable clock
wire			post1_img_Bit;			//Processed Image Bit flag outout(1: Value, 0:inValid)

VIP_Frame_Difference u_VIP_Frame_Difference(
	//global clock
	.clk						(clk),  						//cmos video pixel clock
	.rst_n					(rst_n),						//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(post0_frame_vsync),		//Prepared Image data vsync valid signal
	.per_frame_href		(post0_frame_href),		//Prepared Image data href vaild  signal
	.per_frame_clken		(post0_frame_clken),		//Prepared Image data output/capture enable clock
	.per_img_Y				(post0_img_Y),				//Prepared Image brightness input

	.YCbCr_img_Y_pre		(YCbCr_img_Y_pre),
	
	//Image data has been processd
	.post_frame_vsync		(post1_frame_vsync),		//Processed Image data vsync valid signal
	.post_frame_href		(post1_frame_href),		//Processed Image data href vaild  signal
	.post_frame_clken		(post1_frame_clken),		//Processed Image data output/capture enable clock
	.post_img_Bit			(post1_img_Bit),			//Processed Image Bit flag outout(1: Value, 0:inValid)
	
	//User interface
	.Diff_Threshold		(Diff_Threshold)					//Sobel Threshold for image edge detect
);

//--------------------------------------
//Bit Image Process with Erosion before Dilation Detector.
wire			post2_frame_vsync;	//Processed Image data vsync valid signal
wire			post2_frame_href;	//Processed Image data href vaild  signal
wire			post2_frame_clken;	//Processed Image data output/capture enable clock
wire			post2_img_Bit;		//Processed Image Bit flag outout(1: Value, 0:inValid)
VIP_Bit_Erosion_Detector
#(
	.IMG_HDISP	(IMG_HDISP),	//640*480
	.IMG_VDISP	(IMG_VDISP)
)
u_VIP_Bit_Erosion_Detector
(
	//global clock
	.clk						(clk),  				//cmos video pixel clock
	.rst_n					(rst_n),				//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(post1_frame_vsync),	//Prepared Image data vsync valid signal
	.per_frame_href		(post1_frame_href),	//Prepared Image data href vaild  signal
	.per_frame_clken		(post1_frame_clken),	//Prepared Image data output/capture enable clock
	.per_img_Bit			(post1_img_Bit),		//Processed Image Bit flag outout(1: Value, 0:inValid)

	//Image data has been processd
	.post_frame_vsync		(post2_frame_vsync),		//Processed Image data vsync valid signal
	.post_frame_href		(post2_frame_href),		//Processed Image data href vaild  signal
	.post_frame_clken		(post2_frame_clken),		//Processed Image data output/capture enable clock
	.post_img_Bit			(post2_img_Bit)			//Processed Image Bit flag outout(1: Value, 0:inValid)
);


//--------------------------------------
//Bit Image Process with Dilation after Erosion Detector.
wire			post3_frame_vsync;	//Processed Image data vsync valid signal
wire			post3_frame_href;	//Processed Image data href vaild  signal
wire			post3_frame_clken;	//Processed Image data output/capture enable clock
wire			post3_img_Bit;		//Processed Image Bit flag outout(1: Value, 0:inValid)

VIP_Bit_Dilation_Detector
#(
	.IMG_HDISP	(IMG_HDISP),	//640*480
	.IMG_VDISP	(IMG_VDISP)
)
u_VIP_Bit_Dilation_Detector
(
	//global clock
	.clk						(clk),  				//cmos video pixel clock
	.rst_n					(rst_n),				//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(post2_frame_vsync),	//Prepared Image data vsync valid signal
	.per_frame_href		(post2_frame_href),	//Prepared Image data href vaild  signal
	.per_frame_clken		(post2_frame_clken),	//Prepared Image data output/capture enable clock
	.per_img_Bit			(post2_img_Bit),		//Processed Image Bit flag outout(1: Value, 0:inValid)

	//Image data has been processd
	.post_frame_vsync		(post3_frame_vsync),		//Processed Image data vsync valid signal
	.post_frame_href		(post3_frame_href),		//Processed Image data href vaild  signal
	.post_frame_clken		(post3_frame_clken),		//Processed Image data output/capture enable clock
	.post_img_Bit			(post3_img_Bit)				//Processed Image Bit flag outout(1: Value, 0:inValid)
);

wire [9:0] rectangular_up		;
wire [9:0] rectangular_down	;
wire [9:0] rectangular_left	;
wire [9:0] rectangular_right 	;
wire 		  rectangular_flag	;

//检测运动目标所在的矩形区域
VIP_detect_rectangular
#(
	.IMG_HDISP	(IMG_HDISP),	//640*480
	.IMG_VDISP	(IMG_VDISP)
)
u_VIP_detect_rectangular
(
	//global clock
	.clk						(clk),  				//cmos video pixel clock
	.rst_n					(rst_n),				//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(post3_frame_vsync),	//Prepared Image data vsync valid signal
	.per_frame_href		(post3_frame_href),	//Prepared Image data href vaild  signal
	.per_frame_clken		(post3_frame_clken),	//Prepared Image data output/capture enable clock
	.per_img_Bit			(post3_img_Bit),		//Processed Image Bit flag outout(1: Value, 0:inValid)

	//检测出的矩形边界
	.rectangular_up		(rectangular_up	),
	.rectangular_down		(rectangular_down	),
	.rectangular_left		(rectangular_left	),
	.rectangular_right	(rectangular_right), 
	.rectangular_flag		(rectangular_flag)
);

//在输入视频上叠加检测出的矩形框
VIP_Video_add_rectangular
#(
	.IMG_HDISP	(IMG_HDISP),	//640*480
	.IMG_VDISP	(IMG_VDISP)
)
u_VIP_Video_add_rectangular
(
	//global clock
	.clk						(clk),  				//cmos video pixel clock
	.rst_n					(rst_n),				//global reset

	//Image data prepred to be processd
	.per_frame_vsync		(per_frame_vsync),		//Prepared Image data vsync valid signal
	.per_frame_href		(per_frame_href),		//Prepared Image data href vaild  signal
	.per_frame_clken		(per_frame_clken),		//Prepared Image data output/capture enable clock
	.per_img_red			(per_img_red),			//Prepared Image red data input
	.per_img_green			(per_img_green),		//Prepared Image green data input
	.per_img_blue			(per_img_blue),			//Prepared Image blue data input
	
	//检测出的矩形边界
	.rectangular_up		(rectangular_up	),
	.rectangular_down		(rectangular_down	),
	.rectangular_left		(rectangular_left	),
	.rectangular_right	(rectangular_right),
	.rectangular_flag		(rectangular_flag),

	.post_frame_vsync		(post_frame_vsync),		//Prepared Image data vsync valid signal
	.post_frame_href		(post_frame_href),		//Prepared Image data href vaild  signal
	.post_frame_clken		(post_frame_clken),		//Prepared Image data output/capture enable clock
	.post_img_red			(post_img_red),			//Prepared Image red data input
	.post_img_green		(post_img_green),		//Prepared Image green data input
	.post_img_blue			(post_img_blue) 			//Prepared Image blue data input
);

assign target_detect = rectangular_flag;

endmodule

3. LCD driver top module

//功能:Avalon-ST视频流接口的ILI9488驱动模块
module vip_ILI9488(
	input         clk,
	input         clk12p5M,                      
	input         rst_n,
	//Avalon-ST Sink
    input         sink_sop,
    input         sink_valid,
    input  [15:0] sink_data,
    input         sink_eop,
    output        sink_ready,
    //Conduit
    output        lcd_intdone,
	//TFTLCD interface
	output        WR,
	output        RD,
	output        CS,
	output        RS,
	output        BL_cnt,
	output [15:0] data,
	output        RESET
);
wire sop_w0,eop_w0,valid_w0,ready_w0;
wire [15:0] data_w0;
wire        sop_w1;
wire [15:0] data_w1;
wire fifo_empty_w,fifo_rd_w;
wire [7:0] wrusedw_w;
wire pixelReady;
reg  valid_r1;
assign fifo_rd_w = !fifo_empty_w && pixelReady;
assign sink_ready = (wrusedw_w <= 8'd200);
always@(posedge clk12p5M or negedge rst_n)
begin
if(rst_n == 1'b0)
    begin
    valid_r1 <= 1'b0;
    end
else
    begin
    valid_r1 <= fifo_rd_w;
    end
end
vip_ili9488_dcfifo u_vip_ili9488_dcfifo_0 (
	.aclr(!rst_n),
	.data({
    
    sink_sop,sink_data}),
	.rdclk(clk12p5M),
	.rdreq(fifo_rd_w),
	.wrclk(clk),
	.wrreq(sink_valid),
	.q({
    
    sop_w1,data_w1}),
	.rdempty(fifo_empty_w),
	.wrusedw(wrusedw_w)
	);
ILI9488 u_ILI9488_0(
	.clk12p5M(clk12p5M),                      
	.rst_n(rst_n),
	.x_start(10'd0),//横坐标
	.x_end(10'd479),
	.y_start(10'd0),
	.y_end(10'd319),//纵坐标
	.color(data_w1),      //RGB565
	.sop(sop_w1),
	.write_en(valid_r1),   //high active
	.write_ready(pixelReady),//write_en拉高后必须等待write_ready为高才表示
	.lcd_intdone(lcd_intdone),//TFTLCD 初始化完成标志,高有效
	.WR(WR),
	.RD(RD),
	.CS(CS),
	.RS(RS),
	.BL_cnt(BL_cnt),
	.data(data),
	.RESET(RESET)
	);
endmodule 

4. SDRAM controller top module

module Sdram_Control_4Port(
		//	HOST Side
        REF_CLK,
		  OUT_CLK,
        RESET_N,
	//  	CLK,     //
		//CLK_18,  //
		//	FIFO Write Side 1
      WR1_DATA,
		WR1,
		WR1_ADDR,
		WR1_MAX_ADDR,
		WR1_LENGTH,
		WR1_LOAD,
		WR1_CLK,
		WR1_FULL,
		WR1_USE,
		//	FIFO Write Side 2
        WR2_DATA,
		WR2,
		WR2_ADDR,
		WR2_MAX_ADDR,
		WR2_LENGTH,
		WR2_LOAD,
		WR2_CLK,
		WR2_FULL,
		WR2_USE,
		//	FIFO Read Side 1
        RD1_DATA,
		RD1,
		RD1_ADDR,
		RD1_MAX_ADDR,
		RD1_LENGTH,
		RD1_LOAD,	
		RD1_CLK,
		RD1_EMPTY,
		RD1_USE,
		//	FIFO Read Side 2
        RD2_DATA,
		RD2,
		RD2_ADDR,
		RD2_MAX_ADDR,
		RD2_LENGTH,
		RD2_LOAD,
		RD2_CLK,
		RD2_EMPTY,
		RD2_USE,
		//	SDRAM Side
        SA,
        BA,
        CS_N,
        CKE,
        RAS_N,
        CAS_N,
        WE_N,
        DQ,
        DQM,
		SDR_CLK,
		// user inter
		Sdram_Init_Done
        );

		  

`include        "Sdram_Params.h"
//	HOST Side
input                           REF_CLK;                //System Clock
input                           OUT_CLK;
input                           RESET_N;                //System Reset
//	FIFO Write Side 1
input   [`DSIZE-1:0]            WR1_DATA;               //Data input
input							WR1;					//Write Request
input	[`ASIZE-1:0]			WR1_ADDR;				//Write start address
input	[`ASIZE-1:0]			WR1_MAX_ADDR;			//Write max address
input	[8:0]					WR1_LENGTH;				//Write length
input							WR1_LOAD;				//Write register load & fifo clear
input							WR1_CLK;				//Write fifo clock
output							WR1_FULL;				//Write fifo full
output	[15:0]					WR1_USE;				//Write fifo usedw
//	FIFO Write Side 2
input   [`DSIZE-1:0]            WR2_DATA;               //Data input
input							WR2;					//Write Request
input	[`ASIZE-1:0]			WR2_ADDR;				//Write start address
input	[`ASIZE-1:0]			WR2_MAX_ADDR;			//Write max address
input	[8:0]					WR2_LENGTH;				//Write length
input							WR2_LOAD;				//Write register load & fifo clear
input							WR2_CLK;				//Write fifo clock
output							WR2_FULL;				//Write fifo full
output	[15:0]					WR2_USE;				//Write fifo usedw
//	FIFO Read Side 1
output  [`DSIZE-1:0]            RD1_DATA;               //Data output
input							RD1;					//Read Request
input	[`ASIZE-1:0]			RD1_ADDR;				//Read start address
input	[`ASIZE-1:0]			RD1_MAX_ADDR;			//Read max address
input	[8:0]					RD1_LENGTH;				//Read length
input							RD1_LOAD;				//Read register load & fifo clear
input							RD1_CLK;				//Read fifo clock
output							RD1_EMPTY;				//Read fifo empty
output	[15:0]					RD1_USE;				//Read fifo usedw
//	FIFO Read Side 2
output  [`DSIZE-1:0]            RD2_DATA;               //Data output
input							RD2;					//Read Request
input	[`ASIZE-1:0]			RD2_ADDR;				//Read start address
input	[`ASIZE-1:0]			RD2_MAX_ADDR;			//Read max address
input	[8:0]					RD2_LENGTH;				//Read length
input							RD2_LOAD;				//Read register load & fifo clear
input							RD2_CLK;				//Read fifo clock
output							RD2_EMPTY;				//Read fifo empty
output	[15:0]					RD2_USE;				//Read fifo usedw
//	SDRAM Side
output  [11:0]                  SA;                     //SDRAM address output
output  [1:0]                   BA;                     //SDRAM bank address
output  [1:0]                   CS_N;                   //SDRAM Chip Selects
output                          CKE;                    //SDRAM clock enable
output                          RAS_N;                  //SDRAM Row address Strobe
output                          CAS_N;                  //SDRAM Column address Strobe
output                          WE_N;                   //SDRAM write enable
inout   [`DSIZE-1:0]            DQ;                     //SDRAM data bus
output  [`DSIZE/8-1:0]          DQM;                    //SDRAM data mask lines
output							SDR_CLK;				//SDRAM clock
assign SDR_CLK=OUT_CLK;
wire   CLK=REF_CLK;
output    Sdram_Init_Done;
//	Internal Registers/Wires
//	Controller
reg		[`ASIZE-1:0]			mADDR;					//Internal address
reg		[8:0]					mLENGTH;				//Internal length
reg		[`ASIZE-1:0]			rWR1_ADDR;				//Register write address				
reg		[`ASIZE-1:0]			rWR1_MAX_ADDR;			//Register max write address				
reg		[8:0]					rWR1_LENGTH;			//Register write length
reg		[`ASIZE-1:0]			rWR2_ADDR;				//Register write address				
reg		[`ASIZE-1:0]			rWR2_MAX_ADDR;			//Register max write address				
reg		[8:0]					rWR2_LENGTH;			//Register write length
reg		[`ASIZE-1:0]			rRD1_ADDR;				//Register read address
reg		[`ASIZE-1:0]			rRD1_MAX_ADDR;			//Register max read address
reg		[8:0]					rRD1_LENGTH;			//Register read length
reg		[`ASIZE-1:0]			rRD2_ADDR;				//Register read address
reg		[`ASIZE-1:0]			rRD2_MAX_ADDR;			//Register max read address
reg		[8:0]					rRD2_LENGTH;			//Register read length
reg		[1:0]					WR_MASK;				//Write port active mask
reg		[1:0]					RD_MASK;				//Read port active mask
reg								mWR_DONE;				//Flag write done, 1 pulse SDR_CLK
reg								mRD_DONE;				//Flag read done, 1 pulse SDR_CLK
reg								mWR,Pre_WR;				//Internal WR edge capture
reg								mRD,Pre_RD;				//Internal RD edge capture
reg 	[9:0] 					ST;						//Controller status
reg		[1:0] 					CMD;					//Controller command
reg								PM_STOP;				//Flag page mode stop
reg								PM_DONE;				//Flag page mode done
reg								Read;					//Flag read active
reg								Write;					//Flag write active
reg	    [`DSIZE-1:0]           	mDATAOUT;               //Controller Data output
wire    [`DSIZE-1:0]           	mDATAIN;                //Controller Data input
wire    [`DSIZE-1:0]           	mDATAIN1;                //Controller Data input 1
wire    [`DSIZE-1:0]           	mDATAIN2;                //Controller Data input 2
wire                          	CMDACK;                 //Controller command acknowledgement
//	DRAM Control
reg  	[`DSIZE/8-1:0]          DQM;                    //SDRAM data mask lines
reg     [11:0]                  SA;                     //SDRAM address output
reg     [1:0]                   BA;                     //SDRAM bank address
reg     [1:0]                   CS_N;                   //SDRAM Chip Selects
reg                             CKE;                    //SDRAM clock enable
reg                             RAS_N;                  //SDRAM Row address Strobe
reg                             CAS_N;                  //SDRAM Column address Strobe
reg                             WE_N;                   //SDRAM write enable
wire    [`DSIZE-1:0]            DQOUT;					//SDRAM data out link
wire  	[`DSIZE/8-1:0]          IDQM;                   //SDRAM data mask lines
wire    [11:0]                  ISA;                    //SDRAM address output
wire    [1:0]                   IBA;                    //SDRAM bank address
wire    [1:0]                   ICS_N;                  //SDRAM Chip Selects
wire                            ICKE;                   //SDRAM clock enable
wire                            IRAS_N;                 //SDRAM Row address Strobe
wire                            ICAS_N;                 //SDRAM Column address Strobe
wire                            IWE_N;                  //SDRAM write enable
//	FIFO Control
reg								OUT_VALID;				//Output data request to read side fifo
reg								IN_REQ;					//Input	data request to write side fifo
wire	[15:0]					write_side_fifo_rusedw1;
wire	[15:0]					read_side_fifo_wusedw1;
wire	[15:0]					write_side_fifo_rusedw2;
wire	[15:0]					read_side_fifo_wusedw2;
//	DRAM Internal Control
wire    [`ASIZE-1:0]            saddr;
wire                            load_mode;
wire                            nop;
wire                            reada;
wire                            writea;
wire                            refresh;
wire                            precharge;
wire                            oe;
wire							ref_ack;
wire							ref_req;
wire							init_req;
wire							cm_ack;
wire							active;

/*
Sdram_PLL sdram_pll1	(
				.inclk0(REF_CLK),
				.c0(CLK),
				.c1(SDR_CLK),
				.c2(CLK_18)
				);
*/				

control_interface control1 (
                .CLK(CLK),
                .RESET_N(RESET_N),
                .CMD(CMD),
                .ADDR(mADDR),
                .REF_ACK(ref_ack),
                .CM_ACK(cm_ack),
                .NOP(nop),
                .READA(reada),
                .WRITEA(writea),
                .REFRESH(refresh),
                .PRECHARGE(precharge),
                .LOAD_MODE(load_mode),
                .SADDR(saddr),
                .REF_REQ(ref_req),
		    		.INIT_REQ(init_req),
                .CMD_ACK(CMDACK),
					 .Sdram_Init_Done(Sdram_Init_Done)
                );

command command1(
                .CLK(CLK),
                .RESET_N(RESET_N),
                .SADDR(saddr),
                .NOP(nop),
                .READA(reada),
                .WRITEA(writea),
                .REFRESH(refresh),
				.LOAD_MODE(load_mode),
                .PRECHARGE(precharge),
                .REF_REQ(ref_req),
				.INIT_REQ(init_req),
                .REF_ACK(ref_ack),
                .CM_ACK(cm_ack),
                .OE(oe),
				.PM_STOP(PM_STOP),
				.PM_DONE(PM_DONE),
                .SA(ISA),
                .BA(IBA),
                .CS_N(ICS_N),
                .CKE(ICKE),
                .RAS_N(IRAS_N),
                .CAS_N(ICAS_N),
                .WE_N(IWE_N)
                );
                
sdr_data_path data_path1(
                .CLK(CLK),
                .RESET_N(RESET_N),
                .DATAIN(mDATAIN),
                .DM(2'b00),
                .DQOUT(DQOUT),
                .DQM(IDQM)
                );

Sdram_WR_FIFO 	write_fifo1(
				.data(WR1_DATA),
				.wrreq(WR1),
				.wrclk(WR1_CLK),
				.aclr(WR1_LOAD),
				.rdreq(IN_REQ&WR_MASK[0]),
				.rdclk(CLK),
				.q(mDATAIN1),
				.wrfull(WR1_FULL),
				.wrusedw(WR1_USE),
				.rdusedw(write_side_fifo_rusedw1)
				);

Sdram_WR_FIFO 	write_fifo2(
				.data(WR2_DATA),
				.wrreq(WR2),
				.wrclk(WR2_CLK),
				.aclr(WR2_LOAD),
				.rdreq(IN_REQ&WR_MASK[1]),
				.rdclk(CLK),
				.q(mDATAIN2),
				.wrfull(WR2_FULL),
				.wrusedw(WR2_USE),
				.rdusedw(write_side_fifo_rusedw2)
				);
				
assign	mDATAIN	=	(WR_MASK[0])	?	mDATAIN1	:
										mDATAIN2	;

Sdram_RD_FIFO 	read_fifo1(
				.data(mDATAOUT),
				.wrreq(OUT_VALID&RD_MASK[0]),
				.wrclk(CLK),
				.aclr(RD1_LOAD),
				.rdreq(RD1),
				.rdclk(RD1_CLK),
				.q(RD1_DATA),
				.wrusedw(read_side_fifo_wusedw1),
				.rdempty(RD1_EMPTY),
				.rdusedw(RD1_USE)
				);
				
Sdram_RD_FIFO 	read_fifo2(
				.data(mDATAOUT),
				.wrreq(OUT_VALID&RD_MASK[1]),
				.wrclk(CLK),
				.aclr(RD2_LOAD),
				.rdreq(RD2),
				.rdclk(RD2_CLK),
				.q(RD2_DATA),
				.wrusedw(read_side_fifo_wusedw2),
				.rdempty(RD2_EMPTY),
				.rdusedw(RD2_USE)
				);

always @(posedge CLK)
begin
	SA      <= (ST==SC_CL+mLENGTH)			?	12'h200	:	ISA;
    BA      <= IBA;
    CS_N    <= ICS_N;
    CKE     <= ICKE;
    RAS_N   <= (ST==SC_CL+mLENGTH)			?	1'b0	:	IRAS_N;
    CAS_N   <= (ST==SC_CL+mLENGTH)			?	1'b1	:	ICAS_N;
    WE_N    <= (ST==SC_CL+mLENGTH)			?	1'b0	:	IWE_N;
	PM_STOP	<= (ST==SC_CL+mLENGTH)			?	1'b1	:	1'b0;
	PM_DONE	<= (ST==SC_CL+SC_RCD+mLENGTH+2)	?	1'b1	:	1'b0;
	DQM	   <= {
    
    (`DSIZE/8){
    
    1'b0}}; //( active && (ST>=SC_CL) )	?	(	((ST==SC_CL+mLENGTH) && Write)?	2'b11	:	2'b00	)	:	2'b11	;
	mDATAOUT<= DQ;
end

assign  DQ = oe ? DQOUT : `DSIZE'hzzzz;
assign	active	=	Read | Write;

always@(posedge CLK or negedge RESET_N)
begin
	if(RESET_N==0)
	begin
		CMD			<=  0;
		ST			<=  0;
		Pre_RD		<=  0;
		Pre_WR		<=  0;
		Read		<=	0;
		Write		<=	0;
		OUT_VALID	<=	0;
		IN_REQ		<=	0;
		mWR_DONE	<=	0;
		mRD_DONE	<=	0;
	end
	else
	begin
		Pre_RD	<=	mRD;
		Pre_WR	<=	mWR;
		case(ST)
		0:	begin
				if({
    
    Pre_RD,mRD}==2'b01)
				begin
					Read	<=	1;
					Write	<=	0;
					CMD		<=	2'b01;
					ST		<=	1;
				end
				else if({
    
    Pre_WR,mWR}==2'b01)
				begin
					Read	<=	0;
					Write	<=	1;
					CMD		<=	2'b10;
					ST		<=	1;
				end
			end
		1:	begin
				if(CMDACK==1)
				begin
					CMD<=2'b00;
					ST<=2;
				end
			end
		default:	
			begin	
				if(ST!=SC_CL+SC_RCD+mLENGTH+1)
				ST<=ST+1;
				else
				ST<=0;
			end
		endcase
	
		if(Read)
		begin
			if(ST==SC_CL+SC_RCD+1)
			OUT_VALID	<=	1;
			else if(ST==SC_CL+SC_RCD+mLENGTH+1)
			begin
				OUT_VALID	<=	0;
				Read		<=	0;
				mRD_DONE	<=	1;
			end
		end
		else
		mRD_DONE	<=	0;
		
		if(Write)
		begin
			if(ST==SC_CL-1)
			IN_REQ	<=	1;
			else if(ST==SC_CL+mLENGTH-1)
			IN_REQ	<=	0;
			else if(ST==SC_CL+SC_RCD+mLENGTH)
			begin
				Write	<=	0;
				mWR_DONE<=	1;
			end
		end
		else
		mWR_DONE<=	0;

	end
end
//	Internal Address & Length Control
always@(posedge CLK or negedge RESET_N)
begin
	if(!RESET_N)
	begin
		rWR1_ADDR		<=	WR1_ADDR;
		rWR1_MAX_ADDR	<=	WR1_MAX_ADDR;
		rWR2_ADDR		<=	WR2_ADDR;
		rWR2_MAX_ADDR	<=	WR2_MAX_ADDR;
		rRD1_ADDR		<=	RD1_ADDR;
		rRD1_MAX_ADDR	<=	RD1_MAX_ADDR;
		rRD2_ADDR		<=	RD2_ADDR;
		rRD2_MAX_ADDR	<=	RD2_MAX_ADDR;
		rWR1_LENGTH		<=WR1_LENGTH;
		rRD1_LENGTH		<=RD1_LENGTH;
		rWR2_LENGTH		<=WR2_LENGTH;
		rRD2_LENGTH		<=RD2_LENGTH;
	end
	else
	begin
		//	Write Side 1
		if(WR1_LOAD)
		begin
			rWR1_ADDR	<=	WR1_ADDR;
			rWR1_LENGTH	<=	WR1_LENGTH;
		end
		else if(mWR_DONE&WR_MASK[0])
		begin
			if(rWR1_ADDR<rWR1_MAX_ADDR-rWR1_LENGTH)
			rWR1_ADDR	<=	rWR1_ADDR+rWR1_LENGTH;
			else
			rWR1_ADDR	<=	WR1_ADDR;
		end
		//	Write Side 2
		if(WR2_LOAD)
		begin
			rWR2_ADDR	<=	WR2_ADDR;
			rWR2_LENGTH	<=	WR2_LENGTH;
		end
		else if(mWR_DONE&WR_MASK[1])
		begin
			if(rWR2_ADDR<rWR2_MAX_ADDR-rWR2_LENGTH)
			rWR2_ADDR	<=	rWR2_ADDR+rWR2_LENGTH;
			else
			rWR2_ADDR	<=	WR2_ADDR;
		end
		//	Read Side 1
		if(RD1_LOAD)
		begin
			rRD1_ADDR	<=	RD1_ADDR;
			rRD1_LENGTH	<=	RD1_LENGTH;
		end
		else if(mRD_DONE&RD_MASK[0])
		begin
			if(rRD1_ADDR<rRD1_MAX_ADDR-rRD1_LENGTH)
			rRD1_ADDR	<=	rRD1_ADDR+rRD1_LENGTH;
			else
			rRD1_ADDR	<=	RD1_ADDR;
		end
		//	Read Side 2
		if(RD2_LOAD)
		begin
			rRD2_ADDR	<=	RD2_ADDR;
			rRD2_LENGTH	<=	RD2_LENGTH;
		end
		else if(mRD_DONE&RD_MASK[1])
		begin
			if(rRD2_ADDR<rRD2_MAX_ADDR-rRD2_LENGTH)
			rRD2_ADDR	<=	rRD2_ADDR+rRD2_LENGTH;
			else
			rRD2_ADDR	<=	RD2_ADDR;
		end
	end
end
//	Auto Read/Write Control
always@(posedge CLK or negedge RESET_N)
begin
	if(!RESET_N)
	begin
		mWR		<=	0;
		mRD		<=	0;
		mADDR	<=	0;
		mLENGTH	<=	0;
	   RD_MASK <= 0;
	   WR_MASK <= 0; 
	end
	else if(Sdram_Init_Done)
	begin
		if( (mWR==0) && (mRD==0) && (ST==0) &&
			(WR_MASK==0)	&&	(RD_MASK==0) &&
			(WR1_LOAD==0)	&&	(RD1_LOAD==0) &&
			(WR2_LOAD==0)	&&	(RD2_LOAD==0) )
		begin
			//	Read Side 1
			if( (read_side_fifo_wusedw1 < rRD1_LENGTH) )
			begin
				mADDR	<=	rRD1_ADDR;
				mLENGTH	<=	rRD1_LENGTH;
				WR_MASK	<=	2'b00;
				RD_MASK	<=	2'b01;
				mWR		<=	0;
				mRD		<=	1;				
			end
			//	Read Side 2
			else if( (read_side_fifo_wusedw2 < rRD2_LENGTH) )
			begin
				mADDR	<=	rRD2_ADDR;
				mLENGTH	<=	rRD2_LENGTH;
				WR_MASK	<=	2'b00;
				RD_MASK	<=	2'b10;
				mWR		<=	0;
				mRD		<=	1;
			end
			//	Write Side 1
			else if( (write_side_fifo_rusedw1 >= rWR1_LENGTH) && (rWR1_LENGTH!=0) )
			begin
				mADDR	<=	rWR1_ADDR;
				mLENGTH	<=	rWR1_LENGTH;
				WR_MASK	<=	2'b01;
				RD_MASK	<=	2'b00;
				mWR		<=	1;
				mRD		<=	0;
			end
			//	Write Side 2
			else if( (write_side_fifo_rusedw2 >= rWR2_LENGTH) && (rWR2_LENGTH!=0) )
			begin
				mADDR	<=	rWR2_ADDR;
				mLENGTH	<=	rWR2_LENGTH;
				WR_MASK	<=	2'b10;
				RD_MASK	<=	2'b00;
				mWR		<=	1;
				mRD		<=	0;
			end
		end
		if(mWR_DONE)
		begin
			WR_MASK	<=	0;
			mWR		<=	0;
		end
		if(mRD_DONE)
		begin
			RD_MASK	<=	0;
			mRD		<=	0;
		end
	end
end

endmodule

5. Host computer sending module


module uart_tx_ctrl(
	input 				clk,
	input 				rst_n,
	
	input 				target_detect,
	
	output reg 			uart_tx_en  ,
	output reg [7:0]	uart_tx_data,
    
    input               uart_tx_done
);

wire [ 7:0] string_data [15:0];      //待发送字符串

assign string_data[0] = "I";
assign string_data[1] = "n";
assign string_data[2] = "t";
assign string_data[3] = "r";
assign string_data[4] = "u";
assign string_data[5] = "d";
assign string_data[6] = "e";
assign string_data[7] = "r";
assign string_data[8] = 8'h21;  // '!'
assign string_data[9] = 8'h0A;  // '\n'

reg [4:0] ctrl_state  ;
reg [3:0] cmd_byte_cnt;

//状态机, 
always @(posedge clk or negedge rst_n) begin 
    if (!rst_n) begin 
        ctrl_state      <= 5'd0;
        cmd_byte_cnt    <= 4'd0;
        uart_tx_en      <= 1'b0;
        uart_tx_data    <= 8'd0;
    end
    else begin
        case(ctrl_state)
            //Idle,无数据发送状态
            5'd0: begin
                cmd_byte_cnt   <= 4'd0;
                uart_tx_en     <= 1'b0;
                uart_tx_data   <= 8'd0;
            
                if(target_detect  == 1'b1) begin   //有目标出现  
                    ctrl_state     <= 5'd1;          
                end
                else begin                      
                    ctrl_state  <= 5'd0;            
                end
            end

            //开始发送串口数据
            5'd1: begin
                uart_tx_en      <= 1'b1;    //拉高发送使能
                uart_tx_data    <= string_data[cmd_byte_cnt];
                ctrl_state      <= 5'd2;    //等待发送完成
            end
            
            //等待字节发送完成 
            5'd2: begin
                uart_tx_en   <= 1'b0;
                
                if(uart_tx_done) begin   // 字节发送完成
                    if(cmd_byte_cnt < 4'd9) begin   
                        ctrl_state      <= 5'd1;    //字符串继续发送
                        cmd_byte_cnt    <= cmd_byte_cnt + 1'b1;
                    end
                    else begin
                        ctrl_state      <= 5'd0;    //字符串继续发送
                        cmd_byte_cnt    <= 4'd0;
                    end
                end
            end
            
            default: begin
                ctrl_state  <= 5'd0; 
            end

        endcase
    end
end

endmodule 

5. Obtaining engineering and kits

1. Project acquisition

A: Click to download directly: Based on FPGA: moving target detection (LCD display + serial port output, complete project).zip

B: Private message me or add email to get it (complete schematic diagram + source code project + key module simulation) (in addition, a VGA display based on FPGA single-target motion detection will be given as a gift)

2. Suite

      I find it troublesome to debug. I have several sets of debugged kits in my hand. If necessary, I can buy them. You can see the phenomenon after powering on, which is convenient. If you need to add my email: [email protected].
insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/weixin_46423500/article/details/130657425