原创 VGA实验

2013-7-27 22:08 1170 8 8 分类: FPGA/CPLD 文集: FPGA学习过程

今天又试着做了VGA显示实验,虽然回过头来看也是相当简单的,但其中有几个细节还是应该注意的(对我来说。。。。)。
首先,就是行消隐和场消隐的数据宽度,我第一次在网上随便找了一组数据试着写了写,仿真出的结果和这组数据的本来预期是准确的,但是,下载到板子上在显示器上运行下,就出问题了,有信号但这个屏幕都是黑的。
没办法,我直接用了特权同学系列教程中提供的数据,这次就直接可以了。
另一方面,在消隐信号过程中rgb必须保持置0,否则也会出现整个屏幕全黑的状态。
至于VGA的扫描过**的比较简单,(假定为800*600)每一帧的扫描为一个整体,首先场同步信号拉低一定时间,然后拉高保持一段时间,这也是场消隐过程,之后正式开始行扫描,行同步信号拉低一定时间,然后保持一段时间,属于行消隐,之后800个时钟周期用于显示一行,后继续拉高行同步信号,也属于行消隐,在下一次行同步信号拉低前为一小部分,这样的小部分执行600次,场同步信号再次拉高一段时间,属于场消隐,在下一次场同步信号拉低前为一个整体结束。
虽然我写的代码在屏幕上正确显示了,但按照我写的刷新频率应该是72HZ,比标准的60HZ要高,测试的时候居然显示超出频率限制,真挫。。。。
最后附上代码。
/*-----------------------------------------------------------------------------------------
Module Name:    test_vga.v
File Author:    creation
Finish Time:    2013-07-27
Description:    VGA实验
-------------------------------------------------------------------------------------------
Version         Design      Coding      Simulate        Review      Rel data
V1.0
-------------------------------------------------------------------------------------------
Version         Modified History
V1.0            draft
-----------------------------------------------------------------------------------------*/
`timescale 1ns / 10ps
module test_vga(
            input       wire            asy_rst         ,//复位
            input       wire            clk             ,//50MHZ
            output      wire    [7:0]   o_vga_rgb       ,//开发板上8个I/O控制256色显示
            output      wire            o_vsync         ,//场同步信号
            output      wire            o_hsync          //行同步信号
);
/*---------------------------Internal registers and wires--------------------------------*/
/* Register Output Signals */
reg     [7:0]       vga_rgb;            //8位rgb寄存器
reg                 hsync;              //场同步寄存器
reg                 vsync;              //行同步寄存器
/* internal logic use signals */
reg     [10:0]      cnt_x;              //每行上的元素计数(相当于x坐标)
reg     [8:0]       cnt_y;              //行计数(相当于y坐标)
reg     [10:0]      xpos;               //可在屏幕上显示的x坐标
reg     [9:0]       ypos;               //可在屏幕上显示的y坐标
reg                 valid;
reg                 dian;
/* ----------------------Logical Implementation------------------------------------------*/
/*-----------------------------------------------------------------------------------------
gen the cnt_x signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        cnt_x <= 1'b0;
    else if ( cnt_x == 11'd1039 )       //行同步信号每隔1040个时钟周期拉低一次
        cnt_x <= 1'b0;
    else
        cnt_x <= cnt_x + 1'b1;
end
/*-----------------------------------------------------------------------------------------
gen the cnt_y signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        cnt_y <= 1'b0;
    else if ( cnt_y == 10'd665 )        //场同步信号每隔666个时钟周期拉低一次
        cnt_y <= 1'b0;
    else if ( cnt_x == 11'd1039  )      //每扫描一行,扫描位置下降一行,
        cnt_y <= cnt_y + 1'b1;
    else
        cnt_y <= cnt_y;
end
/*-----------------------------------------------------------------------------------------
gen the xpos signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        xpos <= 1'b0;
    else
        xpos <= cnt_x - 8'd187;         //每行的前187个时钟周期为行消隐信号
end
/*-----------------------------------------------------------------------------------------
gen the ypos signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        ypos <= 1'b0;
    else
        ypos <= cnt_y - 5'd31;          //每帧的前31行为场消隐信号
end
/*-----------------------------------------------------------------------------------------
gen the valid signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        valid = 1'b0;                   //每帧中的186     else if ( (cnt_x>8'd186) && (cnt_x<10'd988) && (cnt_y>5'd30) && (cnt_y<10'd632) )
        valid = 1'b1;
    else
        valid = 1'b0;
end
/*-----------------------------------------------------------------------------------------
gen the hsync signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        hsync <= 1'b1;
    else if ( cnt_x == 1'b0 )
        hsync <= 1'b0;
    else if ( cnt_x == 7'd120 )         //行消隐信号中的前120个时钟周期用于拉低行同步信号,开始行扫描
        hsync <= 1'b1;
    else
        hsync <= hsync;
end
assign o_hsync = hsync;
/*-----------------------------------------------------------------------------------------
gen the vsync signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        vsync <= 1'b1;
    else if ( cnt_y == 1'b0 )
        vsync <= 1'b0;
    else if ( cnt_y == 3'd6 )           //场消隐信号中的前6行用于拉低场同步信号,开始新一帧的扫描
        vsync <= 1'b1;
    else
        vsync <= vsync;
end
assign o_vsync = vsync;
/*-----------------------------------------------------------------------------------------
gen the dian signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        dian <= 1'b0;
    else                        //此处dian内的坐标为想显示红色的坐标范围
        dian <=  (xpos>8'd200) && (xpos<10'd600) && (ypos>8'd200) && (ypos<9'd400);
end
/*-----------------------------------------------------------------------------------------
gen the vga_rgb signal
-----------------------------------------------------------------------------------------*/
always @ ( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        vga_rgb <= 8'd0;
    else if ( valid )
    begin
        if ( dian )             //dian内的坐标位置显示红色
            vga_rgb <= 8'd128;
        else                    //不在dian内的坐标位置显示绿色
            vga_rgb <= 8'd55;
    end
    else                //消隐信号过程中rgb保持0,这一步必须
        vga_rgb <= 8'd0;
end
assign o_vga_rgb = vga_rgb;     //输出rgb
endmodule<988,30

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条