FPGA强化(9):TFT_LCD液晶屏驱动

简介: FPGA强化(9):TFT_LCD液晶屏驱动

第44讲:TFT-LCD液晶屏驱动设计与验证

理论部分

液晶显示器(Liquid Crystal Display,LCD),相对于上一代CRT显示器(阴极射线管显示器),LCD显示器具有功耗低、体积小、承载的信息量大及不伤眼的特点,因而它成为了现在的主流电子显示设备,其中包括电视、电脑显示器、手机屏幕及各种嵌入式设备的显示器。

设计与实现

tft_pic

`timescale  1ns/1ns
module  tft_pic
(
    input   wire            tft_clk_9m  ,   //输入工作时钟,频率9MHz
    input   wire            sys_rst_n   ,   //输入复位信号,低电平有效
    input   wire    [9:0]   pix_x       ,   //输入TFT有效显示区域像素点X轴坐标
    input   wire    [9:0]   pix_y       ,   //输入TFT有效显示区域像素点Y轴坐标
    output  reg     [15:0]  pix_data        //输出像素点色彩信息
);
parameter   H_VALID =   10'd480 ,   //行有效数据
            V_VALID =   10'd272 ;   //场有效数据
parameter   RED     =   16'hF800,   //红色
            ORANGE  =   16'hFC00,   //橙色
            YELLOW  =   16'hFFE0,   //黄色
            GREEN   =   16'h07E0,   //绿色
            CYAN    =   16'h07FF,   //青色
            BLUE    =   16'h001F,   //蓝色
            PURPPLE =   16'hF81F,   //紫色
            BLACK   =   16'h0000,   //黑色
            WHITE   =   16'hFFFF,   //白色
            GRAY    =   16'hD69A;   //灰色
//pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge tft_clk_9m or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pix_data    <= 16'd0;
    else    if((pix_x >= 0) && (pix_x < (H_VALID/10)*1))
        pix_data    <=  RED;
    else    if((pix_x >= (H_VALID/10)*1) && (pix_x < (H_VALID/10)*2))
        pix_data    <=  ORANGE;
    else    if((pix_x >= (H_VALID/10)*2) && (pix_x < (H_VALID/10)*3))
        pix_data    <=  YELLOW;
    else    if((pix_x >= (H_VALID/10)*3) && (pix_x < (H_VALID/10)*4))
        pix_data    <=  GREEN;
    else    if((pix_x >= (H_VALID/10)*4) && (pix_x < (H_VALID/10)*5))
        pix_data    <=  CYAN;
    else    if((pix_x >= (H_VALID/10)*5) && (pix_x < (H_VALID/10)*6))
        pix_data    <=  BLUE;
    else    if((pix_x >= (H_VALID/10)*6) && (pix_x < (H_VALID/10)*7))
        pix_data    <=  PURPPLE;
    else    if((pix_x >= (H_VALID/10)*7) && (pix_x < (H_VALID/10)*8))
        pix_data    <=  BLACK;
    else    if((pix_x >= (H_VALID/10)*8) && (pix_x < (H_VALID/10)*9))
        pix_data    <=  WHITE;
    else    if((pix_x >= (H_VALID/10)*9) && (pix_x < H_VALID))
        pix_data    <=  GRAY;
    else
        pix_data    <=  BLACK;
endmodule

tft_ctrl

`timescale  1ns/1ns
module  tft_ctrl
(
    input   wire            tft_clk_9m  ,   //输入时钟,频率9MHz
    input   wire            sys_rst_n   ,   //系统复位,低电平有效
    input   wire    [15:0]  pix_data    ,   //待显示数据
    output  wire    [9:0]   pix_x       ,   //输出TFT有效显示区域像素点X轴坐标
    output  wire    [9:0]   pix_y       ,   //输出TFT有效显示区域像素点Y轴坐标
    output  wire    [15:0]  rgb_tft     ,   //TFT显示数据
    output  wire            hsync       ,   //TFT行同步信号
    output  wire            vsync       ,   //TFT场同步信号
    output  wire            tft_clk     ,   //TFT像素时钟
    output  wire            tft_de      ,   //TFT数据使能
    output  wire            tft_bl          //TFT背光信号
);
//parameter define
parameter H_SYNC    =   10'd41  ,   //行同步
          H_BACK    =   10'd2   ,   //行时序后沿
          H_VALID   =   10'd480 ,   //行有效数据
          H_FRONT   =   10'd2   ,   //行时序前沿
          H_TOTAL   =   10'd525 ;   //行扫描周期
parameter V_SYNC    =   10'd10  ,   //场同步
          V_BACK    =   10'd2   ,   //场时序后沿
          V_VALID   =   10'd272 ,   //场有效数据
          V_FRONT   =   10'd2   ,   //场时序前沿
          V_TOTAL   =   10'd286 ;   //场扫描周期
//wire  define
wire            rgb_valid       ;   //VGA有效显示区域
wire            pix_data_req    ;   //像素点色彩信息请求信号
//reg   define
reg     [9:0]   cnt_h   ;   //行扫描计数器
reg     [9:0]   cnt_v   ;   //场扫描计数器
//tft_clk,tft_de,tft_bl:TFT像素时钟、数据使能、背光信号
assign  tft_clk = tft_clk_9m    ;
assign  tft_de  = rgb_valid     ;
assign  tft_bl  = sys_rst_n     ;
//cnt_h:行同步信号计数器
always@(posedge tft_clk_9m or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_h   <=  10'd0   ;
    else    if(cnt_h == H_TOTAL - 1'd1)
        cnt_h   <=  10'd0   ;
    else
        cnt_h   <=  cnt_h + 1'd1   ;
//hsync:行同步信号
assign  hsync = (cnt_h  <=  H_SYNC - 1'd1) ? 1'b1 : 1'b0  ;
//cnt_v:场同步信号计数器
always@(posedge tft_clk_9m or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_v   <=  10'd0 ;
    else    if((cnt_v == V_TOTAL - 1'd1) &&  (cnt_h == H_TOTAL-1'd1))
        cnt_v   <=  10'd0 ;
    else    if(cnt_h == H_TOTAL - 1'd1)
        cnt_v   <=  cnt_v + 1'd1 ;
    else
        cnt_v   <=  cnt_v ;
//vsync:场同步信号
assign  vsync = (cnt_v  <=  V_SYNC - 1'd1) ? 1'b1 : 1'b0  ;
//rgb_valid:VGA有效显示区域
assign  rgb_valid = (((cnt_h >= H_SYNC + H_BACK)
                    && (cnt_h < H_SYNC + H_BACK + H_VALID))
                    &&((cnt_v >= V_SYNC + V_BACK)
                    && (cnt_v < V_SYNC + V_BACK + V_VALID)))
                    ? 1'b1 : 1'b0;
//pix_data_req:像素点色彩信息请求信号,超前rgb_valid信号一个时钟周期
assign  pix_data_req = (((cnt_h >= H_SYNC + H_BACK - 1'b1)
                    && (cnt_h < H_SYNC + H_BACK + H_VALID - 1'b1))
                    &&((cnt_v >= V_SYNC + V_BACK)
                    && (cnt_v < V_SYNC + V_BACK + V_VALID)))
                    ? 1'b1 : 1'b0;
//pix_x,pix_y:VGA有效显示区域像素点坐标
assign  pix_x = (pix_data_req == 1'b1) ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'h3ff;
assign  pix_y = (pix_data_req == 1'b1) ? (cnt_v - (V_SYNC + V_BACK )) : 10'h3ff;
//rgb_tft:输出像素点色彩信息
assign  rgb_tft = (rgb_valid == 1'b1) ? pix_data : 16'b0 ;
endmodule

tft_colorbar

`timescale  1ns/1ns
module  tft_colorbar
(
    input   wire            sys_clk     ,   //输入工作时钟,频率50MHz
    input   wire            sys_rst_n   ,   //输入复位信号,低电平有效
    output  wire    [15:0]  rgb_tft     ,   //输出像素信息
    output  wire            hsync       ,   //输出行同步信号
    output  wire            vsync       ,   //输出场同步信号
    output  wire            tft_clk     ,   //输出TFT时钟信号
    output  wire            tft_de      ,   //输出TFT使能信号
    output  wire            tft_bl          //输出背光信号
);
//wire  define
wire            tft_clk_9m  ;   //TFT工作时钟,频率9MHz
wire            locked      ;   //PLL locked信号
wire            rst_n       ;   //TFT模块复位信号
wire    [9:0]   pix_x       ;   //TFT有效显示区域X轴坐标
wire    [9:0]   pix_y       ;   //TFT有效显示区域Y轴坐标
wire    [15:0]  pix_data    ;   //TFT像素点色彩信息
//rst_n:TFT模块复位信号
assign  rst_n = (sys_rst_n & locked);
//------------- clk_gen_inst -------------
clk_gen clk_gen_inst
(
    .areset     (~sys_rst_n ),  //输入复位信号,高电平有效,1bit
    .inclk0     (sys_clk    ),  //输入50MHz晶振时钟,1bit
    .c0         (tft_clk_9m ),  //输出TFT工作时钟,频率9Mhz,1bit
    .locked     (locked     )   //输出pll locked信号,1bit
);
//------------- tft_ctrl_inst -------------
tft_ctrl    tft_ctrl_inst
(
    .tft_clk_9m  (tft_clk_9m),   //输入时钟,频率9MHz
    .sys_rst_n   (rst_n     ),   //系统复位,低电平有效
    .pix_data    (pix_data  ),   //待显示数据
    .pix_x       (pix_x     ),   //输出TFT有效显示区域像素点X轴坐标
    .pix_y       (pix_y     ),   //输出TFT有效显示区域像素点Y轴坐标
    .rgb_tft     (rgb_tft   ),   //TFT显示数据
    .hsync       (hsync     ),   //TFT行同步信号
    .vsync       (vsync     ),   //TFT场同步信号
    .tft_clk     (tft_clk   ),   //TFT像素时钟
    .tft_de      (tft_de    ),   //TFT数据使能
    .tft_bl      (tft_bl    )    //TFT背光信号
);
//------------- tft_pic_inst -------------
tft_pic tft_pic_inst
(
    .tft_clk_9m  (tft_clk_9m),   //输入工作时钟,频率9MHz
    .sys_rst_n   (rst_n     ),   //输入复位信号,低电平有效
    .pix_x       (pix_x     ),   //输入TFT有效显示区域像素点X轴坐标
    .pix_y       (pix_y     ),   //输入TFT有效显示区域像素点Y轴坐标
    .pix_data    (pix_data  )    //输出像素点色彩信息
);
endmodule

tb_tft_colorbar

`timescale  1ns/1ns
module  tb_tft_colorbar();
//wire  define
wire            hsync   ;
wire    [15:0]  rgb_tft ;
wire            vsync   ;
wire            tft_clk ;
wire            tft_de  ;
wire            tft_bl  ;
//reg   define
reg             sys_clk     ;
reg             sys_rst_n   ;
//sys_clk,rst_n初始赋值
initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
        #200
        sys_rst_n   <=  1'b1;
    end
//clk:产生时钟
always  #10 sys_clk = ~sys_clk  ;
//------------- tft_colorbar_inst -------------
tft_colorbar    tft_colorbar_inst
(
    .sys_clk     (sys_clk   ),   //输入工作时钟,频率50MHz
    .sys_rst_n   (sys_rst_n ),   //输入复位信号,低电平有效
    .rgb_tft     (rgb_tft   ),   //输出像素信息
    .hsync       (hsync     ),   //输出行同步信号
    .vsync       (vsync     ),   //输出场同步信号
    .tft_clk     (tft_clk   ),   //输出TFT时钟信号
    .tft_de      (tft_de    ),   //输出TFT使能信号
    .tft_bl      (tft_bl    )    //输出背光信号
);
endmodule




第45讲:TFT_LCD液晶屏字符显示

实验目标

tft_pic

`timescale  1ns/1ns
module  tft_pic
(
    input   wire            tft_clk_9m  ,   //输入工作时钟,频率9MHz
    input   wire            sys_rst_n   ,   //输入复位信号,低电平有效
    input   wire    [9:0]   pix_x       ,   //输入TFT有效显示区域像素点X轴坐标
    input   wire    [9:0]   pix_y       ,   //输入TFT有效显示区域像素点Y轴坐标
    output  reg     [15:0]  pix_data        //输出像素点色彩信息
);
parameter   H_VALID =   10'd480 ,   //行有效数据
            V_VALID =   10'd272 ;   //场有效数据
parameter   CHAR_B_H=   10'd112 ,   //字符开始X轴坐标
            CHAR_B_V=   10'd104 ;   //字符开始Y轴坐标
parameter   CHAR_W  =   10'd256 ,   //字符宽度
            CHAR_H  =   10'd64  ;   //字符高度
parameter   BLACK   =   16'h0000,   //黑色
            GOLDEN  =   16'hFEC0;   //金色
//wire  define
wire    [9:0]   char_x  ;   //字符显示X轴坐标
wire    [9:0]   char_y  ;   //字符显示Y轴坐标
//reg   define
reg     [255:0] char    [63:0]  ;   //字符数据
//字符显示坐标
assign  char_x  =   (((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
                    && ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
                    ? (pix_x - CHAR_B_H) : 10'h3FF;
assign  char_y  =   (((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
                    && ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
                    ? (pix_y - CHAR_B_V) : 10'h3FF;
//char:字符数据
always@(posedge tft_clk_9m)
    begin
        char[0]     <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[1]     <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[2]     <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[3]     <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[4]     <=  256'h00000000003C0000000000000000000000000000000070000000000000000000;
        char[5]     <=  256'h0000000E003E00000000000000000000000000000000F0000000000000000000;
        char[6]     <=  256'h000000FF001F00000000000000000000000000000001F0000000000000400000;
        char[7]     <=  256'h000007FF000F00000000000000000000000010000001F8000000000000E00000;
        char[8]     <=  256'h00007FFE000F000000000000000000000003FE000001F8000000000000F00000;
        char[9]     <=  256'h0000FE7E003F00000000000000000000000FFF800001F80000003E0000F00000;
        char[10]    <=  256'h0000E07C01F8000000000000000000000007FF81F801FC0000003F0000F00000;
        char[11]    <=  256'h0000E0F80380000000000000000000000003FF80FE00780000003F0001E00000;
        char[12]    <=  256'h0000E0F80380000000000000000000000001FF80FF00780000003F0001E00000;
        char[13]    <=  256'h0780E1F003FC000000000000000000000000FF80FF80780000003E0001E00000;
        char[14]    <=  256'h07C0FFF003FE0000000000020000000000003F007F80780000003E0001E00000;
        char[15]    <=  256'h07E0FFE001FE0000000000070000000000000E007F00780000003C0001FF0000;
        char[16]    <=  256'h07F3FFE0000E00000000000700000000000000007E00F80000003C0001FF0000;
        char[17]    <=  256'h07F9FFC0000E00000000000F0000000000003E00CC01F80000007C0003FE0000;
        char[18]    <=  256'h03F9FFC0001C03E00000000F8000000000003F010001F80000007E0003F80000;
        char[19]    <=  256'h03F9FF8000781FF80000001F8000000000007F038001F8000000FF0007F00000;
        char[20]    <=  256'h03F9FF8001F07FF80000001F878000000000FE078001F8000000FF000FE00000;
        char[21]    <=  256'h03FDFF0007C3FFF00000003FFFC000000001FC07C001F8000001FF003FE00000;
        char[22]    <=  256'h03FDFF000F9F8FF00001C03FFFC000000007F807F001F8000007FE003FC00000;
        char[23]    <=  256'h03FFFE001FFF8FE00001E07FFFC00000001FF807FC01F800000FFC0003C00000;
        char[24]    <=  256'h01FFF0007FFF8FC00003E07FFC000000067FF007FE01FC00001FF80003800000;
        char[25]    <=  256'h01FFC000FFEF9F800003E0FE000000000FFFF003FC01FE00007FF00007800000;
        char[26]    <=  256'h01FF8001FF8F9F000007E0FE000000000FFFF041F803FC0000FFE00007800000;
        char[27]    <=  256'h01FF8007FC1F9E00001FE0FE000000000FFFF180F00FFC000001E00007000000;
        char[28]    <=  256'h00FF8007F01F3C00003FE1FC00000000007FF601E01FF8000001E000071C0000;
        char[29]    <=  256'h00FF8007C01FFC00003FE1FC00000000001FFC03C0FFF8000001E0000F3E0000;
        char[30]    <=  256'h00030002001FF800003FC3FC00000000003FF807C3FFF8000001E7800FFE0000;
        char[31]    <=  256'h00070000001FF000007FC3F800000000003FF80F9FFFF0000001FF000FFE0000;
        char[32]    <=  256'h0007F000001FE000007F83F800000000007FF01FFFC3F0000001FE000FFE0000;
        char[33]    <=  256'h001FF000001FC000003F83F00000000000FFF01FFE03F0000001FC001FFE0000;
        char[34]    <=  256'h007FE000001F8000003F07F00000000000FFE03FF003F0000003F8001F3E0000;
        char[35]    <=  256'h007FC000001F8000001807F00000000001FFE03F8003F0000003F0001F3C0000;
        char[36]    <=  256'h00078600001F000000000FF80000000003FFC07E0003F0000003F0001E3C0000;
        char[37]    <=  256'h000F1E00001F000000000FFC0000000007FFC0180003F0000007E003843C0000;
        char[38]    <=  256'h003FFC00001F800000001FDE0000000007FFC0000003F000000FF001E03C0000;
        char[39]    <=  256'h007FF800001F800000003FDF8000000007C7C0000003F00000FFF000F83C0000;
        char[40]    <=  256'h00FFF000001F800000007F9FF00000000787C0000003F00007FFF0007F3C0000;
        char[41]    <=  256'h01FFE000001F80000000FF0FFE0000000707C0000003F0001FF1F8003FFC0000;
        char[42]    <=  256'h03FF8000001F80000001FE0FFFE000000003C0000003F0003F81F8001FFC0000;
        char[43]    <=  256'h07FF0000003F80000003FC07FFFE0000000300000003F0003E01FC000FFE0000;
        char[44]    <=  256'h07FC0000003F80000007F803FFFFE000000000000003F0001F83FC0007FFF000;
        char[45]    <=  256'h07F80000003F8000000FF001FFFFFF80000000000003F0000FFFFC0003FFFF80;
        char[46]    <=  256'h03E00000007F8000001FC0007FFFFFC0000000000003F00003FFFE0007FFFFF0;
        char[47]    <=  256'h0000000000FF8000007F80001FFFFFE0000000000003F000007FFE003FBFFFF8;
        char[48]    <=  256'h0000000001FF800000FE000007FFFFE0000000000003E000000FFC03FE0FFFF8;
        char[49]    <=  256'h0000000007FF800001F8000001FFFFF0000000000003E0000000F8FFC003FFF8;
        char[50]    <=  256'h000000007FFF000003E00000001FFFC0000000000003C0000000000000007FF8;
        char[51]    <=  256'h00000007FFFE0000070000000001FFC0000000000003C0000000000000000FF0;
        char[52]    <=  256'h0000000200F800000000000000000F8000000000000300000000000000000060;
        char[53]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[54]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[55]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[56]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[57]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[58]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[59]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[60]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[61]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[62]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
        char[63]    <=  256'h0000000000000000000000000000000000000000000000000000000000000000;
    end
//pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge tft_clk_9m or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pix_data    <= BLACK;
    else    if(((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
                && ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
        begin
            if(char[char_y][10'd255 - char_x] == 1'b1)
                pix_data    <=  GOLDEN;
            else
                pix_data    <=  BLACK;
        end
    else
        pix_data    <= BLACK;
endmodule

tft_ctrl

`timescale  1ns/1ns
module  tft_ctrl
(
    input   wire            tft_clk_9m  ,   //输入时钟,频率9MHz
    input   wire            sys_rst_n   ,   //系统复位,低电平有效
    input   wire    [15:0]  pix_data    ,   //待显示数据
    output  wire    [9:0]   pix_x       ,   //输出TFT有效显示区域像素点X轴坐标
    output  wire    [9:0]   pix_y       ,   //输出TFT有效显示区域像素点Y轴坐标
    output  wire    [15:0]  rgb_tft     ,   //TFT显示数据
    output  wire            hsync       ,   //TFT行同步信号
    output  wire            vsync       ,   //TFT场同步信号
    output  wire            tft_clk     ,   //TFT像素时钟
    output  wire            tft_de      ,   //TFT数据使能
    output  wire            tft_bl          //TFT背光信号
);
//parameter define
parameter H_SYNC    =   10'd41  ,   //行同步
          H_BACK    =   10'd2   ,   //行时序后沿
          H_VALID   =   10'd480 ,   //行有效数据
          H_FRONT   =   10'd2   ,   //行时序前沿
          H_TOTAL   =   10'd525 ;   //行扫描周期
parameter V_SYNC    =   10'd10  ,   //场同步
          V_BACK    =   10'd2   ,   //场时序后沿
          V_VALID   =   10'd272 ,   //场有效数据
          V_FRONT   =   10'd2   ,   //场时序前沿
          V_TOTAL   =   10'd286 ;   //场扫描周期
//wire  define
wire            rgb_valid       ;   //VGA有效显示区域
wire            pix_data_req    ;   //像素点色彩信息请求信号
//reg   define
reg     [9:0]   cnt_h   ;   //行扫描计数器
reg     [9:0]   cnt_v   ;   //场扫描计数器
//tft_clk,tft_de,tft_bl:TFT像素时钟、数据使能、背光信号
assign  tft_clk = tft_clk_9m    ;
assign  tft_de  = rgb_valid     ;
assign  tft_bl  = sys_rst_n     ;
//cnt_h:行同步信号计数器
always@(posedge tft_clk_9m or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_h   <=  10'd0   ;
    else    if(cnt_h == H_TOTAL - 1'd1)
        cnt_h   <=  10'd0   ;
    else
        cnt_h   <=  cnt_h + 1'd1   ;
//hsync:行同步信号
assign  hsync = (cnt_h  <=  H_SYNC - 1'd1) ? 1'b1 : 1'b0  ;
//cnt_v:场同步信号计数器
always@(posedge tft_clk_9m or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_v   <=  10'd0 ;
    else    if((cnt_v == V_TOTAL - 1'd1) &&  (cnt_h == H_TOTAL-1'd1))
        cnt_v   <=  10'd0 ;
    else    if(cnt_h == H_TOTAL - 1'd1)
        cnt_v   <=  cnt_v + 1'd1 ;
    else
        cnt_v   <=  cnt_v ;
//vsync:场同步信号
assign  vsync = (cnt_v  <=  V_SYNC - 1'd1) ? 1'b1 : 1'b0  ;
//rgb_valid:VGA有效显示区域
assign  rgb_valid = (((cnt_h >= H_SYNC + H_BACK)
                    && (cnt_h < H_SYNC + H_BACK + H_VALID))
                    &&((cnt_v >= V_SYNC + V_BACK)
                    && (cnt_v < V_SYNC + V_BACK + V_VALID)))
                    ? 1'b1 : 1'b0;
//pix_data_req:像素点色彩信息请求信号,超前rgb_valid信号一个时钟周期
assign  pix_data_req = (((cnt_h >= H_SYNC + H_BACK - 1'b1)
                    && (cnt_h < H_SYNC + H_BACK + H_VALID - 1'b1))
                    &&((cnt_v >= V_SYNC + V_BACK)
                    && (cnt_v < V_SYNC + V_BACK + V_VALID)))
                    ? 1'b1 : 1'b0;
//pix_x,pix_y:VGA有效显示区域像素点坐标
assign  pix_x = (pix_data_req == 1'b1)
                ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'h3ff;
assign  pix_y = (pix_data_req == 1'b1)
                ? (cnt_v - (V_SYNC + V_BACK )) : 10'h3ff;
//rgb_tft:输出像素点色彩信息
assign  rgb_tft = (rgb_valid == 1'b1) ? pix_data : 16'b0 ;
endmodule

tft_char

`timescale  1ns/1ns
module  tft_char
(
    input   wire            sys_clk     ,   //输入工作时钟,频率50MHz
    input   wire            sys_rst_n   ,   //输入复位信号,低电平有效
    output  wire    [15:0]  rgb_tft     ,   //输出像素信息
    output  wire            hsync       ,   //输出行同步信号
    output  wire            vsync       ,   //输出场同步信号
    output  wire            tft_clk     ,   //输出TFT时钟信号
    output  wire            tft_de      ,   //输出TFT使能信号
    output  wire            tft_bl          //输出背光信号
);
//wire  define
wire            tft_clk_9m  ;   //VGA工作时钟,频率25MHz
wire            locked      ;   //PLL locked信号
wire            rst_n       ;   //VGA模块复位信号
wire    [9:0]   pix_x       ;   //VGA有效显示区域X轴坐标
wire    [9:0]   pix_y       ;   //VGA有效显示区域Y轴坐标
wire    [15:0]  pix_data    ;   //VGA像素点色彩信息
//rst_n:VGA模块复位信号
assign  rst_n = (sys_rst_n & locked);
//------------- clk_gen_inst -------------
clk_gen clk_gen_inst
(
    .areset     (~sys_rst_n ),  //输入复位信号,高电平有效,1bit
    .inclk0     (sys_clk    ),  //输入50MHz晶振时钟,1bit
    .c0         (tft_clk_9m ),  //输出TFT工作时钟,频率9Mhz,1bit
    .locked     (locked     )   //输出pll locked信号,1bit
);
//------------- tft_ctrl_inst -------------
tft_ctrl    tft_ctrl_inst
(
    .tft_clk_9m  (tft_clk_9m),   //输入时钟,频率9MHz,1bit
    .sys_rst_n   (rst_n     ),   //系统复位,低电平有效,1bit
    .pix_data    (pix_data  ),   //待显示数据,16bit
    .pix_x       (pix_x     ),   //输出TFT有效显示区域像素点X轴坐标,10bit
    .pix_y       (pix_y     ),   //输出TFT有效显示区域像素点Y轴坐标,10bit
    .rgb_tft     (rgb_tft   ),   //输出TFT显示数据,16bit
    .hsync       (hsync     ),   //输出TFT行同步信号,1bit
    .vsync       (vsync     ),   //输出TFT场同步信号,1bit
    .tft_clk     (tft_clk   ),   //输出TFT像素时钟,1bit
    .tft_de      (tft_de    ),   //输出TFT数据使能,1bit
    .tft_bl      (tft_bl    )    //输出TFT背光信号,1bit
);
//------------- tft_pic_inst -------------
tft_pic tft_pic_inst
(
    .tft_clk_9m  (tft_clk_9m),   //输入工作时钟,频率9MHz,1bit
    .sys_rst_n   (rst_n     ),   //输入复位信号,低电平有效,1bit
    .pix_x       (pix_x     ),   //输入TFT有效显示区域像素点X轴坐标,10bit
    .pix_y       (pix_y     ),   //输入TFT有效显示区域像素点Y轴坐标,10bit
    .pix_data    (pix_data  )    //输出像素点色彩信息,16bit
);
endmodule

tb_tft_char

`timescale  1ns/1ns
module  tb_tft_char();
//wire  define
wire            hsync   ;
wire    [15:0]  rgb_tft ;
wire            vsync   ;
wire            tft_clk ;
wire            tft_de  ;
wire            tft_bl  ;
//reg   define
reg             sys_clk     ;
reg             sys_rst_n   ;
//sys_clk,sys_rst_n初始赋值
initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
        #200
        sys_rst_n   <=  1'b1;
    end
//sys_clk:产生时钟
always  #10 sys_clk = ~sys_clk  ;
//------------- tft_char_inst -------------
tft_char    tft_char_inst
(
    .sys_clk     (sys_clk   ),   //输入工作时钟,频率50MHz,1bit
    .sys_rst_n   (sys_rst_n ),   //输入复位信号,低电平有效,1bit
    .rgb_tft     (rgb_tft   ),   //输出像素信息,16bit
    .hsync       (hsync     ),   //输出行同步信号,1bit
    .vsync       (vsync     ),   //输出场同步信号,1bit
    .tft_clk     (tft_clk   ),   //输出TFT时钟信号,1bit
    .tft_de      (tft_de    ),   //输出TFT使能信号,1bit
    .tft_bl      (tft_bl    )    //输出背光信号,1bit
);
endmodule


目录
相关文章
|
7月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(一)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
226 2
|
7月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(三)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
176 4
|
5月前
|
数据采集 计算机视觉 异构计算
FPGA进阶(2):基于I2C协议的EEPROM驱动控制
FPGA进阶(2):基于I2C协议的EEPROM驱动控制
82 0
|
5月前
|
异构计算 内存技术
FPGA进阶(1):基于SPI协议的Flash驱动控制(二)
FPGA进阶(1):基于SPI协议的Flash驱动控制
68 0
|
5月前
|
异构计算 内存技术
FPGA进阶(1):基于SPI协议的Flash驱动控制(一)
FPGA进阶(1):基于SPI协议的Flash驱动控制(一)
226 0
|
5月前
|
异构计算
FPGA强化(8):HDMI显示器驱动
FPGA入门(8):VGA显示器驱动
50 0
|
7月前
|
存储 芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(二)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
186 4
|
20天前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
121 69

热门文章

最新文章