LCD1602 IP Core之verilog代码

下面是综合代码:

`timescale 1ns/1ns
module	LCD1602(
	input 				clk,//100M
	input				rst_n,
	//user interface 
	input				wr_req_cmd,
	input				wr_req_data,
	output	reg			wr_cmd_done,
	output	reg			wr_data_done,
	input				row,
	input	[3:0] 		col,
	input	[7:0] 		data,
//	output				isout_sim,
	//LCD1602 interface
	output 				lcd_vo,
	output reg			lcd_rs,
	output reg			lcd_rw,
	output reg			lcd_e,
	inout [7:0]			lcd_db
);
parameter lcd_e_period	=199;
parameter lcd_e_quarter	=49;
parameter lcd_e_half		=99;
reg	[7:0] 	state;
reg	[7:0] 	retu;
reg	[7:0] 	jump;
reg	[31:0]	c1;
reg	[7:0] 	busy;
reg				isout;
reg	[7:0] 	lcd_dbr;
reg	[7:0] 	data_temp;
reg	[7:0]		send_data;
reg	[3:0]		pwm_cnt;

//assign isout_sim=isout;
assign lcd_db	= isout ? lcd_dbr: 8'dz;
always@(posedge clk or negedge rst_n)
	if(rst_n==1'b0)begin
		data_temp=0;
	end
	else if(wr_req_data)begin
		data_temp=data;
	end
	
always@(posedge clk or negedge rst_n)
	if(rst_n==1'b0)begin
		state<= #4 0;
		retu<= #4 8'd0;
		jump<= #4 8'd0;
		c1<= #4 0;
		lcd_rs<= #4 1'b0;
		lcd_rw<= #4 1'b0;
		lcd_e<= #4 1'b0;
		busy<= #4 8'd0;
		isout=1'b1;
		lcd_dbr<= #4 8'd0;
		send_data<= #4 8'd0;
		wr_cmd_done<= #4 1'b0;
		wr_data_done<= #4 1'b0;
	end
	else begin
		case(state)
			0:begin
				if(c1==1499999)begin
					c1<= #4 0;
					state<= #4 state+1'b1;
				end
				else begin
					c1<= #4 c1+1'b1;
				end
			end
			1:begin//写指令38H
				state<= #4 16;
				send_data<= #4 8'h38;
				retu<= #4 state+1'b1;
			end
			2:begin
				if(c1==499999)begin
					c1<= #4 0;
					state<= #4 state+1'b1;
				end
				else begin
					c1<= #4 c1+1'b1;
				end
			end
			3:begin//写指令38H
				state<= #4 16;
				send_data<= #4 8'h38;
				retu<= #4 state+1'b1;
			end
			4:begin
				if(c1==499999)begin
					c1<= #4 0;
					state<= #4 state+1'b1;
				end
				else begin
					c1<= #4 c1+1'b1;
				end
			end
			5:begin//写指令38H
				state<= #4 16;
				send_data<= #4 8'h38;
				retu<= #4 state+1'b1;
			end
			6:begin//写指令38H
				state<= #4 13;
				send_data<= #4 8'h38;
				retu<= #4 state+1'b1;
				jump<= #4 16;
			end
			7:begin//写指令08H
				state<= #4 13;
				send_data<= #4 8'h08;
				retu<= #4 state+1'b1;
				jump<= #4 16;
			end
			8:begin//写指令01H
				state<= #4 13;
				send_data<= #4 8'h01;
				retu<= #4 state+1'b1;
				jump<= #4 16;
			end
			9:begin//写指令06H
				state<= #4 13;
				send_data<= #4 8'h06;
				retu<= #4 state+1'b1;
				jump<= #4 16;
			end
			10:begin//写指令0cH
				state<= #4 13;
				send_data<= #4 8'h0c;
				retu<= #4 state+1'b1;
				jump<= #4 16;
			end
			11:begin//IDLE
				if(wr_req_cmd)begin//write cmd requst
					state<= #4 13;
					send_data<= #4 data;
					retu<= #4 11;
					jump<= #4 16;
				end
				else if(wr_req_data) begin//write data requst
					send_data<= #4 row?(8'hC0|col):(8'h80|col);
					state<= #4 13;
					retu<= #4 state+1'b1;
					jump<= #4 16;
				end
				else begin
					state<= #4 11;
					retu<= #4 8'd0;
					jump<= #4 8'd0;
					c1<= #4 0;
					lcd_rs<= #4 1'b0;
					lcd_rw<= #4 1'b0;
					lcd_e<= #4 1'b0;
					busy<= #4 8'd0;
					isout=1'b1;
					lcd_dbr<= #4 8'd0;
					send_data<= #4 8'd0;
					wr_cmd_done<= #4 1'b0;
					wr_data_done<= #4 1'b0;
				end
			end
			12:begin//write data 
				state<= #4 13;
				send_data<= #4 data_temp;
				retu<= #4 11;
				jump<= #4 15;	
			end
		
//***************wait 1ms*************************
			13:begin
				if(c1==99999)begin
					c1<= #4 0;
					state<= #4 state+1'b1;
				end
				else begin
					c1<= #4 c1+1'b1;
				end
			end
//***************jump*************************
			14:begin
					state<= #4 jump;
			end
//***************write data******************************
			15:begin
				if(c1==0) begin
					lcd_rs<= #4 1'b1;
					lcd_rw<= #4 1'b0;
					lcd_e<= #4 1'b0;
					isout=1'b1;
					lcd_dbr<= #4 send_data;
				end
				else if(c1==lcd_e_quarter)
					lcd_e<= #4 1'b1;
				else if(c1==lcd_e_half)
					lcd_e<= #4 1'b0;
				else if(c1==198)
					wr_data_done<= #4 1'b1;
				if(c1==lcd_e_period) begin
					c1<= #4 0;
					lcd_dbr<= #4 8'd0;
					wr_data_done<= #4 1'b0;
					state<= #4 retu;
				end
				else begin
					c1<= #4 c1+1'b1;
				end	
			end
//***************write cmd*******************************			
			16:begin
				if(c1==0) begin
					lcd_rs<= #4 1'b0;
					lcd_rw<= #4 1'b0;
					lcd_e<= #4 1'b0;
					isout=1'b1;
					lcd_dbr<= #4 send_data;
				end
				else if(c1==lcd_e_quarter)
					lcd_e<= #4 1'b1;
				else if(c1==lcd_e_half)
					lcd_e<= #4 1'b0;
				else if(c1==198)
					wr_cmd_done<= #4 1'b1;
				if(c1==lcd_e_period) begin
					c1<= #4 0;
					lcd_dbr<= #4 8'd0;
					state<= #4 retu;
					wr_cmd_done<= #4 1'b0;
				end
				else begin
					c1<= #4 c1+1'b1;
				end	
			end
		endcase
	end

always@(posedge clk or negedge rst_n)
		if(!rst_n)
			pwm_cnt <= #4  4'd0;
		else
			pwm_cnt <= #4  pwm_cnt + 1'b1;
			
assign lcd_vo = (pwm_cnt>9);

endmodule

仿真代码:

`timescale 1ns/1ns
`define clk_period 10
module LCD1602_sim;
reg 					clk;//100M
reg					rst_n;
reg					wr_req_data;
reg					wr_req_cmd;
wire					wr_cmd_done;
wire					wr_data_done;
reg					row;
reg	[3:0] 		col;
reg	[7:0] 		data;
//wire					isout_sim;
wire					lcd_vo;
wire					lcd_rs;
wire					lcd_rw;
wire					lcd_e;
wor	[7:0]			lcd_db;

reg	[7:0]			lcd_db_r;
assign lcd_db=lcd_db_r;
LCD1602 LCD1602(
	.clk(clk),//100M
	.rst_n(rst_n),
	.wr_req_cmd(wr_req_cmd),
	.wr_req_data(wr_req_data),
	.wr_cmd_done(wr_cmd_done),
	.wr_data_done(wr_data_done),
	.row(row),
	.col(col),
	.data(data),
//	.isout_sim(isout_sim),
	.lcd_vo(lcd_vo),
	.lcd_rs(lcd_rs),
	.lcd_rw(lcd_rw),
	.lcd_e(lcd_e),
	.lcd_db(lcd_db)
);
initial clk=1;
always#(`clk_period/2) clk=~clk;

initial begin
	rst_n =0;
	wr_req_cmd=0;
	wr_req_data=0;
	row=0;
	col=0;
	data=0;
	lcd_db_r=0;
	#(`clk_period*50+3);
	rst_n =1;
	#30_000_000;
	wr_cmd(8'haa);
	wr_data(1,5,8'h55);
	wr_data(0,8,8'h66);
	wr_data(1,3,8'h33);
	wr_data(0,2,8'h77);
	wr_cmd(8'hcc);
	#30_000;
	$stop;
end

task wr_cmd;
input [7:0] data_r;
begin
	data=data_r;
	wr_req_cmd=1;
	#(`clk_period);
	wr_req_cmd=0;
	@(negedge wr_cmd_done);
end
endtask

task wr_data;
input 		row_r;
input [3:0] col_r;
input [7:0] data_r;
begin
	data=data_r;
	row=row_r;
	col=col_r;
	wr_req_data=1;
	#(`clk_period);
	wr_req_data=0;
	@(negedge wr_data_done);
end
endtask

endmodule

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值