📄 lcd_interface.v
字号:
module LCD_INTERFACE(
clk, //The Avalon clk 100MHz
lcd_clk,
reset_n,
//avalon slave port;it is a control port and CPU can get data from this port
//input
s_chipselect,
s_address,
s_write,
s_read,
s_writedata,
//output
s_readdata,
//avalon master port;
m_address,
m_read,
m_readdata,
m_readdatavalid,
m_waitrequest,
//export
LCM_DATA, // LCM Data 8 Bits
LCM_HSYNC, // LCM HSYNC
LCM_VSYNC); // LCM VSYNC
input clk;
input lcd_clk;
input reset_n;
//avalon slave port
input s_chipselect;
input [2:0] s_address;
input s_write;
input s_read;
input [31:0] s_writedata;
output [31:0] s_readdata;
//avalon master port
input m_readdatavalid;
input m_waitrequest;
input [7:0] m_readdata;
output [31:0] m_address;
output m_read;
output [7:0] LCM_DATA;
output LCM_HSYNC;
output LCM_VSYNC;
reg [31:0] s_readdata;
reg [31:0] m_address;
reg [31:0] ColorValue; //颜色深度
reg [31:0] LineLength; //单次传输的数据个数
reg [31:0] ControlReg; //一次测量的所有采样点数
reg [31:0] BufferAddress; //测量后的波形数据存放首地址
reg [31:0] CursorBaseX; //光标横坐标
reg [31:0] CursorBaseY; //光标纵坐标
reg [31:0] ShowCursor; //是否显示光标
reg [10:0] HCount;
reg [10:0] VCount;
reg VGA_H_SYNC;
reg VGA_V_SYNC;
reg [1:0] MOD_3;
parameter idle = 1'b0;
parameter read = 1'b1;
reg master_state;
reg next_state;
wire rdempty;
wire cycle_end;
wire [7:0] colorreg;
wire FifoWrReq;
wire FifoRdReq;
wire [7:0] FifoData;
reg [31:0] FrameAdrCnt;
reg [31:0] Address_reg;
reg [31:0] Length_count;
reg DispTag;
reg Transreg;
reg TransTag;
reg TransCtr;
reg VGA_HLineBuf;
//cursor
reg [10:0] cursor_addr;
wire [10:0] VCursor_Base;
wire [10:0] HCursor_Base;
wire [7:0] cursor_data;
reg cursor_en;
assign LCM_VSYNC = VGA_V_SYNC;
assign LCM_HSYNC = VGA_H_SYNC;
assign LCM_DATA = (ShowCursor[0] && cursor_en && (cursor_data != 8'b11111111)) ? cursor_data : colorreg;
// Horizontal Parameter ( Pixel )
parameter H_SYNC_CYC = 5;
parameter H_SYNC_BACK = 208;
parameter H_SYNC_ACT = 960;
parameter H_SYNC_FRONT = 84;
parameter H_SYNC_TOTAL = 1252;
// Virtical Parameter ( Line )
parameter V_SYNC_CYC = 3;
parameter V_SYNC_BACK = 18;
parameter V_SYNC_ACT = 234;
parameter V_SYNC_FRONT = 10;
parameter V_SYNC_TOTAL = 262;
always @ (posedge clk or negedge reset_n) //write Frame Buffer Address register
begin
if(reset_n == 1'b0)
begin
ColorValue <= 0;
LineLength <= 0;
ControlReg <= 0;
BufferAddress <= 0;
CursorBaseX <= 0;
CursorBaseY <= 0;
ShowCursor <= 0;
end
else
if(s_write & s_chipselect)
begin
case(s_address)
3'b000:ColorValue <= s_writedata;
3'b001:LineLength <= s_writedata;
3'b010:ControlReg <= s_writedata;
3'b011:BufferAddress <= s_writedata;
3'b100:CursorBaseX <= s_writedata;
3'b101:CursorBaseY <= s_writedata;
3'b110:ShowCursor <= s_writedata;
endcase
end
end
always @ (posedge clk )
begin
if(reset_n == 1'b0)
s_readdata <= 0;
else
if(s_read & s_chipselect)
begin
case(s_address)
3'b000:s_readdata <= ColorValue;
3'b001:s_readdata <= LineLength;
3'b010:s_readdata <= ControlReg;
3'b011:s_readdata <= BufferAddress;
3'b100:s_readdata <= CursorBaseX;
3'b101:s_readdata <= CursorBaseY;
3'b110:s_readdata <= ShowCursor;
endcase
end
end
always @ (posedge lcd_clk or negedge reset_n)
begin
if(!reset_n)
begin
HCount <= 1;
VGA_H_SYNC <= 0;
VGA_HLineBuf <= 0;
end
else
begin
if(HCount == H_SYNC_TOTAL)
HCount <= 1;
else
HCount <= HCount + 1;
if(HCount <= H_SYNC_CYC)
begin
VGA_H_SYNC <= 0;
VGA_HLineBuf <= 0;
end
else if(HCount <= H_SYNC_BACK)
begin
VGA_H_SYNC <= 1;
VGA_HLineBuf <= 0;
end
else if(HCount <= H_SYNC_ACT + H_SYNC_BACK)
begin
VGA_H_SYNC <= 1;
VGA_HLineBuf <= 1;
end
else if(HCount <= H_SYNC_TOTAL)
begin
VGA_H_SYNC <= 1;
VGA_HLineBuf <= 0;
end
end
end
always @ (posedge lcd_clk or negedge reset_n)
begin
if(!reset_n)
begin
VCount <= 1;
VGA_V_SYNC <= 0;
end
else
begin
if(HCount == H_SYNC_TOTAL)
begin
if(VCount == V_SYNC_TOTAL)
VCount <= 1;
else
VCount <= VCount + 1;
end
if(VCount <= V_SYNC_CYC)
begin
VGA_V_SYNC <= 0;
end
else
begin
VGA_V_SYNC <= 1;
end
end
end
//avalon master
always @ (posedge clk or negedge reset_n) //this state machine used for control the master port status (either idle or read data from sdram)
if(!reset_n)
master_state = idle;
else
master_state = next_state;
always @ (master_state or BufferAddress or LineLength or Length_count)
case(master_state)
idle:
begin
Transreg = 1'b1;
if(rdempty & TransTag) //when Fifo is empty and the 3th Control register bit is 1 then master port into Transmit status
next_state = read;
else
next_state = idle;
end
read:
begin
Transreg = 1'b0;
if(Length_count == 32'h0) //When transmit the number of data(equal to Length_reg) then master port into idle status
next_state = idle;
else
next_state = read;
end
default:
next_state = idle;
endcase
assign m_read = master_state; //The master port output read signal to Avalon switch fabric means the port want read Transfer
assign cycle_end = m_read & ~m_waitrequest; //if a waitrequest signal is true, means slave device is ready otherwist waiting
always @(posedge clk or negedge reset_n) //Master address increment
if(reset_n == 1'b0)
m_address <= 0;
else if(Transreg)
m_address <= FrameAdrCnt;
else if (cycle_end)
m_address <= m_address + 32'h00000001;
always @ (posedge clk or negedge reset_n) //Length counter decrement
if(reset_n == 1'b0)
Length_count <= 0;
else if(Transreg)
Length_count <= LineLength;
else if(cycle_end)
Length_count <= Length_count - 1;
always @ (posedge lcd_clk or negedge reset_n)
if(!reset_n)
begin
TransTag <= 1'b0;//(开始传输标签(输入) 写请求
TransCtr <= 1'b0;
DispTag <= 1'b0;//(显示传输标签(输出) 读请求)
end
else
begin
if(VCount == 11'd1)
begin
TransTag <= 1'b0;
TransCtr <= 1'b1;
DispTag <= 1'b0;
end
else if(VCount <= V_SYNC_BACK || VCount > V_SYNC_BACK + V_SYNC_ACT)
begin
TransTag <= 1'b0;
DispTag <= 1'b0;
end
else if(VCount == V_SYNC_BACK + V_SYNC_ACT)
begin
TransTag <= 1'b0;
DispTag <= 1'b1;
end
else
begin
DispTag <= 1'b1;
if(TransCtr)
TransTag<=1'b1;
else
TransTag<=1'b0;
end
end
always @ (posedge VGA_HLineBuf)
if(TransTag)
begin
FrameAdrCnt <= FrameAdrCnt + LineLength;
end
else
begin
FrameAdrCnt <= BufferAddress;
end
always @ (negedge lcd_clk or negedge reset_n)
if(!reset_n)
begin
cursor_addr <= 0;
cursor_en <= 0;
end
else
begin
if( (ShowCursor[0]) &&
((HCount - H_SYNC_BACK - H_SYNC_CYC) >= CursorBaseX[9:0]) &&
((HCount - H_SYNC_BACK - H_SYNC_CYC) <= CursorBaseX[9:0] + 29) &&
((VCount - V_SYNC_BACK - V_SYNC_CYC) >= CursorBaseY[9:0]) &&
((VCount - V_SYNC_BACK - V_SYNC_CYC) <= CursorBaseY[9:0] + 14))
begin
cursor_addr <= VCursor_Base * 30 + HCursor_Base;
cursor_en <= 1;
end
else
begin
cursor_addr <= 0;
cursor_en <= 0;
end
end
assign VCursor_Base = (VCount - V_SYNC_BACK - V_SYNC_CYC) - CursorBaseY[9:0];
assign HCursor_Base = (HCount - H_SYNC_BACK - H_SYNC_CYC) - CursorBaseX[9:0];
assign FifoData = (TransTag) ? m_readdata : 8'hZZ;
assign FifoWrReq = (TransTag) ? m_readdatavalid : 1'b0;
assign FifoRdReq = DispTag && (!rdempty) && VGA_HLineBuf;
cursor cursor_inst(
.data(16'h0000),
.rdaddress(cursor_addr),
.rdclock(lcd_clk),
.rden(cursor_en),
.wraddress(10'b0000000000),
.wrclock(clk),
.wren(1'b0),
.q(cursor_data));
FrameBufferFifo FBF_inst(
.aclr(~reset_n),
.data(FifoData),
.rdclk(lcd_clk),
.rdreq(FifoRdReq),
.wrclk(clk),
.wrreq(FifoWrReq),
.q(colorreg),
.rdempty(rdempty),
.wrusedw());
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -