📄 i2c_controller.v
字号:
// --------------------------------------------------------------------
// Copyright (c) 2005 by Terasic Technologies Inc.
// --------------------------------------------------------------------
//
// Permission:
//
// Terasic grants permission to use and modify this code for use
// in synthesis for all Terasic Development Boards and Altrea Development
// Kits made by Terasic. Other use of this code, including the selling
// ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Terasic provides no warranty regarding the use
// or functionality of this code.
//
// --------------------------------------------------------------------
//
// Terasic Technologies Inc
// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,
// HsinChu County, Taiwan
// 302
//
// web: http://www.terasic.com/
// email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions:i2c controller
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// Ver :| Author :| Mod. Date :| Changes Made:
// V1.0 :| Joe Yang :| 05/07/10 :| Initial Revision
// --------------------------------------------------------------------
module I2C_Controller (
CLOCK,
I2C_SCLK,//I2C CLOCK
I2C_SDAT,//I2C DATA
I2C_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
GO, //GO transfor
END, //END transfor
// W_R, //W_R
ACK, //ACK
RESET
//TEST
// SD_COUNTER,
// SDO
);
input CLOCK;
input [31:0]I2C_DATA;
input GO;
input RESET;
// input W_R;
inout I2C_SDAT;
output I2C_SCLK;
output END;
output ACK;
//TEST
//output [5:0] SD_COUNTER;
//output SDO;
reg SDO;
reg SCLK;
reg END;
reg [31:0]SD;
reg [7:0]SD_COUNTER;
wire I2C_SCLK=SCLK; //| ( ((SD_COUNTER >= 3) & (SD_COUNTER <=29))? ~CLOCK :0 );
wire I2C_SDAT=SDO?1'bz:0 ;
reg ACK1,ACK2,ACK3,ACK4;
wire ACK=ACK1 | ACK2 | ACK3 | ACK4;
//--I2C COUNTER
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) SD_COUNTER<=8'b11111111;
else begin
if (GO==0)
SD_COUNTER<=0;
else
if (SD_COUNTER < 8'b11111111) SD_COUNTER<=SD_COUNTER+1;
end
end
//----
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) begin SCLK<=1;SDO<=1; ACK1<=1;ACK2<=1;ACK3<=1; END<=0; end
else
case (SD_COUNTER)
8'd0 : begin ACK1<=1 ;ACK2<=1 ;ACK3<=1 ; END<=0; SDO<=1; SCLK<=1;end
//start
8'd1 : begin SD<=I2C_DATA;SDO<=0;end
8'd2 : SCLK<=0;
//SLAVE ADDR
8'd3 : SDO<=SD[31];
8'd4 : SCLK<=1;
8'd5 : SCLK<=1;
8'd6 : SCLK<=0;
8'd7 : SDO<=SD[30];
8'd8 : SCLK<=1;
8'd9 : SCLK<=1;
8'd10 : SCLK<=0;
8'd11 : SDO<=SD[29];
8'd12 : SCLK<=1;
8'd13 : SCLK<=1;
8'd14 : SCLK<=0;
8'd15 : SDO<=SD[28];
8'd16 : SCLK<=1;
8'd17 : SCLK<=1;
8'd18 : SCLK<=0;
8'd19 : SDO<=SD[27];
8'd20 : SCLK<=1;
8'd21 : SCLK<=1;
8'd22 : SCLK<=0;
8'd23 : SDO<=SD[26];
8'd24 : SCLK<=1;
8'd25 : SCLK<=1;
8'd26 : SCLK<=0;
8'd27 : SDO<=SD[25];
8'd28 : SCLK<=1;
8'd29 : SCLK<=1;
8'd30 : SCLK<=0;
8'd31 : SDO<=SD[24];
8'd32 : SCLK<=1;
8'd33 : SCLK<=1;
8'd34 : SCLK<=0;
8'd35 : SDO<=1'b1;//ACK
8'd36 : SCLK<=1;
8'd37 : begin SCLK<=1;ACK1<=I2C_SDAT;end
8'd38 : SCLK<=0;
//SUB ADDR
8'd39 : SDO<=SD[23];
8'd40 : SCLK<=1;
8'd41 : SCLK<=1;
8'd42 : SCLK<=0;
8'd43 : SDO<=SD[22];
8'd44 : SCLK<=1;
8'd45 : SCLK<=1;
8'd46 : SCLK<=0;
8'd47 : SDO<=SD[21];
8'd48 : SCLK<=1;
8'd49 : SCLK<=1;
8'd50 : SCLK<=0;
8'd51 : SDO<=SD[20];
8'd52 : SCLK<=1;
8'd53 : SCLK<=1;
8'd54 : SCLK<=0;
8'd55 : SDO<=SD[19];
8'd56 : SCLK<=1;
8'd57 : SCLK<=1;
8'd58 : SCLK<=0;
8'd59 : SDO<=SD[18];
8'd60 : SCLK<=1;
8'd61 : SCLK<=1;
8'd62 : SCLK<=0;
8'd63 : SDO<=SD[17];
8'd64 : SCLK<=1;
8'd65 : SCLK<=1;
8'd66 : SCLK<=0;
8'd67 : SDO<=SD[16];
8'd68 : SCLK<=1;
8'd69 : SCLK<=1;
8'd70 : SCLK<=0;
8'd71 : SDO<=1'b1;//ACK
8'd72 : SCLK<=1;
8'd73 : begin SCLK<=1;ACK2<=I2C_SDAT;end
8'd74 : SCLK<=0;
//DATA1
8'd75 : SDO<=SD[15];
8'd76 : SCLK<=1;
8'd77 : SCLK<=1;
8'd78 : SCLK<=0;
8'd79 : SDO<=SD[14];
8'd80 : SCLK<=1;
8'd81 : SCLK<=1;
8'd82 : SCLK<=0;
8'd83 : SDO<=SD[13];
8'd84 : SCLK<=1;
8'd85 : SCLK<=1;
8'd86 : SCLK<=0;
8'd87 : SDO<=SD[12];
8'd88 : SCLK<=1;
8'd89 : SCLK<=1;
8'd90 : SCLK<=0;
8'd91 : SDO<=SD[11];
8'd92 : SCLK<=1;
8'd93 : SCLK<=1;
8'd94 : SCLK<=0;
8'd95 : SDO<=SD[10];
8'd96 : SCLK<=1;
8'd97 : SCLK<=1;
8'd98 : SCLK<=0;
8'd99 : SDO<=SD[9];
8'd100 : SCLK<=1;
8'd101 : SCLK<=1;
8'd102 : SCLK<=0;
8'd103 : SDO<=SD[8];
8'd104 : SCLK<=1;
8'd105 : SCLK<=1;
8'd106 : SCLK<=0;
8'd107 : SDO<=1'b1;//ACK
8'd108 : SCLK<=1;
8'd109 : begin SCLK<=1;ACK3<=I2C_SDAT;end
8'd110 : SCLK<=0;
8'd111 : SDO<=0;
//DATA2
8'd112 : SDO<=SD[7];
8'd113 : SCLK<=1;
8'd114 : SCLK<=1;
8'd115 : SCLK<=0;
8'd116 : SDO<=SD[6];
8'd117 : SCLK<=1;
8'd118 : SCLK<=1;
8'd119 : SCLK<=0;
8'd120 : SDO<=SD[5];
8'd121 : SCLK<=1;
8'd122 : SCLK<=1;
8'd123 : SCLK<=0;
8'd124 : SDO<=SD[4];
8'd125 : SCLK<=1;
8'd126 : SCLK<=1;
8'd127 : SCLK<=0;
8'd128 : SDO<=SD[3];
8'd129 : SCLK<=1;
8'd130 : SCLK<=1;
8'd131 : SCLK<=0;
8'd132 : SDO<=SD[2];
8'd133 : SCLK<=1;
8'd134 : SCLK<=1;
8'd135 : SCLK<=0;
8'd136 : SDO<=SD[1];
8'd137 : SCLK<=1;
8'd138 : SCLK<=1;
8'd139 : SCLK<=0;
8'd140 : SDO<=SD[0];
8'd141 : SCLK<=1;
8'd142 : SCLK<=1;
8'd143 : SCLK<=0;
8'd144 : SDO<=1'b1;//ACK
8'd145 : SCLK<=1;
8'd146 : begin SCLK<=1;ACK4<=I2C_SDAT;end
8'd147 : SCLK<=0;
8'd148 : SDO<=0;
//stop
8'd149 : SCLK<=1'b1;
8'd150 : begin SDO<=1'b1;END<=1; end
default: begin SCLK<=1'b1; SDO<=1'b1; end
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -