热度 8
2013-7-27 22:08
1173 次阅读|
0 个评论
今天又试着做了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 o_vga_rgb ,//开发板上8个I/O控制256色显示 output wire o_vsync ,//场同步信号 output wire o_hsync //行同步信号 ); /*---------------------------Internal registers and wires--------------------------------*/ /* Register Output Signals */ reg vga_rgb; //8位rgb寄存器 reg hsync; //场同步寄存器 reg vsync; //行同步寄存器 /* internal logic use signals */ reg cnt_x; //每行上的元素计数(相当于x坐标) reg cnt_y; //行计数(相当于y坐标) reg xpos; //可在屏幕上显示的x坐标 reg 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_x8'd186) (cnt_x10'd988) (cnt_y5'd30) (cnt_y10'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 = (xpos8'd200) (xpos10'd600) (ypos8'd200) (ypos9'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 endmodule988,30