FPGA学习——VGA显示

这篇具有很好参考价值的文章主要介绍了FPGA学习——VGA显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、VGA原理

(一)VGA协议

VGA(Video Graphics Array)是IBM在1987年随PS/2机⼀起推出的⼀种视频,具有分辨率⾼、显⽰速率快、颜⾊丰富等优点,在彩 ⾊显⽰器领域得到了⼴泛的应⽤。不⽀持热插拔,不⽀持⾳频传输。对于⼀些嵌⼊式VGA显⽰系统,可以在不使⽤VGA显⽰卡和计算机的 情况下,实现VGA图像的显⽰和控制。VGA显⽰器具有成本低、结构简单、应⽤灵活的优点。

(二)VGA端口结构

VGA端口是视频输出端口,端口一共包含15个管脚,如下图
FPGA学习——VGA显示
在通常使用的连接方法里面,15个管脚里面的5个是最重要的,他们
包括3个基本红,绿,蓝三条基本色彩线和水平与垂直两条控制线。
FPGA学习——VGA显示

(三)⾊彩原理

三基⾊是指通过其他颜⾊的混合⽆法得到的“基本 ⾊”由于⼈的⾁眼有感知红、绿、蓝三种不同颜⾊的锥体细胞,因此⾊彩空间通常可以由三种基本⾊来表达
FPGA学习——VGA显示

设计RGB信号时,既可以R信号、G信号和B信号独⽴的赋值,最后连到端⼝上,也可以直接⽤RGB当做⼀个整体信号,RGB信号在使
⽤时的位宽有三种常见格式,以你的VGA解码芯⽚的配置有关。

  1. RGB_8,R:G:B = 3:3:2,即RGB332
  2. RGB_16,R:G:B = 5:6:5,即RGB565
  3. RGB_24,R:G:B = 8:8:8,即RGB888

(四)扫描原理

1.扫描方式

VGA显⽰器扫描⽅式分为逐⾏扫描和隔⾏扫描:逐⾏扫描是扫描从屏幕左上⾓⼀点开始,从左像右逐点扫描,每扫描完⼀⾏,电⼦束回 到屏幕的左边下⼀⾏的起始位置,在这期间,CRT对电⼦束进⾏消隐,每⾏结束时,⽤⾏同步信号进⾏同步;当扫描完所有的⾏,形成⼀ 帧,⽤场同步信号进⾏场同步,并使扫描回到屏幕左上⽅,同时进⾏场消隐,开始下⼀帧。隔⾏扫描是指电⼦束扫描时每隔⼀⾏扫⼀线,完成 ⼀屏后在返回来扫描剩下的线,隔⾏扫描的显⽰器闪烁的厉害,会让使⽤者的眼睛疲劳。因此我们⼀般都采⽤逐⾏扫描的⽅式。
FPGA学习——VGA显示

2.逐行扫描

一行紧跟一行的扫描方式称为逐行扫描
电子束在在靶面上或者屏幕上的扫描轨迹称为扫描光栅

  • 逐行扫描电流
  • 行偏转线圈、场偏转线圈共同控制电子束的方向

FPGA学习——VGA显示
FPGA学习——VGA显示
FPGA学习——VGA显示

3.隔行扫描

·隔行扫描所应满足的条件:
1.下一帧扫描起始点应上一帧起始点相同,以便保证各帧扫描光栅重叠。一帧的总行数Z必须为整数
⒉.相邻两场扫描光栅必须均匀镶嵌,以获得最高清晰度
一帧的总行数必须为奇数,或任何一场必须包含-个半行

FPGA学习——VGA显示
FPGA学习——VGA显示
优点

  • 隔行扫描电视信号的频带是逐行扫描电视信号频带的一半,即把帧频降低了一半‘’

缺点

  • 行间闪烁效应
  • 并行显像
  • 真实并行
  • 视在并行
  • “锯齿化”现象
  • 隔行扫描的垂直分解力低于逐行扫描的垂直分解力

(五)⾏场信号

FPGA学习——VGA显示
⼀开始看这个时序图可能看不懂,它是把⾏场信号绘制在同⼀张图⾥,说明⾏场信号的控制是相似的,只是时间参数不⼀样⽽已。如果 展开的话,其实时序是这样的:
FPGA学习——VGA显示
这样就清楚了,⼤致是若⼲个HS信号才组合⽽成⼀个VS,如果在⼀副图⽚中,那正确的时序表⽰⽅式应该如下图这样。
FPGA学习——VGA显示
video为“显⽰区域”,Right porder和Front porch常常加在⼀起称为“显⽰前沿”,⼀个时序其实就是先拉⾼⼀段较短的“信号同 步”时间,然后拉低⼀段很长的时间,这就是⼀个回合。同时需要注意,其实也可以完全相反。即先拉低⼀段时间“信号同步”时间,然后 拉⾼⼀段很长的时间。

二、显示姓名学号

(一)实验用具

1.VGA显示器
2.Cyclone IV E系列 EP4CE115F29C7开发板
3.字模工具软件PCtoLCD2002
百度网盘.链接:https://pan.baidu.com/s/1LLpNgYiH5zf6sXZoU8j9aw
提取码:8888

(二)生成字模

使用工具
1.点击设置
FPGA学习——VGA显示
2.汉字字模
FPGA学习——VGA显示

3.数字字模
FPGA学习——VGA显示

(三)代码

module vga_text(
OSC_50,     //原CLK2_50时钟信号
VGA_CLK,    //VGA自时钟
VGA_HS,     //行同步信号
VGA_VS,     //场同步信号
VGA_BLANK,  //复合空白信号控制信号  当BLANK为低电平时模拟视频输出消隐电平,此时从R9~R0,G9~G0,B9~B0输入的所有数据被忽略
VGA_SYNC,   //符合同步控制信号      行时序和场时序都要产生同步脉冲
VGA_R,      //VGA绿色
VGA_B,      //VGA蓝色
VGA_G);     //VGA绿色
 input OSC_50;     //外部时钟信号CLK2_50
 output VGA_CLK,VGA_HS,VGA_VS,VGA_BLANK,VGA_SYNC;
 output [7:0] VGA_R,VGA_B,VGA_G;
 parameter H_FRONT = 16;     //行同步前沿信号周期长
 parameter H_SYNC = 96;      //行同步信号周期长
 parameter H_BACK = 48;      //行同步后沿信号周期长
 parameter H_ACT = 640;      //行显示周期长
 parameter H_BLANK = H_FRONT+H_SYNC+H_BACK;        //行空白信号总周期长
 parameter H_TOTAL = H_FRONT+H_SYNC+H_BACK+H_ACT;  //行总周期长耗时
 parameter V_FRONT = 11;     //场同步前沿信号周期长
 parameter V_SYNC = 2;       //场同步信号周期长
 parameter V_BACK = 31;      //场同步后沿信号周期长
 parameter V_ACT = 480;      //场显示周期长
 parameter V_BLANK = V_FRONT+V_SYNC+V_BACK;        //场空白信号总周期长
 parameter V_TOTAL = V_FRONT+V_SYNC+V_BACK+V_ACT;  //场总周期长耗时
 reg [10:0] H_Cont;        //行周期计数器
 reg [10:0] V_Cont;        //场周期计数器
 wire [7:0] VGA_R;         //VGA红色控制线
 wire [7:0] VGA_B;         //VGA绿色控制线
 wire [7:0] VGA_G;         //VGA蓝色控制线
 reg VGA_HS;
 reg VGA_VS;
 reg [10:0] X;             //当前行第几个像素点
 reg [10:0] Y;             //当前场第几行
 reg CLK_25;
 always@(posedge OSC_50)
    begin 
      CLK_25=~CLK_25;         //时钟
    end 
    assign VGA_SYNC = 1'b0;   //同步信号低电平
    assign VGA_BLANK = ~((H_Cont<H_BLANK)||(V_Cont<V_BLANK));  //当行计数器小于行空白总长或场计数器小于场空白总长时,空白信号低电平
    assign VGA_CLK = ~CLK_to_DAC;  //VGA时钟等于CLK_25取反
    assign CLK_to_DAC = CLK_25;
 always@(posedge CLK_to_DAC)
    begin
        if(H_Cont<H_TOTAL)           //如果行计数器小于行总时长
            H_Cont<=H_Cont+1'b1;      //行计数器+1
        else H_Cont<=0;              //否则行计数器清零
        if(H_Cont==H_FRONT-1)        //如果行计数器等于行前沿空白时间-1
            VGA_HS<=1'b0;             //行同步信号置0
        if(H_Cont==H_FRONT+H_SYNC-1) //如果行计数器等于行前沿+行同步-1
            VGA_HS<=1'b1;             //行同步信号置1
        if(H_Cont>=H_BLANK)          //如果行计数器大于等于行空白总时长
            X<=H_Cont-H_BLANK;        //X等于行计数器-行空白总时长   (X为当前行第几个像素点)
        else X<=0;                   //否则X为0
    end
 always@(posedge VGA_HS)
    begin
        if(V_Cont<V_TOTAL)           //如果场计数器小于行总时长
            V_Cont<=V_Cont+1'b1;      //场计数器+1
        else V_Cont<=0;              //否则场计数器清零
        if(V_Cont==V_FRONT-1)       //如果场计数器等于场前沿空白时间-1
            VGA_VS<=1'b0;             //场同步信号置0
        if(V_Cont==V_FRONT+V_SYNC-1) //如果场计数器等于行前沿+场同步-1
            VGA_VS<=1'b1;             //场同步信号置1
        if(V_Cont>=V_BLANK)          //如果场计数器大于等于场空白总时长
            Y<=V_Cont-V_BLANK;        //Y等于场计数器-场空白总时长    (Y为当前场第几行)  
        else Y<=0;                   //否则Y为0
    end
    reg valid_yr;
 always@(posedge CLK_to_DAC)
    if(V_Cont == 10'd56)         //场计数器=32时
        valid_yr<=1'b1;           //行输入激活
    else if(V_Cont==10'd512)     //场计数器=512时
        valid_yr<=1'b0;           //行输入冻结
    wire valid_y=valid_yr;       //连线   
    reg valid_r;            
 always@(posedge CLK_to_DAC)   
    if((H_Cont == 10'd56)&&valid_y)     //行计数器=32时
        valid_r<=1'b1;                   //像素输入激活
    else if((H_Cont==10'd512)&&valid_y) //行计数器=512时 
        valid_r<=1'b0;                   //像素输入冻结
    wire valid = valid_r;               //连线
    wire[10:0] x_dis;     //像素显示控制信号
    wire[10:0] y_dis;     //行显示控制信号
    assign x_dis=X;       //连线X   192 = (640-256 ) /2
    assign y_dis=Y;       //连线Y   231 = (480- 18) /2
        parameter  //点阵字模:每一行char_lineXX是显示的一行,共272列,256
    char_line00=256'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,  //第1行
    char_line01=256'h0000000000000000000000000000000000000000000000000000000000000000,  //第2行
    char_line02=256'h0100044000000000000000000000000000000000000000000000000000000000,  //第3行
    char_line03=256'h210804407FFC0000000000000000000000000000000000000000000000000000,  //第4行
    char_line04=256'h1110044001000000000000000000000000000000000000000000000000000000,  //第5行
    char_line05=256'h092004400100000007F00FE000800FE007E01FFC07E007F007E01FF80FF01FF8,  //第6行
    char_line06=256'h0100444411100000081830180780301818183008181808181818100030181000,  //第7行
    char_line07=256'h3FF8244409100000100038180180300C381C2010381C1000381C1000380C1000,  //第8行
    char_line08=256'h2008244809200000300000180180700C300C0020300C3000300C100010181000,  //第9行
    char_line09=256'h2008144801007FFE37F000600180301C300C0040300C37F0300C17F0001817F0,  //第10行
    char_line0a=256'h3FF81450FFFE0000380C01F00180382C300C0080300C380C300C181800601818,  //第11行
    char_line0b=256'h2008146001000000300C001801800FCC300C0180300C300C300C000C0180000C,  //第12行
    char_line0c=256'h2008044001000000300C000C0180001C300C0300300C300C300C000C0600000C,  //第13行
    char_line0d=256'h3FF8044001000000300C380C01800018381803003818300C3818380C0804380C,  //第14行
    char_line0e=256'h200804400100000018183018018038301C1003801C1018181C103018300C3018,  //第15行
    char_line0f=256'h200804400100000007E00FE00FF80FC007E0030007E007E007E00FE03FF80FE0,  //第16行
    char_line10=256'h2028FFFE01000000000000000000000000000000000000000000000000000000,  //第17行
    char_line11=256'h2010000001000000000000000000000000000000000000000000000000000000;  //第18行
    reg [7:0] char_bit;
    always@(posedge CLK_to_DAC)
        if(X==10'd192)char_bit<=8'd256;   //当显示到192像素时准备开始输出图像数据
        else if(X>10'd192&&X<10'd448)     //左边距屏幕192像素到448像素时    448=192+256(图像宽度)
            char_bit<=char_bit-1'b1;       //倒着输出图像信息 
        reg[29:0] VGA_Rgb;                //定义颜色缓存
    always@(posedge CLK_to_DAC)    
        if(X>10'd192&&X<10'd448)    //X控制图像的横向显示边界:左边距屏幕左边192像素  右边界距屏幕左边界448像素
            begin case(Y)            //Y控制图像的纵向显示边界:从距离屏幕顶部200像素开始显示第一行数据
                10'd200:
                if(char_line00[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;  //如果该行有数据 则颜色为红色
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;                      //否则为黑色
                10'd202:
                if(char_line01[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd203:
                if(char_line02[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd204:
                if(char_line03[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd205:
                if(char_line04[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000; 
                10'd206:
                if(char_line05[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd207:
                if(char_line06[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000; 
                10'd208:
                if(char_line07[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd209:
                if(char_line08[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000; 
                10'd210:
                if(char_line09[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd211:
                if(char_line0a[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd212:
                if(char_line0b[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd213:
                if(char_line0c[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd214:
                if(char_line0d[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd215:
                if(char_line0e[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd216:
                if(char_line0f[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd217:
                if(char_line10[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                10'd218:
                if(char_line11[char_bit])VGA_Rgb<=30'b1111111111_0000000000_0000000000;
                else VGA_Rgb<=30'b0000000000_0000000000_0000000000;
                default:VGA_Rgb<=30'h0000000000;   //默认颜色黑色
            endcase 
        end
    else VGA_Rgb<=30'h000000000;             //否则黑色
    assign VGA_R=VGA_Rgb[23:16];
    assign VGA_G=VGA_Rgb[15:8];
    assign VGA_B=VGA_Rgb[7:0];
endmodule



// {010021081110092001003FF8200820083FF8200820083FF82008200820282010},/*"X",0*/

// {04400440044004404444244424481448145014600440044004400440FFFE0000},/*"Y",1*/

// {00007FFC010001001110091009200100FFFE0100010001000100010001000100},/*"P",2*/

// {00000000000000000000000000007FFE00000000000000000000000000000000},/*"-",0*/

// {00000000000007F008181000300037F0380C300C300C300C181807E000000000},/*"6",0*/

// {0000000000000FE0301838180018006001F00018000C380C30180FE000000000},/*"3",1*/

// {00000000000000800780018001800180018001800180018001800FF800000000},/*"1",2*/

// {0000000000000FE03018300C700C301C382C0FCC001C001838300FC000000000},/*"9",3*/

// {00000000000007E01818381C300C300C300C300C300C38181C1007E000000000},/*"0",4*/

// {0000000000001FFC300820100020004000800180030003000380030000000000},/*"7",5*/

// {00000000000007E01818381C300C300C300C300C300C38181C1007E000000000},/*"0",6*/

// {00000000000007F008181000300037F0380C300C300C300C181807E000000000},/*"6",7*/

// {00000000000007E01818381C300C300C300C300C300C38181C1007E000000000},/*"0",8*/

// {0000000000001FF810001000100017F01818000C000C380C30180FE000000000},/*"5",9*/

// {0000000000000FF03018380C101800180060018006000804300C3FF800000000},/*"2",10*/

// {0000000000001FF810001000100017F01818000C000C380C30180FE000000000},/*"5",11*/

(四)引脚绑定

package require ::quartus::project

set_location_assignment PIN_C13 -to VGA_VS
set_location_assignment PIN_C10 -to VGA_SYNC
set_location_assignment PIN_E12 -to VGA_R[0]
set_location_assignment PIN_E11 -to VGA_R[1]
set_location_assignment PIN_D10 -to VGA_R[2]
set_location_assignment PIN_F12 -to VGA_R[3]
set_location_assignment PIN_G10 -to VGA_R[4]
set_location_assignment PIN_J12 -to VGA_R[5]
set_location_assignment PIN_H8 -to VGA_R[6]
set_location_assignment PIN_H10 -to VGA_R[7]
set_location_assignment PIN_G13 -to VGA_HS
set_location_assignment PIN_G8 -to VGA_G[0]
set_location_assignment PIN_G11 -to VGA_G[1]
set_location_assignment PIN_D12 -to VGA_B[7]
set_location_assignment PIN_D11 -to VGA_B[6]
set_location_assignment PIN_C12 -to VGA_B[5]
set_location_assignment PIN_A11 -to VGA_B[4]
set_location_assignment PIN_B11 -to VGA_B[3]
set_location_assignment PIN_C11 -to VGA_B[2]
set_location_assignment PIN_A10 -to VGA_B[1]
set_location_assignment PIN_B10 -to VGA_B[0]
set_location_assignment PIN_F11 -to VGA_BLANK
set_location_assignment PIN_A12 -to VGA_CLK
set_location_assignment PIN_C9 -to VGA_G[7]
set_location_assignment PIN_F10 -to VGA_G[6]
set_location_assignment PIN_B8 -to VGA_G[5]
set_location_assignment PIN_C8 -to VGA_G[4]
set_location_assignment PIN_H12 -to VGA_G[3]
set_location_assignment PIN_F8 -to VGA_G[2]
set_location_assignment PIN_AG14 -to OSC_50

(五)结果显示

FPGA学习——VGA显示

三、显示彩条

本实验用到了上面实验的两个用具
1.VGA显示器
2.Cyclone IV E系列 EP4CE115F29C7开发板

(一)VGA时序

分辨率480X640,帧数60Hz

FPGA学习——VGA显示

颜色RGB,6‘hffffff,24位,data_disp[23:0]
颜色深度888
屏幕分辨率:2048 ✖ 1080
h_sync[10:0]//行信号2048
v_sync[10:0]//场信号(列)1080
vga_r;[7:0]//三通道,红色
vga_g;[7:0]//三通道,绿色
vga_b;[7:0]//三通道,蓝色
vga_clk //显示器显示时钟
FPGA学习——VGA显示

(二)代码

1.顶层模块

//顶层文件
 module vga_top( 
     input                  clk     ,//时钟信号
     input                  rst_n   ,//复位信号
     
     output  wire           hsync   ,//
     output  wire           vsync   ,// 
     output  wire           sync    ,
     output  wire [7:0]     vga_r   ,//三通道,红色
     output  wire [7:0]     vga_g   ,//三通道,绿色
     output  wire [7:0]     vga_b   ,//三通道,蓝色 
     output  wire           vga_blk ,
     output  wire           vga_clk 
     
   );           
     wire         [10:0]    h_addr  ;//数据有效显示区域行地址
     wire         [10:0]    v_addr  ;//数据有效显示区域场地址  
     wire         [23:0]    data_dis;
 //例化
  data_gen u_data_gen(
     .clk       (clk     ) ,//时钟信号
     .rst_n     (rst_n   ) ,//复位信号
     .h_addr    (h_addr  ) ,//数据有效显示区域行地址
     .v_addr    (v_addr  ) ,//数据有效显示区域场地址
     .data_dis  (data_dis) //需要显示的信号 
  );
 //例化
   vga_ctrl u_vga_ctrl(
     .clk       (clk     ) ,//时钟信号
     .rst_n     (rst_n   ) ,//复位信号
     .data_dis  (data_dis) ,//需要显示的信号
     .h_addr    (h_addr  ) ,//数据有效显示区域行地址
     .v_addr    (v_addr  ) ,//数据有效显示区域场地址
     .hsync     (hsync   ) ,//
     .vsync     (vsync   ) ,//
     .sync      (sync    ) ,
     .vga_r     (vga_r   ) ,//三通道,红色
     .vga_g     (vga_g   ) ,//三通道,绿色
     .vga_b     (vga_b   ) ,//三通道,蓝色
     .vga_blk   (vga_blk ) ,
     .vga_clk   (vga_clk )  //显示器显示时钟         
 );

 endmodule

2.彩条数据模块

//数据生成
 module data_gen(
     input                 clk     ,//时钟信号
     input                 rst_n   ,//复位信号
   
     input       [10:0]    h_addr  ,//数据有效显示区域行地址
     input       [10:0]    v_addr  ,//数据有效显示区域场地址

     output  reg [23:0]    data_dis //需要显示的信号 
 );         
 //参数定义
  parameter  BLACK    = 24'h000000,
             RED      = 24'hFF0000,
             GREEN    = 24'h00FF00,
             BLUE     = 24'h0000FF,
             YELLOW   = 24'hFFFF00,
             SKY_BLUE = 24'h00FFFF,
             PURPLE   = 24'hFF00FF,
             GRAY     = 24'hC0C0C0,
             WHITE    = 24'hFFFFFF;

 //赋值
  always@(posedge clk or negedge rst_n)begin
     if(!rst_n)begin
        data_dis <= BLACK;
     end
     else begin
        case(h_addr)
           0      : data_dis <= BLUE    ;
           80     : data_dis <= RED      ;
           160    : data_dis <= GREEN    ;
           240    : data_dis <= BLUE     ;
           320    : data_dis <= YELLOW   ;
           400    : data_dis <= SKY_BLUE ;
           480    : data_dis <= PURPLE   ;
           560    : data_dis <= GRAY     ;
           default: data_dis <= data_dis ;
        endcase
     end
  end
 
 endmodule

3.VGA显示模块

//VGA显示,实训讲解
`define vga_640_480
`include "vga_para.v"
 module vga_ctrl(
     input                 clk     ,//时钟信号
     input                 rst_n   ,//复位信号
     input       [23:0]    data_dis,//需要显示的信号
   
     output  reg [10:0]    h_addr  ,//数据有效显示区域行地址
     output  reg [10:0]    v_addr  ,//数据有效显示区域场地址

     output  reg           hsync   ,//行同步信号
     output  reg           vsync   ,//场同步信号
     output                sync    ,

     output  reg [7:0]     vga_r   ,//三通道,红色
     output  reg [7:0]     vga_g   ,//三通道,绿色
     output  reg [7:0]     vga_b   ,//三通道,蓝色
     output  reg           vga_blk ,//复合空白信号控制信号,VGA消隐信号显示数据时为1电产,其他时候为低电平
     output                vga_clk  //显示器显示时钟         
 );
 //参数定义
     parameter H_SYNC_STA =  1 ;
     parameter H_SYNC_STO =  `H_Sync_Time ;
     parameter H_Data_STA =  `H_Sync_Time + `H_Back_Porch + `H_Left_Border;
     parameter H_Data_STO =  `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time;   
     parameter V_SYNC_STA =  1 ;
     parameter V_SYNC_STO =  `V_Sync_Time ;
     parameter V_Data_STA =  `V_Sync_Time  + `V_Back_Porch + `V_Top_Border;
     parameter V_Data_STO =  `V_Sync_Time  + `V_Back_Porch + `V_Top_Border + `V_Data_Time;

    //   parameter H_SYNC_STA = `H_Right_Border + `H_Front_Porch;
    //   parameter H_SYNC_STO = `H_Right_Border + `H_Front_Porch + `H_Sync_Time ;
    //   parameter H_Data_STA = `H_Right_Border + `H_Front_Porch + `H_Sync_Time ;
    //   parameter H_Data_STO = `H_Right_Border + `H_Front_Porch + `H_Sync_Time + `H_Data_Time ;
    //   
    //   parameter V_SYNC_STA = `V_Bottom_Border + `V_Front_Porch;
    //   parameter V_SYNC_STO = `V_Bottom_Border + `V_Front_Porch + `V_Sync_Time;
    //   parameter V_Data_STA = `V_Bottom_Border + `V_Front_Porch + `V_Sync_Time ;
    //   parameter V_Data_STO = `V_Bottom_Border + `V_Front_Porch + `V_Sync_Time + `V_Data_Time ;        
 //信号定义
  reg  [11:0]  cnt_h_addr;//行地址计数器
  wire         add_h_addr;
  wire         end_h_addr;

  reg  [11:0]  cnt_v_addr;//场地址计数器
  wire         add_v_addr;
  wire         end_v_addr;

  reg          clk_25M   ;

 assign sync = 1'b0;
  //assign vga_blk = ~((cnt_h_addr<(`H_Front_Porch+`H_Sync_Time+`H_Back_Porch))||
  //                   (cnt_v_addr<`V_Front_Porch+`V_Sync_Time+`V_Back_Porch));
 //clk_25M
  always @(posedge clk or negedge rst_n) begin
      if(!rst_n)begin
        clk_25M <= 1'b0;
      end
      else begin
        clk_25M <= ~clk_25M;
      end
  end
  assign vga_clk = clk_25M;

 //cnt_h_addr
  always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        cnt_h_addr <= 12'd0;
     end
     else if(add_h_addr) begin
        if(end_h_addr)begin
           cnt_h_addr <= 12'd0;
        end
        else begin
           cnt_h_addr = cnt_h_addr + 12'd1;
        end
     end
     else begin
       cnt_h_addr <= 12'd0;
     end
  end
  assign add_h_addr = 1'b1;//开启条件
  assign end_h_addr = add_h_addr && cnt_h_addr >= `H_Total_Time - 1;
 
 //cnt_v_addr
  always@(posedge vga_clk or negedge rst_n)begin
   if(!rst_n)begin
      cnt_v_addr <= 12'd0;
   end
   else if(add_v_addr) begin
      if(end_v_addr)begin
         cnt_v_addr <= 12'd0;
      end
      else begin
         cnt_v_addr = cnt_v_addr + 12'd1;
      end
   end
   else begin
      cnt_v_addr = cnt_v_addr;
   end
  end
  assign add_v_addr = end_h_addr;
  assign end_v_addr = add_v_addr && cnt_v_addr >= `V_Total_Time - 1;

 //行同步信号
  always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        hsync <= 1'b1;
     end
     else if(cnt_h_addr == H_SYNC_STA -1)begin
        hsync <= 1'b0;
     end
     else if(cnt_h_addr == H_SYNC_STO - 1) begin
        hsync <= 1'b1;
     end
     else begin
        hsync <= hsync ;
     end
  end
 
 //场同步信号
  always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        vsync <= 1'b1;
     end
     else if(cnt_v_addr == V_SYNC_STA -1)begin
        vsync <= 1'b0;
     end
     else if(cnt_v_addr == V_SYNC_STO - 1) begin
        vsync <= 1'b1;
     end
     else begin
        vsync <= vsync ;
     end
  end
  

 //数据有效显示区域定义
  always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        h_addr <= 11'd0;
     end
     else if ((cnt_h_addr >= H_Data_STA - 1 )&&(cnt_h_addr <= H_Data_STO -1)) begin
        h_addr <= cnt_h_addr - H_Data_STA -1 ;
     end
     else begin
        h_addr <= 11'd0;
     end
  end

 //场地址有效显示区域定义
    always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        v_addr <= 11'd0;
     end
     else if ((cnt_v_addr >= V_Data_STA - 1 )&& (cnt_v_addr <= V_Data_STO -1)) begin
        v_addr <= cnt_v_addr - V_Data_STA -1 ;
     end
     else begin
        v_addr <= 11'd0;
     end
  end

 //显示数据
  always@(posedge vga_clk or negedge rst_n)begin
     if(!rst_n)begin
        vga_r <= 8'd0;
        vga_b <= 8'd0;
        vga_g <= 8'd0;
        vga_blk <= 1'b0;
     end
     else if((cnt_h_addr >= H_Data_STA - 1 )&&(cnt_h_addr <= H_Data_STO -1)
            && (cnt_v_addr >= V_Data_STA - 1 )&& (cnt_v_addr <= V_Data_STO -1))begin
        vga_r <= data_dis[23:16];//data_dis[23-:8]
        vga_g <= data_dis[15:8] ;//data_dis[15-:8]
        vga_b <= data_dis[7:0]  ;//data_dis[7- :8] 
        vga_blk <= 1'b1;
     end
     else begin
        vga_r <= 8'd0;
        vga_b <= 8'd0;
        vga_g <= 8'd0;
        vga_blk <= 1'b0;
     end
  end
  

 endmodule

4.参数模块

`define vga_640_480
`define vga_1920_1080 
`define vga_1024_768 
`ifdef  vga_640_480  //执行操作B
    `define H_Right_Border    8   //行同步右沿信号
    `define H_Front_Porch     8   //行同步前沿信号周期长
    `define H_Sync_Time       96  //行同步信号周期长
    `define H_Back_Porch      40  //行同步后沿信号周期长
    `define H_Left_Border     4   //行同步左沿信号
    `define H_Data_Time       640 //行显示周期长
    `define H_Total_Time      800

    `define V_Bottom_Border   8   //场同步底沿信号 
    `define V_Front_Porch     2   //场同步前沿信号周期长
    `define V_Sync_Time       2   //场同步信号周期长
    `define V_Back_Porch      25  //场同步后沿信号周期长
    `define V_Top_Border      8   //场同步顶沿信号
    `define V_Data_Time       480 //场显示周期长
    `define V_Total_Time      525
     
      
`elsif vga_1920_1080 //执行操作B
    `define H_Right_Border    0
    `define H_Front_Porch     88
    `define H_Sync_Time       44
    `define H_Back_Porch      148
    `define H_Left_Border     0
    `define H_Data_Time       1920
    `define H_Total_Time      2200

    `define V_Bottom_Border   0
    `define V_Front_Porch     4
    `define V_Sync_Time       5
    `define V_Back_Porch      36
    `define V_Top_Border      0
    `define V_Data_Time       1080
    `define V_Total_Time      1125

`elsif vga_1024_768    
    `define H_Right_Border    0
    `define H_Front_Porch     24
    `define H_Sync_Time       136
    `define H_Back_Porch      160
    `define H_Left_Border     0
    `define H_Data_Time       1024
    `define H_Total_Time      1344
   
    `define V_Bottom_Borde    0 
    `define V_Front_Porch     3 
    `define V_Sync_Time       6 
    `define V_Back_Porch      29
    `define V_Top_Border      0 
    `define V_Data_Time       768 
    `define V_Total_Time      806
 
`else //可以没有

`endif

(三)仿真

`timescale 1ps/1ps
  module vga_top_tb(); 
     reg            clk     ;//时钟信号
     reg            rst_n   ;//复位信号
     
     wire           hsync   ;//
     wire           vsync   ;// 
     wire           sync    ;
     wire   [7:0]   vga_r   ;//三通道,红色
     wire   [7:0]   vga_g   ;//三通道,绿色
     wire   [7:0]   vga_b   ;//三通道,蓝色 
     wire           vga_blk ;//复合空白信号控制信号,VGA消隐信号显示数据时为1电产,其他时候为低电平
     wire           vga_clk ;//显示器显示时钟
  
 //参数定义
  parameter CYCLE = 40;

  always #(CYCLE/2) clk = ~ clk;
 //例化
   vga_top vga_top(
     .clk           (clk     ),//时钟信号
     .rst_n         (rst_n   ),//复位信号

     .hsync         (hsync   ),//
     .vsync         (vsync   ),// 
     .sync          (sync    ) ,
     .vga_r         (vga_r   ),//三通道,红色
     .vga_g         (vga_g   ),//三通道,绿色
     .vga_b         (vga_b   ),//三通道,蓝色 
     .vga_blk       (vga_blk ),//复合空白信号控制信号,VGA消隐信号显示数据时为1电产,其他时候为低电平
     .vga_clk       (vga_clk )//显示器显示时钟
    ); 

 //ASCII 显示颜色字母
    reg  [63:0]   CHAR_CLO;//1位ASCII码需要8bit显示
 //参数定义
    parameter    BLACK    = 24'h000000,
                 RED      = 24'hFF0000,
                 GREEN    = 24'h00FF00,
                 BLUE     = 24'h0000FF,
                 YELLOW   = 24'hFFFF00,
                 SKY_BLUE = 24'h00FFFF,
                 PURPLE   = 24'hFF00FF,
                 GRAY     = 24'hC0C0C0,
                 WHITE    = 24'hFFFFFF;

    always@(*)begin
       case(vga_top.data_dis)
            BLACK    :CHAR_CLO = "BLACK"   ;
            RED      :CHAR_CLO = "RED"     ;
            GREEN    :CHAR_CLO = "GREEN"   ;
            BLUE     :CHAR_CLO = "BLUE"    ;
            YELLOW   :CHAR_CLO = "YELLOW"  ;
            SKY_BLUE :CHAR_CLO = "SKY_BLUE";
            PURPLE   :CHAR_CLO = "PURPLE"  ;
            GRAY     :CHAR_CLO = "GRAY"    ;
            WHITE    :CHAR_CLO = "WHITE"   ; 
            default  :CHAR_CLO = "WHITE"   ;
       endcase
    end
 //初始化
  initial begin
      clk = 1'b1;
      rst_n = 1'b0;
      #(CYCLE * 20 +3);
      rst_n = 1'b1;
      #(CYCLE * 20);
      repeat(2)begin
        @(negedge vsync);
      end
      #1000;
      $stop;

  end

  endmodule

(四)引脚绑定

在这里插入代码片package require ::quartus::project

set_location_assignment PIN_C13 -to vsync
set_location_assignment PIN_C10 -to sync 
set_location_assignment PIN_E12 -to vga_r[0]
set_location_assignment PIN_E11 -to vga_r[1]
set_location_assignment PIN_D10 -to vga_r[2]
set_location_assignment PIN_F12 -to vga_r[3]
set_location_assignment PIN_G10 -to vga_r[4]
set_location_assignment PIN_J12 -to vga_r[5]
set_location_assignment PIN_H8 -to  vga_r[6]
set_location_assignment PIN_H10 -to vga_r[7]
set_location_assignment PIN_G13 -to hsync
set_location_assignment PIN_G8 -to  vga_g[0]
set_location_assignment PIN_G11 -to vga_g[1]
set_location_assignment PIN_D12 -to vga_b[7]
set_location_assignment PIN_D11 -to vga_b[6]
set_location_assignment PIN_C12 -to vga_b[5]
set_location_assignment PIN_A11 -to vga_b[4]
set_location_assignment PIN_B11 -to vga_b[3]
set_location_assignment PIN_C11 -to vga_b[2]
set_location_assignment PIN_A10 -to vga_b[1]
set_location_assignment PIN_B10 -to vga_b[0]
set_location_assignment PIN_F11 -to vga_blk
set_location_assignment PIN_A12 -to vga_clk
set_location_assignment PIN_C9 -to vga_g[7]
set_location_assignment PIN_F10 -to vga_g[6]
set_location_assignment PIN_B8 -to vga_g[5]
set_location_assignment PIN_C8 -to vga_g[4]
set_location_assignment PIN_H12 -to vga_g[3]
set_location_assignment PIN_F8 -to vga_g[2]
set_location_assignment PIN_AG14 -to clk

(五)结果

FPGA学习——VGA显示

四、显示图片

(一)实验用具

本实验用到了上面实验的两个用具
1.VGA显示器
2.Cyclone IV E系列的EP4CE6F17C8
3.图片工具
百度网盘·链接:https://pan.baidu.com/s/1-3VHjLBmhacrKBqdPR-dSQ
提取码:8888

(二)转图片格式

1.图片信息如下,需要一张小BMP格式的小图片

FPGA学习——VGA显示

2.使用工具把图片转为HEX文件
FPGA学习——VGA显示

FPGA学习——VGA显示
3.用记事本打开如下
FPGA学习——VGA显示

(三)调用IP核

1.本次使用到的芯片是Cyclone IV E系列的EP4CE6F17C8
FPGA学习——VGA显示
2.搜索IP核ROM:1-PORT,命名后保存

图片数据太多需要使用ROM来存储数据

FPGA学习——VGA显示
3设置如下
FPGA学习——VGA显示

4.取消勾选
FPGA学习——VGA显示

5.找到刚才生成的data1.hex文件
FPGA学习——VGA显示

6.勾选例化
FPGA学习——VGA显示

(四)代码

1.顶层模块

//顶层模块 
  module vga_picture (
                input		  	wire					    	clk    ,
                input		  	wire					    	rst_n  ,
                output			wire					    	vga_clk,
                output			wire					    	h_sync ,
                output			wire					    	v_sync ,
                output			wire		[ 4:0 ]			rgb_r  ,
                output			wire		[ 5:0 ]			rgb_g  ,
                output			wire		[ 4:0 ]			rgb_b  
    );
      reg			[ 27:0 ]			cnt			        ;
      wire		[ 11:0 ]		  addr_h          ;
      wire		[ 11:0 ]		  addr_v          ;
      wire		[ 15:0 ]			rgb_data			  ;
  //vga模块
   vga_dirve u_vga_dirve(
   .clk      ( clk ),
   .rst_n    ( rst_n ),
   .rgb_data ( rgb_data ),
   .vga_clk  ( vga_clk ),
   .h_sync   ( h_sync ),
   .v_sync   ( v_sync ),
   .rgb_r    ( rgb_r ),
   .rgb_g    ( rgb_g ),
   .rgb_b    ( rgb_b ),
   .addr_h   ( addr_h ),
   .addr_v   ( addr_v )
   );

 //数据模块
  data_drive u_data_drive(
  .vga_clk ( vga_clk ),
  .rst_n   ( rst_n ),
  .addr_h  ( addr_h ),
  .addr_v  ( addr_v ),
  .rgb_data  ( rgb_data )
  );


endmodule // vga_top


2.图片数据模块

 module data_drive (
                   input			wire						vga_clk,
                   input			wire						rst_n,
                   input			wire		[ 11:0 ]		addr_h,
                   input			wire		[ 11:0 ]		addr_v,
                   output			reg		    [ 15:0 ]	    rgb_data);
    
   //参数定义
    parameter	height = 100; // 图片高度
    parameter	width  = 100; // 图片宽度
    localparam	black  = 16'd0;
    localparam	white  = 16'd65503;
    reg			[ 13:0 ]		rom_address				; // ROM地址
    wire		[ 15:0 ]		rom_data				; // 图片数据
     
    wire						flag_enable_out 		; // 图片有效区域
    wire						flag_clear_rom_address	; // 地址清零
    wire						flag_begin_h			; // 图片显示行
    wire						flag_begin_v			; // 图片显示列

  //显示图片
   always @(posedge vga_clk or negedge rst_n ) begin
       if ( !rst_n ) begin
           rgb_data = white;
       end
       else if (flag_enable_out) begin
           rgb_data = rom_data;
       end
       else begin
           rgb_data = white;
      end
   end
  assign flag_begin_h     = addr_h > ( ( 640 - width ) / 2 ) && addr_h < ( ( 640 - width ) / 2 ) + width + 1;
  assign flag_begin_v     = addr_v > ( ( 480 - height )/2 ) && addr_v <( ( 480 - height )/2 ) + height + 1;
  assign flag_enable_out  = flag_begin_h && flag_begin_v;
  
//ROM地址计数器
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rom_address <= 0;
    end
    else if ( flag_clear_rom_address ) begin //计数满清零
        rom_address <= 0;
    end
        else if ( flag_enable_out ) begin  //在有效区域内+1
        rom_address <= rom_address + 1;
        end
    else begin  //无效区域保持
        rom_address <= rom_address;
    end
end
assign flag_clear_rom_address = rom_address == height * width - 1;


//实例化ROM

ROM1_port	ROM1_port_inst (
	.address ( rom_address ),
	.clock ( vga_clk ),
	.q ( rom_data )
	);

endmodule // data_drive


3.VGA显示模块

module vga_dirve (input			wire						clk     ,            //系统时钟
                  input			wire						rst_n   ,          //复位
                  input			wire		[ 15:0 ]		rgb_data,       //16位RGB对应值
                  output		wire	    				vga_clk ,    //vga时钟 25M
                  output		reg		    				h_sync  ,     //行同步信号
                  output		reg		    				v_sync  ,     //场同步信号
                  output		reg		    [ 11:0 ]		addr_h  , //行地址
                  output		reg		    [ 11:0 ]		addr_v  ,  //列地址
                  output		wire	    [ 4:0 ]	    	rgb_r   ,  //红基色
                  output		wire	    [ 5:0 ]	    	rgb_g   ,  //绿基色
                  output		wire	    [ 4:0 ]	    	rgb_b  //蓝基色
);

// 640 * 480 60HZ
localparam	 H_FRONT = 16; // 行同步前沿信号周期长
localparam	 H_SYNC  = 96; // 行同步信号周期长
localparam	 H_BLACK = 48; // 行同步后沿信号周期长
localparam	 H_ACT   = 640; // 行显示周期长
localparam	 V_FRONT = 11; // 场同步前沿信号周期长
localparam	 V_SYNC  = 2; // 场同步信号周期长
localparam	 V_BLACK = 31; // 场同步后沿信号周期长
localparam	 V_ACT   = 480; // 场显示周期长

// 800 * 600 72HZ
// localparam	 H_FRONT = 40; // 行同步前沿信号周期长
// localparam	 H_SYNC  = 120; // 行同步信号周期长
// localparam	 H_BLACK = 88; // 行同步后沿信号周期长
// localparam	 H_ACT   = 800; // 行显示周期长
// localparam	 V_FRONT = 37; // 场同步前沿信号周期长
// localparam	 V_SYNC  = 6; // 场同步信号周期长
// localparam	 V_BLACK = 23; // 场同步后沿信号周期长
// localparam	 V_ACT   = 600; // 场显示周期长


localparam	H_TOTAL = H_FRONT + H_SYNC + H_BLACK + H_ACT; // 行周期
localparam	V_TOTAL = V_FRONT + V_SYNC + V_BLACK + V_ACT; // 列周期

reg			[ 11:0 ]			cnt_h			; // 行计数器
reg			[ 11:0 ]			cnt_v			; // 场计数器
reg			[ 15:0 ]			rgb			; // 对应显示颜色值

// 对应计数器开始、结束、计数信号
wire							flag_enable_cnt_h			;
wire							flag_clear_cnt_h			;
wire							flag_enable_cnt_v			;
wire							flag_clear_cnt_v			;
wire							flag_add_cnt_v  			;
wire							valid_area      			;


// 25M时钟 行周期*场周期*刷新率 = 800 * 525* 60
reg						    	clk_25			;
// 50M时钟 1040 * 666 * 72
wire							clk_50			;
//PLL
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
      clk_25 = 1'b0;
   end
   else begin
      clk_25 = ~ clk_25 ;
   end
end
assign vga_clk = clk_25;
// 行计数
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        cnt_h <= 0;
    end
    else if ( flag_enable_cnt_h ) begin
        if ( flag_clear_cnt_h ) begin
            cnt_h <= 0;
        end
        else begin
            cnt_h <= cnt_h + 1;
        end
    end
    else begin
        cnt_h <= 0;
    end
end
assign flag_enable_cnt_h = 1;
assign flag_clear_cnt_h  = cnt_h == H_TOTAL - 1;

// 行同步信号
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        h_sync <= 0;
    end
    else if ( cnt_h == H_SYNC - 1 ) begin // 同步周期时为1
        h_sync <= 1;
    end
        else if ( flag_clear_cnt_h ) begin // 其余为0
        h_sync <= 0;
        end
    else begin
        h_sync <= h_sync;
    end
end

// 场计数
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        cnt_v <= 0;
    end
    else if ( flag_enable_cnt_v ) begin
        if ( flag_clear_cnt_v ) begin
            cnt_v <= 0;
        end
        else if ( flag_add_cnt_v ) begin
            cnt_v <= cnt_v + 1;
        end
        else begin
            cnt_v <= cnt_v;
        end
    end
    else begin
        cnt_v <= 0;
    end
end
assign flag_enable_cnt_v = flag_enable_cnt_h;
assign flag_clear_cnt_v  = cnt_v == V_TOTAL - 1;
assign flag_add_cnt_v    = flag_clear_cnt_h;

// 场同步信号
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        v_sync <= 0;
    end
    else if ( cnt_v == V_SYNC - 1 ) begin
        v_sync <= 1;
    end
        else if ( flag_clear_cnt_v ) begin
        v_sync <= 0;
        end
    else begin
        v_sync <= v_sync;
    end
end

// 对应有效区域行地址 1-640
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        addr_h <= 0;
    end
    else if ( valid_area ) begin
        addr_h <= cnt_h - H_SYNC - H_BLACK + 1;
    end
    else begin
        addr_h <= 0;
    end
end
// 对应有效区域列地址 1-480
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        addr_v <= 0;
    end
    else if ( valid_area ) begin
        addr_v <= cnt_v -V_SYNC - V_BLACK + 1;
    end
    else begin
        addr_v <= 0;
    end
end
// 有效显示区域
assign valid_area = cnt_h >= H_SYNC + H_BLACK && cnt_h <= H_SYNC + H_BLACK + H_ACT && cnt_v >= V_SYNC + V_BLACK && cnt_v <= V_SYNC + V_BLACK + V_ACT;


// 显示颜色
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rgb <= 16'h0;
    end
    else if ( valid_area ) begin
        rgb <= rgb_data;
    end
    else begin
        rgb <= 16'b0;
    end
end
assign rgb_r = rgb[ 15:11 ];
assign rgb_g = rgb[ 10:5 ];
assign rgb_b = rgb[ 4:0 ];

endmodule // vga_dirve


(五)引脚绑定

package require ::quartus::project

set_location_assignment PIN_E1 -to clk
set_location_assignment PIN_E15 -to rst_n
set_location_assignment PIN_C16 -to h_sync
set_location_assignment PIN_D15 -to v_sync


set_location_assignment PIN_A14 -to rgb_b[4]
set_location_assignment PIN_B14 -to rgb_b[3]
set_location_assignment PIN_A15 -to rgb_b[2]
set_location_assignment PIN_B16 -to rgb_b[1]
set_location_assignment PIN_C15 -to rgb_b[0]


set_location_assignment PIN_A11 -to rgb_g[5]
set_location_assignment PIN_B11 -to rgb_g[4]
set_location_assignment PIN_A12 -to rgb_g[3]
set_location_assignment PIN_B12 -to rgb_g[2]
set_location_assignment PIN_A13 -to rgb_g[1]
set_location_assignment PIN_B13 -to rgb_g[0]

set_location_assignment PIN_C8 -to rgb_r[4]
set_location_assignment PIN_A9 -to rgb_r[3]
set_location_assignment PIN_B9 -to rgb_r[2]
set_location_assignment PIN_A10 -to rgb_r[1]
set_location_assignment PIN_B10 -to rgb_r[0]

(六)结果

FPGA学习——VGA显示

五、总结

本次实验了解了VGA协议的相关原理,以及VGA显示的一个基本设计思路。了解到VGA不同的扫描方式。逐行扫描、隔行扫描两种方式,以及他们各自的特点。

六、参考资料

基于FPGA的VGA显示彩条、字符、图片文章来源地址https://www.toymoban.com/news/detail-443263.html

到了这里,关于FPGA学习——VGA显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA开发】VGA彩条显示及VGA白块位移

    为了理解VGA的工作模式,并且进行vga一部分的模板开发,方便后续图像处理显示的需求。这里通过对vga时序进行分析,进行简单的vga图像控制。实验阶段进行的是640*480@60hz的分辨率和刷新率,后续因为需要适应显示器的规格。会在模块化的阶段进行参数的重新分配,变成可编

    2024年01月21日
    浏览(42)
  • FPGA—VGA 显示器显示彩条(附代码)

    目录 1. 理论 2. 实操 2.1 顶层设计 2.1.1 模块框图 2.1.2 代码编写  2.1.3 仿真验证 2.2 时钟生成模块 2.3 VGA时序控制模块 2.3.1 模块框图 2.3.2 波形图绘制 2.3.3 代码编写 2.3.4 仿真验证 2.4 图像数据生成模块 2.4.1 模块框图 2.4.2 波形图绘制 2.4.3 代码编写 3.总结 VGA简介        图像显示

    2024年02月09日
    浏览(96)
  • 基于FPGA的VGA图像显示

    引言:本文我们介绍利用FPGA实现VGA图像显示,主要介绍VGA硬件接口、VGA接口时序原理以及FPGA代码实现VGA接口时序、仿真等内容。 VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口

    2024年02月06日
    浏览(33)
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注:大部分参考内容来自“征途Pro《FPGA Verilog开发实战指南——基于Altera EP4CE10》2021.7.10(上)”  贴个下载地址: 野火FPGA-Altera-EP4CE10征途开发板_核心板 — 野火产品资料下载中心 文档 hdmi显示器驱动设计与验证 — [野火]FPGA Verilog开发实战指南——基于Altera EP4CE10 征途Pro开

    2024年02月09日
    浏览(47)
  • 【FPGA开发】SDRAM的读写VGA显示

            实验的目的旨在使用sdram作为中间媒介,在sdram上读写以在显示器上显示图像的目的。 1.2.1 SDRAM型号介绍 这里我们使用的 sdram为 Hynix 公司生产的型号为 HY57V281620F 的 芯片,其存储空间可以分为4Bank x 2M x16Bit ,其中 4Bank 指的是该芯片有 4 个bank区间, 2M 指的是每个 ba

    2024年01月17日
    浏览(46)
  • FPGA_简单工程_VGA显示驱动器

    一 理论 使用640*480@60显示模式,将数字信号转换位模拟信号,经由VGA进行显示。 使用3GM723,3路高清视频编码芯片。 3GM7123编码芯片:                                该芯片的主要功能是将RGB888的颜色数据转换成模拟的电压信号,然后进入到VGA接口的3个RGB接口。例如RGB8

    2024年02月20日
    浏览(38)
  • FPGA_工程_基于Rom的VGA图像显示

    一 工程框图 框图中,CLK_in,Vga_ctrl,Vga_pic模块已有,只需要对顶层模块进行修改,并将rom ip例化添加到Vga_pic模块的.v文件中,对Vga_pic的.v文件进行一定修改。 二 理论补充 显示图像的方法:                           使用matlab将图像格式转化为,.mif数据文件,再使用.m

    2024年02月20日
    浏览(36)
  • 【FPGA】VGA显示文字、彩条、图片——基于DE2-115

    **VGA(Video Graphics Array)**视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号

    2024年02月02日
    浏览(43)
  • 【FPGA实验】基于DE2-115平台的VGA显示

    VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及

    2024年02月03日
    浏览(36)
  • 基于Quartus Prime平台FPGA关于VGA显示的模块化设计:VGA八种单色屏1s切换显示、横条纹、竖条纹、棋盘格显示、显示模式按键可调、数码管显示单色屏序号

    VGA(Video Graphics Array)是一种显示接口标准,它最初由IBM于1987年推出。VGA协议定义了计算机视频输出信号的格式和特性。它主要用于连接计算机和显示器之间的传输,实现图像和视频的显示。 VGA协议支持最高分辨率为640x480像素,色彩深度为16位色(即65,536种颜色)。它使用模

    2024年02月03日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包