module lcd_pdf( clk,lcd_data, lcd_rw,lcd_rs, lcd_en,rst_n);input clk;input rst_n;output reg [7:0] lcd_data;output reg lcd_rw; // wirte Loutput reg lcd_en; output reg lcd_rs;//clock 分频reg [24:0] cnt;reg clk_10;always @(posedge clk or negedge rst_n) if(!rst_n)begin cnt <= 25'd0; clk_10 <= 1'b0; end else begin if(cnt == 5)begin clk_10 =~ clk_10; cnt <= cnt + 1'b1; end end //shixualways @(posedge clk_10 or negedge rst_n) if(!rst_n)begin lcd_rw <= 1'b0; lcd_en <= 1'b0; end else begin case(cnt) 100000:begin lcd_en <= 1'b0; lcd_data <= 8'h30; lcd_rw <= 1'b0; lcd_rs <= 1'b0; end 100001:begin lcd_en <= 1'b1; end 100010:begin lcd_en <= 1'b0; lcd_data <= 8'h0c; lcd_rw <= 1'b0; lcd_rs <= 1'b0; end 100011:begin lcd_en <= 1'b1; end 100020:begin lcd_en <= 1'b0; lcd_data <= 8'h01; lcd_rw <= 1'b0; lcd_rs <= 1'b0; end 100021:begin lcd_en <= 1'b1; end 100030:begin lcd_en <= 1'b0; lcd_data <= 8'h80; lcd_rw <= 1'b0; lcd_rs <= 1'b0; end 100031:begin lcd_en <= 1'b1; end 100040:begin lcd_en <= 1'b0; lcd_data <= 8'h30;//字符0 lcd_rw <= 1'b0; lcd_rs <= 1'b1; end 100041:begin lcd_en <= 1'b1; end default:lcd_en <= 1'b0; endcase endendmodule
主要还是按照时序图的时间顺序一步步的写,没有上机验证 而且tb在处理很大的数的时候不知道具体咋弄,留下以后解决
//-----------------------------------2-10号修改------------------------------------------//
module fsm_lcd( rs,rw,en,data, clk,rst_n);input wire clk;input wire rst_n;output reg rs; //write_cmd -L or write_data -Houtput wire rw; //write - Loutput reg en; //写数据或者写指令 高脉冲output reg [7:0] data;//上电20ms稳定电源parameter TIME_20MS = 20'd1_0-1;//为了仿真将时间缩短reg [19:0] cnt_init;always @(posedge clk or negedge rst_n) if(!rst_n) cnt_init <= 'd0; else if(cnt_init == TIME_20MS) cnt_init <= TIME_20MS; else cnt_init <= cnt_init + 1'b1; //分频 1602为慢速器件,要降低clk频率parameter DIV_CNT = 20'd5 - 1;//加快仿真速度;reg [19:0] cnt_div;reg clk_500hz;always @(posedge clk or negedge rst_n) if(!rst_n)begin cnt_div <= 'd0; clk_500hz <= 'd0; end else if(cnt_div == DIV_CNT)begin cnt_div <= 'd0; clk_500hz =~ clk_500hz; end else cnt_div <= cnt_div + 1'b1; //fsmreg [4:0] state;reg [2:0] cnt_ms;always @(posedge clk_500hz or negedge rst_n) if(!rst_n)begin data <= 8'd0; en <= 1'd0; rs <= 1'd0; state <= 'd0; cnt_ms <= 'd0; end else if(cnt_init == TIME_20MS) case(state) 5'd0:begin data <= 8'd0; en <= 1'd0; rs <= 1'd0; state <= 5'd1; end 5'd1:begin data <= 8'h38; //显示模式 en <= 1'd0; rs <= 1'd0; state <= 5'd2; end 5'd2: if(cnt_ms == 3'd2)begin cnt_ms <= 'd0; en <= 1'd1; rs <= 1'd0; state <= 5'd3; end else cnt_ms <= cnt_ms + 1'b1; 5'd3:begin //0x0c 开显示不显示光标 data <= 8'h0c; en <= 1'd0; rs <= 1'd0; state <= 5'd4; end 5'd4:begin en <= 1'd1; state <= 5'd5; end 5'd5: if(cnt_ms == 3'd2)begin cnt_ms <= 'd0; en <= 1'd0; state <= 5'd6; end else cnt_ms <= cnt_ms + 1'b1; 5'd6:begin //0x80 首地址 en <= 1'd0; data <= 8'h80; state <= 5'd7; end 5'd7:begin en <= 1'd1; state <= 5'd8; end 5'd8:if(cnt_ms == 3'd2)begin //write_data cnt_ms <= 'd0; en <= 1'd0; rs <= 1'd1; data <= 8'h1; state <= 5'd9; end else cnt_ms <= cnt_ms + 1'b1; 5'd9:begin en <= 1'd1; state <= 5'd10; end 5'd10: if(cnt_ms == 3'd2)begin cnt_ms <= 'd0; en <= 1'd0; state <= 5'd0; end else cnt_ms <= cnt_ms + 1'b1; default:state <= 5'd0; endcase assign rw = 1'b0;endmodule