FPGA ax516_eeprom_24lc04_iic

400k

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2019/09/04 19:06:31
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
    input CLK_50M,
    input RSTn,
    output [3:0]LED,
    
    output SCL,          //EEPROM IIC clock
    inout SDA            //EEPROM IIC data
    );
    
reg [3:0] led_r;
    reg [7:0] addr;
    reg [7:0] data;
    wire [7:0] data_rd;
    reg cmd;
    reg is_start;
    wire is_done; 
    
    iic iic_inst(
        .clk(CLK_50M),
        .rst_n(RSTn),
        .scl(SCL),          
        .sda(SDA),            
        .addr(addr),
        .data(data),
        .data_rd(data_rd),
        .cmd(cmd),
        .is_start(is_start),
        .is_done(is_done)
    );
    
	reg [31:0] cnt;
    reg [3:0] state;
    always @(posedge CLK_50M or negedge RSTn)
    begin
        if(!RSTn) begin
            state <= 4'd0;
            is_start <= 1'd0;
            cmd <= 1'd0;
			cnt <= 32'd0;
        end
        else begin
            case(state)
				4'd0: begin
					if(cnt == 32'd249_999_999) begin
						cnt <= 32'd0;
						state <= state + 4'd1;
					end
					else cnt <= cnt + 32'd1;
				end
                4'd1: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h18;
                        cmd <= 1'd1;
                    end
                end
                4'd2: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                        led_r <= data_rd[3:0];
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h12;
                        cmd <= 1'd0;
                    end
                end
            endcase
        end
    end
    
    assign LED = led_r;    
    
    
    
    
endmodule


`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    21:39:05 08/26/2019 
// Design Name: 
// Module Name:    iic 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module iic(
	input clk,
	input rst_n,
	output scl,          //EEPROM IIC clock
	inout sda,            //EEPROM IIC data
	input [7:0] addr,
	input [7:0] data,
	output [7:0] data_rd,
	input cmd,
	input is_start,
	output is_done
);

reg is_out;
reg scl_r;
reg sda_r;
reg ack;
reg [7:0] data_r;
reg [7:0] data_rd_r;
reg [7:0] data_rd_r1;
reg [7:0] cnt;
reg [4:0] i;
reg [4:0] go;
reg is_done_r;
always @(posedge clk or negedge rst_n)
begin
	if(!rst_n) begin
		is_out <= 1'd1;
		scl_r <= 1'd1;
		sda_r <= 1'd1;
		cnt <= 8'd0;
		i <= 5'd0;
		is_done_r <= 1'd0;
	end
	else if(is_start) begin
		if(cmd) begin	//wr
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 8'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 8'd118) cnt <= 8'd0;
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd49) sda_r <= 1'd0;
					if(cnt == 8'd99) scl_r <= 1'd0;
					
					if(cnt == 8'd118) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					data_r <= data; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd5: begin
					if(cnt == 8'd144) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd18) scl_r <= 1'd1; 
					if(cnt == 8'd68) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
				end
				5'd6: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd8, 5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15: begin
					if(cnt == 8'd87) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 8'd1;
					
					sda_r <= data_r[5'd15 - i];
					is_out <= 1'd1;
					
					if(cnt == 8'd18) scl_r <= 1'd1; 
					if(cnt == 8'd68) scl_r <= 1'd0; 
				end
				5'd16: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 8'd87) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd43) ack <= sda;
					if(cnt == 8'd18) scl_r <= 1'd1; 
                    if(cnt == 8'd68) scl_r <= 1'd0; 
				end
				5'd17: begin
					if(~ack) i <= go;
					else i <= 5'd0;
					
					is_out <= 1'd1;
					sda_r <= 1'd0; 
				end
			endcase
		end
		else begin		//rd
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 8'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 8'd118) cnt <= 8'd0;
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd49) sda_r <= 1'd0;
					if(cnt == 8'd99) scl_r <= 1'd0;
					
					if(cnt == 8'd118) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					if(cnt == 8'd118) cnt <= 8'd0;
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd49) sda_r <= 1'd0;
					if(cnt == 8'd99) scl_r <= 1'd0;
					
					if(cnt == 8'd118) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
					
					if(cnt == 8'd0) begin
                        sda_r <= 1'd1;
                        scl_r <= 1'd1;
					end
				end
				5'd5: begin
					data_r <= 8'ha1; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd6: begin
					//data_r <= data; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd7: begin
					if(cnt == 8'd144) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd18) scl_r <= 1'd1; 
					if(cnt == 8'd68) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
					
					if(cnt == 8'd0) begin
					   scl_r <= 1'd0; 
					   sda_r <= 1'd0; 
					end
				end
				5'd8: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15, 5'd16: begin
					if(cnt == 8'd87) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 8'd1;
					
					if(go == 5'd7) begin
						if(cnt == 8'd43) data_rd_r[5'd16 - i] <= sda;
						is_out <= 1'd0;
					end
					else begin
						sda_r <= data_r[5'd16 - i];
						is_out <= 1'd1;
					end
					
					if(cnt == 8'd18) scl_r <= 1'd1; 
					if(cnt == 8'd68) scl_r <= 1'd0; 
				end
				5'd17: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 8'd87) begin
						cnt <= 8'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 8'd1;
					
					if(cnt == 8'd43) ack <= sda;
					if(cnt == 8'd18) scl_r <= 1'd1; 
                    if(cnt == 8'd68) scl_r <= 1'd0; 
				end
				5'd18: begin
					if(go == 5'd7) begin
						i <= go;
						data_rd_r1 <= data_rd_r;
					end
					else begin
						if(~ack) i <= go;
						else i <= 5'd0;
					end

					is_out <= 1'd1;
				end
			endcase
		end
	end
	else begin
		i <= 5'd0;
	end
end

assign scl = scl_r;
assign sda = is_out ? sda_r : 1'dz;
assign data_rd = data_rd_r1;
assign is_done = is_done_r;

endmodule


200k
物理时序在400k基础上扩大一倍

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2019/09/04 19:06:31
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
    input CLK_50M,
    input RSTn,
    output [3:0]LED,
    
    output SCL,          //EEPROM IIC clock
    inout SDA            //EEPROM IIC data
    );
    
reg [3:0] led_r;
    reg [7:0] addr;
    reg [7:0] data;
    wire [7:0] data_rd;
    reg cmd;
    reg is_start;
    wire is_done; 
    
    iic iic_inst(
        .clk(CLK_50M),
        .rst_n(RSTn),
        .scl(SCL),          
        .sda(SDA),            
        .addr(addr),
        .data(data),
        .data_rd(data_rd),
        .cmd(cmd),
        .is_start(is_start),
        .is_done(is_done)
    );
    
	reg [31:0] cnt;
    reg [3:0] state;
    always @(posedge CLK_50M or negedge RSTn)
    begin
        if(!RSTn) begin
            state <= 4'd0;
            is_start <= 1'd0;
            cmd <= 1'd0;
			cnt <= 32'd0;
        end
        else begin
            case(state)
				4'd0: begin
					if(cnt == 32'd249_999_999) begin
						cnt <= 32'd0;
						state <= state + 4'd1;
					end
					else cnt <= cnt + 32'd1;
				end
                4'd1: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h19;
                        cmd <= 1'd1;
                    end
                end
                4'd2: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                        led_r <= data_rd[3:0];
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h12;
                        cmd <= 1'd0;
                    end
                end
            endcase
        end
    end
    
    assign LED = led_r;    
    
    
    
    
endmodule

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    21:39:05 08/26/2019 
// Design Name: 
// Module Name:    iic 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module iic(
	input clk,
	input rst_n,
	output scl,          //EEPROM IIC clock
	inout sda,            //EEPROM IIC data
	input [7:0] addr,
	input [7:0] data,
	output [7:0] data_rd,
	input cmd,
	input is_start,
	output is_done
);

reg is_out;
reg scl_r;
reg sda_r;
reg ack;
reg [7:0] data_r;
reg [7:0] data_rd_r;
reg [7:0] data_rd_r1;
reg [9:0] cnt;
reg [4:0] i;
reg [4:0] go;
reg is_done_r;
always @(posedge clk or negedge rst_n)
begin
	if(!rst_n) begin
		is_out <= 1'd1;
		scl_r <= 1'd1;
		sda_r <= 1'd1;
		cnt <= 10'd0;
		i <= 5'd0;
		is_done_r <= 1'd0;
	end
	else if(is_start) begin
		if(cmd) begin	//wr
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 10'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 10'd237) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd99) sda_r <= 1'd0;
					if(cnt == 10'd199) scl_r <= 1'd0;
					
					if(cnt == 10'd237) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					data_r <= data; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd5: begin
					if(cnt == 10'd289) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd37) scl_r <= 1'd1; 
					if(cnt == 10'd137) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
				end
				5'd6: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd8, 5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15: begin
					if(cnt == 10'd175) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					sda_r <= data_r[5'd15 - i];
					is_out <= 1'd1;
					
					if(cnt == 10'd37) scl_r <= 1'd1; 
					if(cnt == 10'd137) scl_r <= 1'd0; 
				end
				5'd16: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 10'd175) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd87) ack <= sda;
					if(cnt == 10'd37) scl_r <= 1'd1; 
                    if(cnt == 10'd137) scl_r <= 1'd0; 
				end
				5'd17: begin
					if(~ack) i <= go;
					else i <= 5'd0;
					
					is_out <= 1'd1;
					sda_r <= 1'd0; 
				end
			endcase
		end
		else begin		//rd
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 10'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 10'd237) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd99) sda_r <= 1'd0;
					if(cnt == 10'd199) scl_r <= 1'd0;
					
					if(cnt == 10'd237) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					if(cnt == 10'd237) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd99) sda_r <= 1'd0;
					if(cnt == 10'd199) scl_r <= 1'd0;
					
					if(cnt == 10'd237) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
					
					if(cnt == 10'd0) begin
                        sda_r <= 1'd1;
                        scl_r <= 1'd1;
					end
				end
				5'd5: begin
					data_r <= 8'ha1; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd6: begin
					//data_r <= data; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd7: begin
					if(cnt == 10'd289) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd37) scl_r <= 1'd1; 
					if(cnt == 10'd137) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
					
					if(cnt == 10'd0) begin
					   scl_r <= 1'd0; 
					   sda_r <= 1'd0; 
					end
				end
				5'd8: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15, 5'd16: begin
					if(cnt == 10'd175) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(go == 5'd7) begin
						if(cnt == 10'd87) data_rd_r[5'd16 - i] <= sda;
						is_out <= 1'd0;
					end
					else begin
						sda_r <= data_r[5'd16 - i];
						is_out <= 1'd1;
					end
					
					if(cnt == 10'd37) scl_r <= 1'd1; 
					if(cnt == 10'd137) scl_r <= 1'd0; 
				end
				5'd17: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 10'd175) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd87) ack <= sda;
					if(cnt == 10'd37) scl_r <= 1'd1; 
                    if(cnt == 10'd137) scl_r <= 1'd0; 
				end
				5'd18: begin
					if(go == 5'd7) begin
						i <= go;
						data_rd_r1 <= data_rd_r;
					end
					else begin
						if(~ack) i <= go;
						else i <= 5'd0;
					end

					is_out <= 1'd1;
				end
			endcase
		end
	end
	else begin
		i <= 5'd0;
	end
end

assign scl = scl_r;
assign sda = is_out ? sda_r : 1'dz;
assign data_rd = data_rd_r1;
assign is_done = is_done_r;

endmodule

100k
物理时序在200k基础上扩大一倍

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2019/09/04 19:06:31
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
    input CLK_50M,
    input RSTn,
    output [3:0]LED,
    
    output SCL,          //EEPROM IIC clock
    inout SDA            //EEPROM IIC data
    );
    
reg [3:0] led_r;
    reg [7:0] addr;
    reg [7:0] data;
    wire [7:0] data_rd;
    reg cmd;
    reg is_start;
    wire is_done; 
    
    iic iic_inst(
        .clk(CLK_50M),
        .rst_n(RSTn),
        .scl(SCL),          
        .sda(SDA),            
        .addr(addr),
        .data(data),
        .data_rd(data_rd),
        .cmd(cmd),
        .is_start(is_start),
        .is_done(is_done)
    );
    
	reg [31:0] cnt;
    reg [3:0] state;
    always @(posedge CLK_50M or negedge RSTn)
    begin
        if(!RSTn) begin
            state <= 4'd0;
            is_start <= 1'd0;
            cmd <= 1'd0;
			cnt <= 32'd0;
        end
        else begin
            case(state)
				4'd0: begin
					if(cnt == 32'd249_999_999) begin
						cnt <= 32'd0;
						state <= state + 4'd1;
					end
					else cnt <= cnt + 32'd1;
				end
                4'd1: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h1b;
                        cmd <= 1'd1;
                    end
                end
                4'd2: begin
                    if(is_done) begin
                        is_start <= 1'd0;
                        state <= state + 4'd1;
                        led_r <= data_rd[3:0];
                    end
                    else begin
                        is_start <= 1'd1;
                        addr <= 8'd0;
                        data <= 8'h12;
                        cmd <= 1'd0;
                    end
                end
            endcase
        end
    end
    
    assign LED = led_r;    
    
    
    
    
endmodule

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    21:39:05 08/26/2019 
// Design Name: 
// Module Name:    iic 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module iic(
	input clk,
	input rst_n,
	output scl,          //EEPROM IIC clock
	inout sda,            //EEPROM IIC data
	input [7:0] addr,
	input [7:0] data,
	output [7:0] data_rd,
	input cmd,
	input is_start,
	output is_done
);

reg is_out;
reg scl_r;
reg sda_r;
reg ack;
reg [7:0] data_r;
reg [7:0] data_rd_r;
reg [7:0] data_rd_r1;
reg [9:0] cnt;
reg [4:0] i;
reg [4:0] go;
reg is_done_r;
always @(posedge clk or negedge rst_n)
begin
	if(!rst_n) begin
		is_out <= 1'd1;
		scl_r <= 1'd1;
		sda_r <= 1'd1;
		cnt <= 10'd0;
		i <= 5'd0;
		is_done_r <= 1'd0;
	end
	else if(is_start) begin
		if(cmd) begin	//wr
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 10'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 10'd475) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd199) sda_r <= 1'd0;
					if(cnt == 10'd399) scl_r <= 1'd0;
					
					if(cnt == 10'd475) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					data_r <= data; 
					i <= 5'd8;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd5: begin
					if(cnt == 10'd579) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd75) scl_r <= 1'd1; 
					if(cnt == 10'd275) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
				end
				5'd6: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd8, 5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15: begin
					if(cnt == 10'd351) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					sda_r <= data_r[5'd15 - i];
					is_out <= 1'd1;
					
					if(cnt == 10'd75) scl_r <= 1'd1; 
					if(cnt == 10'd275) scl_r <= 1'd0; 
				end
				5'd16: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 10'd351) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd175) ack <= sda;
					if(cnt == 10'd75) scl_r <= 1'd1; 
                    if(cnt == 10'd275) scl_r <= 1'd0; 
				end
				5'd17: begin
					if(~ack) i <= go;
					else i <= 5'd0;
					
					is_out <= 1'd1;
					sda_r <= 1'd0; 
				end
			endcase
		end
		else begin		//rd
			case(i)
				5'd0: begin
					scl_r <= 1'd1;
					sda_r <= 1'd1;
					cnt <= 10'd0;
					i <= i + 5'd1;
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd1: begin
					if(cnt == 10'd475) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd199) sda_r <= 1'd0;
					if(cnt == 10'd399) scl_r <= 1'd0;
					
					if(cnt == 10'd475) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
				end
				5'd2: begin
					data_r <= 8'ha0; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd3: begin
					data_r <= addr; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd4: begin
					if(cnt == 10'd475) cnt <= 10'd0;
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd199) sda_r <= 1'd0;
					if(cnt == 10'd399) scl_r <= 1'd0;
					
					if(cnt == 10'd475) begin
						i <= i + 5'd1;
					end
					
					is_out <= 1'd1;
					is_done_r <= 1'd0;
					
					if(cnt == 10'd0) begin
                        sda_r <= 1'd1;
                        scl_r <= 1'd1;
					end
				end
				5'd5: begin
					data_r <= 8'ha1; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd6: begin
					//data_r <= data; 
					i <= 5'd9;
					go <= i + 5'd1;
					is_out <= 1'd1;
				end
				5'd7: begin
					if(cnt == 10'd579) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
						is_done_r <= 1'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd75) scl_r <= 1'd1; 
					if(cnt == 10'd275) sda_r <= 1'd1; 
					
					is_out <= 1'd1;
					
					if(cnt == 10'd0) begin
					   scl_r <= 1'd0; 
					   sda_r <= 1'd0; 
					end
				end
				5'd8: begin
					is_done_r <= 1'd0;
					i <= 5'd0;
				end
				
				5'd9, 5'd10, 5'd11, 5'd12, 5'd13, 5'd14, 5'd15, 5'd16: begin
					if(cnt == 10'd347) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(go == 5'd7) begin
						if(cnt == 10'd175) data_rd_r[5'd16 - i] <= sda;
						is_out <= 1'd0;
					end
					else begin
						sda_r <= data_r[5'd16 - i];
						is_out <= 1'd1;
					end
					
					if(cnt == 10'd75) scl_r <= 1'd1; 
					if(cnt == 10'd275) scl_r <= 1'd0; 
				end
				5'd17: begin	//ack
					is_out <= 1'd0;
					
					if(cnt == 10'd351) begin
						cnt <= 10'd0;
						i <= i + 5'd1;
					end
					else cnt <= cnt + 10'd1;
					
					if(cnt == 10'd175) ack <= sda;
					if(cnt == 10'd75) scl_r <= 1'd1; 
                    if(cnt == 10'd275) scl_r <= 1'd0; 
				end
				5'd18: begin
					if(go == 5'd7) begin
						i <= go;
						data_rd_r1 <= data_rd_r;
					end
					else begin
						if(~ack) i <= go;
						else i <= 5'd0;
					end

					is_out <= 1'd1;
				end
			endcase
		end
	end
	else begin
		i <= 5'd0;
	end
end

assign scl = scl_r;
assign sda = is_out ? sda_r : 1'dz;
assign data_rd = data_rd_r1;
assign is_done = is_done_r;

endmodule

你可能感兴趣的:(FPGA,fpga开发)