zoukankan      html  css  js  c++  java
  • 基于NIOS II的液晶显示设计——TFT驱动

    基于NIOS II的液晶显示设计——TFT驱动
    本设计的液晶使用的是320*240,采用的DE模式,具体的时序见本博客文章《基于TFT LCD320*240 液晶显示 —— 碰碰球》,设计思想为以SRAM为缓存器,FIFO读SRAM的数据在TFT上显示出来,NIOS II对SRAM进行读写从而对TFT控制,框架图如下:

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    1、sync_level异步复位、同步释放

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    module sync_level (
    clk,
    clk_rst_n,
    async_sig,
    sync_sig);

    parameter SIGNAL_WIDTH = 1;

    input clk;
    input clk_rst_n;
    input [SIGNAL_WIDTH-1:0] async_sig;
    output [SIGNAL_WIDTH-1:0] sync_sig;

    reg [SIGNAL_WIDTH-1:0] sync_sig_pre, sync_sig;

    always @(posedge clk or negedge clk_rst_n)
    if (!clk_rst_n)
        {sync_sig_pre, sync_sig} <= 2'b00;
    else
        {sync_sig_pre, sync_sig} <= {async_sig, sync_sig_pre};

    endmodule 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    2、 DE .v TFT DE model时序

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    module de (
    fifo_rclk,
    rclk_rst_n,
    fifo_empty,
    fifo_rdata,
    fifo_rd,
    lcd_enable,
    red, green, blue);

    input fifo_rclk;
    input rclk_rst_n;
    input fifo_empty;
    input [15:0] fifo_rdata;
    output fifo_rd;
    output lcd_enable;
    output [5:0] red, green, blue;

    wire clr_cnt_h;
    reg [8:0] cnt_h;
    reg [7:0] cnt_v;
    wire lcd_enable_h, lcd_enable_v, lcd_enable_w;
    wire fifo_rd_v_en;
    reg lcd_enable_w_d, lcd_enable;
    reg fifo_rd_d;
    reg [5:0] red, green, blue;


    /////////////////////////////////////////////////////////////
    // TFT LCD DE Mode timing
    assign clr_cnt_h = (cnt_h >= 9'd384) ? 1'b1 : 1'b0;

    always @(posedge fifo_rclk or negedge rclk_rst_n)
    if (!rclk_rst_n)
        cnt_h <= 0;
    else if(clr_cnt_h)
        cnt_h <= 0;
    else
        cnt_h <= cnt_h + 1'b1;

    always @(posedge fifo_rclk or negedge rclk_rst_n)
    if (!rclk_rst_n)
        cnt_v <= 0;
    else if (clr_cnt_h)
        cnt_v <= cnt_v + 1'b1;

    assign lcd_enable_h = (cnt_h<9'd320) ? 1'b1 : 1'b0;
    assign lcd_enable_v = (cnt_v<8'd243) ? 1'b1 : 1'b0;
    assign lcd_enable_w = lcd_enable_h & lcd_enable_v;
    assign fifo_rd_v_en = (cnt_v<8'd240) ? 1'b1 : 1'b0;
    assign fifo_rd = ~fifo_empty & lcd_enable_h & fifo_rd_v_en;

    always @(posedge fifo_rclk or negedge rclk_rst_n)
    if (!rclk_rst_n)
        {lcd_enable, lcd_enable_w_d} <= 1'b0;
    else
        {lcd_enable, lcd_enable_w_d} <= {lcd_enable_w_d, lcd_enable_w};

    always @(posedge fifo_rclk or negedge rclk_rst_n)
    if (!rclk_rst_n)
        fifo_rd_d <= 1'b0;
    else
        fifo_rd_d <= fifo_rd;

    always @(posedge fifo_rclk or negedge rclk_rst_n)
    if (!rclk_rst_n)
        {red, green, blue} <= 18'd0;
    else if(fifo_rd_d) begin
        red   <= {fifo_rdata[15:11],fifo_rdata[11]};
        green <= fifo_rdata[10:5];
        blue  <= {fifo_rdata[4:0],fifo_rdata[0]};
    end
    endmodule 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    3、FIFO.v Quartus II里面的FIFO

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    module fifo (
     data,
     rdclk,
     rdreq,
     wrclk,
     wrreq,
     q,
     rdempty,
     wrfull);

     input [15:0]  data;
     input   rdclk;
     input   rdreq;
     input   wrclk;
     input   wrreq;
     output [15:0]  q;
     output   rdempty;
     output   wrfull;

     wire  sub_wire0;
     wire  sub_wire1;
     wire [15:0] sub_wire2;
     wire  rdempty = sub_wire0;
     wire  wrfull = sub_wire1;
     wire [15:0] q = sub_wire2[15:0];

     dcfifo dcfifo_component (
        .wrclk (wrclk),
        .rdreq (rdreq),
        .rdclk (rdclk),
        .wrreq (wrreq),
        .data (data),
        .rdempty (sub_wire0),
        .wrfull (sub_wire1),
        .q (sub_wire2)
        // synopsys translate_off
        ,
        .aclr (),
        .rdfull (),
        .rdusedw (),
        .wrempty (),
        .wrusedw ()
        // synopsys translate_on
        );
     defparam
      dcfifo_component.intended_device_family = "Cyclone II",
      dcfifo_component.lpm_numwords = 512,
      dcfifo_component.lpm_showahead = "OFF",
      dcfifo_component.lpm_type = "dcfifo",
      dcfifo_component.lpm_width = 16,
      dcfifo_component.lpm_widthu = 9,
      dcfifo_component.overflow_checking = "ON",
      dcfifo_component.rdsync_delaypipe = 4,
      dcfifo_component.underflow_checking = "ON",
      dcfifo_component.use_eab = "ON",
      dcfifo_component.wrsync_delaypipe = 4;


    endmodule

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    4、wr_fifo.v 产生SRAM读地址

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    module wr_fifo (
    clk,
    clk_rst_n,
    chipselect,
    //Write FIFO
    fifo_full,
    fifo_wr,
    fifo_address);

    input clk;
    input clk_rst_n;
    input chipselect;
    input fifo_full;
    output fifo_wr;
    output [17:0] fifo_address;

    wire fifo_wr;
    reg fifo_wr_en;
    reg [17:0] fifo_address;

    always @(posedge clk or negedge clk_rst_n)
    if(!clk_rst_n)
        fifo_wr_en <= 1'b0;
    else
        fifo_wr_en <= 1'b1;

    assign fifo_wr = fifo_wr_en & ~fifo_full & ~chipselect;

    always @(posedge clk or negedge clk_rst_n)
    if(!clk_rst_n)
        fifo_address <=18'd320;
    else if (fifo_wr) begin
        if(fifo_address == 18'd76799 + 18'd320 )
        fifo_address <= 18'd320;
        else
        fifo_address <= fifo_address + 1'b1;
    end

    /*
    reg [8:0] x_pos,y_pos;
    always@(posedge clk or negedge clk_rst_n)
    begin
     if(!clk_rst_n) begin
      x_pos <= 9'd0;
      y_pos <= 9'd0;
     end
     else if (fifo_wr) begin  
       if( x_pos == 9'd319) x_pos <= 9'd0;
       else begin
        x_pos <= x_pos + 1'b1;
        if(y_pos == 9'd239) y_pos <= 9'd0;
        else y_pos <= y_pos + 1'b1;
       end
     end  
    end
      
    assign fifo_wdata = (x_pos < 100) ? 16'hf000 : 16'h0fc0;

    */
    endmodule 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    5、lcd_buffer.v  NIOS II IP

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    module lcd_buffer(
    clk,
    rst_n,
    //Avalon BUS for NIOS II
    chipselect,
    address,
    write,
    writedata,
    byteenable,
    read,
    readdata,
    //TFT LCD 320*240
    ENB,
    DCLK,
    LEDCTRL,
    RED, GREEN, BLUE,
    //SRAM 256K*16bits
    SRAM_ADDR,
    SRAM_DQ,
    SRAM_WE_N,
    SRAM_OE_N,
    SRAM_UB_N,
    SRAM_LB_N,
    SRAM_CE_N);

    input clk;      //system clock, 50mhz
    input rst_n;    //system async reset, low active

    //Avalon BUS for NIOS II
    input chipselect;
    input[17:0] address;
    input write;
    input[15:0] writedata;
    input[1:0]  byteenable;
    input read;
    output[15:0] readdata;
    //TFT LCD de mode, according to chapter 5.4 in ET0350G0DM6-320-240.pdf
    output LEDCTRL;
    output ENB;     //data enable
    output DCLK;    //dot data clock
    output [5:0] RED, GREEN, BLUE;  //rgb data bits

    //SRAM 256K*16bits
    output[17:0] SRAM_ADDR;
    inout[15:0] SRAM_DQ;
    output SRAM_WE_N;
    output SRAM_OE_N;
    output SRAM_UB_N;
    output SRAM_LB_N;
    output SRAM_CE_N;

    wire [17:0] fifo_address;
    assign SRAM_ADDR= ( chipselect ) ? address : fifo_address;
    assign SRAM_DQ  = ( write & chipselect) ? writedata : 16'hzzzz;
    assign SRAM_WE_N = ~write;
    assign SRAM_OE_N = 1'b0;
    assign SRAM_UB_N = ( chipselect ) ? ~byteenable[1] : 1'b0;
    assign SRAM_LB_N = ( chipselect ) ? ~byteenable[0] : 1'b0;
    assign SRAM_CE_N = 1'b0;
    assign fifo_wdata = ( read & chipselect ) ? 16'hzzzz : SRAM_DQ ;
    assign readdata = ( read & chipselect ) ? SRAM_DQ : 16'hzzzz ;


    reg [2:0] rclk_dcnt;
    wire clk_rst_n;
    wire fifo_full;
    wire fifo_wr;
    wire [15:0] fifo_wdata;
    wire fifo_rclk;
    wire rclk_rst_n;
    wire fifo_empty;
    wire fifo_rd;
    wire [15:0] fifo_rdata;
    wire lcd_enable;
    wire [5:0] red, green, blue;

    assign LEDCTRL = 0;
    //system clk divion 8, to generate fifo_rclk
    always@(posedge clk or negedge clk_rst_n)
    if (!clk_rst_n)
        rclk_dcnt <=0;
    else
        rclk_dcnt <= rclk_dcnt + 1'b1;

    sync_level sync_clk_rst_n (
    .clk        ( clk           ),
    .clk_rst_n  ( rst_n         ),
    .async_sig  ( 1'b1          ),
    .sync_sig   ( clk_rst_n     ));

    assign fifo_rclk = rclk_dcnt[2];

    sync_level sync_rclk_rst_n (
    .clk        ( fifo_rclk     ),
    .clk_rst_n  ( rst_n         ),
    .async_sig  ( 1'b1          ),
    .sync_sig   ( rclk_rst_n    ));

    wr_fifo u_wr_fifo (
    .clk        ( clk           ),
    .clk_rst_n  ( clk_rst_n     ),
    .chipselect ( chipselect    ),
    .fifo_full  ( fifo_full     ),
    .fifo_wr    ( fifo_wr       ),
    .fifo_address( fifo_address  ));

    //FIFO 18bits,512 deepth

    fifo u_fifo (
    .data       ( fifo_wdata    ),
    .rdclk      ( fifo_rclk     ),
    .rdreq      ( fifo_rd       ),
    .wrclk      ( clk           ),
    .wrreq      ( fifo_wr       ),
    .q          ( fifo_rdata    ),
    .rdempty    ( fifo_empty    ),
    .wrfull     ( fifo_full     ));

    de u_de (
    .fifo_rclk  ( fifo_rclk     ),
    .rclk_rst_n ( rclk_rst_n    ),
    .fifo_empty ( fifo_empty    ),
    .fifo_rdata ( fifo_rdata    ),
    .fifo_rd    ( fifo_rd       ),
    .lcd_enable ( lcd_enable    ),
    .red        ( red           ),
    .green      ( green         ),
    .blue       ( blue          ));

    //lcd interface
    assign DCLK = ~rclk_dcnt[2];
    assign ENB = lcd_enable;
    assign RED = red;
    assign GREEN = green;
    assign BLUE = blue;


    endmodule

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    在SOPC里面生产IP即可!

  • 相关阅读:
    C++学习笔记 继承,虚基类
    C++ 学习笔记 静态成员与常成员
    C++学习笔记,初始化列表与构造函数
    C++ 学习笔记 运算符优先级
    C++学习笔记 this指针,对象数组,对象指针数组;
    C++初级基础笔记 标识符 关键字
    C++学习笔记 指向类的数据成员的指针
    C++学习笔记 const修饰类成员与成员函数
    虚幻学习day2 简单手电筒与开关门效果(一)
    虚幻学习Day1(二) 触碰控制灯光开关
  • 原文地址:https://www.cnblogs.com/Neddy/p/2026774.html
Copyright © 2011-2022 走看看