彩条显示:
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