|
楼主 |
发表于 2011-10-27 12:17:21
|
显示全部楼层
这是全部代码,DE驱动,HSync 固定低电平
感谢widesoft2 通关的代码原帖
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4799753&bbs_page_no=1&search_mode=3&search_text=widesoft2&bbs_id=1029
/*
接口说明:
Clk54:系统晶振,选择54M晶振
SysRst:系统复位线.
ExDataBus:外部16位数据总线
ExCs:控制器片选,
ExRs:数据批令选择
ExWr:写信号
ExRd:读信号
RamAddrBus:显存地址线.
RamDataBus:显存数据总线
RamCs:显存片选
RamWe:显存写选通.
LedOn:背光控制PWM
DE:TFT屏
DE:VSyncTFT屏,
HSync:TFT屏
RGB:TFT屏
Pclk:TFT屏);
*/
module Tft_dri43(Clk54, SysRst, ExDataBus, ExCs, ExRs, ExWr, ExRd, RamAddrBus,
RamDataBus, RamCs, RamWe, LedOn, DE, VSync, HSync, RGB, Pclk, RamOe);
input Clk54, SysRst, ExCs, ExRs, ExRd, ExWr;
inout [15:0] ExDataBus;
inout [15:0] RamDataBus;
output [17 : 0] RamAddrBus;
output [15:0] RGB;
output RamCs, RamWe, LedOn, DE, VSync, HSync, Pclk,RamOe;
reg [2:0] ClkCnt_Q3;
reg DotClkEn_Q;
reg Pclk_Q;
reg WrEn_Q;
reg [15:0]ExBusOut_Q;
reg [15:0] ExOutM;
reg [15:0] WriteRgb_Q;
reg ExWrClk_Q;
reg ExRsR_Q;
reg ExCsR_Q;
reg ExRdClk_Q;
reg ExRdClk_Q1;
reg ExRdClk_Q2;
reg ExRdClk_Q3;
reg ExWrClk_Q1;
reg ExWrClk_Q2;
reg ExWrClk_Q3;
reg [12:0] SramAddr;
reg [15:0] PrePareData;
reg [7:0] IndexData;
reg InRamWe;
reg IncAddr;
reg XRegOver;
reg YRegOver;
reg AskWr;
reg [15:0] RGB_Q;
reg [15:0] InBusOut_Q;
reg [8:0] XRegValue_Q;
reg [8:0] YRegValue_Q;
reg [15:0] SysCmdValue_Q;
reg [2:0] RegAddr_Q;
reg RamWeReg_Q;
reg RamTriState_Q;
reg [2:0] FillCount_Q;
reg [15:0] BRGBValue_Q;
reg [15:0] FRGBValue_Q;
reg [17:0] RamAddrBus_Q;
reg FillHead_Q;
reg [8:0] HsCount_Q;
reg [8:0] DotCount_Q;
reg SelDispRam_Q;
reg RamCsReg_Q;
reg DsMark;
reg HsMark;
reg [1:0]DsState_Q;
reg [1:0]HsState_Q;
reg DE_Q;
reg [4:0]LedCount_Q;
reg LedOn_Q,LedOn_W;
assign Pclk = Pclk_Q;
assign RGB = RGB_Q;
assign RamAddrBus = RamAddrBus_Q;
assign RamWe = RamWeReg_Q;
assign RamCs = RamCsReg_Q;
assign RamDataBus = (RamTriState_Q | Clk54)?16'bzzzzzzzzzzzzzzzz:InBusOut_Q;
assign VSync = DE_Q;
assign HSync = 1'b0;
assign DE = DE_Q;
assign LedOn = LedOn_Q;//1'b1;
assign ExDataBus = ExOutM;
assign RamOe=1'b0;
/*
--1.将54M主时钟6分频,产生9M时钟并输出至引脚Pclk
--2.输出DotClkEn为9M信号同步其他进程.高电平为1个主时钟周期,低电平5个主时钟周期
--3.技巧: 001,010,011,100,101,110.共6个状态,高位刚好是6分频等宽.
*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
ClkCnt_Q3 = 3'd1;
Pclk_Q = 1'b0;
DotClkEn_Q = 1'b0;
end else begin
if (ClkCnt_Q3[2] & ClkCnt_Q3[1]) begin
ClkCnt_Q3 <= 3'd1;
end else begin
ClkCnt_Q3 <= ClkCnt_Q3 + 3'd1;
end
Pclk_Q <= (SysCmdValue_Q[7])?1'b0:ClkCnt_Q3[2];
DotClkEn_Q <= ((~ClkCnt_Q3[2]) & ClkCnt_Q3[1] & ClkCnt_Q3[0]);
end
end
/*
--外部接口在RD及CS低电平期间输出内部数据
--RS为0时输出忙信号.RS为1时输出当前地址的内部数据
*/
always @(SysRst or ExBusOut_Q or WrEn_Q or ExCs or ExRs or ExWr or ExRd)
begin
if (!SysRst) begin
ExOutM = 16'bzzzzzzzzzzzzzzzz;
end else begin
if ((~ExCs) & ExWr & (~ExRd)) begin
ExOutM = (ExRs)?ExBusOut_Q:({15'd0,WrEn_Q});
end else begin
ExOutM = 16'bzzzzzzzzzzzzzzzz;
end
end
end
/*
--外部异步WR写入数据.
*/
always @(posedge ExWr or negedge SysRst)
begin
if (!SysRst) begin
WriteRgb_Q = 16'd0;
ExWrClk_Q = 1'b0;
RegAddr_Q = 3'd0;
end else begin
if (!ExCs) begin
if (!ExRs) begin
RegAddr_Q <= ExDataBus[2:0];
end else begin
WriteRgb_Q <= ExDataBus;
ExWrClk_Q <= ~ExWrClk_Q;
end
end
end
end
/*
--外部异步RD读出数据.
*/
always @(negedge ExRd or negedge SysRst)
begin
if (!SysRst) begin
ExRsR_Q = 1'b0;
ExCsR_Q = 1'b1;
end else begin
ExCsR_Q <= ExCs;
ExRsR_Q <= ExRs;
end
end
always @(posedge ExRd or negedge SysRst)
begin
if (!SysRst) begin
ExRdClk_Q = 1'b0;
end else begin
if ((~ExCsR_Q) & ExRsR_Q) begin
ExRdClk_Q <= ~ExRdClk_Q;
end
end
end
/*
--主时钟打两拍同步采用外部读写信号
*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
ExRdClk_Q1 = 1'b0;
ExRdClk_Q2 = 1'b0;
ExRdClk_Q3 = 1'b0;
ExWrClk_Q1 = 1'b0;
ExWrClk_Q2 = 1'b0;
ExWrClk_Q3 = 1'b0;
end else begin
ExRdClk_Q1 <= ExRdClk_Q;
ExRdClk_Q2 <= ExRdClk_Q1;
ExRdClk_Q3 <= ExRdClk_Q2;
ExWrClk_Q1 <= ExWrClk_Q;
ExWrClk_Q2 <= ExWrClk_Q1;
ExWrClk_Q3 <= ExWrClk_Q2;
end
end
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
InBusOut_Q = 16'd0;
ExBusOut_Q = 16'd0;
XRegValue_Q = 9'd0;
YRegValue_Q = 9'd0;
SysCmdValue_Q = 16'b0110000000000000;
WrEn_Q = 1'b0;
RamWeReg_Q = 1'b1;
RamTriState_Q = 1'b1;
RGB_Q = 16'd0;
FillCount_Q = 3'd7;
BRGBValue_Q = 16'd0;
FRGBValue_Q = 16'd0;
RamAddrBus_Q = 18'd0;
RamCsReg_Q = 1'b1;
PrePareData = 16'd0;
end else begin
if ((( ExRdClk_Q3) & (~ExRdClk_Q2) & (~ExRdClk_Q1)) |
((~ExRdClk_Q3) & ( ExRdClk_Q2) & ( ExRdClk_Q1))) begin
IncAddr = 1'b1;
end else begin
IncAddr = 1'b0;
end
if ((( ExWrClk_Q3) & (~ExWrClk_Q2) & (~ExWrClk_Q1)) |
((~ExWrClk_Q3) & (ExWrClk_Q2) & ( ExWrClk_Q1))) begin
AskWr = 1'b1;
end else begin
AskWr = WrEn_Q;
end
XRegOver = (XRegValue_Q == 9'b111011111)?1'b1:1'b0;
YRegOver = (YRegValue_Q == 9'b100001111)?1'b1:1'b0;
PrePareData = WriteRgb_Q;
IndexData[7:0] = WriteRgb_Q[7:0];
InRamWe = 1'b1;
if (!ClkCnt_Q3[0]) begin
if (AskWr) begin
case (RegAddr_Q)
3'b000:begin
XRegValue_Q <= PrePareData[8:0];
WrEn_Q <= 1'b0;
end
3'b001:begin
YRegValue_Q <= PrePareData[8:0];
WrEn_Q <= 1'b0;
end
3'b100:begin
FRGBValue_Q <= PrePareData;
WrEn_Q <= 1'b0;
end
3'b101:begin
BRGBValue_Q <= PrePareData;
WrEn_Q <= 1'b0;
end
3'b110:begin
SysCmdValue_Q <= PrePareData;
WrEn_Q <= 1'b0;
end
3'b010:begin
InRamWe = 1'b0;
IncAddr = 1'b1;
WrEn_Q <= 1'b0;
end
3'b011:begin
if (!IndexData[FillCount_Q]) begin
PrePareData = BRGBValue_Q;
InRamWe = SysCmdValue_Q[12];
end else begin
PrePareData = FRGBValue_Q;
InRamWe = 1'b0;
end
IncAddr = 1'b1;
WrEn_Q <= (FillCount_Q[0] | FillCount_Q[1] | FillCount_Q[2]);
FillCount_Q <= FillCount_Q + 3'd7;
end
3'b111:begin
if (FillHead_Q) begin
IncAddr = 1'b1;
InRamWe = 1'b0;
if (YRegOver & XRegOver) begin
WrEn_Q <= 1'b0;
end
end else begin
WrEn_Q <= 1'b1;
end
end
endcase
end
RGB_Q <= (SysCmdValue_Q[7])?16'd0:RamDataBus;
SramAddr[12:4] = YRegValue_Q[8:0];
SramAddr[3:0] = XRegValue_Q[8:5];
RamAddrBus_Q[4:0] <= XRegValue_Q[4:0];
RamAddrBus_Q[17] <= SysCmdValue_Q[8];
end else begin
if (AskWr) begin
WrEn_Q <= 1'b1;
end
ExBusOut_Q <= RamDataBus;
SramAddr[12:4] = HsCount_Q[8:0];
SramAddr[3:0] = DotCount_Q[8:5];
RamAddrBus_Q[4:0] <= DotCount_Q[4:0];
RamAddrBus_Q[17] <= SelDispRam_Q;
end
InBusOut_Q <= PrePareData;
RamTriState_Q <= InRamWe;
RamWeReg_Q <= InRamWe;
SramAddr[12:0] = SramAddr[12:0] - {4'd0,SramAddr[12:4]};
RamAddrBus_Q[16:5] <= SramAddr[11:0];
/*根据配置字调整XY*/
if (IncAddr) begin
case (SysCmdValue_Q[15:13])
3'b001:begin
if (XRegOver) begin
XRegValue_Q <= 9'd0;
end else begin
XRegValue_Q <= XRegValue_Q + 9'd1;
end
end
3'b011:begin
if (XRegOver) begin
XRegValue_Q <= 9'd0;
if (YRegOver) begin
YRegValue_Q <= 9'd0;
end else begin
YRegValue_Q <= YRegValue_Q + 9'd1;
end
end else begin
XRegValue_Q <= XRegValue_Q + 9'd1;
end
end
3'b110:begin
if (YRegOver) begin
YRegValue_Q <= 9'd0;
end else begin
YRegValue_Q <= YRegValue_Q + 9'd1;
end
end
3'b111:begin
if (YRegOver) begin
YRegValue_Q <= 9'd0;
if (XRegOver) begin
XRegValue_Q <= 9'd0;
end else begin
XRegValue_Q <= XRegValue_Q + 9'd1;
end
end else begin
YRegValue_Q <= YRegValue_Q + 9'd1;
end
end
default:begin
end
endcase
end
RamCsReg_Q <= SysCmdValue_Q[7];
end
end
/*--产生TFT行同步*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
DotCount_Q = 9'd0;
DsState_Q = 2'd0;
DsMark = 1'b0;
end else begin
if (DotClkEn_Q) begin
case (DsState_Q)
2'd0:/*=>--41 相当于<= 40*/
DsMark = (DotCount_Q[5] & DotCount_Q[3]);
2'd1:/*when "01" =>--2 相当于<= 1*/
DsMark = DotCount_Q[0];
2'd2:/*=>--480 相当于<= 479*/
DsMark = (DotCount_Q[0] & DotCount_Q[1] & DotCount_Q[2] & DotCount_Q[3] &
DotCount_Q[4] & DotCount_Q[6] & DotCount_Q[7] & DotCount_Q[8]);
2'd3:/*--2 相当于<= 1*/
DsMark = DotCount_Q[0];
endcase
DsState_Q <= DsState_Q + {1'b0,DsMark};
DotCount_Q <= (DsMark)?9'd0:(DotCount_Q + 9'd1);
end
end
end
/*--产生TFT帧同步信号*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
DE_Q = 1'b0;
end else begin
DE_Q <= (SysCmdValue_Q[7])?1'b0:(HsState_Q[1] & (~HsState_Q[0]) & DsState_Q[1] & (~DsState_Q[0]));
end
end
/*--产生帧同步时钟*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
HsCount_Q = 9'd0;
HsState_Q = 2'd0;
FillHead_Q = 1'b0;
SelDispRam_Q = 1'b0;
LedCount_Q = 5'd0;
end else begin
if (DsState_Q[0] & DsState_Q[1] & DotCount_Q[0] & DotClkEn_Q) begin
case (HsState_Q)
2'd0:/*--10相当于<= 9*/
HsMark = (HsCount_Q[0] & HsCount_Q[3]);
2'd1:/*--2相当于<= 1*/
begin
HsMark = HsCount_Q[0];
FillHead_Q <= (RegAddr_Q[2] & RegAddr_Q[1] & RegAddr_Q[0] & WrEn_Q);
SelDispRam_Q <= SysCmdValue_Q[10];
end
2'd2:/*--272相当于<= 271*/
HsMark = (HsCount_Q[0] & HsCount_Q[1] & HsCount_Q[2] & HsCount_Q[3] & HsCount_Q[8]);
2'd3:/*--2相当于<= 1*/
HsMark = HsCount_Q[0];
endcase
HsState_Q <= HsState_Q + {1'b0,HsMark};
HsCount_Q <= (HsMark)?9'd0:(HsCount_Q + 9'd1);
LedCount_Q <= LedCount_Q + 5'd1;
end
end
end
/*LED调光进程*/
always @(posedge Clk54 or negedge SysRst)
begin
if (!SysRst) begin
LedOn_W = 1'b0;
LedOn_Q = 1'b0;
end else begin
case (SysCmdValue_Q[2:0])
3'd0:
LedOn_W = 1'b0;
3'd1:
LedOn_W = (LedCount_Q < 5'd8)?1'b1:1'b0;
3'd2:
LedOn_W = (LedCount_Q < 5'd12)?1'b1:1'b0;
3'd3:
LedOn_W = (LedCount_Q < 5'd16)?1'b1:1'b0;
3'd4:
LedOn_W = (LedCount_Q < 5'd20)?1'b1:1'b0;
3'd5:
LedOn_W = (LedCount_Q < 5'd24)?1'b1:1'b0;
3'd6:
LedOn_W = (LedCount_Q < 5'd28)?1'b1:1'b0;
default:
LedOn_W = 1'b1;
endcase
// LedOn_Q <= (SysCmdValue_Q[7])?1'b0:LedOn_W;
LedOn_Q <=SysCmdValue_Q[11];
end
end
endmodule |
|