【FPGA】VGA的一些显示代码

彩条显示:

module vga_display(
    input             vga_clk,                  //VGA驱动时钟
    input             sys_rst_n,                //复位信号
    
    input      [ 9:0] pixel_xpos,               //像素点横坐标
    input      [ 9:0] pixel_ypos,               //像素点纵坐标    
    output reg [15:0] pixel_data                //像素点数据
    );    
    
parameter  H_DISP = 10'd640;                    //分辨率——行
parameter  V_DISP = 10'd480;                    //分辨率——列
localparam WHITE  = 16'b10011_111111_11111;     //RGB565 白色
localparam BLACK  = 16'b01100_000000_00000;     //RGB565 黑色
localparam RED    = 16'b11111_000000_00000;     //RGB565 红色
localparam GREEN  = 16'b00000_111111_00000;     //RGB565 绿色
localparam BLUE   = 16'b00000_000000_11111;     //RGB565 蓝色
    
//*****************************************************
//**                    main code
//*****************************************************
//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n)
        pixel_data <= 16'd0;                                  
    else begin
        if((pixel_xpos >= (H_DISP/3)*0) && (pixel_xpos < (H_DISP/3)*1))
            pixel_data <= RED;  
        else if((pixel_xpos >= (H_DISP/3)*1) && (pixel_xpos < (H_DISP/3)*2))
            pixel_data <= GREEN;  
        else 
            pixel_data <= BLUE;  
    end
end

endmodule 

滚动方块:

module vga_display(
    input             vga_clk,                  //VGA驱动时钟
    input             sys_rst_n,                //复位信号
    
    input      [ 9:0] pixel_xpos,               //像素点横坐标
    input      [ 9:0] pixel_ypos,               //像素点纵坐标    
    output reg [15:0] pixel_data                //像素点数据
    );    

//parameter define    
parameter  H_DISP  = 10'd640;                   //分辨率——行
parameter  V_DISP  = 10'd480;                   //分辨率——列

localparam SIDE_W  = 10'd40;                    //边框宽度
localparam BLOCK_W = 10'd40;                    //方块宽度
localparam BLUE    = 16'b00000_000000_11111;    //边框颜色 蓝色
localparam WHITE   = 16'b11111_111111_11111;    //背景颜色 白色
localparam BLACK   = 16'b00000_000000_00000;    //方块颜色 黑色

//reg define
reg [ 9:0] block_x;                             //方块左上角横坐标
reg [ 9:0] block_y;                             //方块左上角纵坐标
reg [21:0] div_cnt;                             //时钟分频计数器
reg        h_direct;                            //方块水平移动方向,1:右移,0:左移
reg        v_direct;                            //方块竖直移动方向,1:向下,0:向上

//wire define   
wire move_en;                                   //方块移动使能信号,频率为100hz

//*****************************************************
//**                    main code
//*****************************************************
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;                   //计数达10ms后清零
    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_xpos >= H_DISP - SIDE_W)
          || (pixel_ypos < SIDE_W) || (pixel_ypos >= V_DISP - SIDE_W))
            pixel_data <= BLUE;                 //绘制边框为蓝色
        else
        if((pixel_xpos >= block_x) && (pixel_xpos < block_x + BLOCK_W)
          && (pixel_ypos >= block_y) && (pixel_ypos < block_y + BLOCK_W))
            pixel_data <= BLACK;                //绘制方块为黑色
        else
            pixel_data <= WHITE;                //绘制背景为白色
    end
end

endmodule 

两个方块:

技术有限,方块间的碰撞没完成

module vga_display(
    input             vga_clk,                  //VGA驱动时钟
    input             sys_rst_n,                //复位信号
    
    input      [ 9:0] pixel_xpos,               //像素点横坐标
    input      [ 9:0] pixel_ypos,               //像素点纵坐标    
    output reg [15:0] pixel_data                //像素点数据
    );    

//parameter define    
parameter  H_DISP  = 10'd640;                   //分辨率——行
parameter  V_DISP  = 10'd480;                   //分辨率——列

localparam SIDE_W  = 10'd40;                    //边框宽度
localparam BLOCK_W = 10'd40;                    //方块宽度
localparam BLUE    = 16'b00000_000000_11111;    //边框颜色 蓝色
localparam WHITE   = 16'b11111_111111_11111;    //背景颜色 白色
localparam BLACK   = 16'b00000_000000_00000;    //方块颜色 黑色
localparam RED		=  16'b11111_000000_00000;    //边框颜色 红色

//reg define
reg [ 9:0] block_x;                             //方块左上角横坐标
reg [ 9:0] block_y;                             //方块左上角纵坐标
reg [21:0] div_cnt;                             //时钟分频计数器
reg        h_direct;                            //方块水平移动方向,1:右移,0:左移
reg        v_direct;                            //方块竖直移动方向,1:向下,0:向上

reg [ 9:0] block_x2;                             //方块左上角横坐标
reg [ 9:0] block_y2;                             //方块左上角纵坐标
reg        h_direct2;                            //方块水平移动方向,1:右移,0:左移
reg        v_direct2;                            //方块竖直移动方向,1:向下,0:向上


//wire define   
wire move_en;                                   //方块移动使能信号,频率为100hz,也就是10ms
reg V_en; 

//*****************************************************
//**                    main code
//*****************************************************
assign move_en = (div_cnt == 22'd250000 - 1'b1) ? 1'b1 : 1'b0;	// VGA的驱动频率为25Mhz,要达到100hz则需要延迟250000时延

//通过对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;                   //计数达10ms后清零
    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

//2方块移动到边界时,改变移动方向
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
		  h_direct2 <= 1'b0;                       //方块初始水平向右移动
        v_direct2 <= 1'b1;                       //方块初始竖直向下移动
    end
    else begin
        if(block_x2 == SIDE_W - 1'b1)            //到达左边界时,水平向右
            h_direct2 <= 1'b1;               
        else if(block_x2 == H_DISP - SIDE_W - BLOCK_W)
            h_direct2 <= 1'b0;               
            
        else if(block_y2 == SIDE_W - 1'b1)            //到达上边界时,竖直向下
            v_direct2 <= 1'b1;                
        else if(block_y2 == V_DISP - SIDE_W - BLOCK_W)
            v_direct2 <= 1'b0;               
		  
		  // 第一个角,竖边和横边
		  else if((block_x2 == block_x + BLOCK_W) && (block_y2 >= block_y) && (block_y2 <= block_y + BLOCK_W)
					&&(block_y2 == block_y + BLOCK_W) && (block_x2 >= block_x) && (block_x2 <= block_x + BLOCK_W))begin
						h_direct2<= ~h_direct2;
						v_direct2<= ~v_direct2;
					end
			
			// 第2个角
		  else if((block_x2 + BLOCK_W == block_x) && (block_y2 >= block_y) && (block_y2 <= block_y + BLOCK_W)
					&&(block_y2 == block_y + BLOCK_W) && (block_x2 + BLOCK_W >= block_x) && (block_x2 + BLOCK_W <= block_x + BLOCK_W))begin
						h_direct2<= ~h_direct2;
						v_direct2<= ~v_direct2;
					end
					
		  // 第3个角
		  else if((block_y2 + BLOCK_W == block_y) && (block_x2 >= block_x) && (block_x2 <= block_x + BLOCK_W)
					&&(block_x2 == block_x + BLOCK_W) && (block_y2 + BLOCK_W >= block_y) && (block_y2 + BLOCK_W <= block_y + BLOCK_W))begin
						h_direct2<= ~h_direct2;
						v_direct2<= ~v_direct2;
					end
		
		// 第4个角
		  else if((block_y2 + BLOCK_W == block_y) && (block_x2 + BLOCK_W >= block_x) && (block_x2 + BLOCK_W <= block_x + BLOCK_W)
					&&(block_x2 + BLOCK_W == block_x) && (block_y2 + BLOCK_W >= block_y) && (block_y2 + BLOCK_W <= block_y + BLOCK_W))begin
						h_direct2<= ~h_direct2;
						v_direct2<= ~v_direct2;
					end
		
		  
//		  else if((block_x2 >= block_x) && (block_x2 <= block_x + BLOCK_W)			// 两个块相撞
//			&&(block_y2 >= block_y) && (block_y2 <= block_y + BLOCK_W)				// 第一个角
//			
//			&&(block_x2 + BLOCK_W >= block_x) && (block_x2 + BLOCK_W <= block_x + BLOCK_W)	// 第2个角
//			
//			&&(block_y2 + BLOCK_W >= block_y) && (block_y2 + BLOCK_W <= block_y + BLOCK_W) // 第3个角
//						
//			&&(block_x2+ BLOCK_W >= block_x) && (block_x2+ BLOCK_W <= block_x + BLOCK_W)	// 第4个角
//			&&(block_y2+ BLOCK_W >= block_y) && (block_y2+ BLOCK_W <= block_y + BLOCK_W))begin
//				h_direct2<= ~h_direct2;
//				v_direct2<= ~v_direct2;
//			end
//			else	begin
//				h_direct2<= h_direct2;
//				v_direct2<= v_direct2;
//			end
		  
    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;                       //方块初始竖直向下移动
//		  h_direct2 <= 1'b1;                       //方块初始水平向右移动
//        v_direct2 <= 1'b1;                       //方块初始竖直向下移动
//    end
//	 else begin
//		  if((block_x2 > block_x + BLOCK_W) && (block_x2 <= block_x - BLOCK_W)
//			&&(block_y2 > block_y + BLOCK_W) && (block_y2 <= block_y - BLOCK_W))begin
//				h_direct <= h_direct ; 
//				v_direct <= v_direct ; 
//				h_direct2<= h_direct2;
//				v_direct2<= v_direct2;
//			end
//			else	begin
//				h_direct <= ~h_direct ; 
//				v_direct <= ~v_direct ; 
//				h_direct2<= ~h_direct2;
//				v_direct2<= ~v_direct2;
//			end
//	 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

//2方块移动方向,改变其纵横坐标
always @(posedge vga_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        block_x2 <= 22'd300;                     //方块初始位置横坐标
        block_y2 <= 22'd300;                     //方块初始位置纵坐标
    end
    else if(move_en) begin
        if(h_direct2) 
            block_x2 <= block_x2 + 1'b1;          //方块向右移动
        else
            block_x2 <= block_x2 - 1'b1;          //方块向左移动
            
        if(v_direct2) 
            block_y2 <= block_y2 + 1'b1;          //方块向下移动
        else
            block_y2 <= block_y2 - 1'b1;          //方块向上移动
    end
    else begin
        block_x2 <= block_x2;
        block_y2 <= block_y2;
    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_xpos >= H_DISP - SIDE_W)
          || (pixel_ypos < SIDE_W) || (pixel_ypos >= V_DISP - SIDE_W))
            pixel_data <= BLUE;                 //绘制边框为蓝色
        else
        if((pixel_xpos >= block_x) && (pixel_xpos < block_x + BLOCK_W)
          && (pixel_ypos >= block_y) && (pixel_ypos < block_y + BLOCK_W))
            pixel_data <= BLACK;                //绘制方块为黑色
			else if((pixel_xpos >= block_x2) && (pixel_xpos < block_x2 + BLOCK_W)
          && (pixel_ypos >= block_y2) && (pixel_ypos < block_y2 + BLOCK_W))
				pixel_data <= RED;						//绘制方块2为红色
        else
            pixel_data <= WHITE;                //绘制背景为白色
    end
end

endmodule 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的FPGA VGA显示彩条的代码示例: ```verilog module vga_color_bar( input clk, // 像素时钟 input rst_n, // 复位信号 output reg [7:0] r, // 红色分量 output reg [7:0] g, // 绿色分量 output reg [7:0] b, // 蓝色分量 output reg hsync, // 水平同步信号 output reg vsync // 垂直同步信号 ); parameter SCREEN_WIDTH = 640; parameter SCREEN_HEIGHT = 480; parameter H_SYNC_PULSE_WIDTH = 96; parameter H_BACK_PORCH = 48; parameter H_FRONT_PORCH = 16; parameter V_SYNC_PULSE_WIDTH = 2; parameter V_BACK_PORCH = 33; parameter V_FRONT_PORCH = 10; reg [9:0] h_count = 0; reg [8:0] v_count = 0; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin h_count <= 0; v_count <= 0; r <= 8'd0; g <= 8'd0; b <= 8'd0; hsync <= 1'b0; vsync <= 1'b0; end else begin if(h_count == SCREEN_WIDTH + H_SYNC_PULSE_WIDTH + H_BACK_PORCH + H_FRONT_PORCH - 1) begin h_count <= 0; if(v_count == SCREEN_HEIGHT + V_SYNC_PULSE_WIDTH + V_BACK_PORCH + V_FRONT_PORCH - 1) begin v_count <= 0; r <= 8'd0; g <= 8'd0; b <= 8'd0; hsync <= 1'b0; vsync <= 1'b0; end else begin v_count <= v_count + 1; hsync <= 1'b0; vsync <= (v_count >= SCREEN_HEIGHT + V_BACK_PORCH && v_count < SCREEN_HEIGHT + V_BACK_PORCH + V_SYNC_PULSE_WIDTH); end end else begin h_count <= h_count + 1; hsync <= (h_count >= SCREEN_WIDTH + H_BACK_PORCH && h_count < SCREEN_WIDTH + H_BACK_PORCH + H_SYNC_PULSE_WIDTH); if(v_count >= V_BACK_PORCH && v_count < V_BACK_PORCH + SCREEN_HEIGHT) begin r <= h_count[3:0] * 32; g <= h_count[3:0] * 8; b <= h_count[3:0] * 2; end else begin r <= 8'd0; g <= 8'd0; b <= 8'd0; end end end end endmodule ``` 该代码使用Verilog语言实现,使用了同步信号和计数器控制VGA信号的输出,通过改变红、绿、蓝三种颜色的分量实现彩条的渐变效果。注意:该代码只是一个简单的示例,实际使用时需要根据具体的FPGA开发板和显示器的参数进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值