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

FPGA学习笔记——VGA显示静态图片(ROM IP核)

目录

一、任务

二、分析

(1)分析

(2)用MATLAB创建.mif文件

三、配置

四、代码

五、现象


一、任务

将下面这幅图片用VGA进行显示,它的分辨为120x68,其中VGA的模式640x480@60。


二、分析

(1)分析

        首先,知道图片的分辨率,可以知道它的大小120x68 = 8160,在配置ROM IP核的深度的时候就是这么大。

        其次,VGA的模式为640x480@60,它的行同步有效信号640场同步有效信号480,如下图所示。

        首先,先定义好图片的初始坐标X,Y,再根据图片的分辨率来写代码,再图片的有效图像里面给颜色赋值,其它位置就以其它颜色为底色。

(2)用MATLAB创建.mif文件

如何用上面给的图片创建出.mif文件:

        我这里是用MATLAB来生成.mif文件,将上面的图片添加到对应的路径下面,然后运行对应的代码就能生成.mif文件。

代码只能生成RGB565格式的.mif文件

% 读取当前文件夹下名为14.bmp的文件
I = imread('2.jpg'); % 获取图像的尺寸
[height, width, ~] = size(I);% 计算总像素数
total_pixels = height * width;% 新建保存数据的mif文件
fid = fopen('2.mif', 'w+'); % 写入MIF文件的头部信息
fprintf(fid, 'DEPTH = %d;\n', total_pixels);  % 存储单元数量
fprintf(fid, 'WIDTH = 16;\n');  % 每个存储单元的位数
fprintf(fid, 'ADDRESS_RADIX = HEX;\n');  % 地址的进制
fprintf(fid, 'DATA_RADIX = HEX;\n');  % 数据的进制
fprintf(fid, 'CONTENT BEGIN\n');% 像素索引
pixel_index = 0;% 遍历图像的每一个像素
for a = 1:heightfor b = 1:width% 提取当前像素的 RGB 通道值red = I(a, b, 1);green = I(a, b, 2);blue = I(a, b, 3);% 将 8 位通道值转换为 RGB565 对应的位数red_5bit = bitshift(red, -3); % 8 位转 5 位green_6bit = bitshift(green, -2); % 8 位转 6 位blue_5bit = bitshift(blue, -3); % 8 位转 5 位% 合并为 16 位的 RGB565 数据rgb565_pixel = bitshift(uint16(red_5bit), 11) + bitshift(uint16(green_6bit), 5) + uint16(blue_5bit);% 写入地址和数据fprintf(fid, '%04x : %04x;\n', pixel_index, rgb565_pixel);% 递增像素索引pixel_index = pixel_index + 1;end
end% 写入文件结尾信息
fprintf(fid, 'END;');% 关闭文件
fclose(fid); 

三、配置

这里只配置ROM IP核,其它IP核配置可以看看FPGA学习笔记——VGA彩条显示-CSDN博客

注意:要是图片的分辨率太大了,你的ROM可能装不下。


四、代码

top.v

module top (
input       wire            clk         ,
input       wire            rst_n       ,
output      wire    [15:0]  data_rgb    ,
output      wire            Hsync       ,
output      wire            Vsync       
);//vga
wire        	De;
wire	[9:0]   X;
wire	[9:0]   Y;vga vga_u(
.        pclk  (pclk  )  ,
.        rst_n (locked)  ,
.        De    (De    )  , //数据有效信号
.        X     (X     )  ,
.        Y     (Y     )  ,
.        Hsync (Hsync )  , //行同步信号
.        Vsync (Vsync )    //场同步信号
);data1 data1_u(
.      clk      (pclk     ) ,
.      rst_n    (locked   ) ,
.	   X        (X        ) ,
.      Y        (Y        ) ,
.      De       (De       ) ,
.      data_rgb (data_rgb ) 
);wire	  pclk;
wire	  locked;pll	pll_inst (.areset ( !rst_n ),.inclk0 ( clk ),.c0     ( pclk     ),.locked ( locked ));endmodule

vga.v

module vga (
input       wire        pclk    ,
input       wire        rst_n   ,
output      wire  [9:0] X       ,
output      wire  [9:0] Y       ,
output      wire        De      , //数据有效信号
output      wire        Hsync   , //行同步信号
output      wire        Vsync     //场同步信号
);localparam  H_Total = 800 ,//行总像素点H_Addr  = 640 ,//有效像素点H_Right = 8   ,//右边框H_Front = 8   ,//前沿H_Sync  = 96  , //同步H_Back  = 40  , //后沿H_Left  = 8   ;//左边框localparam  V_Total  = 525   ,//场总像素点V_Addr   = 480   ,//有效像素点V_Bottom = 8     ,//底边框V_Front  = 2     ,//前沿V_Sync   = 2     , //同步V_Back   = 25    , //后沿V_Top    = 8     ; //上边框reg     [9:0]   cnt_h,cnt_v;//行周期计数
always @(posedge pclk) beginif(!rst_n)cnt_h <= 0;else if( cnt_h == H_Total - 1 )cnt_h <= 0;elsecnt_h <= cnt_h + 1;
end//场周期计数
always @(posedge pclk) beginif(!rst_n)cnt_v <= 0;else if( cnt_h == H_Total - 1 ) beginif( cnt_v == V_Total - 1 )cnt_v <= 0;elsecnt_v <= cnt_v + 1; endelsecnt_v <= cnt_v;
end//行场同步信号
assign Hsync = (cnt_h < H_Sync ) ? 1 : 0;
assign Vsync = (cnt_v < V_Sync ) ? 1 : 0;
assign De    = ((cnt_h > H_Sync + H_Back + H_Left - 1) &&(cnt_h < H_Sync + H_Back + H_Left + H_Addr) &&(cnt_v >= V_Sync + V_Back + V_Top )  &&(cnt_v <  V_Sync + V_Back + V_Top + V_Addr) ) ? 1 : 0;assign  X = (De == 1) ? (cnt_h - H_Sync - H_Back - H_Left) : 0 ;
assign  Y = (De == 1) ? (cnt_v - V_Sync + V_Back + V_Top ) : 0 ;endmodule

data1.v

module data1 (
input       wire                clk     ,
input       wire                rst_n   ,
input       wire                De      ,
input       wire    [9:0]       X       ,
input		wire	[9:0]		Y		,
output      wire    [15:0]      data_rgb
);
//rom
reg     [13:0]  address;
wire    [15:0]  q;
reg     [3:0]   cnt;parameter SIZE  = 119;//边长
parameter WIDE  = 67 ;reg [15:0] data_reg ;localparam  V_Addr  = 480 ,//有效像素点H_Addr  = 640 ;//有效像素点
parameter   data_x  = 100    ,data_y = 100 ;//首坐标//产生方格
always @(posedge clk) beginif( !rst_n )data_reg <= 0;else if (De) beginif ((X >= data_x && X <= SIZE + data_x) && (Y >= data_y && Y <= data_y + WIDE))data_reg <= q;elsedata_reg <= 16'hffff;endelsedata_reg <= 0;
end//控制地址
always @(posedge clk) beginif(!rst_n)address <= 0;else if ( (X >= data_x && X <= SIZE + data_x) && (Y >= data_y && Y <= data_y + WIDE) )address <= address + 1;else if ( X > SIZE + data_x && Y > data_y + WIDE )address <= 0;elseaddress <= address;
endassign data_rgb = data_reg;rom	rom_inst (.aclr ( !rst_n ),.address ( address ),.clock ( clk ),.q ( q ));endmodule

五、现象


以上就是VGA静态显示图片。

http://www.dtcms.com/a/319189.html

相关文章:

  • 【博弈 拓扑序 缩点】P9220 「TAOI-1」椎名真昼|省选-
  • Bosco-and-Mancuso Filter for CFA Image Denoising
  • 如何快速掌握Excel公式?14天轻松通关
  • LeetCode 面试经典 150_数组/字符串_除自身以外数组的乘积(13_238_C++_中等)(前缀积)
  • Swift 实战:高效设计 Tic-Tac-Toe 游戏逻辑(LeetCode 348)
  • 解决chrome下载crx文件被自动删除,加载未打包的扩展程序时提示“无法安装扩展程序,因为它使用了不受支持的清单版本解决方案”
  • 冷库温湿度物联网监控系统解决方案:冷链智能化
  • 普通冷库如何升级物联网冷库?工业智能网关赋能冷链智能化转型
  • AI摄像机如何为煤矿减少90%违规事故?
  • HarmonyOS 页面跳转新方案:HMRouter 路由框架全方位使用指南与实践案例
  • Axure 高阶设计:打造“以假乱真”的多图片上传组件
  • 如何使用vLLM运行gpt-oss
  • Nodejs》》MySql
  • 单链表专题---暴力算法美学(1)(有视频演示)
  • Keil MDK-ARM V5.42a 完整安装教程
  • 如何使用Ollama在本地运行gpt-oss
  • 09-netty基础-手写rpc-原理-01
  • 上位机知识篇---aptapt-get
  • 全栈:怎么把sql导入SQLserver里面
  • [特殊字符] 2025年生成式大模型部署与推理优化全景解析
  • STM32 串口控制电机运行系统
  • PyTorch + PaddlePaddle 语音识别
  • 【基础】go进阶学习笔记
  • Android渲染/合成底层原理详解
  • B 站 SEO 优化全景指南:从基础到进阶的实操方法
  • 贪心+矩阵算法
  • Oracle 关闭 impdp任务
  • 云原生安全挑战与治理策略:从架构思维到落地实践
  • 基于大数据的美食视频播放数据可视化系统 Python+Django+Vue.js
  • 解读 gpt-oss-120b 和 gpt-oss-20b开源模型