|
【国产Tang Primer 25K测评】高云DVI TX(VGA转HDMI)和ROM的IP使用注意点
[复制链接]
本帖最后由 学学学学学学学 于 2024-1-23 23:44 编辑
- 本次以一个HDMI-ROM显示图片的例程为例子,简单看一下在Tang-25K开发板上如何在高云FPGA开发平台运行DVI TX和ROM的IP,以及我碰到的一些问题。(例程借鉴了野火开发板例程以及我自己移植进去的一些代码)
- 首先是DVI TX这个IP例化碰到的问题,我是在编译的时候碰到的
- 报错如下所示:意思是说DVI TX例化输出的tmds_clk_p端口在引脚约束中的电平设置错误。
ERROR (CT1109) : "F:\GOWIN\Project\VGA_ROM\src\VGA_ROM.cst":11 | Illegal attribute type 'IO_TYPE = LVCMOS33D' specified on 'tmds_clk_p'
- 解决办法:把IO电平设置为ELVDS
- 第二个是ROM的IP的使用:
- 其实我本来还想使用芯片所集成的RAM16S这个IP的,但是资源不够,两个RAM的IP都不能储存超过18K的图片数据,报错如下
- RAM资源不够,那么就使用ROM这个IP,依旧是打开IP管理器,搜索pROM,例如图片所示填写方式,我存储的图片数据的地址线位宽(深度)为14bit,所以要填2的14次方,即16384;输出的数据是16位宽,直接填16即可。然后将由图片生成的后缀为 ".mi"的ROM初始化文件路径添加进去。
- 针对高云的ROM初始化要使用的mi文件,这里简单讲一下如何通过matlab,将bmp图片转成mi文件
- 这里程序主要参考了野火生成coe文件的代码和一个博主所发的帖子给出的代码(路径:【FPGA】如何生成.mi文件 - 个人文章 - SegmentFault 思否)
- 我自己简单改代后的matlab文件:里面mi文件和图片的路径要注意更改,以及他们的像素,生成mi文件的图片像素在这段代码里被设置局限在了100*100里,要注意你的图片不能超过这个像素,否则报错。另外就是,我这段代码生成的图片后放进FPGA代码会失真,还是要调一下的,不够我比较懒就。。。。
clear %清理命令行窗口
clc %清理工作区
% 使用imread函数读取图片,并转化为三维矩阵
%image_array = imread('logo.bmp');
image_array = imread('F:/GOWIN/TangPrimer-25K-example-main/ebf_xc6slx16_pro_tutorial_code-master/30_vga_rom_pic_jump/matlab/image2.bmp');
% 使用size函数计算图片矩阵三个维度的大小
% 第一维为图片的高度,第二维为图片的宽度,第三维为图片维度
[height,width,z]=size(image_array); % 100*100*3
red = image_array(:,:,1); % 提取红色分量,数据类型为uint8
green = image_array(:,:,2); % 提取绿色分量,数据类型为uint8
blue = image_array(:,:,3); % 提取蓝色分量,数据类型为uint8
% 使用reshape函数将各个分量重组成一个一维矩阵
%为了避免溢出,将uint8类型的数据扩大为uint32类型
r = uint32(reshape(red' , 1 ,height*width));
g = uint32(reshape(green' , 1 ,height*width));
b = uint32(reshape(blue' , 1 ,height*width));
% 初始化要写入.COE文件中的RGB颜色矩阵
rgb=zeros(1,height*width);
% 导入的图片为24bit真彩色图片,每个像素占用24bit,RGB888
% 将RGB888转换为RGB565
% 红色分量右移3位取出高5位,左移11位作为ROM中RGB数据的第15bit到第11bit
% 绿色分量右移2位取出高6位,左移5位作为ROM中RGB数据的第10bit到第5bit
% 蓝色分量右移3位取出高5位,左移0位作为ROM中RGB数据的第4bit到第0bit
for i = 1:height*width
rgb(i) = bitshift(bitshift(r(i),-3),11)+ bitshift(bitshift(g(i),-2),5)+ bitshift(bitshift(b(i),-3),0);
end
%fid = fopen( 'image.mi', 'w+' );
fid = fopen( 'F:/GOWIN/TangPrimer-25K-example-main/ebf_xc6slx16_pro_tutorial_code-master/30_vga_rom_pic_jump/matlab/image.mi', 'w+' );
% .mi文件字符串打印
fprintf( fid, '#File_format=Hex\n');
fprintf( fid, '#Address_depth=16384\n');
fprintf( fid, '#Data_width=16\n');
% 写入图片数据
for i = 1:height*width
if i == height*width
fprintf(fid,'%04x\n',rgb(i)); %最后一个数据后面加分号
else
if i<=5
fprintf(fid,'%04x\n',rgb(i));
else
fprintf(fid,'%04x\n',rgb(i));
end
end
end
fclose( fid ); % 关闭文件指针
- 碰到的问题就到此为止了,这里仅贴一下顶层文件和效果,会贴上附件,需要的话可以下载,或者私信我?
VGA_ROM.zip
(596.9 KB, 下载次数: 11)
`timescale 1ns/1ns
////////////////////////////////////////////////////////////////////////
// 初始例程来源: 野火_踏浪Pro_FPGA开发板
// 论坛 : http://www.firebbs.cn
////////////////////////////////////////////////////////////////////////
module vga_rom_pic_jump
(
input wire sys_clk , //输入工作时钟,频率50MHz
input wire sys_rst_n , //输入复位信号,低电平有效
// output wire hsync , //输出行同步信号
// output wire vsync , //输出场同步信号
// output wire [15:0] rgb //输出像素信息
//hdmi接口
output tmds_clk_p, // TMDS 时钟通道
output tmds_clk_n,
output [2:0] tmds_d_p, // TMDS 数据通道
output [2:0] tmds_d_n
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
wire hsync ; //输出行同步信号
wire vsync ; //输出场同步信号
wire [15:0] rgb ; //输出像素信息
//wire define
wire vga_clk ; //VGA工作时钟,频率25MHz
wire locked ; //PLL locked信号
wire rst_n ; //VGA模块复位信号
wire [9:0] pix_x ; //VGA有效显示区域X轴坐标
wire [9:0] pix_y ; //VGA有效显示区域Y轴坐标
wire [15:0] pix_data; //VGA像素点色彩信息
//rst_n:VGA模块复位信号
assign rst_n = (sys_rst_n & locked);
//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
Gowin_PLL clk_gen_u0(
.lock (locked ), //output lock
.clkout0(vga_clk ), //output clkout0
.clkin (sys_clk ), //input clkin
.reset (~sys_rst_n ) //input reset
);
wire vga_en;
vga vga_u1(
.clk (vga_clk ),
.rst_n (rst_n ),
.pixel_data (pix_data ),
.data_req (),
.posx (pix_x),
.posy (pix_y),
.hsync (hsync),
.vsync (vsync),
.vga_en (vga_en),
.vga_out (rgb),
.h_disp (), //HDMI屏水平分辨率
.v_disp () //HDMI屏垂直分辨率
);
wire [7:0] r_out ; //输出24位真值信号
wire [7:0] g_out ;
wire [7:0] b_out ;
assign r_out={rgb[15:11],3'b000};
assign g_out={rgb[10:5],2'b00};
assign b_out={rgb[4:0],3'b000};
//例化HDMI驱动模块
DVI_TX_Top HDMI_u2(
.I_rst_n(rst_n), //input I_rst_n
.I_rgb_clk(vga_clk), //input I_rgb_clk
.I_rgb_vs(vsync), //input I_rgb_vs
.I_rgb_hs(hsync), //input I_rgb_hs
.I_rgb_de(vga_en), //input I_rgb_de
.I_rgb_r(r_out), //input [7:0] I_rgb_r
.I_rgb_g(g_out), //input [7:0] I_rgb_g
.I_rgb_b(b_out), //input [7:0] I_rgb_b
.O_tmds_clk_p(tmds_clk_p), //output O_tmds_clk_p
.O_tmds_clk_n(tmds_clk_n), //output O_tmds_clk_n
.O_tmds_data_p(tmds_d_p), //output [2:0] O_tmds_data_p
.O_tmds_data_n(tmds_d_n) //output [2:0] O_tmds_data_n
);
//------------- vga_pic_inst -------------
vga_pic vga_pic_inst(
.vga_clk (vga_clk ), //输入工作时钟,频率25MHz,1bit
.sys_rst_n (rst_n ), //输入复位信号,低电平有效,1bit
.pix_x (pix_x ), //输入VGA有效显示区域像素点X轴坐标,10bit
.pix_y (pix_y ), //输入VGA有效显示区域像素点Y轴坐标,10bit
.pix_data_out (pix_data ) //输出像素点色彩信息,16bit
);
endmodule
|
|