当前位置:   article > 正文

基于FPGA:运动目标检测(LCD显示+串口输出,纯Verilog工程)_fpga运动目标检测

fpga运动目标检测

前言

      最早做了基于FPGA:运动目标检测(VGA显示,原理图+源码+硬件选择),有网友反应,VGA一个大大的屏幕,做起来很不方便,并且功能过于单一。
     因此,在上个工程的基础上,修改成了TFT-LCD屏幕检测,并且将检测结果通过串口输出到电脑上位机上,以便大家做扩展开发。

一、先看效果

      话不多说,先上视频看效果。

基于FPGA运动目标检测(LCD显示-串口输出)

二、硬件选择

开发板Altera:EP4CE6F17C8(兼容E10)
摄像头:OV5640
屏幕:TFT-LCD
缓存数据:SDRAM
板子是自制的

三、系统框架

      本系统在图像采集之前,由于板载晶振与摄像头模块及 TFT-LCD 模块频率不一致,所以在系统工作之前,需要设计锁相环模块输出与OV5640摄像头一致的时钟信号。时钟输入后,根据 OV5640 的手册进行寄存器配置,使 OV5640 的工作模式符合本系统的设计需求。CMOS 传感器采集进来的图像进入到图像处理模块,输出当前帧的灰度,用于写入SDRAM。同时从SDRAM中读出前一帧的灰度(与当前输出相差一个时钟周期)重新进入图像处理模块进行帧差法的图像处理(即运动目标检测相关的处理)。
      在本系统中,满足选择功能的情况下,更需要满足实时性,所以选择只输入一路视频流。并且根据时钟域不同,设计了异步 FIFO 完成数据传输缓存。最后将处理结果通过 ILI9488 驱动模块显示在屏幕上,并将检测信息通过串口输出到上位机上。

在这里插入图片描述

四、程序模块

      代码框架:本设计基本使用纯Verilog设计,运用了较少的IP,如:PLL,FIFO。代码附带注释,可读性强,便于大家移植,参加竞赛、毕设。

在这里插入图片描述
      部分模块仿真:

在这里插入图片描述在这里插入图片描述

1、系统顶层模块

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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391

2、图像处理顶层模块

`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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237

3、LCD驱动顶层模块

//功能: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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

4、SDRAM控制器顶层模块

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565

5、上位机发送模块


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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

五、工程及套件获取

1、工程获取

A:直接点击下载:基于FPGA:运动目标检测(LCD显示+串口输出,完整工程).zip

B:私信我或添加邮箱获取(完整原理图+源码工程+关键模块仿真)(另外赠送基于FPGA单目标运动检测VGA显示)

2、套件

      觉得调试麻烦的,我手上有几套调试好的套件,有需要的话,可以购买,上电就可以看现象,方便。有需要添加我邮箱:bumianzhe@126.com。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/470083
推荐阅读
相关标签
  

闽ICP备14008679号