data/full_repos/permissive/490299936/verilog/iic_controller.v
1: b'%Warning-WIDTH: data/full_repos/permissive/490299936/verilog/iic_controller.v:89: Operator EQ expects 12 bits on the LHS, but LHS\'s VARREF \'scl_cnt\' generates 10 bits.\n                                                                                : ... In instance iic_controller\nwire scl_h_sta = (scl_cnt == 12\'d1);\n                          ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/490299936/verilog/iic_controller.v:90: Operator EQ expects 12 bits on the LHS, but LHS\'s VARREF \'scl_cnt\' generates 10 bits.\n                                                                                : ... In instance iic_controller\nwire scl_h_cen = (scl_cnt == 12\'d257);\n                          ^~\n%Warning-WIDTH: data/full_repos/permissive/490299936/verilog/iic_controller.v:91: Operator EQ expects 12 bits on the LHS, but LHS\'s VARREF \'scl_cnt\' generates 10 bits.\n                                                                                : ... In instance iic_controller\nwire scl_l_sta = (scl_cnt == 12\'d513);\n                          ^~\n%Warning-WIDTH: data/full_repos/permissive/490299936/verilog/iic_controller.v:92: Operator EQ expects 12 bits on the LHS, but LHS\'s VARREF \'scl_cnt\' generates 10 bits.\n                                                                                : ... In instance iic_controller\nwire scl_l_cen = (scl_cnt == 12\'d769);\n                          ^~\n%Error: Exiting due to 4 warning(s)\n'
module iic_controller(
	input clk,
	input rst_n,

	input iicwr_req,
	input iicrd_req,

	input [7:0] iic_addr,

	input [7:0] iic_wrdb,
	output reg[7:0] iic_rddb,

	output iic_ack,
	output reg scl,
	inout sda
);

reg [3:0] cstate,nstate;

parameter DIDLE = 4'b0000,
		  DSTAR = 4'b0001,

		  DSADRW = 4'b0010,
		  D1ACK = 4'b0011,

		  DRADR = 4'b0100,
		  D2ACK = 4'b0101,

		  DWRDB = 4'b0110,
		  D3ACK = 4'b0111,

		  DRSTA = 4'b1000,
		  DSADRR = 4'b1001,
		  D4ACK = 4'b1010,
		  DRDDB = 4'b1011,
		  D5ACK = 4'b1100,
		  DSTOP = 4'b1101;


parameter DEVICE_WRADDR = 8'ha6,
		  DEVICE_RDADDR = 8'ha7;



reg [9:0] scl_cnt;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		scl_cnt <= 10'd0;
	end
	else begin
		scl_cnt <= scl_cnt + 1'b1;
	end
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		scl <= 1'b1;
	end
	else if(nstate == DIDLE) begin
		scl <= 1'b1;
	end
	else begin
		scl <= ~scl_cnt[9];
	end
end


wire scl_h_sta = (scl_cnt == 12'd1);
wire scl_h_cen = (scl_cnt == 12'd257);
wire scl_l_sta = (scl_cnt == 12'd513);
wire scl_l_cen = (scl_cnt == 12'd769);


reg [2:0] bit_cnt;

reg sda_r;

reg sda_link;


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cstate <= DIDLE;
	end
	else begin
		cstate <= nstate;
	end
end


always @(cstate or iicwr_req or iicrd_req
		 or scl_h_cen or scl_l_cen
		 or scl_h_sta or scl_l_sta
		 or bit_cnt) begin
	case(cstate)

		DIDLE: if( (iicwr_req || iicrd_req) && scl_h_sta ) begin
			nstate <= DSTAR;
		end
		else begin
			nstate <= DIDLE;
		end

		DSTAR: if(scl_l_sta) begin
			nstate <= DSADRW;
		end
		else begin
			nstate <= DSTAR;
		end

		DSADRW: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D1ACK;
		end
		else begin
			nstate <= DSADRW;
		end

		D1ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DRADR;
		end
		else begin
			nstate <= D1ACK;
		end

		DRADR: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D2ACK;
		end
		else begin
			nstate <= DRADR;
		end


		D2ACK: if(scl_l_sta && (bit_cnt == 3'd7) && iicwr_req) begin
			nstate <= DWRDB;
		end
		else if(scl_l_sta && (bit_cnt == 3'd7) && iicrd_req) begin
			nstate <= DRSTA;
		end
		else begin
			nstate <= D2ACK;
		end

		DWRDB: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D3ACK;
		end
		else begin
			nstate <= DWRDB;
		end

		D3ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DSTOP;
		end
		else begin
			nstate <= D3ACK;
		end

		DRSTA: if(scl_l_sta) begin

			nstate <= DSADRR;
		end
		else begin
			nstate <= DRSTA;
		end

		DSADRR: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D4ACK;
		end
		else begin
			nstate <= DSADRR;
		end

		D4ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DRDDB;
		end
		else begin
			nstate <= D4ACK;
		end

		DRDDB: if(scl_h_cen && (bit_cnt == 3'd7)) begin

			nstate <= D5ACK;
		end
		else begin
			nstate <= DRDDB;
		end

		D5ACK: if(scl_l_sta && (bit_cnt == 3'd6)) begin

			nstate <= DSTOP;
		end
		else begin
			nstate <= D5ACK;
		end

		DSTOP: if(scl_l_sta) begin

			nstate <= DIDLE;
		end
		else begin
			nstate <= DSTOP;
		end
	endcase
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		bit_cnt <= 3'd0;
	end
	else begin
		case(cstate)

			DIDLE: bit_cnt <= 3'd7;

			DSADRW,DRADR,DWRDB,DSADRR: if(scl_h_sta) begin
				bit_cnt <= bit_cnt - 1'b1;
			end
			DRDDB: if(scl_h_sta) begin
				bit_cnt <= bit_cnt - 1'b1;
			end

			D1ACK,D2ACK,D3ACK: if(scl_l_cen) begin
				bit_cnt <= 3'd7;
			end
			D4ACK: if(scl_l_sta) begin
				bit_cnt <= 3'd7;
			end

			D5ACK: if(scl_l_cen) begin
				bit_cnt <= bit_cnt - 1'b1;
			end
			default: ;
		endcase
	end
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		sda_r <= 1'b1;
		sda_link <= 1'b1;
		iic_rddb <= 8'd0;
	end
	else begin
		case(cstate)

			DIDLE: begin
				sda_r <= 1'b1;

				sda_link <= 1'b1;
			end

			DSTAR: begin
				if(scl_h_cen) begin
					sda_r <= 1'b0;
				end
			end

			DSADRW: begin
				if(scl_l_cen) begin
					sda_r <= DEVICE_WRADDR[bit_cnt];
				end
			end

			D1ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end

			DRADR: begin
				if(scl_l_cen) begin
					sda_r <= iic_addr[bit_cnt];

					sda_link <= 1'b1;
				end
			end

			D2ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end


			DWRDB: begin
				if(scl_l_cen) begin
					sda_r <= iic_wrdb[bit_cnt];

					sda_link <= 1'b1;
				end
			end

			D3ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end



			DRSTA: begin
				if(scl_h_cen) begin
					sda_r <= 1'b0;
				end
				else if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b1;
				end
			end

			DSADRR: begin
				if(scl_l_cen) begin
					sda_r <= DEVICE_RDADDR[bit_cnt];
				end
			end

			D4ACK: begin
				if(scl_l_cen && (bit_cnt == 3'd7)) begin

					sda_link <= 1'b0;
				end
			end

			DRDDB: begin
				if(scl_h_cen) begin
					iic_rddb[bit_cnt + 1'b1] <= sda;
					sda_r <= 1'b1;
				end
			end

			D5ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b0;
					sda_link <= 1'b1;
				end
			end


			DSTOP: begin
				if(scl_l_cen) begin
					sda_link <= 1'b1;
					sda_r <= 1'b0;
				end
				else if(scl_h_cen) begin
					sda_r <= 1'b1;
				end
			end
			default: ;
		endcase
	end
end

assign sda = sda_link? sda_r:1'bz;

assign iic_ack = (cstate == DSTOP) && scl_h_sta;

endmodule
module iic_controller(
	input clk,
	input rst_n,

	input iicwr_req,
	input iicrd_req,

	input [7:0] iic_addr,

	input [7:0] iic_wrdb,
	output reg[7:0] iic_rddb,

	output iic_ack,
	output reg scl,
	inout sda
);


reg [3:0] cstate,nstate;

parameter DIDLE = 4'b0000,
		  DSTAR = 4'b0001,

		  DSADRW = 4'b0010,
		  D1ACK = 4'b0011,

		  DRADR = 4'b0100,
		  D2ACK = 4'b0101,

		  DWRDB = 4'b0110,
		  D3ACK = 4'b0111,

		  DRSTA = 4'b1000,
		  DSADRR = 4'b1001,
		  D4ACK = 4'b1010,
		  DRDDB = 4'b1011,
		  D5ACK = 4'b1100,
		  DSTOP = 4'b1101;


parameter DEVICE_WRADDR = 8'ha6,
		  DEVICE_RDADDR = 8'ha7;



reg [9:0] scl_cnt;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		scl_cnt <= 10'd0;
	end
	else begin
		scl_cnt <= scl_cnt + 1'b1;
	end
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		scl <= 1'b1;
	end
	else if(nstate == DIDLE) begin
		scl <= 1'b1;
	end
	else begin
		scl <= ~scl_cnt[9];
	end
end


wire scl_h_sta = (scl_cnt == 12'd1);
wire scl_h_cen = (scl_cnt == 12'd257);
wire scl_l_sta = (scl_cnt == 12'd513);
wire scl_l_cen = (scl_cnt == 12'd769);


reg [2:0] bit_cnt;

reg sda_r;

reg sda_link;


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cstate <= DIDLE;
	end
	else begin
		cstate <= nstate;
	end
end


always @(cstate or iicwr_req or iicrd_req
		 or scl_h_cen or scl_l_cen
		 or scl_h_sta or scl_l_sta
		 or bit_cnt) begin
	case(cstate)

		DIDLE: if( (iicwr_req || iicrd_req) && scl_h_sta ) begin
			nstate <= DSTAR;
		end
		else begin
			nstate <= DIDLE;
		end

		DSTAR: if(scl_l_sta) begin
			nstate <= DSADRW;
		end
		else begin
			nstate <= DSTAR;
		end

		DSADRW: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D1ACK;
		end
		else begin
			nstate <= DSADRW;
		end

		D1ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DRADR;
		end
		else begin
			nstate <= D1ACK;
		end

		DRADR: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D2ACK;
		end
		else begin
			nstate <= DRADR;
		end


		D2ACK: if(scl_l_sta && (bit_cnt == 3'd7) && iicwr_req) begin
			nstate <= DWRDB;
		end
		else if(scl_l_sta && (bit_cnt == 3'd7) && iicrd_req) begin
			nstate <= DRSTA;
		end
		else begin
			nstate <= D2ACK;
		end

		DWRDB: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D3ACK;
		end
		else begin
			nstate <= DWRDB;
		end

		D3ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DSTOP;
		end
		else begin
			nstate <= D3ACK;
		end

		DRSTA: if(scl_l_sta) begin

			nstate <= DSADRR;
		end
		else begin
			nstate <= DRSTA;
		end

		DSADRR: if(scl_l_cen && (bit_cnt == 3'd0)) begin

			nstate <= D4ACK;
		end
		else begin
			nstate <= DSADRR;
		end

		D4ACK: if(scl_l_sta && (bit_cnt == 3'd7)) begin

			nstate <= DRDDB;
		end
		else begin
			nstate <= D4ACK;
		end

		DRDDB: if(scl_h_cen && (bit_cnt == 3'd7)) begin

			nstate <= D5ACK;
		end
		else begin
			nstate <= DRDDB;
		end

		D5ACK: if(scl_l_sta && (bit_cnt == 3'd6)) begin

			nstate <= DSTOP;
		end
		else begin
			nstate <= D5ACK;
		end

		DSTOP: if(scl_l_sta) begin

			nstate <= DIDLE;
		end
		else begin
			nstate <= DSTOP;
		end
	endcase
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		bit_cnt <= 3'd0;
	end
	else begin
		case(cstate)

			DIDLE: bit_cnt <= 3'd7;

			DSADRW,DRADR,DWRDB,DSADRR: if(scl_h_sta) begin
				bit_cnt <= bit_cnt - 1'b1;
			end
			DRDDB: if(scl_h_sta) begin
				bit_cnt <= bit_cnt - 1'b1;
			end

			D1ACK,D2ACK,D3ACK: if(scl_l_cen) begin
				bit_cnt <= 3'd7;
			end
			D4ACK: if(scl_l_sta) begin
				bit_cnt <= 3'd7;
			end

			D5ACK: if(scl_l_cen) begin
				bit_cnt <= bit_cnt - 1'b1;
			end
			default: ;
		endcase
	end
end


always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		sda_r <= 1'b1;
		sda_link <= 1'b1;
		iic_rddb <= 8'd0;
	end
	else begin
		case(cstate)

			DIDLE: begin
				sda_r <= 1'b1;

				sda_link <= 1'b1;
			end

			DSTAR: begin
				if(scl_h_cen) begin
					sda_r <= 1'b0;
				end
			end

			DSADRW: begin
				if(scl_l_cen) begin
					sda_r <= DEVICE_WRADDR[bit_cnt];
				end
			end

			D1ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end

			DRADR: begin
				if(scl_l_cen) begin
					sda_r <= iic_addr[bit_cnt];

					sda_link <= 1'b1;
				end
			end

			D2ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end


			DWRDB: begin
				if(scl_l_cen) begin
					sda_r <= iic_wrdb[bit_cnt];

					sda_link <= 1'b1;
				end
			end

			D3ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b0;
				end
			end



			DRSTA: begin
				if(scl_h_cen) begin
					sda_r <= 1'b0;
				end
				else if(scl_l_cen) begin
					sda_r <= 1'b1;

					sda_link <= 1'b1;
				end
			end

			DSADRR: begin
				if(scl_l_cen) begin
					sda_r <= DEVICE_RDADDR[bit_cnt];
				end
			end

			D4ACK: begin
				if(scl_l_cen && (bit_cnt == 3'd7)) begin

					sda_link <= 1'b0;
				end
			end

			DRDDB: begin
				if(scl_h_cen) begin
					iic_rddb[bit_cnt + 1'b1] <= sda;
					sda_r <= 1'b1;
				end
			end

			D5ACK: begin
				if(scl_l_cen) begin
					sda_r <= 1'b0;
					sda_link <= 1'b1;
				end
			end


			DSTOP: begin
				if(scl_l_cen) begin
					sda_link <= 1'b1;
					sda_r <= 1'b0;
				end
				else if(scl_h_cen) begin
					sda_r <= 1'b1;
				end
			end
			default: ;
		endcase
	end
end

assign sda = sda_link? sda_r:1'bz;

assign iic_ack = (cstate == DSTOP) && scl_h_sta;

endmodule