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

Subversion Repositories i2c

[/] [i2c/] [tags/] [asyst_3/] [rtl/] [verilog/] [i2c_master_byte_ctrl.v] - Blame information for rev 13

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

Line No. Rev Author Line
1 10 rherveille
//
2
// WISHBONE revB2 compiant I2C master core
3
//
4
// author: Richard Herveille
5 13 rherveille
// rev. 0.1 August  24th, 2001. Initial Verilog release.
6
// rev. 0.2 October 25th, 2001. Fixed some synthesis warnings.
7 10 rherveille
//
8
 
9
`include "timescale.v"
10
`include "i2c_master_defines.v"
11
 
12
module i2c_master_byte_ctrl (
13
        clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
14
        cmd_ack, ack_out, dout, i2c_busy, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
15
 
16
        //
17
        // inputs & outputs
18
        //
19
        input clk;     // master clock
20
        input rst;     // synchronous active high reset
21
        input nReset;  // asynchronous active low reset
22
        input ena;     // core enable signal
23
 
24
        input [15:0] clk_cnt; // 4x SCL
25
 
26
        // control inputs
27
        input       start;
28
        input       stop;
29
        input       read;
30
        input       write;
31
        input       ack_in;
32
        input [7:0] din;
33
 
34
        // status outputs
35
        output       cmd_ack;
36
        reg cmd_ack;
37
        output       ack_out;
38
        reg ack_out;
39
        output       i2c_busy;
40
        output [7:0] dout;
41
 
42
        // I2C signals
43
        input  scl_i;
44
        output scl_o;
45
        output scl_oen;
46
        input  sda_i;
47
        output sda_o;
48
        output sda_oen;
49
 
50
 
51
        //
52
        // Variable declarations
53
        //
54
 
55
        // statemachine
56
        parameter [4:0] ST_IDLE  = 5'b0_0000;
57
        parameter [4:0] ST_START = 5'b0_0001;
58
        parameter [4:0] ST_READ  = 5'b0_0010;
59
        parameter [4:0] ST_WRITE = 5'b0_0100;
60
        parameter [4:0] ST_ACK   = 5'b0_1000;
61
        parameter [4:0] ST_STOP  = 5'b1_0000;
62
 
63
        // signals for bit_controller
64
        reg  [3:0] core_cmd;
65
        reg        core_txd;
66
        wire       core_ack, core_rxd;
67
 
68
        // signals for shift register
69
        reg [7:0] sr; //8bit shift register
70
        reg       shift, ld;
71
 
72
        // signals for state machine
73
        wire       go;
74
        reg  [3:0] dcnt;
75
        wire       cnt_done;
76
 
77
        //
78
        // Module body
79
        //
80
 
81
        // hookup bit_controller
82
        i2c_master_bit_ctrl bit_controller (
83
                .clk(clk),
84
                .rst(rst),
85
                .nReset(nReset),
86
                .ena(ena),
87
                .clk_cnt(clk_cnt),
88
                .cmd(core_cmd),
89
                .cmd_ack(core_ack),
90
                .busy(i2c_busy),
91
                .din(core_txd),
92
                .dout(core_rxd),
93
                .scl_i(scl_i),
94
                .scl_o(scl_o),
95
                .scl_oen(scl_oen),
96
                .sda_i(sda_i),
97
                .sda_o(sda_o),
98
                .sda_oen(sda_oen)
99
        );
100
 
101
        // generate go-signal
102
        assign go = (read || write || stop) && !cmd_ack;
103
 
104
        // assign dout output to shift-register
105
        assign dout = sr;
106
 
107
        // generate shift register
108
        always@(posedge clk or negedge nReset)
109
                if (!nReset)
110
                        sr <= #1 8'h0;
111
                else if (rst)
112
                        sr <= #1 8'h0;
113
                else if (ld)
114
                        sr <= #1 din;
115
                else if (shift)
116
                        sr <= #1 {sr[6:0], core_rxd};
117
 
118
        // generate counter
119
        always@(posedge clk or negedge nReset)
120
                if (!nReset)
121
                        dcnt <= #1 4'h0;
122
                else if (rst)
123
                        dcnt <= #1 4'h0;
124
                else if (ld)
125
                        dcnt <= #1 4'h7;
126
                else if (shift)
127
                        dcnt <= #1 dcnt - 4'h1;
128
 
129
        assign cnt_done = !(|dcnt);
130
 
131
        //
132
        // state machine
133
        //
134
        reg [4:0] c_state; // synopsis enum_state
135
 
136
        always@(posedge clk or negedge nReset)
137
                if (!nReset)
138
                        begin
139
                                core_cmd <= #1 `I2C_CMD_NOP;
140 13 rherveille
                                core_txd <= #1 1'b0;
141 10 rherveille
 
142
                                shift    <= #1 1'b0;
143
                                ld       <= #1 1'b0;
144
 
145
                                cmd_ack  <= #1 1'b0;
146
                                c_state  <= #1 ST_IDLE;
147
                        end
148
                else if (rst)
149
                        begin
150
                                core_cmd <= #1 `I2C_CMD_NOP;
151
                                core_txd <= #1 1'b0;
152
 
153
                                shift    <= #1 1'b0;
154
                                ld       <= #1 1'b0;
155
 
156
                                cmd_ack  <= #1 1'b0;
157
                                c_state  <= #1 ST_IDLE;
158
                        end
159
        else
160 13 rherveille
                begin
161
                        // initially reset all signals
162
                        core_txd <= #1 sr[7];
163 10 rherveille
 
164 13 rherveille
                        shift    <= #1 1'b0;
165
                        ld       <= #1 1'b0;
166 10 rherveille
 
167 13 rherveille
                        cmd_ack  <= #1 1'b0;
168 10 rherveille
 
169 13 rherveille
                        case (c_state) // synopsis full_case parallel_case
170
                                ST_IDLE:
171
                                        if (go)
172
                                                begin
173
                                                        if (start)
174
                                                                begin
175
                                                                        c_state  <= #1 ST_START;
176
                                                                        core_cmd <= #1 `I2C_CMD_START;
177
                                                                end
178
                                                        else if (read)
179
                                                                begin
180
                                                                        c_state  <= #1 ST_READ;
181
                                                                        core_cmd <= #1 `I2C_CMD_READ;
182
                                                                end
183
                                                        else if (write)
184
                                                                begin
185
                                                                        c_state  <= #1 ST_WRITE;
186
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
187
                                                                end
188
                                                        else // stop
189
                                                                begin
190
                                                                        c_state  <= #1 ST_STOP;
191
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
192 10 rherveille
 
193 13 rherveille
                                                                        // generate command acknowledge signal
194
                                                                        cmd_ack  <= #1 1'b1;
195
                                                                end
196 10 rherveille
 
197 13 rherveille
                                                        ld       <= #1 1'b1;
198
                                                end
199 10 rherveille
 
200 13 rherveille
                                ST_START:
201
                                        if (core_ack)
202
                                                begin
203
                                                        if (read)
204
                                                                begin
205
                                                                        c_state  <= #1 ST_READ;
206
                                                                        core_cmd <= #1 `I2C_CMD_READ;
207
                                                                end
208
                                                        else
209
                                                                begin
210
                                                                        c_state  <= #1 ST_WRITE;
211
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
212
                                                                end
213
 
214
                                                        ld       <= #1 1'b1;
215
                                                end
216
 
217
                                ST_WRITE:
218
                                        if (core_ack)
219
                                                if (cnt_done)
220 10 rherveille
                                                        begin
221 13 rherveille
                                                                c_state  <= #1 ST_ACK;
222 10 rherveille
                                                                core_cmd <= #1 `I2C_CMD_READ;
223
                                                        end
224
                                                else
225
                                                        begin
226 13 rherveille
                                                                c_state  <= #1 ST_WRITE;       // stay in same state
227
                                                                core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
228
 
229
                                                                shift    <= #1 1'b1;
230 10 rherveille
                                                        end
231
 
232 13 rherveille
                                ST_READ:
233
                                                if (core_ack)
234
                                                        begin
235
                                                                if (cnt_done)
236
                                                                        begin
237
                                                                                c_state  <= #1 ST_ACK;
238
                                                                                core_cmd <= #1 `I2C_CMD_WRITE;
239
                                                                        end
240
                                                                else
241
                                                                        begin
242
                                                                                c_state  <= #1 ST_READ;       // stay in same state
243
                                                                                core_cmd <= #1 `I2C_CMD_READ; // read next bit
244
                                                                        end
245 10 rherveille
 
246 13 rherveille
                                                                shift    <= #1 1'b1;
247
                                                        end
248 10 rherveille
 
249 13 rherveille
                                ST_ACK:
250 10 rherveille
                                        if (core_ack)
251
                                                begin
252 13 rherveille
                                                        if (stop)
253 10 rherveille
                                                                begin
254 13 rherveille
                                                                        c_state  <= #1 ST_STOP;
255
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
256 10 rherveille
                                                                end
257
                                                        else
258
                                                                begin
259 13 rherveille
                                                                        c_state  <= #1 ST_IDLE;
260
                                                                        core_cmd <= #1 `I2C_CMD_NOP;
261 10 rherveille
                                                                end
262
 
263 13 rherveille
                                                        // assign ack_out output to bit_controller_rxd (contains last received bit)
264
                                                        ack_out = core_rxd;
265 10 rherveille
 
266 13 rherveille
                                                        // generate command acknowledge signal
267
                                                        cmd_ack  <= #1 1'b1;
268 10 rherveille
 
269 13 rherveille
                                                        core_txd <= #1 1'b1;
270
                                                end
271
                                        else
272
                                                core_txd <= #1 ack_in;
273 10 rherveille
 
274 13 rherveille
                                ST_STOP:
275
                                        if (core_ack)
276
                                                begin
277
                                                        c_state  <= #1 ST_IDLE;
278
                                                        core_cmd <= #1 `I2C_CMD_NOP;
279
                                                end
280 10 rherveille
 
281 13 rherveille
                        endcase
282
                end
283 10 rherveille
endmodule
284
 
285
 

powered by: WebSVN 2.1.0

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