OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [XUPV5-LX110T_SoC/] [MIPS32-Pipelined-Hw/] [src/] [I2C/] [I2C_Phy.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ayersg
`timescale 1ns / 1ps
2
/*
3
 * File         : I2C_Phy.v
4
 * Project      : University of Utah, XUM Project MIPS32 core
5
 * Creator(s)   : Grant Ayers (ayers@cs.utah.edu)
6
 *
7
 * Modification History:
8
 *   Rev   Date         Initials  Description of Change
9
 *   1.0   25-Jun-2012  GEA       Initial design.
10
 *
11
 * Standards/Formatting:
12
 *   Verilog 2001, 4 soft tab, wide column.
13
 *
14
 * Description:
15
 *   I2C Master controller made for a single-master I2C bus.
16
 *   Uses a FIFO to store transmit and receive data, and is made
17
 *   to be generic enough to use with a wide variety of I2C slave devices.
18
 *   A Read command sends a bus address byte then receives a requested number
19
 *   of bytes, while a Write command writes all bytes that are presently in
20
 *   the FIFO.
21
 */
22
 
23
module I2C_Phy(
24
    input  clock,
25
    input  reset,
26
    input  Read,
27
    input  Write,
28
    input  ReadCountSet,
29
    input  EnQ,
30
    input  DeQ,
31
    input  Clear,
32
    input  [7:0] DataIn,
33
    output reg [7:0] DataOut,
34
    output Ack,
35
    output reg Nack,
36
    output Fifo_Empty,
37
    output Fifo_Full,
38
    inout  i2c_scl,
39
    inout  i2c_sda
40
    );
41
 
42
    localparam [5:0]    IDLE=0, ENQ=1, DEQ=2, START=3, ADDR6=4, ADDR5=5, ADDR4=6, ADDR3=7, ADDR2=8,
43
                        ADDR1=9, ADDR0=10, RWBIT=11, A_DEQ=12, A_ACK=13, WDWAIT=14, WDATA7=15,
44
                        WDATA6=16, WDATA5=17, WDATA4=18, WDATA3=19, WDATA2=20, WDATA1=21, WDATA0=22,
45
                        W_DEQ=23, W_ACK=24, RDATA7=25, RDATA6=26, RDATA5=27, RDATA4=28, RDATA3=29,
46
                        RDATA2=30, RDATA1=31, RDATA0=32, R_ENQ=33, R_ACKW=34, R_ACK=35, NACK=36,
47
                        STOPW=37, STOP=38, BUSW=39, CLEAR=40, RNSET=41;
48
 
49
    // FIFO signals
50
    wire Fifo_Clear, Fifo_EnQ, Fifo_DeQ;
51
    wire [7:0] Fifo_In, Fifo_Out;
52
 
53
    wire scl, scl_tick_90;
54
    reg [5:0] state;
55
    reg [7:0] Rx_Data;
56
    reg sda;
57
    reg [7:0] Rx_Todo, Rx_Remain;
58
 
59
    // The I2C bus is high-impedance instead of a driven 1.
60
    assign i2c_sda = (sda) ? 1'bz : 1'b0;
61
    assign i2c_scl = (scl | (state == IDLE)) ? 1'bz : 1'b0;
62
 
63
    // Control logic : 4-way handshaking
64
    assign Ack = (state == BUSW);
65
 
66
    always @(posedge clock) begin
67
        Rx_Todo   <= (reset) ? 8'h00 : ((state == RNSET) ? DataIn : Rx_Todo);
68
        Rx_Remain <= (reset) ? 8'h00 : ((state == IDLE) ? Rx_Todo : ((state == R_ENQ) ? Rx_Remain - 1 : Rx_Remain));
69
    end
70
 
71
    always @(posedge clock) begin
72
        DataOut <= (reset) ? 8'h00 : ((state == DEQ) ? Fifo_Out : DataOut);
73
    end
74
 
75
    always @(posedge clock) begin
76
        Nack <= (reset | (state == START)) ? 0 : ((state == NACK) ? 1 : Nack);
77
    end
78
 
79
    assign Fifo_EnQ   = (state == ENQ) || (state == R_ENQ);
80
    assign Fifo_DeQ   = (state == DEQ) || (state == A_DEQ) || (state == W_DEQ);
81
    assign Fifo_In    = (state == R_ENQ) ? Rx_Data : DataIn;
82
    assign Fifo_Clear = (state == CLEAR);
83
 
84
    // Main state machine
85
    always @(posedge clock) begin
86
        if (reset) begin
87
            state <= IDLE;
88
        end
89
        else begin
90
            case (state)
91
                IDLE:   begin
92
                            if      (EnQ)           state <= ENQ;
93
                            else if (DeQ)           state <= DEQ;
94
                            else if (Clear)         state <= CLEAR;
95
                            else if (ReadCountSet)  state <= RNSET;
96
                            else if ((Read | Write) & scl & scl_tick_90) state <= START;
97
                            else    state <= IDLE;
98
                        end
99
                ENQ:    state <= BUSW;
100
                DEQ:    state <= BUSW;
101
                CLEAR:  state <= BUSW;
102
                RNSET:  state <= BUSW;
103
                START:  state <= (~scl & scl_tick_90) ? ADDR6 : START;
104
                ADDR6:  state <= (~scl & scl_tick_90) ? ADDR5 : ADDR6;
105
                ADDR5:  state <= (~scl & scl_tick_90) ? ADDR4 : ADDR5;
106
                ADDR4:  state <= (~scl & scl_tick_90) ? ADDR3 : ADDR4;
107
                ADDR3:  state <= (~scl & scl_tick_90) ? ADDR2 : ADDR3;
108
                ADDR2:  state <= (~scl & scl_tick_90) ? ADDR1 : ADDR2;
109
                ADDR1:  state <= (~scl & scl_tick_90) ? ADDR0 : ADDR1;
110
                ADDR0:  state <= (~scl & scl_tick_90) ? RWBIT : ADDR0;
111
                RWBIT:  state <= (~scl & scl_tick_90) ? A_DEQ : RWBIT;
112
                A_DEQ:  state <= A_ACK;
113
                A_ACK:  state <= ( scl & scl_tick_90) ? ((i2c_sda) ? NACK : ((Read) ? RDATA7 : WDWAIT)) : A_ACK;
114
 
115
                // Writes
116
                WDWAIT: state <= (~scl & scl_tick_90) ? WDATA7 : WDWAIT;
117
                WDATA7: state <= (~scl & scl_tick_90) ? WDATA6 : WDATA7;
118
                WDATA6: state <= (~scl & scl_tick_90) ? WDATA5 : WDATA6;
119
                WDATA5: state <= (~scl & scl_tick_90) ? WDATA4 : WDATA5;
120
                WDATA4: state <= (~scl & scl_tick_90) ? WDATA3 : WDATA4;
121
                WDATA3: state <= (~scl & scl_tick_90) ? WDATA2 : WDATA3;
122
                WDATA2: state <= (~scl & scl_tick_90) ? WDATA1 : WDATA2;
123
                WDATA1: state <= (~scl & scl_tick_90) ? WDATA0 : WDATA1;
124
                WDATA0: state <= (~scl & scl_tick_90) ? W_DEQ  : WDATA0;
125
                W_DEQ:  state <= W_ACK;
126
                W_ACK:  state <= ( scl & scl_tick_90) ? ((i2c_sda) ? NACK : ((Fifo_Empty) ? STOPW : WDWAIT)) : W_ACK;
127
 
128
                // Reads
129
                RDATA7: state <= ( scl & scl_tick_90) ? RDATA6 : RDATA7;
130
                RDATA6: state <= ( scl & scl_tick_90) ? RDATA5 : RDATA6;
131
                RDATA5: state <= ( scl & scl_tick_90) ? RDATA4 : RDATA5;
132
                RDATA4: state <= ( scl & scl_tick_90) ? RDATA3 : RDATA4;
133
                RDATA3: state <= ( scl & scl_tick_90) ? RDATA2 : RDATA3;
134
                RDATA2: state <= ( scl & scl_tick_90) ? RDATA1 : RDATA2;
135
                RDATA1: state <= ( scl & scl_tick_90) ? RDATA0 : RDATA1;
136
                RDATA0: state <= ( scl & scl_tick_90) ? R_ENQ  : RDATA0;
137
                R_ENQ:  state <= R_ACKW;
138
                R_ACKW: state <= (~scl & scl_tick_90) ? R_ACK : R_ACKW;
139
                R_ACK:  state <= (~scl & scl_tick_90) ? ((Rx_Remain != 8'h00) ? RDATA7 : STOP) : R_ACK;
140
 
141
                // Termination
142
                NACK:   state <= STOPW;
143
                STOPW:  state <= (~scl & scl_tick_90) ? STOP : STOPW;
144
                STOP:   state <= ( scl & scl_tick_90) ? BUSW : STOP;
145
                BUSW:   state <= (Read | Write | EnQ | DeQ) ? BUSW : IDLE;
146
                default: state <= 6'bxxxxxx;
147
            endcase
148
        end
149
    end
150
 
151
    // Incoming data capture
152
    always @(posedge clock) begin
153
        if (reset) begin
154
            Rx_Data <= 8'h00;
155
        end
156
        else begin
157
            Rx_Data[7] <= ((state == RDATA7) & scl & scl_tick_90) ? i2c_sda : Rx_Data[7];
158
            Rx_Data[6] <= ((state == RDATA6) & scl & scl_tick_90) ? i2c_sda : Rx_Data[6];
159
            Rx_Data[5] <= ((state == RDATA5) & scl & scl_tick_90) ? i2c_sda : Rx_Data[5];
160
            Rx_Data[4] <= ((state == RDATA4) & scl & scl_tick_90) ? i2c_sda : Rx_Data[4];
161
            Rx_Data[3] <= ((state == RDATA3) & scl & scl_tick_90) ? i2c_sda : Rx_Data[3];
162
            Rx_Data[2] <= ((state == RDATA2) & scl & scl_tick_90) ? i2c_sda : Rx_Data[2];
163
            Rx_Data[1] <= ((state == RDATA1) & scl & scl_tick_90) ? i2c_sda : Rx_Data[1];
164
            Rx_Data[0] <= ((state == RDATA0) & scl & scl_tick_90) ? i2c_sda : Rx_Data[0];
165
        end
166
    end
167
 
168
    // I2C data line assignment
169
    always @(*) begin
170
        case (state)
171
            IDLE:   sda <= 1;
172
            ENQ:    sda <= 1;
173
            DEQ:    sda <= 1;
174
            CLEAR:  sda <= 1;
175
            START:  sda <= 0;
176
            ADDR6:  sda <= Fifo_Out[6];
177
            ADDR5:  sda <= Fifo_Out[5];
178
            ADDR4:  sda <= Fifo_Out[4];
179
            ADDR3:  sda <= Fifo_Out[3];
180
            ADDR2:  sda <= Fifo_Out[2];
181
            ADDR1:  sda <= Fifo_Out[1];
182
            ADDR0:  sda <= Fifo_Out[0];
183
            RWBIT:  sda <= Read;   // 0 is write, 1 is read
184
            A_DEQ:  sda <= 1;
185
            A_ACK:  sda <= 1;
186
            WDWAIT: sda <= 1;
187
            WDATA7: sda <= Fifo_Out[7];
188
            WDATA6: sda <= Fifo_Out[6];
189
            WDATA5: sda <= Fifo_Out[5];
190
            WDATA4: sda <= Fifo_Out[4];
191
            WDATA3: sda <= Fifo_Out[3];
192
            WDATA2: sda <= Fifo_Out[2];
193
            WDATA1: sda <= Fifo_Out[1];
194
            WDATA0: sda <= Fifo_Out[0];
195
            W_DEQ:  sda <= 1;
196
            W_ACK:  sda <= 1;
197
            RDATA7: sda <= 1;
198
            RDATA6: sda <= 1;
199
            RDATA5: sda <= 1;
200
            RDATA4: sda <= 1;
201
            RDATA3: sda <= 1;
202
            RDATA2: sda <= 1;
203
            RDATA1: sda <= 1;
204
            RDATA0: sda <= 1;
205
            R_ENQ:  sda <= 1;
206
            R_ACKW: sda <= 1;
207
            R_ACK:  sda <= (Rx_Remain == 8'h00); // Low for more data, high for done
208
            NACK:   sda <= 1;
209
            STOPW:  sda <= 1;
210
            STOP:   sda <= 0;
211
            BUSW:   sda <= 1;
212
            default: sda <= 1;
213
        endcase
214
    end
215
 
216
    // I2C Clock Generation
217
    I2C_Clock I2C_Clock (
218
        .clock        (clock),
219
        .reset        (reset),
220
        .scl          (scl),
221
        .scl_tick_90  (scl_tick_90)
222
    );
223
 
224
    FIFO_Clear FIFO (
225
        .clock     (clock),
226
        .reset     (reset),
227
        .clear     (Fifo_Clear),
228
        .enQ       (Fifo_EnQ),
229
        .deQ       (Fifo_DeQ),
230
        .data_in   (Fifo_In),
231
        .data_out  (Fifo_Out),
232
        .empty     (Fifo_Empty),
233
        .full      (Fifo_Full)
234
    );
235
 
236
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.