【【RGB LCD字符 和图片的显示实验】】

RGB LCD字符 和图片的显示实验

本次实验参考自《正点原子 领航者ZYNQ 之 FPGA 开发指南》 RGB LCD字符和图片显示实验
本次实验采用的板子是 正点原子 ZYNQ 7020
本次实验 的大体代码可以参照 上次实验的代码
主要是为了 学习 字体取模的操作 然后将其 显示在屏幕上
实验任务
通过领航者开发板上的 RGB TFT-LCD 接口,在正点原子的 RGB LCD 液晶屏的左上角位置从上到下依次显示图片以及 4 个汉字“正点原子”。其中每个汉字的大小为 3232,图片的大小为100100。
说实话 我觉得 用 纯FPGA 去做 会显得很吃力 很复杂 但是主要学一个思路
倒不如用MCU 搭配 控制 寄存器来的方便
这和我们之前玩 51单片机的方法类似 其实是一个道理 只是各种实现的层次不同
51单片机自带了 点阵还有核心的链接 FPGA 都没有 只有输出的几个管脚 这反而 凸显了 FPGA无与伦比的强大 特性
由于本章实验与“RGB LCD 彩条显示实验”基本一致,所以我们可以在“RGB LCD 彩条显示实验”的系统框图稍作修改。那么需要修改什么地方呢?只需要修、改 LCD 显示模块就可以实现在 LCD 液晶屏上显示字符和图片的功能。另外,由于图片的像素数据较多,因此我们采用在 LCD 显示模块中例化了一个 ROM,用来存储图片数据。
【【RGB LCD字符 和图片的显示实验】】_第1张图片

我们这边记录一下 图片的显示原理
其实图片和字模的实现原理差不多 图片是通过 COE文件生成的
字模我们在这里通过一个PCtoLCD2002这个软件实现

因为 对于 一个图片来说 一些点阵真的是 太大了 用点阵并不能很好的实现
所以我们需要的是通过 COE 将其转化成信息
在FPGA内部 我们可以通过内部资源构建 ROM 只读文件 将其存进去 方便使用

我们直接点击下面的生成字模 之后 会发现 其实 生成的是多个汉字的 并不方便我们去操作
我们最好是将其另存为一下
【【RGB LCD字符 和图片的显示实验】】_第2张图片

先保存BMP 然后再打开 就会把这几个字 变成一个字模了
【【RGB LCD字符 和图片的显示实验】】_第3张图片

LCD 显示模块中的 ROM 是通过例化 IP 核来实现的只读存储器,它使用 FPGA 的片上存储资源,即BRAM。由于 FPGA 的片上存储资源有限,所以 ROM 中存储的图片大小也受到限制,本次实验采用的图片分辨率为 100100。领航者 ZYNQ 开发板上的 RGB TFT-LCD 接口采用 RGB888 数据格式,即每个像素点的颜色用 24bit 的数据来表示,因此大小为 100100*24bit = 240000bit=234.375Kbit≈0.23Mbit。XC7Z020 芯片的 BRAM 存储容量为 4.9Mbit
系统框图 如下所示
【【RGB LCD字符 和图片的显示实验】】_第4张图片

对于 本节实验 我们的 字模可以直接放进 verilog代码中 而 COE 文件放入 ROM中进行存储
ROM 作为只读存储器,在调用 IP 核时需要指定初始化文件,在这里就是写入存储器中的图片数据,各种格式的图片(bmp、jpg 等)在 Xilinx 开发软件中都是以 COE 文件或者 HEX 文件的形式导入到 ROM 中的。COE 文件格式较为简单,因此本次实验选取 COE 的文件格式。COE 是一种 Xilinx 工具能识别的文件格式,在文件的开头定义了存储数据的进制和初始化的数据,存储的数据最后一行以“;”结束,其余的以“,”结束。例如一个存储数据为 16 进制深度为 5 的 COE 文件内容如下图所示:
【【RGB LCD字符 和图片的显示实验】】_第5张图片

第一行定义存储的数据为 16 进制,第二行初始化的数值向量,分别对应不同存储单元的数据,存储地址从 0 开始,依次累加,最后一个存储地址的数据以“;”结束。
【【RGB LCD字符 和图片的显示实验】】_第6张图片

我们拼成一个大字模 这里就会显示 32*5 与 32 具体长宽怎么显示的 我还没研究

我们来叙述一些之前了解到的设计的具体含义
pixel_xpos 的 初始值为1
assign pixel_xpos = data_reg ? (h_cnt - ( h_sync + h_back - 1) 坐标 从 1 开始
同理 其实它也是想把值 限定在 pixel_ypos 从1开始取

它其实就是想把 pixel_xpos的值 限定在 从1开始 计数

h_cnt 其实从主端口开始 就是一直变化的 不断移动
需要注意的是 它移动的显示的范围永远是这么大 你管它是叫从0 开始 从1 开始 我从外部进来扫描的这个过程中
其实整个大小就是这么大 未曾改变

这样来说的话 我们 x_cnt这个计数值又重新归为从0 开始取了
就相当于 指定了第一个像素点的位置是 (0,0)
好的 看完了 正点原子的 叙述 我们现在下面开始自己对于此处代码段的写作

clk_div.v

module clk_div(
    input               clk,          //50Mhz
    input               rst_n,
    input       [15:0]  lcd_id,
    output  reg         lcd_pclk
    );

reg          clk_25m;
reg          clk_12_5m;
reg          div_4_cnt;

//时钟2分频 输出25MHz时钟 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        clk_25m <= 1'b0;
    else 
        clk_25m <= ~clk_25m;
end

//时钟4分频 输出12.5MHz时钟 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        div_4_cnt <= 1'b0;
        clk_12_5m <= 1'b0;
    end    
    else begin
        div_4_cnt <= div_4_cnt + 1'b1;
        if(div_4_cnt == 1'b1)
            clk_12_5m <= ~clk_12_5m;
    end        
end

always @(*) begin
    case(lcd_id)
        16'h4342 : lcd_pclk = clk_12_5m;
        16'h7084 : lcd_pclk = clk_25m;       
        16'h7016 : lcd_pclk = clk;
        16'h4384 : lcd_pclk = clk_25m;
        16'h1018 : lcd_pclk = clk;
        default :  lcd_pclk = 1'b0;
    endcase      
end

endmodule

lcd_display.v

module lcd_display(
    input             lcd_pclk,     //时钟
    input             rst_n,        //复位,低电平有效
                                    
    input      [10:0] pixel_xpos,   //像素点横坐标
    input      [10:0] pixel_ypos,   //像素点纵坐标    
    output reg [23:0] pixel_data    //像素点数据,
);                                   
                                     
//parameter define                   
localparam PIC_X_START = 11'd1;      //图片起始点横坐标
localparam PIC_Y_START = 11'd1;      //图片起始点纵坐标
localparam PIC_WIDTH   = 11'd100;    //图片宽度
localparam PIC_HEIGHT  = 11'd100;    //图片高度
                       
localparam CHAR_X_START= 11'd1;      //字符起始点横坐标
localparam CHAR_Y_START= 11'd110;    //字符起始点纵坐标
localparam CHAR_WIDTH  = 11'd128;    //字符宽度,4个字符:32*4
localparam CHAR_HEIGHT = 11'd32;     //字符高度
                       
localparam BACK_COLOR  = 24'hE0FFFF; //背景色,浅蓝色
localparam CHAR_COLOR  = 24'hff0000; //字符颜色,红色

//reg define
reg   [127:0] char[31:0];  //字符数组
reg   [13:0]  rom_addr  ;  //ROM地址

//wire define   
wire  [10:0]  x_cnt;       //横坐标计数器
wire  [10:0]  y_cnt;       //纵坐标计数器
wire          rom_rd_en ;  //ROM读使能信号
wire  [23:0]  rom_rd_data ;//ROM数据

//*****************************************************
//**                    main code
//*****************************************************

assign  x_cnt = pixel_xpos - CHAR_X_START; //像素点相对于字符区域起始点水平坐标
assign  y_cnt = pixel_ypos - CHAR_Y_START; //像素点相对于字符区域起始点垂直坐标
assign  rom_rd_en = 1'b1;                  //读使能拉高,即一直读ROM数据

//给字符数组赋值,显示汉字“正点原子”,每个汉字大小为32*32
always @(posedge lcd_pclk) begin
    char[0 ]  <= 128'h00000000000000000000000000000000;
    char[1 ]  <= 128'h00000000000000000000000000000000;
    char[2 ]  <= 128'h00000000000100000000002000000000;
    char[3 ]  <= 128'h000000100001800002000070000000C0;
    char[4 ]  <= 128'h000000380001800003FFFFF803FFFFE0;
    char[5 ]  <= 128'h07FFFFFC0001800003006000000001E0;
    char[6 ]  <= 128'h0000C000000180600300600000000300;
    char[7 ]  <= 128'h0000C0000001FFF00300C00000000600;
    char[8 ]  <= 128'h0000C000000180000310804000001800;
    char[9 ]  <= 128'h0000C00000018000031FFFE000003000;
    char[10]  <= 128'h0000C00000018000031800400001C000;
    char[11]  <= 128'h0000C00000018000031800400001C000;
    char[12]  <= 128'h00C0C000018181800318004000018000;
    char[13]  <= 128'h00C0C00001FFFFC0031FFFC000018010;
    char[14]  <= 128'h00C0C060018001800318004000018038;
    char[15]  <= 128'h00C0FFF001800180031800403FFFFFFC;
    char[16]  <= 128'h00C0C000018001800318004000018000;
    char[17]  <= 128'h00C0C000018001800218004000018000;
    char[18]  <= 128'h00C0C00001800180021FFFC000018000;
    char[19]  <= 128'h00C0C000018001800210304000018000;
    char[20]  <= 128'h00C0C00001FFFF800200300000018000;
    char[21]  <= 128'h00C0C000018001800606300000018000;
    char[22]  <= 128'h00C0C000018001000607370000018000;
    char[23]  <= 128'h00C0C00000000000060E31C000018000;
    char[24]  <= 128'h00C0C000001000400418307000018000;
    char[25]  <= 128'h00C0C000020830600430303800018000;
    char[26]  <= 128'h00C0C010020C18300860301800018000;
    char[27]  <= 128'h00C0C038060E18180883700800018000;
    char[28]  <= 128'h3FFFFFFC0C0618181100F008003F8000;
    char[29]  <= 128'h000000001C0408182000600000070000;
    char[30]  <= 128'h00000000000000000000000000020000;
    char[31]  <= 128'h00000000000000000000000000000000;
end

//为LCD不同显示区域绘制图片、字符和背景色
always @(posedge lcd_pclk or negedge rst_n) begin
    if (!rst_n)
        pixel_data <= BACK_COLOR;
    else if( (pixel_xpos >= PIC_X_START) && (pixel_xpos < PIC_X_START + PIC_WIDTH) 
          && (pixel_ypos >= PIC_Y_START) && (pixel_ypos < PIC_Y_START + PIC_HEIGHT) )
        pixel_data <= rom_rd_data ;  //显示图片
    else if((pixel_xpos >= CHAR_X_START) && (pixel_xpos < CHAR_X_START + CHAR_WIDTH)
         && (pixel_ypos >= CHAR_Y_START) && (pixel_ypos < CHAR_Y_START + CHAR_HEIGHT)) begin
        if(char[y_cnt][CHAR_WIDTH -1'b1 - x_cnt])
            pixel_data <= CHAR_COLOR;    //显示字符
        else
            pixel_data <= BACK_COLOR;    //显示字符区域的背景色
    end
    else
        pixel_data <= BACK_COLOR;        //屏幕背景色
end

//根据当前扫描点的横纵坐标为ROM地址赋值
always @(posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)
        rom_addr <= 14'd0;
    //当横纵坐标位于图片显示区域时,累加ROM地址    
    else if((pixel_ypos >= PIC_Y_START) && (pixel_ypos < PIC_Y_START + PIC_HEIGHT) 
        && (pixel_xpos >= PIC_X_START) && (pixel_xpos < PIC_X_START + PIC_WIDTH)) 
        rom_addr <= rom_addr + 1'b1;
    //当横纵坐标位于图片区域最后一个像素点时,ROM地址清零    
    else if((pixel_ypos >= PIC_Y_START + PIC_HEIGHT))
        rom_addr <= 14'd0;
end

//ROM:存储图片
blk_mem_gen_0  blk_mem_gen_0 (
  .clka  (lcd_pclk),    // input wire clka
  .ena   (rom_rd_en),   // input wire ena
  .addra (rom_addr),    // input wire [13 : 0] addra
  .douta (rom_rd_data)  // output wire [23 : 0] douta
);

endmodule 

lcd_driver.v

module lcd_driver(
    input                lcd_pclk,    //时钟
    input                rst_n,       //复位,低电平有效
    input        [15:0]  lcd_id,      //LCD屏ID
    input        [23:0]  pixel_data,  //像素数据
    output       [10:0]  pixel_xpos,  //当前像素点横坐标
    output       [10:0]  pixel_ypos,  //当前像素点纵坐标   
    output  reg  [10:0]  h_disp,      //LCD屏水平分辨率
    output  reg  [10:0]  v_disp,      //LCD屏垂直分辨率   
    //RGB LCD接口
    output               lcd_de,      //LCD 数据使能信号
    output               lcd_hs,      //LCD 行同步信号
    output               lcd_vs,      //LCD 场同步信号
    output               lcd_bl,      //LCD 背光控制信号
    output               lcd_clk,     //LCD 像素时钟
    output               lcd_rst,     //LCD 复位
    output       [23:0]  lcd_rgb      //LCD RGB888颜色数据
    );

//parameter define  
// 4.3' 480*272
parameter  H_SYNC_4342   =  11'd41;     //行同步
parameter  H_BACK_4342   =  11'd2;      //行显示后沿
parameter  H_DISP_4342   =  11'd480;    //行有效数据
parameter  H_FRONT_4342  =  11'd2;      //行显示前沿
parameter  H_TOTAL_4342  =  11'd525;    //行扫描周期
   
parameter  V_SYNC_4342   =  11'd10;     //场同步
parameter  V_BACK_4342   =  11'd2;      //场显示后沿
parameter  V_DISP_4342   =  11'd272;    //场有效数据
parameter  V_FRONT_4342  =  11'd2;      //场显示前沿
parameter  V_TOTAL_4342  =  11'd286;    //场扫描周期
   
// 7' 800*480   
parameter  H_SYNC_7084   =  11'd128;    //行同步
parameter  H_BACK_7084   =  11'd88;     //行显示后沿
parameter  H_DISP_7084   =  11'd800;    //行有效数据
parameter  H_FRONT_7084  =  11'd40;     //行显示前沿
parameter  H_TOTAL_7084  =  11'd1056;   //行扫描周期
   
parameter  V_SYNC_7084   =  11'd2;      //场同步
parameter  V_BACK_7084   =  11'd33;     //场显示后沿
parameter  V_DISP_7084   =  11'd480;    //场有效数据
parameter  V_FRONT_7084  =  11'd10;     //场显示前沿
parameter  V_TOTAL_7084  =  11'd525;    //场扫描周期       
   
// 7' 1024*600   
parameter  H_SYNC_7016   =  11'd20;     //行同步
parameter  H_BACK_7016   =  11'd140;    //行显示后沿
parameter  H_DISP_7016   =  11'd1024;   //行有效数据
parameter  H_FRONT_7016  =  11'd160;    //行显示前沿
parameter  H_TOTAL_7016  =  11'd1344;   //行扫描周期
   
parameter  V_SYNC_7016   =  11'd3;      //场同步
parameter  V_BACK_7016   =  11'd20;     //场显示后沿
parameter  V_DISP_7016   =  11'd600;    //场有效数据
parameter  V_FRONT_7016  =  11'd12;     //场显示前沿
parameter  V_TOTAL_7016  =  11'd635;    //场扫描周期
   
// 10.1' 1280*800   
parameter  H_SYNC_1018   =  11'd10;     //行同步
parameter  H_BACK_1018   =  11'd80;     //行显示后沿
parameter  H_DISP_1018   =  11'd1280;   //行有效数据
parameter  H_FRONT_1018  =  11'd70;     //行显示前沿
parameter  H_TOTAL_1018  =  11'd1440;   //行扫描周期
   
parameter  V_SYNC_1018   =  11'd3;      //场同步
parameter  V_BACK_1018   =  11'd10;     //场显示后沿
parameter  V_DISP_1018   =  11'd800;    //场有效数据
parameter  V_FRONT_1018  =  11'd10;     //场显示前沿
parameter  V_TOTAL_1018  =  11'd823;    //场扫描周期

// 4.3' 800*480   
parameter  H_SYNC_4384   =  11'd128;    //行同步
parameter  H_BACK_4384   =  11'd88;     //行显示后沿
parameter  H_DISP_4384   =  11'd800;    //行有效数据
parameter  H_FRONT_4384  =  11'd40;     //行显示前沿
parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期
   
parameter  V_SYNC_4384   =  11'd2;      //场同步
parameter  V_BACK_4384   =  11'd33;     //场显示后沿
parameter  V_DISP_4384   =  11'd480;    //场有效数据
parameter  V_FRONT_4384  =  11'd10;     //场显示前沿
parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期    

//reg define
reg  [10:0] h_sync ;
reg  [10:0] h_back ;
reg  [10:0] h_total;
reg  [10:0] v_sync ;
reg  [10:0] v_back ;
reg  [10:0] v_total;
reg  [10:0] h_cnt  ;
reg  [10:0] v_cnt  ;

//wire define    
wire        lcd_en;
wire        data_req;

//*****************************************************
//**                    main code
//*****************************************************

//RGB LCD 采用DE模式时,行场同步信号需要拉高
assign  lcd_hs = 1'b1;        //LCD行同步信号
assign  lcd_vs = 1'b1;        //LCD场同步信号

assign  lcd_bl = 1'b1;        //LCD背光控制信号  
assign  lcd_clk = lcd_pclk;   //LCD像素时钟
assign  lcd_rst= 1'b1;        //LCD复位
assign  lcd_de = lcd_en;      //LCD数据有效信号

//使能RGB888数据输出
assign  lcd_en = ((h_cnt >= h_sync + h_back) && (h_cnt < h_sync + h_back + h_disp)
                  && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp)) 
                  ? 1'b1 : 1'b0;

//请求像素点颜色数据输入  
assign data_req = ((h_cnt >= h_sync + h_back - 1'b1) && (h_cnt < h_sync + h_back + h_disp - 1'b1)
                  && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp)) 
                  ? 1'b1 : 1'b0;

//像素点坐标  
assign pixel_xpos = data_req ? (h_cnt - (h_sync + h_back - 1'b1)) : 11'd0;
assign pixel_ypos = data_req ? (v_cnt - (v_sync + v_back - 1'b1)) : 11'd0;

//RGB888数据输出
assign lcd_rgb = lcd_en ? pixel_data : 24'd0;

//行场时序参数
always @(*) begin
    case(lcd_id)
        16'h4342 : begin
            h_sync  = H_SYNC_4342; 
            h_back  = H_BACK_4342; 
            h_disp  = H_DISP_4342; 
            h_total = H_TOTAL_4342;
            v_sync  = V_SYNC_4342; 
            v_back  = V_BACK_4342; 
            v_disp  = V_DISP_4342; 
            v_total = V_TOTAL_4342;            
        end
        16'h7084 : begin
            h_sync  = H_SYNC_7084; 
            h_back  = H_BACK_7084; 
            h_disp  = H_DISP_7084; 
            h_total = H_TOTAL_7084;
            v_sync  = V_SYNC_7084; 
            v_back  = V_BACK_7084; 
            v_disp  = V_DISP_7084; 
            v_total = V_TOTAL_7084;        
        end
        16'h7016 : begin
            h_sync  = H_SYNC_7016; 
            h_back  = H_BACK_7016; 
            h_disp  = H_DISP_7016; 
            h_total = H_TOTAL_7016;
            v_sync  = V_SYNC_7016; 
            v_back  = V_BACK_7016; 
            v_disp  = V_DISP_7016; 
            v_total = V_TOTAL_7016;            
        end
        16'h4384 : begin
            h_sync  = H_SYNC_4384; 
            h_back  = H_BACK_4384; 
            h_disp  = H_DISP_4384; 
            h_total = H_TOTAL_4384;
            v_sync  = V_SYNC_4384; 
            v_back  = V_BACK_4384; 
            v_disp  = V_DISP_4384; 
            v_total = V_TOTAL_4384;             
        end        
        16'h1018 : begin
            h_sync  = H_SYNC_1018; 
            h_back  = H_BACK_1018; 
            h_disp  = H_DISP_1018; 
            h_total = H_TOTAL_1018;
            v_sync  = V_SYNC_1018; 
            v_back  = V_BACK_1018; 
            v_disp  = V_DISP_1018; 
            v_total = V_TOTAL_1018;        
        end
        default : begin
            h_sync  = H_SYNC_4342; 
            h_back  = H_BACK_4342; 
            h_disp  = H_DISP_4342; 
            h_total = H_TOTAL_4342;
            v_sync  = V_SYNC_4342; 
            v_back  = V_BACK_4342; 
            v_disp  = V_DISP_4342; 
            v_total = V_TOTAL_4342;          
        end
    endcase
end

//行计数器对像素时钟计数
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n) 
        h_cnt <= 11'd0;
    else begin
        if(h_cnt == h_total - 1'b1)
            h_cnt <= 11'd0;
        else
            h_cnt <= h_cnt + 1'b1;           
    end
end

//场计数器对行计数
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n) 
        v_cnt <= 11'd0;
    else begin
        if(h_cnt == h_total - 1'b1) begin
            if(v_cnt == v_total - 1'b1)
                v_cnt <= 11'd0;
            else
                v_cnt <= v_cnt + 1'b1;    
        end
    end    
end

endmodule

lcd_rgb_char.v

module  lcd_rgb_char(
    input              sys_clk ,
    input              sys_rst_n ,
    //RGB LCD接口 
    output             lcd_hs  ,       //LCD 行同步信号
    output             lcd_vs  ,       //LCD 场同步信号
    output             lcd_de  ,       //LCD 数据输入使能
    inout      [23:0]  lcd_rgb ,       //LCD RGB565颜色数据
    output             lcd_bl  ,       //LCD 背光控制信号
    output             lcd_rst,        //LCD 复位
    output             lcd_clk         //LCD 采样时钟
);
    
//wire define    
wire  [15:0]  lcd_id    ;    //LCD屏ID
wire          lcd_pclk  ;    //LCD像素时钟
              
wire  [10:0]  pixel_xpos;    //当前像素点横坐标
wire  [10:0]  pixel_ypos;    //当前像素点纵坐标
wire  [10:0]  h_disp    ;    //LCD屏水平分辨率
wire  [10:0]  v_disp    ;    //LCD屏垂直分辨率
wire  [23:0]  pixel_data;    //像素数据
wire  [23:0]  lcd_rgb_o ;    //输出的像素数据
wire  [23:0]  lcd_rgb_i ;    //输入的像素数据

//*****************************************************
//**                    main code
//*****************************************************

//像素数据方向切换
assign lcd_rgb = lcd_de ?  lcd_rgb_o :  {24{1'bz}};
assign lcd_rgb_i = lcd_rgb;

//读LCD ID模块
rd_id u_rd_id(
    .clk          (sys_clk  ),
    .rst_n        (sys_rst_n),
    .lcd_rgb      (lcd_rgb_i),
    .lcd_id       (lcd_id   )
    );    

//时钟分频模块    
clk_div u_clk_div(
    .clk           (sys_clk  ),
    .rst_n         (sys_rst_n),
    .lcd_id        (lcd_id   ),
    .lcd_pclk      (lcd_pclk )
    );    

//LCD显示模块    
lcd_display u_lcd_display(
    .lcd_pclk       (lcd_pclk  ),
    .rst_n          (sys_rst_n ),
    .pixel_xpos     (pixel_xpos),
    .pixel_ypos     (pixel_ypos),
    .pixel_data     (pixel_data)
    );    

//LCD驱动模块
lcd_driver u_lcd_driver(
    .lcd_pclk      (lcd_pclk  ),
    .rst_n         (sys_rst_n ),
    .lcd_id        (lcd_id    ),
    .pixel_data    (pixel_data),
    .pixel_xpos    (pixel_xpos),
    .pixel_ypos    (pixel_ypos),
    .h_disp        (h_disp    ),
    .v_disp        (v_disp    ),

    .lcd_de        (lcd_de    ),
    .lcd_hs        (lcd_hs    ),
    .lcd_vs        (lcd_vs    ),
    .lcd_bl        (lcd_bl    ),
    .lcd_clk       (lcd_clk   ),
    .lcd_rst       (lcd_rst   ),
    .lcd_rgb       (lcd_rgb_o )
    );

endmodule

rd_id.v

module rd_id(
    input                   clk    ,    //时钟
    input                   rst_n  ,    //复位,低电平有效
    input           [23:0]  lcd_rgb,    //RGB LCD像素数据,用于读取ID
    output   reg    [15:0]  lcd_id     //LCD屏ID
    );

//reg define
reg            rd_flag;  //读ID标志

//*****************************************************
//**                    main code
//*****************************************************

//获取LCD ID   M2:B7  M1:G7  M0:R7
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_flag <= 1'b0;
        lcd_id <= 16'd0;
    end    
    else begin
        if(rd_flag == 1'b0) begin
            rd_flag <= 1'b1; 
            case({lcd_rgb[7],lcd_rgb[15],lcd_rgb[23]})
                3'b000 : lcd_id <= 16'h4342;    //4.3' RGB LCD  RES:480x272
                3'b001 : lcd_id <= 16'h7084;    //7'   RGB LCD  RES:800x480
                3'b010 : lcd_id <= 16'h7016;    //7'   RGB LCD  RES:1024x600
                3'b100 : lcd_id <= 16'h4384;    //4.3' RGB LCD  RES:800x480
                3'b101 : lcd_id <= 16'h1018;    //10'  RGB LCD  RES:1280x800
                default : lcd_id <= 16'd0;
            endcase    
        end
    end    
end

endmodule

你可能感兴趣的:(FPGA学习,图像学习,fpga开发)