最近在网上找了很多用verilog驱动LCD1602的程序,但基本没有一个是完美运行,很多论坛所谓大神的代码综合时候一样很多缺陷,要知道每一个warning都有可能是导致最终失败的原因。于是乎只能自己下功夫,找到一个稍微靠谱的开发板配套例程,但是分频器模块编的叫一塌糊涂,主时钟分频后继续分频而且组合时序乱用,通过分频模块重新编写后基本无warning完美运行,仿真功能实现并且下载显示成功,后面附上了我的testbench,本人用的软件为ISE12.2,不过个人感觉quartus应该一样跑,下面是代码,需要在1602显示什么字符自己改显示函数就行,希望对大家有帮助。modulelcd1602(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD_D);inputclk,rst;outputLCD_E,LCD_RW,LCD_RS;output[7:0]LCD_D;regLCD_E,LCD_RW,LCD_RS;reg[7:0]LCD_D;reg[9:0]state;reg[5:0]address;parameterIDLE=10'b0000000000;parameterCLEAR=10'b0000000001;//清屏parameterRETURNCURSOR=10'b0000000010;//归home位parameterSETMODE=10'b0000000111;//输入方式设置,读写数据后ram地址增/减1;画面动/不动parameterSWITCHMODE=10'b0000001111;//显示状态设置,显示开/关;光标开/关;闪烁开/关parameterSHIFT=10'b0000011100;//光标画面滚动画面/光标平移一位;左/右平移一位parameterSETFUNCTION=10'b0000111100;//工作方式设置1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵parameterSETCGRAM=10'b0001000000;//设置CGRAMparameterSETDDRAM1=10'b0010000001;//设置DDRAMparameterSETDDRAM2=10'b0010000010;//设置DDRAMparameterREADFLAG=10'b0100000000;//读状态parameterWRITERAM1=10'b1000000001;//写RAMparameterWRITERAM2=10'b1000000010;//写RAMparameterREADRAM=10'b1100000000;//读RAMparametercur_inc=1;parametercur_dec=0;parametercur_shift=1;parametercur_noshift=0;parameteropen_display=1;parameteropen_cur=0;parameterblank_cur=0;parametershift_display=1;parametershift_cur=0;parameterright_shift=1;parameterleft_shift=0;parameterLCD_Dwidth8=1;parameterLCD_Dwidth4=0;parametertwoline=1;parameteroneline=0;parameterfont5x10=1;parameterfont5x7=0;/******************************************************************/function[7:0]ddram;//写入需要的字符数据input[5:0]n;begincase(n)0:ddram=8'h48;//H1:ddram=8'h65;//e2:ddram=8'h6c;//l3:ddram=8'h6c;//l4:ddram=8'h6f;//o5:ddram=8'h21;//!6:ddram=8'h21;//!7:ddram=8'hA0;//space8:ddram=8'h7E;//-9:ddram=8'hA0;//space10:ddram=8'h5A;//Z11:ddram=8'h52;//R12:ddram=8'h74;//t13:ddram=8'h65;//e14:ddram=8'h63;//c15:ddram=8'h68;//h16:ddram=8'h77;//w17:ddram=8'h77;//w18:ddram=8'h77;//w19:ddram=8'h2E;//.20:ddram=8'h5A;//Z21:ddram=8'h52;//R22:ddram=8'hB0;//R23:ddram=8'h74;//t24:ddram=8'h65;//e25:ddram=8'h63;//c26:ddram=8'h68;//h27:ddram=8'h2E;//.28:ddram=8'h6E;//n29:ddram=8'h65;//e30:ddram=8'h74;//t31:ddram=8'hA0;//spacedefault:ddram=8'hxx;endcaseendendfunction/******************************************************************///分频模块reg[16:0]clkcnt;regclkdiv;always@(posedgeclk)if(!rst)clkcnt=17'b0_0000_0000_0000_0000;elsebeginif(clkcnt17'b0_1001_1100_0100_0000)//16'b1001_1100_0100_0000beginclkcnt=clkcnt+1;clkdiv=0;endelseif(clkcnt==17'b1_0011_1000_0111_1111)clkcnt=17'b0_0000_0000_0000_0000;elsebeginclkcnt=clkcnt+1;clkdiv=1;endendregclk_int;always@(posedgeclkdivornegedgerst)//原为clkdivif(!rst)clk_int=0;elseclk_int=~clk_int;always@(negedgeclkdivornegedgerst)//T为clkdiv的2倍,100000个clk:500Hz,2msif(!rst)LCD_E=0;elseLCD_E=~LCD_E;/******************************************************************/always@(posedgeclk_intornegedgerst)if(!rst)beginstate=IDLE;address=6'b000000;LCD_D=8'b00000000;LCD_RS=0;LCD_RW=0;endelsebegincase(state)IDLE:beginLCD_D=8'bzzzz_zzzz;state=CLEAR;endCLEAR:beginLCD_RS=0;LCD_RW=0;LCD_D=8'b0000_0001;//清屏01state=SETFUNCTION;endSETFUNCTION:beginLCD_RS=0;LCD_RW=0;LCD_D[7:5]=3'b001;//功能设置3CLCD_D[4]=LCD_Dwidth8;LCD_D[3]=twoline;LCD_D[2]=font5x10;LCD_D[1:0]=2'b00;state=SWITCHMODE;endSWITCHMODE:beginLCD_RS=0;LCD_RW=0;LCD_D[7:3]=5'b00001;//显示状态开关设置0CLCD_D[2]=open_display;LCD_D[1]=open_cur;LCD_D[0]=blank_cur;state=SETMODE;endSETMODE:beginLCD_RS=0;LCD_RW=0;LCD_D[7:2]=6'b000001;//输入方式设置06LCD_D[1]=cur_inc;LCD_D[0]=cur_noshift;state=SHIFT;endSHIFT:beginLCD_RS=0;LCD_RW=0;LCD_D[7:4]=4'b0001;//光标画面滚动LCD_D[3]=shift_cur;LCD_D[2]=left_shift;LCD_D[1:0]=2'b00;state=SETDDRAM1;endSETDDRAM1:beginLCD_RS=0;LCD_RW=0;LCD_D=8'b10000000;//显示数据存储器地址80state=WRITERAM1;endSETDDRAM2:beginLCD_RS=0;LCD_RW=0;LCD_D=8'b11000000;//显示数据存储器地址80+40state=WRITERAM2;endWRITERAM1:begin//写第一行数据if(address=15)beginLCD_RS=1;LCD_RW=0;LCD_D=ddram(address);address=address+1;state=WRITERAM1;endelsebeginLCD_RS=0;LCD_RW=0;state=SETDDRAM2;endendWRITERAM2:begin//写第二行数据if(address=31)beginLCD_RS=1;LCD_RW=0;LCD_D=ddram(address);address=address+1;state=WRITERAM2;endelsebeginLCD_RS=0;LCD_RW=0;state=SHIFT;address=6'b000000;endendendcaseendendmodule下面是testbench代码`timescale1ns/1ps//////////////////////////////////////////////////////////////////////////////////Company:HITsz//Engineer:LIYANG////CreateDate:14:13:0508/13/2013//DesignName:lcd1602//ModuleName:E:/xilinx/ise/example/lcd1602/testwave.v//ProjectName:project//TargetDevice://Toolversions://Description:////VerilogTestFixturecreatedbyISEformodule:lcd1602////Dependencies:////Revision://Revision0.01-FileCreated//AdditionalComments://////////////////////////////////////////////////////////////////////////////////moduletestwave;//Inputsregclk;regrst;//OutputswireLCD_E;wireLCD_RW;wireLCD_RS;wire[7:0]LCD_D;//InstantiatetheUnitUnderTest(UUT)lcd1602uut(.clk(clk),.rst(rst),.LCD_E(LCD_E),.LCD_RW(LCD_RW),.LCD_RS(LCD_RS),.LCD_D(LCD_D));ini