zoukankan      html  css  js  c++  java
  • fpga 通过vga模块使电脑显示图片

      对vga模块搞了好几天,vga接口时序不难,就是行计数,列计数,对应到每一个像素上去。这里我先把vga控制模块的程序付上。采用的是小梅哥的程序。屏幕是800X600,配置的时钟是40M.注意改变屏幕尺寸时记得重新配置pll.我就是拿着小梅哥的例子直接用,结果屏幕显示输入信号超出范围。

    /*============================================================================
    *
    * LOGIC CORE: VGA驱动模块
    * MODULE NAME: VGA_CTRL()
    * COMPANY: 芯航线电子工作室
    * http://xiaomeige.taobao.com
    * author: 小梅哥
    * author QQ Group:472607506
    * REVISION HISTORY:
    *
    * Revision 1.0 01/01/2016 Description: Initial Release.
    *
    * FUNCTIONAL DESCRIPTION:
    ===========================================================================*/
    module VGA_CTRL(
    Clk_40M, //系统输入时钟25MHZ
    Rst_n, //复位输入,低电平复位
    data_in, //待显示数据
    hcount, //VGA行扫描计数器
    vcount, //VGA场扫描计数器
    VGA_RGB, //VGA数据输出
    VGA_HS, //VGA行同步信号
    VGA_VS, //VGA场同步信号
    VGA_BLK, //VGA 场消隐信号
    VGA_CLK //VGA DAC输出时钟
    );

    //----------------模块输入端口----------------
    input Clk_40M; //系统输入时钟25MHZ
    input Rst_n;
    input [23:0]data_in; //待显示数据

    //----------------模块输出端口----------------
    output [10:0]hcount;
    output [9:0]vcount;
    output [23:0]VGA_RGB; //VGA数据输出
    output VGA_HS; //VGA行同步信号
    output VGA_VS; //VGA场同步信号
    output VGA_BLK; //VGA 场消隐信号
    output VGA_CLK; //VGA DAC输出时钟


    //将VGA控制器时钟信号取反输出,作为DAC数据锁存信号
    assign VGA_CLK = ~Clk_40M;

    //----------------内部寄存器定义----------------
    reg [10:0] hcount_r; //VGA行扫描计数器
    reg [9:0] vcount_r; //VGA场扫描计数器
    //----------------内部连线定义----------------
    wire hcount_ov;
    wire vcount_ov;
    wire dat_act;//有效显示区标定

    //VGA行、场扫描时序参数表
    parameter VGA_HS_end=10'd127,
    hdat_begin=10'd216,
    hdat_end=10'd1016,
    hpixel_end=11'd1055,
    VGA_VS_end=10'd3,
    vdat_begin=10'd26,
    vdat_end=10'd626,
    vline_end=10'd627;

    assign hcount=dat_act?(hcount_r-hdat_begin):11'd0;
    assign vcount=dat_act?(vcount_r-vdat_begin):10'd0;

    //**********************VGA驱动部分**********************
    //行扫描
    always@(posedge Clk_40M or negedge Rst_n)
    if(!Rst_n)
    hcount_r<=11'd0;
    else if(hcount_ov)
    hcount_r<=11'd0;
    else
    hcount_r<=hcount_r+11'd1;

    assign hcount_ov=(hcount_r==hpixel_end);

    //场扫描
    always@(posedge Clk_40M or negedge Rst_n)
    if(!Rst_n)
    vcount_r<=10'd0;
    else if(hcount_ov) begin
    if(vcount_ov)
    vcount_r<=10'd0;
    else
    vcount_r<=vcount_r+10'd1;
    end
    else
    vcount_r<=vcount_r;

    assign vcount_ov=(vcount_r==vline_end);

    //数据、同步信号输出
    assign dat_act=((hcount_r>=hdat_begin)&&(hcount_r<hdat_end))
    &&((vcount_r>=vdat_begin)&&(vcount_r<vdat_end));

    assign VGA_BLK = dat_act;

    assign VGA_HS=(hcount_r>VGA_HS_end);
    assign VGA_VS=(vcount_r>VGA_VS_end);
    assign VGA_RGB=(dat_act)?data_in:24'h000000;

    endmodule

    接下来是图片的处理,我选着了一张自己喜欢的图片,从jpg->bmp->mif文件,也是费了一点功夫。而且bmp文件应再处理一次,我把像素变为100X56,rgb888格式。这样配置rom时可以节省不少资源(也可以配置成rgb565)。但还是最后用了46%的存储资源,我用的芯片是ep4cf10c8n.

    rom和pll的配置大家自己去弄。

    接下来是图片数据如何输入到屏幕上。这个方法是在规定的像素点,对应的去读取相应地址rom的数据。

    接下来我贴一下代码。

    module imgdata_send(
    Clk,
    Rst_n,

    hcount,//行
    vcount,//列
    data_in

    );

    input Clk;
    input Rst_n;

    input [10:0]hcount;
    input [9:0]vcount;

    output [23:0]data_in;


    wire img_ack;//图片数据使能

    localparam img_h = 100,//图片横向像素电个数。
    img_v = 56,//图片竖向像素电个数。
    vga_hm=800,//屏幕横向像素电个数
    vga_vm= 600,//屏幕竖向像素电个数

    img_hbegin = 250,//图片显示横向初始位置

    reg [13:0]addr;     //rom的地址
    wire [23:0]img_data;   //地址的内容

    vga_rom vga_rom(
    .address(addr),
    .clock(Clk),
    .q(img_data)
    );

    assign img_ack = ((hcount >= img_hbegin && hcount < img_hbegin + img_h)|| && (vcount >= img_vbegin && vcount < img_vbegin + img_v))?1'b1:1'b0;     //我们想要图片显示位置区域内,信号为高

    always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
    addr <= 14'd0;  //初始化
    else if(img_ack)
    addr <= ((hcount - img_hbegin) + (vcount - img_vbegin)*img_h);//计算地址,
    else
    addr <= 14'd0;


    assign data_in = img_ack ? img_data : 24'h0;//数据赋值

    endmodule

    下面是效果。原图我找不到了,只能用bmp文件再一次转为png文件。所以图片很小。

    下面是编译之后的顶层文件netlist  viewer.一开始我还很担心vga_ctrl模块与rom模块形成一个反馈,但是发现担心是多余的。接下来我当时学习一下sdrom模块的使用。如何让电脑显示更清晰的图片。

    附上顶层模块描述:

    module vga_top(
    Clk,
    Rst_n,
    VGA_RGB,
    VGA_HS,
    VGA_VS,
    VGA_BLK,
    VGA_CLK

    );

    input Clk;
    input Rst_n;
    output [23:0]VGA_RGB;
    output VGA_HS;
    output VGA_VS;
    output VGA_BLK;
    output VGA_CLK;

    wire Clk_40M;
    wire [10:0]hcount;
    wire [9:0]vcount;
    wire [23:0]data_in;
    VGA_CTRL VGA_CTRL(
    .Clk_40M(Clk_40M), //系统输入时钟25MHZ
    .Rst_n(Rst_n), //复位输入,低电平复位
    .data_in(data_in), //待显示数据
    .hcount(hcount), //VGA行扫描计数器
    .vcount(vcount), //VGA场扫描计数器
    .VGA_RGB(VGA_RGB), //VGA数据输出
    .VGA_HS(VGA_HS), //VGA行同步信号
    .VGA_VS(VGA_VS), //VGA场同步信号
    .VGA_BLK(VGA_BLK), //VGA 场消隐信号
    .VGA_CLK (VGA_CLK) //VGA DAC输出时钟
    );

    imgdata_send imgdata_send(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .hcount(hcount),
    .vcount(vcount),
    .data_in(data_in)

    );

    vga_pll vga_pll(
    .inclk0(Clk),
    .c0(Clk_40M)
    );

    endmodule

      

  • 相关阅读:
    CSS之旅——第二站 如何更深入的理解各种选择器
    CSS之旅——第一站 为什么要用CSS
    记录一些在用wcf的过程中走过的泥巴路 【第一篇】
    asp.net mvc 之旅—— 第二站 窥探Controller下的各种Result
    asp.net mvc 之旅—— 第一站 从简单的razor入手
    Sql Server之旅——终点站 nolock引发的三级事件的一些思考
    Sql Server之旅——第十四站 深入的探讨锁机制
    Sql Server之旅——第十三站 对锁的初步认识
    Sql Server之旅——第十二站 sqltext的参数化处理
    Sql Server之旅——第十一站 简单说说sqlserver的执行计划
  • 原文地址:https://www.cnblogs.com/wyjalx/p/13341966.html
Copyright © 2011-2022 走看看