zjixxw 发表于 2013-4-18 10:20:58

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

最近在做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     vga_r;
   output     vga_g;
   output     vga_b;
   
   
   wire            pclk;
   wire            valid;
   wire       h_cnt;
   wire       v_cnt;
   reg        vga_data;
   
   reg       rom_addr;
   wire       douta;
        reg                        rClk;
        always@(posedge clk)        rClk<=        rClk+1;//rclk为25MHz
        assign        plck=        rClk;

        logo_rom u1 (
                .clka(pclk),      // input clka
                .addra(rom_addr), // input addra
                .douta(douta)   // output 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;
   assign vga_g = vga_data;
   assign vga_b = vga_data;
   
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 h_cnt;
   output 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     x_cnt;
   reg     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



zjixxw 发表于 2013-4-18 11:22:52

希望大家能够解答一下,谢谢!

wang110 发表于 2013-4-18 19:04:32

reset rst 一高电平复位,一低电平复位 ?

zjixxw 发表于 2013-4-18 19:48:33

wang110 发表于 2013-4-18 19:04 static/image/common/back.gif
reset rst 一高电平复位,一低电平复位 ?

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

wang110 发表于 2013-4-18 21:58:09

首先看下显示器是否识别了640*480模式,否则需检查hsync、vsync。
另外,在消隐期间,vga_r,vga_g,vga_b应送0

zjixxw 发表于 2013-4-19 09:10:36

wang110 发表于 2013-4-18 21:58 static/image/common/back.gif
首先看下显示器是否识别了640*480模式,否则需检查hsync、vsync。
另外,在消隐期间,vga_r,vga_g,vga_b ...

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

wang110 发表于 2013-4-19 22:30:50

本帖最后由 wang110 于 2013-4-19 22:32 编辑

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

ISE14.1

zjixxw 发表于 2013-4-22 09:18:49

wang110 发表于 2013-4-19 22:30 static/image/common/back.gif
VGA800*600显示。图像从ROM中读取,ROM大小2048*16,随意保存的文件,非图片。

ISE14.1 ...

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

zjixxw 发表于 2013-4-22 09:34:43

wang110 发表于 2013-4-19 22:30 static/image/common/back.gif
VGA800*600显示。图像从ROM中读取,ROM大小2048*16,随意保存的文件,非图片。

ISE14.1 ...

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

Codoox 发表于 2013-4-22 10:47:30

本帖最后由 Codoox 于 2013-4-22 10:49 编辑

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

Codoox 发表于 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读地址

zjixxw 发表于 2013-4-22 11:35:38

Codoox 发表于 2013-4-22 11:06 static/image/common/back.gif
always @(posedge pclk or negedge rst)
   begin
      if (!rst)


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

zjixxw 发表于 2013-4-22 14:36:45

Codoox 发表于 2013-4-22 11:06 static/image/common/back.gif
always @(posedge pclk or negedge rst)
   begin
      if (!rst)


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

Codoox 发表于 2013-4-22 15:30:15

zjixxw 发表于 2013-4-22 14:36 static/image/common/back.gif
您说的h_cnt和v_cnt拼接是不是要在有效区内呀?是h_cnt>10'd0和v_cnt>10'd0这个意思吗? ...

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

zjixxw 发表于 2013-4-22 15:52:53

Codoox 发表于 2013-4-22 15:30 static/image/common/back.gif
有这层意思,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

Codoox 发表于 2013-4-22 16:08:54

zjixxw 发表于 2013-4-22 15:52 static/image/common/back.gif
你好,我把我的程序改成这样了。但是还是没有显示
assign ready = ((v_cnt >=1) & (v_cnt =1) & (h_cnt ...

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

孙风雷 发表于 2013-4-22 16:53:41

zjixxw 发表于 2013-4-19 09:10 static/image/common/back.gif
怎么看显示器有没有识别640*480模式?不懂,就是显示器一点都不显示!

同步头的问题吧!

zjixxw 发表于 2013-4-22 17:12:47

孙风雷 发表于 2013-4-22 16:53 static/image/common/back.gif
同步头的问题吧!

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

zjixxw 发表于 2013-4-22 21:02:04

Codoox 发表于 2013-4-22 16:08 static/image/common/back.gif
如果显示错乱的话可能是上面所说的问题,如果是一概都不显示,那问题有可能是:
1.行场时序产生不对,偏 ...

由于刚接触fpga不久,没有示波器,而且怎么判断行场时序对不对?能不能说的详细点,谢谢!
页: [1]
查看完整版本: fpga通过vga来显示图像的问题求教