搜索
bottom↓
回复: 18

fpga通过vga来显示图像的问题求教

[复制链接]

出0入0汤圆

发表于 2013-4-18 10:20:58 | 显示全部楼层 |阅读模式
最近在做fpga的vga的显示,把一张图像转化为.coe文件储存rom,通过vga接口显示图像,总是显示不了,希望大神能够解答。附上程序
`timescale 1ns / 1ps
module vgab(clk, rst, hsync, vsync, vga_r, vga_g, vga_b);
   input           clk;
   input           rst;
   
   output          hsync;
   output          vsync;
   output [2:0]    vga_r;
   output [2:0]    vga_g;
   output [1:0]    vga_b;
   
   
   wire            pclk;
   wire            valid;
   wire [9:0]      h_cnt;
   wire [9:0]      v_cnt;
   reg [7:0]       vga_data;
   
   reg [17:0]      rom_addr;
   wire [7:0]      douta;
        reg                [1:0]        rClk;
        always@(posedge clk)        rClk<=        rClk+1;//rclk为25MHz
        assign        plck=        rClk[0];

        logo_rom u1 (
                .clka(pclk),      // input clka
                .addra(rom_addr), // input [12 : 0] addra
                .douta(douta)     // output [7 : 0] douta
                );

        vga_640x480 u2 (
                .pclk(pclk),
                .reset(rst),
                .hsync(hsync),
                .vsync(vsync),
                .valid(valid),
                .h_cnt(h_cnt),
                .v_cnt(v_cnt)
                );

   
   
   always @(posedge pclk or negedge rst)
   begin
      if (!rst)
         vga_data <= 8'b00000000;
      else
      begin
         if (valid == 1'b0)
                        begin
            vga_data <= 8'b00000000;
            rom_addr <= 18'b000000000000000010;
                        end
         else
                        begin
               rom_addr <= rom_addr + 18'b000000000000000001;
               vga_data <= douta;
         end
      end
   end
   
   assign vga_r = vga_data[7:5];
   assign vga_g = vga_data[4:2];
   assign vga_b = vga_data[1:0];
   
endmodule   





`timescale 1 ns / 1 ns
module vga_640x480(pclk, reset, hsync, vsync, valid, h_cnt, v_cnt);
   input        pclk;
   input        reset;
   output       hsync;
   output       vsync;
   output       valid;
   output [9:0] h_cnt;
   output [9:0] v_cnt;
   
   parameter    h_frontporch = 96;
   parameter    h_active = 144;
   parameter    h_backporch = 784;
   parameter    h_total = 800;
   
   parameter    v_frontporch = 2;
   parameter    v_active = 35;
   parameter    v_backporch = 515;
   parameter    v_total = 525;
   
   reg [9:0]    x_cnt;
   reg [9:0]    y_cnt;
   
   wire         h_valid;
   wire         v_valid;
   
   
   always @(posedge reset or posedge pclk)
      if (reset == 1'b1)
         x_cnt <= 1;
      else
      begin
         if (x_cnt == h_total)
            x_cnt <= 1;
         else
            x_cnt <= x_cnt + 1;
      end
   
   
   always @(posedge pclk)
      if (reset == 1'b1)
         y_cnt <= 1;
      else
      begin
         if (y_cnt == v_total & x_cnt == h_total)
            y_cnt <= 1;
         else if (x_cnt == h_total)
            y_cnt <= y_cnt + 1;
      end
   
   assign hsync = ((x_cnt > h_frontporch)) ? 1'b1 :
                  1'b0;
   assign vsync = ((y_cnt > v_frontporch)) ? 1'b1 :
                  1'b0;
   
   assign h_valid = ((x_cnt > h_active) & (x_cnt <= h_backporch)) ? 1'b1 :
                    1'b0;
   assign v_valid = ((y_cnt > v_active) & (y_cnt <= v_backporch)) ? 1'b1 :
                    1'b0;
   
   assign valid = ((h_valid == 1'b1) & (v_valid == 1'b1)) ? 1'b1 :
                  1'b0;
   
   assign h_cnt = ((h_valid == 1'b1)) ? x_cnt - 144 :
                  {10{1'b0}};
   assign v_cnt = ((v_valid == 1'b1)) ? y_cnt - 35 :
                  {10{1'b0}};
   
endmodule



阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-4-18 11:22:52 | 显示全部楼层
希望大家能够解答一下,谢谢!

出0入0汤圆

发表于 2013-4-18 19:04:32 | 显示全部楼层
reset rst 一高电平复位,一低电平复位 ?

出0入0汤圆

 楼主| 发表于 2013-4-18 19:48:33 | 显示全部楼层
wang110 发表于 2013-4-18 19:04
reset rst 一高电平复位,一低电平复位 ?

谢谢你的回答!但是都改成低电平了,还是不行

出0入0汤圆

发表于 2013-4-18 21:58:09 | 显示全部楼层
首先看下显示器是否识别了640*480模式,否则需检查hsync、vsync。
另外,在消隐期间,vga_r,vga_g,vga_b应送0

出0入0汤圆

 楼主| 发表于 2013-4-19 09:10:36 | 显示全部楼层
wang110 发表于 2013-4-18 21:58
首先看下显示器是否识别了640*480模式,否则需检查hsync、vsync。
另外,在消隐期间,vga_r,vga_g,vga_b ...

怎么看显示器有没有识别640*480模式?不懂,就是显示器一点都不显示!

出0入0汤圆

发表于 2013-4-19 22:30:50 | 显示全部楼层
本帖最后由 wang110 于 2013-4-19 22:32 编辑

VGA800*600显示。图像从ROM中读取,ROM大小2048*16,随意保存的文件,非图片。

ISE14.1

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-22 09:18:49 | 显示全部楼层
wang110 发表于 2013-4-19 22:30
VGA800*600显示。图像从ROM中读取,ROM大小2048*16,随意保存的文件,非图片。

ISE14.1 ...

谢谢你给的程序!请问一下,这个是基于xilinx的那个开发板编的?

出0入0汤圆

 楼主| 发表于 2013-4-22 09:34:43 | 显示全部楼层
wang110 发表于 2013-4-19 22:30
VGA800*600显示。图像从ROM中读取,ROM大小2048*16,随意保存的文件,非图片。

ISE14.1 ...

你是基于xc3s50的芯片,不知道你对zedboard这个开发板知道的多少?我就是想通过zedboard的fpga部分实现vga图片显示,vga的引脚rgb各有四个

出0入0汤圆

发表于 2013-4-22 10:47:30 | 显示全部楼层
本帖最后由 Codoox 于 2013-4-22 10:49 编辑

zynq 逻辑实现跟普通FPGA没有区别吧

出0入0汤圆

发表于 2013-4-22 11:06:28 | 显示全部楼层
   always @(posedge pclk or negedge rst)
   begin
      if (!rst)
         vga_data <= 8'b00000000;
      else
      begin
         if (valid == 1'b0)
                        begin
            vga_data <= 8'b00000000;
            rom_addr <= 18'b000000000000000010;
                        end
         else
                        begin
               rom_addr <= rom_addr + 18'b000000000000000001;
               vga_data <= douta;
         end
      end
   end

应该将h_cnt和v_cnt拼接后作为rom读地址

出0入0汤圆

 楼主| 发表于 2013-4-22 11:35:38 | 显示全部楼层
Codoox 发表于 2013-4-22 11:06
always @(posedge pclk or negedge rst)
   begin
      if (!rst)


谢谢你的回答!嗯,zedboard的fpga部分和其他的没有什么区别。我设置vailid为1的时候,即在有效的区域内的,地址加1的

出0入0汤圆

 楼主| 发表于 2013-4-22 14:36:45 | 显示全部楼层
Codoox 发表于 2013-4-22 11:06
always @(posedge pclk or negedge rst)
   begin
      if (!rst)

您说的h_cnt和v_cnt拼接是不是要在有效区内呀?是h_cnt>10'd0和v_cnt>10'd0这个意思吗?

出0入0汤圆

发表于 2013-4-22 15:30:15 | 显示全部楼层
zjixxw 发表于 2013-4-22 14:36
您说的h_cnt和v_cnt拼接是不是要在有效区内呀?是h_cnt>10'd0和v_cnt>10'd0这个意思吗? ...

有这层意思,ROM里面存的是640*480的图像,即有效显示区域的大小,像素地址应该是实际有效区域地址,即h_cnt和V_cnt拼接所得。
valid有效计数肯定大于640*480,用这个计数值来寻址是不对的。
我猜你是参考了别人的代码,没有完全消化吧

出0入0汤圆

 楼主| 发表于 2013-4-22 15:52:53 | 显示全部楼层
Codoox 发表于 2013-4-22 15:30
有这层意思,ROM里面存的是640*480的图像,即有效显示区域的大小,像素地址应该是实际有效区域地址,即h_ ...

你好,我把我的程序改成这样了。但是还是没有显示
  assign ready = ((v_cnt >=1) & (v_cnt <= 480) & (h_cnt >=1) & (h_cnt <=640)) ? 1'b1 : 1'b0 ;
       
  always @(posedge pclk or negedge rst)
   begin
      if (!rst)
         vga_data <= 8'b00000000;
      else
      begin
         if (valid == 1'b1)
         begin
            if (ready == 1'b1)
            begin
               rom_addr <= rom_addr + 18'b000000000000000001;
               vga_data <= douta;
            end
            else
            begin
               rom_addr <= rom_addr;
            end
         end
         else
         begin
            if (v_cnt == 0)
               rom_addr <= 18'b000000000000000010;
         end
      end
   end

出0入0汤圆

发表于 2013-4-22 16:08:54 | 显示全部楼层
zjixxw 发表于 2013-4-22 15:52
你好,我把我的程序改成这样了。但是还是没有显示
  assign ready = ((v_cnt >=1) & (v_cnt =1) & (h_cnt ...

如果显示错乱的话可能是上面所说的问题,如果是一概都不显示,那问题有可能是:
1.行场时序产生不对,偏离标准值太大;
2.ROM初始化不成功,
3.初始化ROM成功,读取有问题。
你可以排查一下:
用示波器看一下行场时序对不对,(这个可以从代码就可以计算出来),先排除问题1;
或者给图像数据赋不同的纯色图片值,如果能随不同的值有所改变,即排除问题1;
监测一下ROM读地址是否变化,如果变化,说明ROM值是一样的,即ROM初始化不成功。

出0入0汤圆

发表于 2013-4-22 16:53:41 | 显示全部楼层
zjixxw 发表于 2013-4-19 09:10
怎么看显示器有没有识别640*480模式?不懂,就是显示器一点都不显示!

同步头的问题吧!

出0入0汤圆

 楼主| 发表于 2013-4-22 17:12:47 | 显示全部楼层
孙风雷 发表于 2013-4-22 16:53
同步头的问题吧!

那请问一下应该怎么改呢?

出0入0汤圆

 楼主| 发表于 2013-4-22 21:02:04 | 显示全部楼层
Codoox 发表于 2013-4-22 16:08
如果显示错乱的话可能是上面所说的问题,如果是一概都不显示,那问题有可能是:
1.行场时序产生不对,偏 ...

由于刚接触fpga不久,没有示波器,而且怎么判断行场时序对不对?能不能说的详细点,谢谢!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表