data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v
None: at end of input
1: b'%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:1: Cannot find include file: i2c_macro.inc\n`include "i2c_macro.inc" \n         ^~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic,data/full_repos/permissive/130996185/i2c_macro.inc\n             data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic,data/full_repos/permissive/130996185/i2c_macro.inc.v\n             data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic,data/full_repos/permissive/130996185/i2c_macro.inc.sv\n             i2c_macro.inc\n             i2c_macro.inc.v\n             i2c_macro.inc.sv\n             obj_dir/i2c_macro.inc\n             obj_dir/i2c_macro.inc.v\n             obj_dir/i2c_macro.inc.sv\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:8: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n input [`I2C_SLV_ADDR_WIDTH-1:0] i2c_slave,  \n        ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:9: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n input [`I2C_REG_ADDR_WIDTH-1:0] i2c_reg_addr,  \n        ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:11: Define or directive not defined: \'`I2C_REG_DATA_WIDTH\'\n output [`I2C_REG_DATA_WIDTH-1:0] i2c_rdata,   \n         ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:14: Define or directive not defined: \'`I2C_REG_DATA_WIDTH\'\n input [`I2C_REG_DATA_WIDTH-1:0] i2c_wdata,   \n        ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:23: Define or directive not defined: \'`I2C_CLK_BASE_COUNT\'\n reg  [`I2C_CLK_BASE_COUNT-1:0] i2c_base_cnt;  \n       ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:29: Define or directive not defined: \'`I2C_SCK_FREQ_FACTR\'\n  else if(i2c_base_cnt >= (`I2C_SCK_FREQ_FACTR-1))\n                           ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:89: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\nreg  [`I2C_SLV_ADDR_WIDTH-1:0] i2c_slave_reg;  \n      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:90: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\nreg  [`I2C_SLV_ADDR_WIDTH-1:0] i2c_slave_reg2;  \n      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:91: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\nreg  [`I2C_REG_ADDR_WIDTH-1:0] i2c_reg_addr_reg;  \n      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:92: Define or directive not defined: \'`I2C_REG_DATA_WIDTH\'\nreg  [`I2C_REG_DATA_WIDTH-1:0] i2c_reg_data_reg;  \n      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:143: Define or directive not defined: \'`I2C_WRITE_FLAG\'\n i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;\n                            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:143: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;\n                                           ^\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:146: Define or directive not defined: \'`I2C_READ_FLAG\'\n i2c_slave_reg2 <= i2c_slave+`I2C_READ_FLAG;\n                             ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:146: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n i2c_slave_reg2 <= i2c_slave+`I2C_READ_FLAG;\n                                           ^\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:165: Define or directive not defined: \'`I2C_WRITE_FLAG\'\n i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;\n                            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:165: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;\n                                           ^\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:176: Define or directive not defined: \'`I2C_REG_DATA_WIDTH\'\nreg  [`I2C_REG_DATA_WIDTH-1:0] i2c_rdata_shift;  \n      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:181: Define or directive not defined: \'`I2C_SCK_FREQ_FACTR\'\n if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))\n                   ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:211: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n     i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];\n                                  ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:212: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n     i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1\'B1};\n                                     ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:228: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n     if(i2c_bit_cnt>=(`I2C_SLV_ADDR_WIDTH-1))\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:240: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n      i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];\n                                   ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:241: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n      i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1\'B1};   \n                                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:255: Define or directive not defined: \'`I2C_ACK_TOLR_DELAY\'\n    if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:255: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)\n                                         ^\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:263: syntax error, unexpected else, expecting endcase\n    else\n    ^~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:284: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n       i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];\n                                       ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:285: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n       i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1\'B1}; \n                                             ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:307: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n     if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:319: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n      i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];\n                                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:320: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n      i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1\'B1}; \n                                            ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:334: Define or directive not defined: \'`I2C_ACK_TOLR_DELAY\'\n    if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:334: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)\n                                         ^\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:341: syntax error, unexpected else\n    else\n    ^~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:388: syntax error, unexpected end\n    end\n    ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:407: syntax error, unexpected end\n   end\n   ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:426: syntax error, unexpected end\n   end\n   ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:437: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n     i2c_sda_reg <= i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-1];\n                                   ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:438: Define or directive not defined: \'`I2C_SLV_ADDR_WIDTH\'\n     i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-2:0], 1\'B1};\n                                       ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:446: syntax error, unexpected end\n   end\n   ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:455: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n     if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:467: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n      i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];\n                                    ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:468: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n      i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1\'B1}; \n                                        ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:476: syntax error, unexpected end\n   end\n   ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:482: Define or directive not defined: \'`I2C_ACK_TOLR_DELAY\'\n    if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)\n                      ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:488: syntax error, unexpected end\n    end\n    ^~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:510: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n       i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];\n                                     ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:511: Define or directive not defined: \'`I2C_REG_ADDR_WIDTH\'\n       i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1\'B1}; \n                                         ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/130996185/projects/zFPGA_DE10_NANO_SoC/00_user_logic/i2c_user_fsm.v:523: syntax error, unexpected end\n    end\n    ^~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module i2c_user_fsm(
	input 	wire 		sys_clk, sys_rst_n,

	output				i2c_sck,
	inout				i2c_sda,

	input	[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave,
	input	[`I2C_REG_ADDR_WIDTH-1:0]	i2c_reg_addr,

	output	[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata,
	output								i2c_rdata_valid,
	input								i2c_read_req,
	input	[`I2C_REG_DATA_WIDTH-1:0]	i2c_wdata,
	input								i2c_write_req,
	output								i2c_fail,
	output								i2c_ready,
	output								i2c_wait_ack,
	output								i2c_wait_sda,
	input								i2c_as_sccb
	);
	
	reg		[`I2C_CLK_BASE_COUNT-1:0]	i2c_base_cnt;

	reg		i2c_base_cnt_clr_n;
	always @(posedge sys_clk)
		if(!sys_rst_n || !i2c_base_cnt_clr_n)
			i2c_base_cnt <= 0;
		else if(i2c_base_cnt >= (`I2C_SCK_FREQ_FACTR-1))
			i2c_base_cnt <= 0;
		else
			i2c_base_cnt <= i2c_base_cnt + 1;
	

	reg		[2:0]	cstate;
	parameter		IDLE = 0;
	parameter		READ = 1;
	parameter		WRITE = 2;
	parameter		FINISH = 3;
	parameter		FAIL = 4;

	always @(posedge sys_clk)
		if(!sys_rst_n)
			init_system_task;
		else
		begin
			case(cstate)
				IDLE: begin

					if(i2c_read_req)
						jump_to_read_task;

					else if(i2c_write_req)
						jump_to_write_task;
					else
						init_system_task;
				end

				READ: begin
					do_read_task;
				end
				WRITE: begin
					do_write_task;
				end				

				FINISH: begin
					init_system_task;
				end

				FAIL: begin
					do_fail_task;
				end

				default: begin
					do_fail_task;
				end
			endcase		
		end


reg		[9:0]	ack_delay_cnt;
reg				ack_signal_cap;
reg		[9:0]	rw_state_in_cnt;
reg		[4:0]	four_phase_cnt;

reg				i2c_sck_reg;
reg				i2c_sda_reg;

reg		[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave_reg;
reg		[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave_reg2;
reg		[`I2C_REG_ADDR_WIDTH-1:0]	i2c_reg_addr_reg;
reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_reg_data_reg;

reg		[4:0]	rw_state;
parameter		RW_IDLE = 15;
parameter		RW_START = 0;
parameter		RW_DEV_ADDR = 1;
parameter		RW_ACK_START = 2;
parameter		RW_REG_ADDR = 3;
parameter		RW_ACK_REG = 4;
parameter		RW_IDLE2 = 5;
parameter		RW_START2 = 6;
parameter		RW_DEV_ADDR2 = 7;
parameter		RW_ACK_ADDR2 = 8;
parameter		RW_DATA = 9;
parameter		RW_ACK_DATA = 10;
parameter		RW_STOP = 11;
parameter		RW_FAIL = 12;
parameter		RW_NO_ACK = 13;
parameter		RW_STOP_SCCB = 14;



task init_system_task;
begin
	cstate <= IDLE;
	ack_delay_cnt <= 0;
	i2c_base_cnt_clr_n <= 1;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask


task jump_to_read_task;
begin
	cstate <= READ;
	i2c_base_cnt_clr_n <= 0;
	ack_delay_cnt <= 0;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;
	i2c_reg_addr_reg <= i2c_reg_addr;

	i2c_slave_reg2 <= i2c_slave+`I2C_READ_FLAG;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask

task jump_to_write_task;
begin
	cstate <= WRITE;
	i2c_base_cnt_clr_n <= 0;
	ack_delay_cnt <= 0;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;
	i2c_reg_addr_reg <= i2c_reg_addr;
	i2c_reg_data_reg <= i2c_wdata;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask

reg		[9:0]	i2c_bit_cnt;
reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata_shift;

task do_read_task;
begin
	i2c_base_cnt_clr_n <= 1;
	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin
		case(rw_state)
			RW_IDLE: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end
			RW_START: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end
			RW_DEV_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_SLV_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_START;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
						i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};			
					end

					four_phase_cnt <= 0;
				end	

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_START: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end

				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_REG_ADDR;

							i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
							i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda||i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_REG_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_REG;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
						i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_REG: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 && !i2c_as_sccb)
						begin

							rw_state <= RW_IDLE2;


							i2c_sda_reg <= 1;

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end

						else if(i2c_as_sccb)
						begin

							rw_state <= RW_STOP_SCCB;


							i2c_sda_reg <= 0;

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_STOP_SCCB: begin

				if(four_phase_cnt==1)
					i2c_sck_reg <= 1;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE2;
					rw_state_in_cnt <= 0;
					i2c_sda_reg <= 1;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_IDLE2: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START2;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end

			RW_START2: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR2;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end

			RW_DEV_ADDR2: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_ADDR2;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];
						i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_ADDR2: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_DATA;

							i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];
							i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_DATA: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;


				else if(four_phase_cnt==1)
					i2c_rdata_shift <= {i2c_rdata_shift[`I2C_REG_DATA_WIDTH-2:0], i2c_sda};

				if(four_phase_cnt==3)
				begin

					if(i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
					begin
						rw_state <= RW_NO_ACK;
						i2c_sda_reg <= 1;
						i2c_bit_cnt <= 0;
					end

					i2c_bit_cnt <= i2c_bit_cnt+1;

					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_NO_ACK: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_STOP;

					i2c_sda_reg <= 0;


					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_STOP: begin
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE;
					i2c_sda_reg <= 1;


					four_phase_cnt <= 0;

					cstate <= FINISH;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			default: begin
				if(four_phase_cnt==3)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end
		endcase
	end
end
endtask


task do_write_task;
begin
	i2c_base_cnt_clr_n <= 1;
	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin
		case(rw_state)
			RW_IDLE: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START;
					rw_state_in_cnt <= 0;


					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end
			RW_START: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end
			RW_DEV_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_SLV_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_START;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
						i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};			
					end

					four_phase_cnt <= 0;
				end	

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_START: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
					ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_REG_ADDR;

							i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
							i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;		
				end
			end

			RW_REG_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_REG;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
						i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_REG: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_DATA;

							i2c_sda_reg <= i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-1];
							i2c_reg_data_reg <= {i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;	
				end
			end

			RW_DATA: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;


				if(four_phase_cnt==3)
				begin

					if(i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
					begin
						rw_state <= RW_ACK_DATA;

						ack_signal_cap <= 0;

						ack_delay_cnt <= 0;
					end

					i2c_bit_cnt <= i2c_bit_cnt+1;

					i2c_sda_reg <= i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-1];
					i2c_reg_data_reg <= {i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-2:0], 1'B1};	

					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_DATA: begin	



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_STOP;

							i2c_sda_reg <= 0;


							ack_signal_cap <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;	
				end
			end

			RW_STOP: begin
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE;
					i2c_sda_reg <= 1;	


					four_phase_cnt <= 0;

					cstate <= FINISH;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end		

			default: begin
				if(four_phase_cnt==3)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end
		endcase
	end
end
endtask


task do_fail_task;
begin


	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin

		i2c_sda_reg <= 0; 
		i2c_sck_reg <= 1;
		if(four_phase_cnt==3)
			cstate <= FINISH;
		else
			four_phase_cnt <= four_phase_cnt + 1;	
	end
end
endtask



assign			i2c_ready = (cstate==IDLE);
assign			i2c_fail = (cstate==FAIL);

assign			i2c_wait_ack = ((rw_state==RW_ACK_DATA)|(rw_state==RW_ACK_REG)|(rw_state==RW_ACK_START)|(rw_state==RW_ACK_ADDR2));

assign			i2c_wait_sda = (cstate==READ && rw_state==RW_DATA);

assign			i2c_sck = i2c_sck_reg;
assign			i2c_sda = (i2c_wait_ack|i2c_wait_sda)? 1'BZ : i2c_sda_reg;

reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata_reg;
reg									i2c_rdata_valid_reg;
always @(posedge sys_clk)
begin
	if(cstate==READ && rw_state==RW_DATA && 
			four_phase_cnt==3 && (i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1)) &&
			i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
	begin
		i2c_rdata_reg <= i2c_rdata_shift;
		i2c_rdata_valid_reg <= 1;
	end
	else
		i2c_rdata_valid_reg <= 0;
end

assign			i2c_rdata = i2c_rdata_reg;
assign			i2c_rdata_valid = i2c_rdata_valid_reg;

endmodule
module i2c_user_fsm(
	input 	wire 		sys_clk, sys_rst_n,

	output				i2c_sck,
	inout				i2c_sda,

	input	[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave,
	input	[`I2C_REG_ADDR_WIDTH-1:0]	i2c_reg_addr,

	output	[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata,
	output								i2c_rdata_valid,
	input								i2c_read_req,
	input	[`I2C_REG_DATA_WIDTH-1:0]	i2c_wdata,
	input								i2c_write_req,
	output								i2c_fail,
	output								i2c_ready,
	output								i2c_wait_ack,
	output								i2c_wait_sda,
	input								i2c_as_sccb
	);

	
	reg		[`I2C_CLK_BASE_COUNT-1:0]	i2c_base_cnt;

	reg		i2c_base_cnt_clr_n;
	always @(posedge sys_clk)
		if(!sys_rst_n || !i2c_base_cnt_clr_n)
			i2c_base_cnt <= 0;
		else if(i2c_base_cnt >= (`I2C_SCK_FREQ_FACTR-1))
			i2c_base_cnt <= 0;
		else
			i2c_base_cnt <= i2c_base_cnt + 1;
	

	reg		[2:0]	cstate;
	parameter		IDLE = 0;
	parameter		READ = 1;
	parameter		WRITE = 2;
	parameter		FINISH = 3;
	parameter		FAIL = 4;

	always @(posedge sys_clk)
		if(!sys_rst_n)
			init_system_task;
		else
		begin
			case(cstate)
				IDLE: begin

					if(i2c_read_req)
						jump_to_read_task;

					else if(i2c_write_req)
						jump_to_write_task;
					else
						init_system_task;
				end

				READ: begin
					do_read_task;
				end
				WRITE: begin
					do_write_task;
				end				

				FINISH: begin
					init_system_task;
				end

				FAIL: begin
					do_fail_task;
				end

				default: begin
					do_fail_task;
				end
			endcase		
		end


reg		[9:0]	ack_delay_cnt;
reg				ack_signal_cap;
reg		[9:0]	rw_state_in_cnt;
reg		[4:0]	four_phase_cnt;

reg				i2c_sck_reg;
reg				i2c_sda_reg;

reg		[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave_reg;
reg		[`I2C_SLV_ADDR_WIDTH-1:0]	i2c_slave_reg2;
reg		[`I2C_REG_ADDR_WIDTH-1:0]	i2c_reg_addr_reg;
reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_reg_data_reg;

reg		[4:0]	rw_state;
parameter		RW_IDLE = 15;
parameter		RW_START = 0;
parameter		RW_DEV_ADDR = 1;
parameter		RW_ACK_START = 2;
parameter		RW_REG_ADDR = 3;
parameter		RW_ACK_REG = 4;
parameter		RW_IDLE2 = 5;
parameter		RW_START2 = 6;
parameter		RW_DEV_ADDR2 = 7;
parameter		RW_ACK_ADDR2 = 8;
parameter		RW_DATA = 9;
parameter		RW_ACK_DATA = 10;
parameter		RW_STOP = 11;
parameter		RW_FAIL = 12;
parameter		RW_NO_ACK = 13;
parameter		RW_STOP_SCCB = 14;



task init_system_task;
begin
	cstate <= IDLE;
	ack_delay_cnt <= 0;
	i2c_base_cnt_clr_n <= 1;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask


task jump_to_read_task;
begin
	cstate <= READ;
	i2c_base_cnt_clr_n <= 0;
	ack_delay_cnt <= 0;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;
	i2c_reg_addr_reg <= i2c_reg_addr;

	i2c_slave_reg2 <= i2c_slave+`I2C_READ_FLAG;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask

task jump_to_write_task;
begin
	cstate <= WRITE;
	i2c_base_cnt_clr_n <= 0;
	ack_delay_cnt <= 0;
	rw_state <= RW_IDLE;
	rw_state_in_cnt <= 0;

	i2c_sck_reg <= 1;
	i2c_sda_reg <= 1;

	i2c_slave_reg <= i2c_slave+`I2C_WRITE_FLAG;
	i2c_reg_addr_reg <= i2c_reg_addr;
	i2c_reg_data_reg <= i2c_wdata;

	four_phase_cnt <= 0;

	ack_signal_cap <= 0;
end
endtask

reg		[9:0]	i2c_bit_cnt;
reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata_shift;

task do_read_task;
begin
	i2c_base_cnt_clr_n <= 1;
	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin
		case(rw_state)
			RW_IDLE: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end
			RW_START: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end
			RW_DEV_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_SLV_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_START;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
						i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};			
					end

					four_phase_cnt <= 0;
				end	

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_START: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end

				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_REG_ADDR;

							i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
							i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda||i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_REG_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_REG;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
						i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_REG: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 && !i2c_as_sccb)
						begin

							rw_state <= RW_IDLE2;


							i2c_sda_reg <= 1;

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end

						else if(i2c_as_sccb)
						begin

							rw_state <= RW_STOP_SCCB;


							i2c_sda_reg <= 0;

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_STOP_SCCB: begin

				if(four_phase_cnt==1)
					i2c_sck_reg <= 1;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE2;
					rw_state_in_cnt <= 0;
					i2c_sda_reg <= 1;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_IDLE2: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START2;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end

			RW_START2: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR2;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end

			RW_DEV_ADDR2: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_ADDR2;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];
						i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_ADDR2: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
					ack_delay_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_DATA;

							i2c_sda_reg <= i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-1];
							i2c_slave_reg2 <= {i2c_slave_reg2[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;
				end
			end

			RW_DATA: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;


				else if(four_phase_cnt==1)
					i2c_rdata_shift <= {i2c_rdata_shift[`I2C_REG_DATA_WIDTH-2:0], i2c_sda};

				if(four_phase_cnt==3)
				begin

					if(i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
					begin
						rw_state <= RW_NO_ACK;
						i2c_sda_reg <= 1;
						i2c_bit_cnt <= 0;
					end

					i2c_bit_cnt <= i2c_bit_cnt+1;

					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_NO_ACK: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_STOP;

					i2c_sda_reg <= 0;


					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_STOP: begin
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE;
					i2c_sda_reg <= 1;


					four_phase_cnt <= 0;

					cstate <= FINISH;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			default: begin
				if(four_phase_cnt==3)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end
		endcase
	end
end
endtask


task do_write_task;
begin
	i2c_base_cnt_clr_n <= 1;
	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin
		case(rw_state)
			RW_IDLE: begin 
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;
				if(four_phase_cnt==3)
				begin
					rw_state <= RW_START;
					rw_state_in_cnt <= 0;


					i2c_sda_reg <= 0;

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;
			end
			RW_START: begin

				if(four_phase_cnt==2)
					i2c_sck_reg <= 0;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_DEV_ADDR;
					rw_state_in_cnt <= 0;

					i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
					i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};

					i2c_bit_cnt <= 0;

					four_phase_cnt <= 0;
				end
				else
					four_phase_cnt <= four_phase_cnt + 1;				
			end
			RW_DEV_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_SLV_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_START;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-1];
						i2c_slave_reg <= {i2c_slave_reg[`I2C_SLV_ADDR_WIDTH-2:0], 1'B1};			
					end

					four_phase_cnt <= 0;
				end	

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_START: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
					ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_REG_ADDR;

							i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
							i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;		
				end
			end

			RW_REG_ADDR: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;

				if(four_phase_cnt==3)
				begin
					if(i2c_bit_cnt>=(`I2C_REG_ADDR_WIDTH-1))
					begin

						rw_state <= RW_ACK_REG;

						ack_signal_cap <= 0;
						ack_delay_cnt <= 0;
					end
					else 
					begin

						i2c_bit_cnt <= i2c_bit_cnt+1;
						i2c_sda_reg <= i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-1];
						i2c_reg_addr_reg <= {i2c_reg_addr_reg[`I2C_REG_ADDR_WIDTH-2:0], 1'B1};	
					end

					four_phase_cnt <= 0;
				end	

				else				
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_REG: begin



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_DATA;

							i2c_sda_reg <= i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-1];
							i2c_reg_data_reg <= {i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-2:0], 1'B1};	

							ack_signal_cap <= 0;

							i2c_bit_cnt <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;	
				end
			end

			RW_DATA: begin

				if(four_phase_cnt==0 || four_phase_cnt==2)
					i2c_sck_reg <= ~i2c_sck_reg;


				if(four_phase_cnt==3)
				begin

					if(i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
					begin
						rw_state <= RW_ACK_DATA;

						ack_signal_cap <= 0;

						ack_delay_cnt <= 0;
					end

					i2c_bit_cnt <= i2c_bit_cnt+1;

					i2c_sda_reg <= i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-1];
					i2c_reg_data_reg <= {i2c_reg_data_reg[`I2C_REG_DATA_WIDTH-2:0], 1'B1};	

					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end

			RW_ACK_DATA: begin	



				if(ack_delay_cnt>=`I2C_ACK_TOLR_DELAY)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end
				else
				begin

					ack_delay_cnt <= ack_delay_cnt+1;

					if(four_phase_cnt==0 || four_phase_cnt==2)
						i2c_sck_reg <= ~i2c_sck_reg;

					else if(four_phase_cnt==1)
						ack_signal_cap <= ~i2c_sda;

					if(four_phase_cnt==3)
					begin

						four_phase_cnt <= 0;

						if(ack_signal_cap==1 || i2c_as_sccb)
						begin

							rw_state <= RW_STOP;

							i2c_sda_reg <= 0;


							ack_signal_cap <= 0;
						end
					end

					else if(four_phase_cnt!=1)
						four_phase_cnt <= four_phase_cnt + 1;
					else if(four_phase_cnt==1 && (!i2c_sda || i2c_as_sccb))
						four_phase_cnt <= four_phase_cnt + 1;	
				end
			end

			RW_STOP: begin
				if(four_phase_cnt==0)
					i2c_sck_reg <= 1;

				if(four_phase_cnt==3)
				begin
					rw_state <= RW_IDLE;
					i2c_sda_reg <= 1;	


					four_phase_cnt <= 0;

					cstate <= FINISH;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end		

			default: begin
				if(four_phase_cnt==3)
				begin
					cstate <= FAIL;
					rw_state <= RW_FAIL;
					four_phase_cnt <= 0;
				end

				else
					four_phase_cnt <= four_phase_cnt + 1;	
			end
		endcase
	end
end
endtask


task do_fail_task;
begin


	if(i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1))
	begin

		i2c_sda_reg <= 0; 
		i2c_sck_reg <= 1;
		if(four_phase_cnt==3)
			cstate <= FINISH;
		else
			four_phase_cnt <= four_phase_cnt + 1;	
	end
end
endtask



assign			i2c_ready = (cstate==IDLE);
assign			i2c_fail = (cstate==FAIL);

assign			i2c_wait_ack = ((rw_state==RW_ACK_DATA)|(rw_state==RW_ACK_REG)|(rw_state==RW_ACK_START)|(rw_state==RW_ACK_ADDR2));

assign			i2c_wait_sda = (cstate==READ && rw_state==RW_DATA);

assign			i2c_sck = i2c_sck_reg;
assign			i2c_sda = (i2c_wait_ack|i2c_wait_sda)? 1'BZ : i2c_sda_reg;

reg		[`I2C_REG_DATA_WIDTH-1:0]	i2c_rdata_reg;
reg									i2c_rdata_valid_reg;
always @(posedge sys_clk)
begin
	if(cstate==READ && rw_state==RW_DATA && 
			four_phase_cnt==3 && (i2c_base_cnt==(`I2C_SCK_FREQ_FACTR-1)) &&
			i2c_bit_cnt==(`I2C_REG_DATA_WIDTH-1))
	begin
		i2c_rdata_reg <= i2c_rdata_shift;
		i2c_rdata_valid_reg <= 1;
	end
	else
		i2c_rdata_valid_reg <= 0;
end

assign			i2c_rdata = i2c_rdata_reg;
assign			i2c_rdata_valid = i2c_rdata_valid_reg;

endmodule