⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftdrivernew_v2.v

📁 TFT液晶屏驱动模块Verilog源码。实现方法:XC95288+K6R4008
💻 V
字号:
module TFTDriver(/*AUTOARG*/
      // Outputs
      HSync, VSync, XCK, DE, RGB, FrameAddr, FrameWE_N, FrameOE_N, FrameCS_N,BufAddr, BufWE_N, BufOE_N, BufCS_N,
      PRT_STB,bData_PRT,
      // Inouts
      data, FrameData,BufData, 
      // Inputs reset,  PRT_BUSY,
      clk,  CS_N, RD_N, WR_N, addr,LED,DATSub,PRT_PE,PRT_SEL,PRT_ERR
      );

input        clk;
//input        reset;
//user interface
input        CS_N;
input        RD_N;
input        WR_N;
input  [2:0] addr;
inout  [7:0] data; 
input  [1:0] DATSub;

//TFT interface
output       HSync;
output       VSync;
output       XCK;
output       DE;
output [7:0] RGB;

//buffer interface
output [18:0] BufAddr;
output        BufWE_N;
output        BufOE_N;
output        BufCS_N;
inout  [7:0]  BufData;

//frame interface
output [18:0] FrameAddr;
output        FrameWE_N;
output        FrameOE_N;
output        FrameCS_N;
inout  [7:0]  FrameData;

//Printer interface
output [7:0]  bData_PRT;
output 	      PRT_STB;
//input	      PRT_BUSY;
input         PRT_PE;
input         PRT_SEL;
input         PRT_ERR;
//input         PRT_ACK;

output [1:0]  LED;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//**********User request Interface************
 parameter ADDR_XREGL = 3'b000;
 parameter ADDR_XREGH = 3'b001; 
 
 parameter ADDR_YREGL = 3'b010;  
 parameter ADDR_YREGH = 3'b011;  
 
 parameter ADDR_PSW   = 3'b111; 
 parameter ADDR_DATA  = 3'b110;
 parameter ADDR_FRONT = 3'b100;
 parameter ADDR_BACK  = 3'b101;

 parameter MAX_X = 10'd 639;
 parameter MAX_Y =  9'd 479;
//******************************************************** 
reg		wCSN;
reg		wRDF;
reg		wWR1;
reg		wWR2;

wire		wRdRqt_Usr;
wire		wWrRqt_Usr;
//************************************************************************
reg	[9:0]	bAddr_BufL   ;
reg	[8:0]	bAddr_BufH   ;
reg	[7:0]	bData_Buf    ;
reg	[7:0]	bDataOut_Buf ;
reg		wState_Wr_Buf;
//reg		wWDataVld_Buf;
//***********************************************************************
 reg    [9:0]   XREG; //addr = 000,001
 reg    [8:0]   YREG; //addr = 010,011
 reg    [7:0]   PSW;  //addr = 111
 reg    [7:0]   DATA; //addr = 110
 reg    [7:0]   FRONT;//addr = 100
 reg    [7:0]   BACK; //addr = 101
 
 wire		WrFrameEn ;
 reg		wState_Wr;
 reg	[2:0]	bCnt  ;
 reg	[7:0]   DataOut;
 
 wire	[7:0]   bColor;
 wire		wRdRqt_Fr;
 wire		wWrRqt_Fr;
//************************************************************************
 reg	[7:0]	bData_PRT;
 reg		PRT_STB;
 reg	[7:0]	bStatus_PRT;
//**************************************************************************
 wire		reset;
// reg	[20:0]  count;
//*************************************************************
/* always @ (posedge XCK or negedge reset)
 begin
   if(~reset)
     count <= 0;
   else
     count <= count + 1;
 end

 assign LED[0] = count[20];
 */
 assign reset =  RD_N | WR_N;	
//*******************User Interface 0(BUF)****************************************  
 always @ (posedge clk or negedge reset)
 begin
   if(~reset)
   begin
     wCSN <= 0;   
     wRDF <= 0;
     wWR1 <= 0;
     wWR2 <= 0;  
     
     bStatus_PRT <= 0;	 
   end
   else
   begin
     wCSN<=  CS_N;
     //first sample            
     wRDF<= ~RD_N;
     wWR1<= ~WR_N;
     //second sample            
     wWR2<= ~wWR1;
     
     bStatus_PRT <= {1'b0,PRT_PE,PRT_SEL,PRT_ERR,4'b0};
   end
 end
 
 assign wRdRqt_Usr = wRDF;
 //单脉冲写信号
 assign wWrRqt_Usr = wWR1 & wWR2;
 
// assign LED[0] = ~CS_N;
 assign LED[1] = ~wWR1;
 
 always @ (posedge clk or negedge reset)
 begin
   if(~reset)
   begin     
     bAddr_BufL    <= 0;
     bAddr_BufH    <= 0;
     bData_Buf     <= 0;
     bDataOut_Buf  <= 0;
     wState_Wr_Buf <= 0;
     
     bData_PRT 	   <= 0;
     PRT_STB	   <= 1'b1;
   end
   else if(wRdRqt_Usr & wCSN) 
     bDataOut_Buf <= BufData;  
   else if(wWrRqt_Usr & wCSN)
   begin
     //if(~addr[1])
       case({addr[2],addr[0]})
         2'b00 : begin bAddr_BufL <= {data,DATSub}; end
         2'b01 : begin bAddr_BufH <= {data,DATSub}; end   
         2'b10 : begin bData_PRT  <= data; PRT_STB <= 1'b0; end     
         2'b11 : begin bData_Buf  <= data; wState_Wr_Buf <= 1'b1;end 
       endcase   
   end
   else if (wState_Wr_Buf )
     wState_Wr_Buf <= 1'b0;
   else if(~PRT_STB)
     PRT_STB <= 1'b1;
 end         
 
//********SRAM R/W control***************** 
 assign BufCS_N  = 0;                                           
 assign BufAddr  = {bAddr_BufH,bAddr_BufL};                   
 assign BufData  = wState_Wr_Buf ? bData_Buf : 8'bzzzz_zzzz;  
 assign BufWE_N  = ~wState_Wr_Buf;
 assign BufOE_N  = 0;       
 
//********SRAM R/W control***************** 

 assign wRdRqt_Fr = wRdRqt_Usr & ~wCSN;
 assign wWrRqt_Fr = wWrRqt_Usr & ~wCSN;
 //多点/8点写时,写入颜色选择前景色;单点写时,选择输入的颜色
 assign bColor  = PSW[1] ? FRONT : DATA;
 //写帧缓冲区的使能信号。写使能逻辑:
 //(1)处于写帧缓冲区状态,且
 //(2)单点写或者
 //     多点/8点写时,当前被写入点DATA[7]有效
 assign WrFrameEn = wState_Wr & ((~PSW[1]) | DATA[7]);
 
 always@(posedge clk or negedge reset)
 begin
   if(~reset)
   begin
     XREG  <= 0;
     YREG  <= 0;
     PSW   <= 0;
     DATA  <= 0;
     FRONT <= 0;
     BACK  <= 0;
         
     wState_Wr  <= 0;
     DataOut    <= 0;
     bCnt       <= 0;
   end
   else if(wRdRqt_Fr) 
       DataOut <= FrameData;             
   else if(wWrRqt_Fr)
   begin
     case({addr[2],DATSub[1],addr[0]})
       ADDR_XREGL : begin XREG[7:0] <= data;      end
       ADDR_XREGH : begin XREG[9:8] <= data[1:0]; end       
       ADDR_YREGL : begin YREG[7:0] <= data;      end  
       ADDR_YREGH : begin YREG[8]   <= data[0];   end 
       ADDR_DATA  : begin 
       					DATA<= data; 
       					wState_Wr <= 1'b1; 
       					//PSW[1],1--多点/8点写,0--单点写
       					bCnt <= PSW[1] ? 7 : 0; 
       				end  
       ADDR_PSW   : PSW             <= data;        
       ADDR_FRONT : FRONT           <= data;
       ADDR_BACK  : BACK            <= data; 
     endcase
   end
   else if (wState_Wr)
   begin   
     wState_Wr <= |bCnt;     
     bCnt  <= bCnt - 1;
     DATA  <= PSW[1] ? (DATA << 1) : DATA;     
     
     //X方向自增
     if(PSW[2]) 
     begin
       if(XREG == MAX_X) begin XREG <= 0; YREG <= YREG + 1; end 
       else XREG <= XREG + 1; 
     end
     //Y方向自增
     if(PSW[3]) 
     begin
       if(YREG == MAX_Y) YREG <= 0;
       else YREG <= YREG + 1;                      
     end                      
   end
 end
 
 assign data = wRdRqt_Usr ? (wCSN ? (DATSub[0] ? bDataOut_Buf //选择Buffer输出
                                               : bStatus_PRT  //选择打印机状态
                                    ) 
                                   : DataOut				  //选择帧缓冲区输出
                            ) 
                           : 8'bzzzz_zzzz;					  //置端口为输入状态
// assign data = wRdRqt_Fr ? DataOut : ((wRdRqt_Usr & wCSN) ? bDataOut_Buf : 8'bzzzz_zzzz);

//********Liquid screen display control*****************  
reg          VSync;
reg          HSync;
reg          XCK;
reg          DE;
reg  [7:0]   RGB;
reg  [9:0]   Row;
reg  [9:0]   Col;
reg          state;
//reg	     wStateK;

parameter  Display=1'b0, NonDisp=1'b1;
parameter  HDP=639, TH_PULSE=96, TH_BACK=48, TH_FRONT=16, VDP=479, TV_FRONT=12, TV_BACK=31, TV_PULSE=2;
  
 // assign FrameCS_N=0;
  //--------------------------------------------------------------
  //TFT Display State Machine
wire [9:0] next_Row;
wire [9:0] next_Col;
  assign next_Row=Row+1;
  assign next_Col=Col+1;
  //if UsrOperating,Stop the TFT display FSM,until UsrOp finished
  always@(posedge clk or negedge reset)
  if(!reset) begin
    XCK <= 0;
  end
  else begin
      XCK <= ~XCK;
  end
  
  always@(posedge XCK or negedge reset)
  if(!reset) begin
    Row<=0;
    Col<=0;
    VSync<=1;
    HSync<=1;
    DE <=1;
    state <= 0;
  end
  else begin
      case(state)
        Display: begin  //HDP          
          case(Row) 
           (HDP+TH_FRONT): begin
               HSync <= 0;
               Row <= next_Row;//Row+1;
             end
           (HDP+TH_FRONT+TH_PULSE): begin
               HSync <= 1;
               Row <= next_Row;//Row+1;
               Col <= next_Col;//Col+1;
             end
           (HDP+TH_FRONT+TH_PULSE+TH_BACK): begin
               Row <= 0;
               if(Col==VDP)
                 state <= NonDisp;  
             end
           default: begin
               DE <= (Row<HDP);
               Row <= next_Row;//Row+1;
               RGB <= 0;//FrameData;
             end
          endcase
         end
       NonDisp: begin
           DE <= 0;
           case(Row)
            (HDP+TH_FRONT): begin
                HSync <= 0;
                Row <= next_Row;//Row+1;
              end
            (HDP+TH_FRONT+TH_PULSE): begin
                HSync <= 1;
                Row <= next_Row;//Row+1;
                Col <= next_Col;//Col+1;
              end
            (HDP+TH_FRONT+TH_PULSE+TH_BACK): begin
                Row <= 0;
                if(Col==(VDP+TV_FRONT)) 
                  VSync <= 0;  
                else if(Col==(VDP+TV_FRONT+TV_PULSE))
                  VSync <= 1;
                if(Col == (VDP+TV_FRONT+TV_PULSE+TV_BACK)) begin
                  Col <= 0;
                  state <= Display;
                end
              end
            default: 
                Row <= next_Row;//Row+1;
           endcase
         end 
      endcase
    
  end 
//********Liquid screen display control*****************  
 
//********SRAM R/W control*****************  
 assign FrameCS_N  = 0;
 assign FrameAddr  = (wRdRqt_Fr | wState_Wr) ? {YREG,XREG} : {Col,Row};
 assign FrameData  = WrFrameEn ? bColor : 8'bzzzz_zzzz;
 assign FrameWE_N  = ~WrFrameEn;
 assign FrameOE_N  = 0;
  
endmodule 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -