7
7
-- I2C Control Link Layer
8
8
--
9
9
-- This block handles the bit-level details of an I2C transaction. It requires higher order logic
10
- -- to actually orchestrate the transaction and is designed for use with i2c_ctrl_txn_layer.
10
+ -- to actually orchestrate the transaction and is designed for use with i2c_ctrl_txn_layer. This
11
+ -- block is written such that the tristate interfaces are push-pull, but that is trivial to change
12
+ -- to open-drain at a higher level if desired.
11
13
--
12
14
-- Notes:
13
15
-- - This block currently does not support block stretching.
@@ -118,41 +120,43 @@ architecture rtl of i2c_ctrl_link_layer is
118
120
rx_data : std_logic_vector (7 downto 0 );
119
121
rx_data_valid : std_logic ;
120
122
tx_data : std_logic_vector (7 downto 0 );
121
- sda_oe : std_logic ;
122
123
rx_ack : std_logic ;
123
124
rx_ack_valid : std_logic ;
125
+ sda_o : std_logic ;
126
+ sda_oe : std_logic ;
124
127
end record ;
125
128
126
129
constant SM_REG_RESET : sm_reg_t := (
127
- IDLE, -- state
128
- 0 , -- bits_shifted
129
- '0' , -- ready
130
- '0' , -- scl_start
131
- '0' , -- scl_active
132
- '0' , -- sda_hold
133
- (others => '0' ),-- counter
134
- '0' , -- count_load
135
- '0' , -- count_decr
136
- '0' , -- count_clr
137
- '0' , -- transition_sda_cntr_en
138
- '0' , -- ack_sending
139
- '0' , -- sr_scl_fedge_seen
140
- '0' , -- stop_requested
141
- (others => '0' ),-- rx_data
142
- '0' , -- rx_data_valid
143
- (others => '0' ),-- tx_data
144
- '0' , -- sda_oe
145
- '0' , -- rx_ack
146
- '0' -- rx_ack_valid
130
+ state => IDLE,
131
+ bits_shifted => 0 ,
132
+ ready => '0' ,
133
+ scl_start => '0' ,
134
+ scl_active => '0' ,
135
+ sda_hold => '0' ,
136
+ counter => (others => '0' ),
137
+ count_load => '0' ,
138
+ count_decr => '0' ,
139
+ count_clr => '0' ,
140
+ transition_sda_cntr_en => '0' ,
141
+ ack_sending => '0' ,
142
+ sr_scl_fedge_seen => '0' ,
143
+ stop_requested => '0' ,
144
+ rx_data => (others => '0' ),
145
+ rx_data_valid => '0' ,
146
+ tx_data => (others => '0' ),
147
+ rx_ack => '0' ,
148
+ rx_ack_valid => '0' ,
149
+ sda_o => '1' ,
150
+ sda_oe => '1'
147
151
);
148
152
149
153
signal sm_reg, sm_reg_next : sm_reg_t;
150
154
151
155
signal sm_count_done : std_logic ;
152
156
153
157
signal scl_toggle : std_logic ;
154
- signal scl_oe : std_logic ;
155
- signal scl_oe_last : std_logic ;
158
+ signal scl_o : std_logic ;
159
+ signal scl_o_last : std_logic ;
156
160
signal scl_redge : std_logic ;
157
161
signal scl_fedge : std_logic ;
158
162
@@ -176,25 +180,23 @@ begin
176
180
);
177
181
178
182
scl_reg : process (clk, reset)
179
- variable scl_oe_next : std_logic := '0' ;
180
183
begin
181
184
if reset then
182
- scl_oe <= '0 ' ;
183
- scl_oe_last <= '0 ' ;
185
+ scl_o <= '1 ' ;
186
+ scl_o_last <= '1 ' ;
184
187
elsif rising_edge (clk) then
185
- scl_oe_last <= scl_oe;
186
- scl_oe_next := not scl_oe;
188
+ scl_o_last <= scl_o;
187
189
188
190
if not sm_reg.scl_active then
189
- scl_oe <= '0 ' ;
191
+ scl_o <= '1 ' ;
190
192
elsif scl_toggle = '1' or sm_reg.scl_start = '1' then
191
- scl_oe <= scl_oe_next ;
193
+ scl_o <= not scl_o ;
192
194
end if ;
193
195
end if ;
194
196
end process ;
195
197
196
- scl_redge <= '1' when scl_oe = '0 ' and scl_oe_last = '1 ' else '0' ;
197
- scl_fedge <= '1' when scl_oe = '1 ' and scl_oe_last = '0 ' else '0' ;
198
+ scl_redge <= '1' when scl_o = '1 ' and scl_o_last = '0 ' else '0' ;
199
+ scl_fedge <= '1' when scl_o = '0 ' and scl_o_last = '1 ' else '0' ;
198
200
199
201
--
200
202
-- SDA Control
@@ -252,7 +254,8 @@ begin
252
254
--
253
255
254
256
sm_next_state : process (all )
255
- variable v : sm_reg_t;
257
+ variable v : sm_reg_t;
258
+ variable counter_done : boolean ;
256
259
begin
257
260
v := sm_reg;
258
261
@@ -261,8 +264,6 @@ begin
261
264
v.count_decr := '0' ;
262
265
v.count_clr := '0' ;
263
266
v.scl_start := '0' ;
264
- v.rx_ack := '0' ;
265
- v.rx_ack_valid := '0' ;
266
267
v.rx_data_valid := '0' ;
267
268
268
269
-- Every time we see a falling edge on SCL we count the number of cycles until we should
@@ -286,11 +287,15 @@ begin
286
287
v.stop_requested := '1' when tx_stop = '1' and txn_next_valid = '1' else '0' ;
287
288
end if ;
288
289
290
+ -- It takes a cycle for load to propagate and the counter to reflect the new value.
291
+ counter_done := sm_count_done = '1' and sm_reg.count_load = '0' ;
292
+
289
293
case sm_reg.state is
290
294
291
295
-- Ready and awaiting the next transaction
292
296
when IDLE =>
293
- v.sda_oe := '0' ;
297
+ v.sda_o := '1' ;
298
+ v.sda_oe := '1' ;
294
299
295
300
if tx_start then
296
301
-- Coming back to IDLE after a transaction means we've waited out tbuf, and tbuf
@@ -311,27 +316,28 @@ begin
311
316
312
317
-- In the event of a repeated START account for setup requirements
313
318
when START_SETUP =>
314
- v.sda_oe := '0' ;
319
+ v.sda_o := '1' ;
320
+ v.sda_oe := '1' ;
321
+ v.count_decr := '1' ;
315
322
316
- if sm_count_done then
323
+ if counter_done then
317
324
v.state := START_HOLD;
318
325
v.counter := START_SETUP_HOLD_TICKS;
319
326
v.count_load := '1' ;
320
- else
321
- v.count_decr := '1' ;
322
327
end if ;
323
328
324
329
when START_HOLD =>
325
- v.sda_oe := '1' ;
326
- if sm_count_done then
330
+ v.sda_o := '0' ;
331
+ v.sda_oe := '1' ;
332
+ v.count_decr := '1' ;
333
+ if counter_done then
327
334
v.state := HANDLE_NEXT;
328
335
v.scl_start := '1' ; -- drop SCL to finish START condition
329
336
v.scl_active := '1' ; -- begin free running counter for SCL transitions
330
- else
331
- v.count_decr := '1' ;
332
337
end if ;
333
338
334
339
when HANDLE_NEXT =>
340
+ v.rx_ack_valid := '0' ;
335
341
if v.stop_requested then
336
342
v.state := STOP_SDA;
337
343
elsif txn_next_valid then
@@ -353,17 +359,19 @@ begin
353
359
end if ;
354
360
355
361
-- Clock out a byte and then wait for an ACK
356
- when BYTE_TX =>
357
- if transition_sda = '1' then
362
+ when BYTE_TX =>
363
+ v.sda_oe := '1' ;
364
+
365
+ if transition_sda then
358
366
if sm_reg.bits_shifted = 8 then
359
367
v.state := ACK_RX;
360
368
v.bits_shifted := 0 ;
361
369
elsif v.stop_requested then
362
370
-- this is a valid SDA transition cycle so drive SDA low and skip STOP_SDA
363
371
v.state := STOP_SCL;
364
- v.sda_oe := '1 ' ;
372
+ v.sda_o := '0 ' ;
365
373
else
366
- v.sda_oe := not sm_reg.tx_data(7 );
374
+ v.sda_o := sm_reg.tx_data(7 );
367
375
v.tx_data := sm_reg.tx_data(sm_reg.tx_data'high - 1 downto sm_reg.tx_data'low ) & '1' ;
368
376
v.bits_shifted := sm_reg.bits_shifted + 1 ;
369
377
end if ;
@@ -374,8 +382,9 @@ begin
374
382
v.sda_oe := '0' ;
375
383
376
384
if scl_redge then
377
- v.state := STOP_SDA when v.stop_requested else HANDLE_NEXT;
378
385
v.rx_ack := not sda_in_syncd;
386
+ elsif scl_fedge then
387
+ v.state := STOP_SDA when v.stop_requested else HANDLE_NEXT;
379
388
v.rx_ack_valid := '1' ;
380
389
end if ;
381
390
@@ -394,11 +403,12 @@ begin
394
403
395
404
-- ACK the target
396
405
when ACK_TX =>
406
+ v.sda_oe := '1' ;
397
407
-- at the first transition_sda pulse start sending the (N)ACK
398
- if transition_sda = '1' then
408
+ if transition_sda then
399
409
if sm_reg.ack_sending = '0' then
400
- v.sda_oe := '1 ' when (tx_ack = '1' and v.stop_requested = '0' )
401
- else '0 ' ;
410
+ v.sda_o := '0 ' when (tx_ack = '1' and v.stop_requested = '0' )
411
+ else '1 ' ;
402
412
v.ack_sending := '1' ;
403
413
else
404
414
-- at the next transition point release the bus
@@ -412,6 +422,7 @@ begin
412
422
when STOP_SDA =>
413
423
if transition_sda then
414
424
v.state := STOP_SCL;
425
+ v.sda_o := '0' ;
415
426
v.sda_oe := '1' ;
416
427
end if ;
417
428
@@ -424,23 +435,21 @@ begin
424
435
end if ;
425
436
426
437
when STOP_SETUP =>
427
- if sm_count_done then
438
+ v.count_decr := '1' ;
439
+ if counter_done then
428
440
v.state := WAIT_TBUF;
429
441
v.counter := STO_TO_STA_BUF_TICKS;
430
442
v.count_load := '1' ;
431
- v.sda_oe := '0' ;
432
- else
433
- v.count_decr := '1' ;
443
+ v.sda_o := '1' ;
444
+ v.sda_oe := '1' ;
434
445
end if ;
435
446
436
447
-- Wait out tbuf to ensure STOP/START spacing
437
448
when WAIT_TBUF =>
438
- if sm_count_done then
449
+ v.count_decr := '1' ;
450
+ if counter_done then
439
451
v := SM_REG_RESET;
440
- else
441
- v.count_decr := '1' ;
442
452
end if ;
443
-
444
453
end case ;
445
454
446
455
v.ready := '1' when v.state = IDLE or
@@ -466,9 +475,9 @@ begin
466
475
rx_data_valid <= sm_reg.rx_data_valid;
467
476
468
477
-- I2C is open-drain, so we only ever drive low
469
- scl_if.o <= '0' ;
470
- scl_if.oe <= scl_oe;
471
- sda_if.o <= '0' ;
478
+ scl_if.o <= scl_o ;
479
+ scl_if.oe <= '1' ; -- SCL stretching is not currently supported
480
+ sda_if.o <= sm_reg.sda_o ;
472
481
sda_if.oe <= sm_reg.sda_oe;
473
482
474
483
end rtl ;
0 commit comments