VGA彩条/方块移动实验

VGA Video Graphics Array
视频图形阵列,一种使用模拟信号进行视频传输的标准
在这里插入图片描述
接口定义
在这里插入图片描述
行同步时序
行扫描,一行扫描周期扫完后继续下一行扫描
在这里插入图片描述
场同步时序
一次场扫描周期中可以完成一帧图像的显示,单位是一个完整的行扫描周期
在这里插入图片描述
分辨率
@60:每秒钟刷新60次
时钟计算:800x525x60=25200000,与时钟周期有微小差异
在这里插入图片描述
系统框图:
在这里插入图片描述
顶层模块原理图
在这里插入图片描述
代码

module vga_colorbar(
	input			sys_clk,
	input			sys_rst_n,
	
	output			vga_hs,
	output			vga_vs,
	output	[15:0]	vga_rgb
);

	wire			vga_clk_w;
	wire			locked_w;
	wire			rst_n_w;
	wire	[15:0]	pixel_data_w;
	wire	[9:0]	pixel_xpos_w;
	wire	[9:0]	pixel_ypos_w;
	
	assign rst_n_w = sys_rst_n & locked_w;
	
	vga_pll u_vga_pll(
		.inclk0		(sys_clk),
		.areset		(~sys_rst_n),
		
		.c0			(vga_clk_w),
		.locked_w	(locked_w)
	);
	
	vga_driver u_vga_driver(
		.vga_clk	(vga_clk_w),
		.sys_rst_n	(rst_n_w),
		
		.vga_hs		(vga_hs),
		.vga_vs		(vga_vs),
		.vga_rgb	(vga_rgb),
		
		.pixel_data	(pixel_data_w),
		.pixel_xpos	(pixel_xpos_w),
		.pixel_ypos	(pixel_ypos_w)
	);
	
	vga_display u_vga_display(
		.vga_clk	(vga_clk_w),
		.sys_rst_n	(rst_n_w),	

		.pixel_data	(pixel_data_w),
		.pixel_xpos	(pixel_xpos_w),
		.pixel_ypos	(pixel_ypos_w)		
	);
	
endmodule

module	vga_driver(
	input			vga_clk	  ,
	input			sys_rst_n,	
							  
	output			vga_hs		,  //行同步信号
	output			vga_vs		,//场同步信号
	output	[15:0]	vga_rgb	  ,//红绿蓝三原色输出
							 
	input	[15:0]	pixel_data,	//像素点数据
	output	[9:0]	pixel_xpos,	//像素点横坐标
	output	[9:0]	pixel_ypos	//像素点纵坐标
);

	parameter	H_SYNC	= 10'd96;  //行同步
	parameter	H_BACK	= 10'd48;  //行显示后沿
	parameter	H_DISP	= 10'd640; //行有效数据
	parameter	H_FRONT	= 10'd16;  //行显示前沿
	parameter	H_TOTAL	= 10'd800; //行扫描周期 
	
	parameter	V_SYNC	= 10'd2;   //场同步
	parameter	V_BACK	= 10'd33;  //场显示后沿
	parameter	V_DISP	= 10'd480; //场有效数据
	parameter	V_FRONT = 10'd10;  //场显示前沿
	parameter	V_TOTAL = 10'd525; //场扫描周期
	
	reg	[9:0]	cnt_h;
	reg	[9:0]	cnt_v;
	
	wire		vga_en;
	wire		data_req;
	
	assign	vga_hs = (cnt_h <= H_SYNC - 1'b1)?1'b0:1'b1;
	assign	vga_vs = (cnt_v <= V_SYNC - 1'b1)?1'b0:1'b1;
	
	assign	vga_en = (((cnt_h >= H_SYNC + H_BACK) && (cnt_h < H_SYNC + H_BACK + H_DISP))
					  && ((cnt_v >= V_SYNC + V_BACK) && (cnt_v < V_SYNC + V_BACK + V_DISP)))
					  ? 1'b1:1'b0;
	
	//RGB565数据输出
	assign	vga_rgb = vga_en ? pixel_data : 16'd0;
	
	//请求像素点颜色数据输入
	assign	vga_req = (((cnt_h >= H_SYNC + H_BACK - 1'b1) && (cnt_h < H_SYNC + H_BACK + H_DISP - 1'b1))
					  && ((cnt_v >= V_SYNC + V_BACK) && (cnt_v < V_SYNC + V_BACK + V_DISP)))
					  ? 1'b1:1'b0;	

	//像素点坐标
	assign pixel_xpos = data_req ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'd0;
	assign pixel_ypos = data_req ? (cnt_v - (V_SYNC + V_BACK - 1'b1)) : 10'd0;

	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			cnt_h <= 10'd0;
		else begin
			if(cnt_h < H_TOTAL - 1'b1)
				cnt_h <= cnt_h + 1'b1;
			else
				cnt_h <= 10'd0;
		end
	end
	
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			cnt_v <= 10'd0;
		else if(cnt_h == H_TOTAL = 1'b1) begin
			if(cnt_v < V_TOTAL - 1'b1)
				cnt_v <= cnt_v + 1'b1;
			else
				cnt_v <= 10'd0;
		end
	end

endmodule

module vga_display(
	input				vga_clk	  ,
	input				sys_rst_n,	
								  ,
	input		[9:0]	pixel_data,
	input		[9:0]	pixel_xpos,
	output	reg	[15:0]	pixel_ypos
);

	parameter	H_DISP = 10'd640; //分辨率--行
	parameter	V_DISP = 10'd480; //分辨率--列
	localparam	WHITE  = 16'b11111_11111_11111; 
	localparam	BLACK  = 16'b00000_00000_00000; 
	localparam	RED    = 16'b11111_00000_00000; 
	localparam	GREEN  = 16'b00000_11111_00000; 
	localparam	BLUE   = 16'b00000_00000_11111; 
	
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			pixel_data <= 16'd0;
		else begin
			if((pixel_data >= 0) && (pixel_xpos <= (H_DISP/5)*1))
				pixel_data <= WHITE;
			else if((pixel_data >= (H_DISP/5)*1)) && (pixel_xpos <= (H_DISP/5)*2))
				pixel_data <= BLACK;
			else if((pixel_data >= (H_DISP/5)*2)) && (pixel_xpos <= (H_DISP/5)*3))
				pixel_data <= RED;
			else if((pixel_data >= (H_DISP/5)*3)) && (pixel_xpos <= (H_DISP/5)*4))
				pixel_data <= GREEN;
			else
				pixel_data <= BLUE;
		end
	end

endmodule

显示结果:
在这里插入图片描述
方块移动只需要更改上述代码的display模块

module vga_display(
	input				vga_clk	  ,
	input				sys_rst_n,	
								  ,
	input		[9:0]	pixel_data,
	input		[9:0]	pixel_xpos,
	output	reg	[15:0]	pixel_ypos
);
	parameter	H_DISP = 10'd640;
	parameter	V_DISP = 10'd480;
	
	localparam	SIDE_W  = 10'd40;
	localparam	BLOCK_W = 10'd40;
	localparam	BLUE	= 16'b00000_00000_11111;
	localparam	WHITE  = 16'b11111_11111_11111; 
	localparam	BLACK  = 16'b00000_00000_00000; 
	
	reg	[9:0]	block_x;
	reg	[9:0]	block_y;
	reg	[21:0]	div_cnt;
	reg			h_direct;
	reg			v_direct;
	
	wire		move_en;
	
	assign	move_en = (div_cnt == 22'd250000 - 1'b1)? 1'b1:1'b0;
	
	//通过对vga驱动时钟技术,实现时钟分频
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			div_cnt <= 22'd0;
		else begin
			if(div_cnt < 22'd250000 - 1'b1)
				div_cnt <= div_cnt + 1'b1;
			else
				div_cnt <= 22'd0;
		end
	end
	
	//当方块移动到边界时,改变移动方向
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n) begin
			h_direct <= 1'b1;
			v_direct <= 1'b1;
		end
		else begin
			if(block_x == SIDE_W - 1'b1)
				h_direct <= 1'b1;
			else
			if(block_x == H_DISP - SIDE_W - BLOCK_W)
				h_direct <= 1'b0;
			else	
				h_direct <= h_direct;
			if(block_y == SIDE_W - 1'b1)
				v_direct <= 1'b1;
			else
			if(block_y == V_DISP - SIDE_W - BLOCK_W)
				v_direct <= 1'b0;
			else
				v_direct <= v_direct; 
		end
	end
	
	//根据方块移动方向,改变其纵横坐标
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n) begin	
			block_x <= 22'd100;
			block_y <= 22'd100;
		end
		else if(move_en) begin
			if(h_direct)
				block_x <= block_x + 1'b1;
			else
				block_x <= block_x - 1'b1;
			if(v_direct)
				block_y <= block_y + 1'b1;
			else
				block_y <= block_y - 1'b1;
		end
		else begin
			block_x <= block_x;
			block_y <= block_y;			
		end
	end
	
	//给不同的区域绘制不同的颜色
	always @(posedge vga_clk or negedge sys_rst_n) begin
		if(!sys_rst_n)
			pixel_data <= BLACK;
		else begin
			if((pixel_xpos < SIDE_W) || (pixel_data >= H_DISP - SIDE_W)
			   || (pixel_ypos < SIDE_W) || (pixel_data >= V_DISP - SIDE_W))
			    pixel_data <= BLUE;
			else
			if((pixel_xpos >= block_x) || (pixel_data < block_x + BLOCK_W)
			   || (pixel_ypos >= block_y) || (pixel_data < block_y + BLOCK_W))
			    pixel_data <= BLUE;
			else
				pixel_data <= WHITE;
		end
	end
endmodule
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值