当前位置: 首页 > article >正文

HDMI色块移动——FPGA学习笔记13

一、方块移动原理

二、实验任务

        使用FPGA开发板上的HDMI接口在显示器上显示一个不停移动的方块,要求方块移动到边界处时能够改变移动方向。显示分辨率为800*480,刷新速率为90hz。(480p分辨率为800*480,像素时钟频率Vga_clk = 800x480x90 = 33264000 ≈33.3Mhz(误差忽略不计))

三、程序设计

1、video_display框图:

`timescale 1ns / 1ps

module video_display(
    input               pixel_clk   ,//驱动时钟
    input               sys_rst_n   ,//复位信号   

    input       [10:0]  pixel_xpos  ,//像素点横坐标
    input       [10:0]  pixel_ypos  ,//像素点纵坐标
    output  reg [23:0]  pixel_data   //像素点数据

);

parameter   H_DISP  = 11'd800       ;           //分辨率   行
parameter   V_DISP  = 11'd480       ;           //分辨率   列
parameter   DIV_CNT = 22'd750000    ;           //分辨率计数器

localparam  SIDE_W  = 11'd40        ;           //屏幕边框宽度
localparam  BLOCK_W = 11'd20        ;           //方块宽度
localparam  BLUE    = 24'h0000ff    ;           //屏幕边框颜色          蓝色
localparam  WHITE   = 24'hffffff    ;           //背景颜色              白色
localparam  BLACK   = 24'h000000    ;           //方块颜色              黑色

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

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

assign  move_en = (div_cnt == DIV_CNT - 1'd1) ? 1'd1 : 1'd0;

//时钟计数器,实现时钟分频
always @(posedge pixel_clk or negedge sys_rst_n ) begin
    if (!sys_rst_n) begin
        div_cnt <= 22'd0;    
    end 
    else begin
        if (div_cnt < DIV_CNT - 1'd1) begin            
            div_cnt <= div_cnt + 1'd1;
        end 
        else begin
            div_cnt <= 22'd0;    //技术到10ms清零
        end
    end
end

//当方块移动到边界时,改变移动方向
 always @(posedge pixel_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) begin     //到达左边界,水平向右
            h_direct <= 1'b1;
        end 
        else begin                              //到达有边界,水平向左  
            if(block_x == H_DISP - SIDE_W - BLOCK_W + 1'd1)begin
                h_direct <= 1'b0; 
            end
            else begin
                h_direct <= h_direct;
            end
        end

        if (block_y == SIDE_W + 1'b1) begin     //到达上边界,竖直向下
            v_direct <= 1'b1;
        end 
        else begin                              //到达下边界,竖直向上
            if(block_y == V_DISP - SIDE_W - BLOCK_W + 1'b1)begin                          
                v_direct <= 1'b0;                           
            end
            else begin
                v_direct <= v_direct;
            end
        end 
    end
 end

//根据方块移动方向,改变横纵坐标
always @(posedge pixel_clk or negedge sys_rst_n ) begin
    if (!sys_rst_n) begin 
        block_x <= SIDE_W + 1'b1;               //方块初始位置横坐标
        block_y <= SIDE_W + 1'b1;               //方块初始位置纵坐标
    end 
    else if(move_en == 1'b1)begin
        if (h_direct == 1'b1) begin
            block_x <= block_x + 1'b1;          //方块向右移动
        end 
        else begin
            block_x <= block_x -1'b1;           //方块向左移动
        end

        if (v_direct == 1'b1) begin
            block_y <= block_y + 1'b1;          //方块向下移动    
        end 
        else begin
            block_y <= block_y -1'b1;           //方块向上移动
        end
    end
    else begin
        block_x <= block_x;
        block_y <= block_y;
    end
end

//对区域给出颜色数据
always @(posedge pixel_clk or negedge sys_rst_n ) begin
    if (!sys_rst_n) begin
        pixel_data <= BLACK;
    end 
    else begin
        if ((pixel_xpos < SIDE_W) || (pixel_xpos >= H_DISP - SIDE_W) || 
            (pixel_ypos <= SIDE_W) || (pixel_ypos > V_DISP - SIDE_W)) begin
            pixel_data <= BLUE;
        end 
        else begin
            if ((pixel_xpos >= block_x -1'b1) && (pixel_xpos < block_x + BLOCK_W - 1'b1) && 
                (pixel_ypos >= block_y) && (pixel_ypos < block_y + BLOCK_W - 1'b1)) begin
                pixel_data <= BLACK;
            end 
            else begin
                pixel_data <= WHITE;
            end
        end    
    end
end

endmodule

其他部分完全延用上一章代码

HDMI彩条显示——FPGA学习笔记12-CSDN博客

2、整体代码框架

3、bug更正 

上一章中该部分表述错误

实际应为800*480*90 = 34560000约等于33.3Mhz

四、仿真分析

五、下载验证

六、总结 


http://www.kler.cn/a/310237.html

相关文章:

  • WPF学习之路,控件的只读、是否可以、是否可见属性控制
  • 使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
  • 常用的Anaconda Prompt命令行指令
  • spring中r类是什么
  • 天才的懈怠 : 平衡二叉树
  • fastapi 查询参数支持 Pydantic Model:参数校验与配置技巧
  • VulhubDC-4靶机详解
  • Linux系统性能调优技巧详解
  • 『功能项目』回调函数处理死亡【54】
  • docker基础学习
  • C++调用C# DLL之踩坑记录
  • Oracle 数据库安装和配置教程
  • 每日学习一个数据结构-红黑树
  • 电脑怎么录屏?四款录屏工具分享
  • C++ | Leetcode C++题解之第416题分割等和子集
  • python简单易懂的lxml读取HTML节点及常用操作方法
  • 前端大模型入门:掌握langchain的核心Runnable接口(一)
  • 全面升级!最新版抖音蓝V商家采集软件,海量资源一网打尽
  • redis集群常用命令梳理
  • 高级java每日一道面试题-2024年9月17日-框架篇-什么是ORM框架?
  • C++---类与对象一
  • wpf 使用Oxyplot 库制作图表示例
  • QT 6.8 C++ snap库 连接西门子PLC
  • 激光雷达点云处理—学习随记
  • 「数据科学」清洗数据,真实数据集中缺失值的查看与处理
  • 高效开发,从暗藏玄机的文件系统开始—合宙Air201资产定位模组LuatOS