i2c Slave

基于一个github项目自己修改编写的,对于一些信号进行了整理,方便读者的理解。已通过FPGA上板测试,写操作无误。

module i2c_slave (scl,sda,rst_n,reg_data_rd,reg_data_wr,reg_addr,wen);
	input scl;//rx from FPGA's peripheral
	inout sda;
	input rst_n;
	input [7:0] reg_data_rd;//rx from regs
	
	output [7:0] reg_data_wr;//tx to regs
	output [1:0] reg_addr;//tx to regs
	output wen;//tx to regs
	
	parameter I2C_ADDR = 7'h27;//device's static addr
	
inout setting
wire sda_in;
reg output_ctrl;

assign sda_in = sda ;
assign sda = output_ctrl ? 1'bz : 1'b0; 
	
start detect
reg start_detect;//when SCL keep high,SDA pull low
reg start_resetter;
wire start_rst;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

assign start_rst = ~rst_n | start_resetter;

	always@(posedge start_rst or negedge sda)begin//trigger condition 
		if(start_rst)
			start_detect <= 1'b0;
		else
			start_detect <= scl;
	end
	
	always@(posedge scl or negedge rst_n)begin
		if(!rst_n)
			start_resetter <= 1'b0;
		else
			start_resetter <= start_detect;
	end

stop detect
reg stop_detect;//when SCL keep high,SDA pull high
reg stop_resetter;//
wire stop_rst;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

assign stop_rst = ~rst_n | stop_resetter;

	always@(posedge stop_rst or posedge sda)begin
		if(stop_rst)
			stop_detect <= 1'b0;
		else
			stop_detect <= scl;
	end
	
	always@(posedge scl or negedge rst_n)begin
		if(!rst_n)
			stop_resetter <= 1'b0;
		else
			stop_resetter <= stop_detect;
	end

counting bit number
reg [3:0] bit_cnt;

wire lsb_bit = (bit_cnt==4'h7) && !start_detect;//the LSB bit is the 8th bit sent
wire ack_bit = (bit_cnt==4'h8) && !start_detect;//the ACK bit is the 9th bit sent

always@(negedge scl)begin
	if(ack_bit || start_detect)
		bit_cnt <= 4'h0;
	else
		bit_cnt <= bit_cnt + 4'h1;
end

address detect
reg [7:0] rx_shift;

always@(posedge scl)begin
	if(!ack_bit)
		rx_shift <= {rx_shift[6:0],sda};
	else 
		rx_shift <= rx_shift;
end

wire addr_detect;
wire rd_or_wr;//(static addr + 'rd_or_wr' + ack/nack )

assign addr_detect = (rx_shift[7:1]==I2C_ADDR) ? 1'b1 : 1'b0 ;
assign rd_or_wr = rx_shift[0];

master's ack/nack detect 
reg sda_from_mst;

always@(posedge scl)begin
	if(ack_bit)
		sda_from_mst <= sda_in;
end

FSM for RX from SDA and TX to reg_core
localparam IDLE 		= 3'b000;//0
localparam DEV_ADDR 	= 3'b001;//1
localparam READ 		= 3'b011;//3
localparam IDX_PTR 	    = 3'b101;//5
localparam WRITE 		= 3'b111;//7

reg [2:0] cstate;
reg [2:0] nstate;

always@(negedge scl or negedge rst_n)begin
	if(!rst_n )
		cstate <= IDLE;
	else if(start_detect)//for restart function
	    cstate <= DEV_ADDR;
	else if(stop_detect)
	    cstate <= IDLE;
	else if(ack_bit)//9bit done, state change
		cstate <= nstate;
end

always@(*)begin
	case(cstate)
	IDLE:begin
		if(start_detect)
			nstate <= DEV_ADDR;
		else
			nstate <= IDLE;
	end
	DEV_ADDR:begin
		if(!addr_detect)
			nstate <= IDLE;
		else if(rd_or_wr)//write --> bit = 0 ;read --> bit = 1
			nstate <= READ;
		else 
			nstate <= IDX_PTR;
	end
	READ:begin
        if(sda_from_mst)// for NACK
			nstate <= IDLE;
		else
			nstate <= READ;
	end
	IDX_PTR:begin
		nstate <= WRITE;
	end
	WRITE:begin
        nstate <= WRITE;
	end
	default:begin
		nstate <= IDLE;
	end
	endcase
end

//regs' pointer
reg [1:0] pointer;

always@(negedge scl or negedge rst_n)begin
	if(!rst_n)
		pointer <= 2'd0;
	else if(stop_detect)
		pointer <= 2'd0;
	else begin
		case(cstate)
			IDLE:begin
				pointer <= 2'd0;
			end
			DEV_ADDR:begin
				if(ack_bit)
					pointer <= pointer + 1'b1;//when 8 bit finished, will restore the tx_shift,so must positioning the pointer early
			end
			READ:begin
				if(ack_bit)
					pointer <= pointer + 1'b1;//姣忎紶瀹?8bit鏁版嵁鍚庯紝鍦板潃+1锛屼緵鍐呴儴绉讳綅瀵勫瓨鍣ㄦ彁鍓嶅瓨鍌ㄦ暟鎹??
			end
			IDX_PTR:begin
				if(ack_bit)
					pointer <= rx_shift[1:0];//as a tester,shall set the first DATA = 8'b0;
			end
			WRITE:begin
				if(ack_bit)
					pointer <= pointer + 1'b1;
			end
			default:begin
				pointer <= 2'd0;
			end
		endcase
	end
end

//slave tx data to bus && ack/nack
reg [7:0] tx_shift;

always@(negedge scl)begin
	if(lsb_bit)
		tx_shift <= reg_data_rd;//when 8 bit finished, restore the tx_shift
	else 
		tx_shift <= {tx_shift[6:0],1'b0};//when 8 bit unfinished, shift bit for tx 
end

always@(negedge scl or negedge rst_n)begin
	if(!rst_n)
		output_ctrl <= 1'b1;
	else begin
		case(cstate)
			IDLE:begin
				output_ctrl <= 1'b1;
			end
			DEV_ADDR:begin
				if(lsb_bit)begin//after negedge sample lsb_bit, slave active on sda bus
					if(addr_detect)
						output_ctrl <= 1'b0;//indicate ack
					else
						output_ctrl <= 1'b1;
				end
				else if (ack_bit)begin
				    if(addr_detect && rd_or_wr)
				        output_ctrl <= tx_shift[7]; Deliver the first bit of DATA in DEV_ADDR. !!important!!
				    else 
				        output_ctrl <= 1'b1;
				end
				else begin
				    output_ctrl <= 1'b1;
				end
			end
			READ:begin
			     if(ack_bit )begin//consider 9bit's master ACK/NACK 
			         if(!sda_from_mst)
			             output_ctrl <= tx_shift[7];//if master ACK
			         else
			             output_ctrl <= 1'b1;//if master NACK
			     end  
			     else begin//other bit
					output_ctrl <= tx_shift[7];//MSB fisrt
				 end
			end
			IDX_PTR:begin
				if(lsb_bit)
					output_ctrl <= 1'b0;//indicate ack
				else
					output_ctrl <= 1'b1;
			end
			WRITE:begin
				if(lsb_bit)
					output_ctrl <= 1'b0;//indicate ack
				else
					output_ctrl <= 1'b1;
			end
			default:begin
				output_ctrl <= 1'b1;
			end
		endcase
	end
end

output assignment
assign reg_addr = pointer;
assign wen = (cstate == WRITE) && ack_bit;
assign reg_data_wr = rx_shift;

endmodule

 原项目                                                                                                                                             Robust I2C slave without a sampling clock

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小土真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值