data/full_repos/permissive/472688398/openlane/i2c_ctrl2202/src/i2c_ctrl2202.v
data/verilator_xmls/76c36363-0541-4152-9482-6c9925dec4f8.xml
module i2c_ctrl2202(

	input 				i_start,
	input					i_cclk,
	input					i_read,
	input					i_stop,
	input 	      i_sda,
	input		[7:1] i_address,
	input 	[8:1] i_txdata,
	output 	[8:1] i_rxdata,
	output 				o_scl,
	output 	reg		o_busy,
	output 	reg   o_sda

);
	
	reg 			a_ack;
	reg 			d_ack;
	reg 			stop_bit;
	reg [2:0] a_cycle;
	reg [3:0] x_cycle;
	reg [8:1] r_txdata;
	reg [8:1] r_rxdata;
	reg [7:1] r_i_address;
	reg [2:0] state;








	parameter	IDLE	= 3'b000,
						ADDR	= 3'b001,
						MODR 	= 3'b010,
						AACK 	= 3'b011,
						READ	= 3'b100,
						WRTE 	= 3'b101,
						FINL	= 3'b110;

	initial begin
		o_sda        <=  1'bz;
		o_busy       <=  1'b0;
		a_ack        <=  1'b0;
		d_ack        <=  'b0;
		stop_bit     <=  'b0;
		a_cycle      <=  3'b111;
		x_cycle      <=  'd8;
		r_txdata     <=  8'd0;
		r_rxdata     <=  8'd0;
		r_i_address  <=  7'b0;
		state        <=  3'b0;
	end



	
	always @(posedge i_cclk)
		case(state)

			3'b000:	
				begin
					if(!i_start & !i_stop) begin
						o_sda        <=  1'b0;
						state        <=  ADDR;
						a_cycle      <=  3'b111;
						r_i_address  <=  i_address;
						o_busy       <=  1'b0;
					end

					else begin
						o_sda   <=  1'b1;
						state   <=  IDLE;
						o_busy  <=  1'b0;
					end
				end


			3'b001:
				begin
					if(a_cycle >= 3'b001) begin
						o_sda    <=  r_i_address[a_cycle];
						a_cycle  <=  a_cycle - 1'b1;
						state    <=  ADDR;
						o_busy   <=  1'b1;
					end

					else begin
						state   <=  MODR;
						o_busy  <=  1'b0;
					end
				end


			3'b010:
				begin
						state <= AACK;
						o_sda <= i_read;
				end


			3'b011:
				begin
					if(i_sda) begin
						a_cycle  <=  3'b111;
						state    <=  ADDR;
						o_busy   <=  1'b0;
						o_sda     <=  1'b1;
					end

					else if(!i_sda) begin
						if(!i_read) begin
							state     <=  WRTE;
							x_cycle   <=  4'd8;
							o_sda     <=  1'b0;
							o_busy    <=  1'b0;
							r_txdata  <=  i_txdata;
						end

						else begin
   						state 		<= READ;
							x_cycle   <=  4'd8;
							o_sda     <=  1'b0;
							o_busy    <=  1'b0;
						end
					end
				end


			3'b100:
				begin
					if(x_cycle >= 1) begin
							r_rxdata[x_cycle] <= i_sda;
							x_cycle <= x_cycle - 1'b1;
							o_busy <= 1'b1;
							state <= READ;
					end

					else begin
						state <= FINL;
						o_busy <= 1'b0;
						x_cycle <= 4'd8;
					end
				end


			3'b101:
				begin
					if(x_cycle > 0) begin
							o_sda <= i_txdata[x_cycle];

							x_cycle <= x_cycle - 1'b1;
							o_busy <= 1'b1;
							state <= WRTE;
					end

					else begin
						state <= FINL;
						o_busy <= 1'b0;
						x_cycle <= 4'd8;
					end
				end




























			3'b110:
				begin
					if(i_sda) begin
						state <= MODR;

					end

					else begin
						o_sda <= 1'b1;
						state <= IDLE;
					end
				end












			default: state <= IDLE;
		endcase



	assign o_scl = i_cclk;
	assign i_rxdata = r_rxdata;

endmodule
module i2c_ctrl2202(

	input 				i_start,
	input					i_cclk,
	input					i_read,
	input					i_stop,
	input 	      i_sda,
	input		[7:1] i_address,
	input 	[8:1] i_txdata,
	output 	[8:1] i_rxdata,
	output 				o_scl,
	output 	reg		o_busy,
	output 	reg   o_sda

);

	
	reg 			a_ack;
	reg 			d_ack;
	reg 			stop_bit;
	reg [2:0] a_cycle;
	reg [3:0] x_cycle;
	reg [8:1] r_txdata;
	reg [8:1] r_rxdata;
	reg [7:1] r_i_address;
	reg [2:0] state;








	parameter	IDLE	= 3'b000,
						ADDR	= 3'b001,
						MODR 	= 3'b010,
						AACK 	= 3'b011,
						READ	= 3'b100,
						WRTE 	= 3'b101,
						FINL	= 3'b110;

	initial begin
		o_sda        <=  1'bz;
		o_busy       <=  1'b0;
		a_ack        <=  1'b0;
		d_ack        <=  'b0;
		stop_bit     <=  'b0;
		a_cycle      <=  3'b111;
		x_cycle      <=  'd8;
		r_txdata     <=  8'd0;
		r_rxdata     <=  8'd0;
		r_i_address  <=  7'b0;
		state        <=  3'b0;
	end



	
	always @(posedge i_cclk)
		case(state)

			3'b000:	
				begin
					if(!i_start & !i_stop) begin
						o_sda        <=  1'b0;
						state        <=  ADDR;
						a_cycle      <=  3'b111;
						r_i_address  <=  i_address;
						o_busy       <=  1'b0;
					end

					else begin
						o_sda   <=  1'b1;
						state   <=  IDLE;
						o_busy  <=  1'b0;
					end
				end


			3'b001:
				begin
					if(a_cycle >= 3'b001) begin
						o_sda    <=  r_i_address[a_cycle];
						a_cycle  <=  a_cycle - 1'b1;
						state    <=  ADDR;
						o_busy   <=  1'b1;
					end

					else begin
						state   <=  MODR;
						o_busy  <=  1'b0;
					end
				end


			3'b010:
				begin
						state <= AACK;
						o_sda <= i_read;
				end


			3'b011:
				begin
					if(i_sda) begin
						a_cycle  <=  3'b111;
						state    <=  ADDR;
						o_busy   <=  1'b0;
						o_sda     <=  1'b1;
					end

					else if(!i_sda) begin
						if(!i_read) begin
							state     <=  WRTE;
							x_cycle   <=  4'd8;
							o_sda     <=  1'b0;
							o_busy    <=  1'b0;
							r_txdata  <=  i_txdata;
						end

						else begin
   						state 		<= READ;
							x_cycle   <=  4'd8;
							o_sda     <=  1'b0;
							o_busy    <=  1'b0;
						end
					end
				end


			3'b100:
				begin
					if(x_cycle >= 1) begin
							r_rxdata[x_cycle] <= i_sda;
							x_cycle <= x_cycle - 1'b1;
							o_busy <= 1'b1;
							state <= READ;
					end

					else begin
						state <= FINL;
						o_busy <= 1'b0;
						x_cycle <= 4'd8;
					end
				end


			3'b101:
				begin
					if(x_cycle > 0) begin
							o_sda <= i_txdata[x_cycle];

							x_cycle <= x_cycle - 1'b1;
							o_busy <= 1'b1;
							state <= WRTE;
					end

					else begin
						state <= FINL;
						o_busy <= 1'b0;
						x_cycle <= 4'd8;
					end
				end




























			3'b110:
				begin
					if(i_sda) begin
						state <= MODR;

					end

					else begin
						o_sda <= 1'b1;
						state <= IDLE;
					end
				end












			default: state <= IDLE;
		endcase



	assign o_scl = i_cclk;
	assign i_rxdata = r_rxdata;

endmodule