|  | 
| 1 m, S, }. f& X' b3 m! O8 m: P+ Q$ H1 E3 Y6 F
 I2C START / STOP Detector Verilog Code/ B- i" f* U* m. J  d
 
 % I( c$ ^+ q! M5 J; R9 h1 S# w9 i( f. Q7 {4 B# G
 module i2c_start_stop_detector (
 & d+ e. L( k$ e+ w9 p    input  wire clk,       // 系統時鐘5 @1 E/ G$ i3 r. J% M5 G
 input  wire rst_n,     // 非同步 Reset6 b8 w: E" Z8 A, V
 input  wire sda,       // I2C 資料線
 6 n# k* Z5 c0 b7 s1 l4 h    input  wire scl,       // I2C 時鐘線
 , T' ^! p  M, _3 J    output reg  start_detected, // Start 條件偵測到$ k6 ?# L" H4 }( v
 output reg  stop_detected   // Stop 條件偵測到
 ' J# M) n/ U" E$ K, c) h);, \' k. z! [) t4 [1 Y, S
 o: V5 Z1 z6 V* N
 
 8 _8 D' c6 A: x    // 前兩個時鐘週期的 SDA 與 SCL 值5 a  N/ k! r, b; b/ v. B
 reg sda_d1, sda_d2;
 9 R: |# Y# k1 G) d, M  Q, y    reg scl_d1;
 ) E6 Y4 Q2 V: _' e& n% u" w
 ]! Y. A: j' y2 C5 u, x  t$ j
 ( {/ K% w! N3 w! y: `: l- S8 ]    wire sda_rising  = (sda_d2 == 1'b0) && (sda_d1 == 1'b1);
 ( p. {, P6 y: ]1 r) K( M    wire sda_falling = (sda_d2 == 1'b1) && (sda_d1 == 1'b0);# x/ }$ L/ p- A  t5 M; C% g
 
 & Q" ]! ?: ]( X
 % {( S' M3 x+ X5 _) {9 A    // Sample SDA and SCL
 + H3 }6 \7 u+ N0 O7 h, v  b    always @(posedge clk or negedge rst_n) begin
 ! R' l. ?( k/ M; Z3 K" m2 d        if (!rst_n) begin
 - s/ q' R+ d: i4 N- _( z/ p2 l            sda_d1 <= 1'b1;: {7 M# I% [* L9 P( A' K  @
 sda_d2 <= 1'b1;
 ) N2 v, J6 Z1 U            scl_d1 <= 1'b1;
 1 D& S+ |& a1 S$ Y        end else begin6 U+ k5 i, C+ e. l+ }" s
 sda_d2 <= sda_d1;1 R) X/ e- @3 ~' H9 C8 N
 sda_d1 <= sda;" i/ k: i7 r' }: ]% G0 A+ J# g
 scl_d1 <= scl;
 ' D( z0 _# ~/ b! S4 P        end# B9 Z' I8 B  f2 Y. Z
 end
 ) h4 P2 j  p6 G; v3 a0 T1 ]. I3 f$ ^4 b4 O* z
 
 + v6 s8 J  P7 }2 `. R7 \* f    // 偵測 Start / Stop 條件
 ! b+ j# j/ e0 g0 f& `    always @(posedge clk or negedge rst_n) begin8 A5 e+ c' X9 s# l# ^. J( J
 if (!rst_n) begin
 4 \) X" S) v- @9 H/ M            start_detected <= 1'b0;
 5 l- M2 M$ g5 K: h            stop_detected <= 1'b0;6 I  T8 D- k4 X( t
 end else begin
 . u! n4 G, `, u3 P" H) l            // I2C START: SDA falling while SCL is high1 ^% C! Z8 K9 K7 b- L, D
 start_detected <= sda_falling && (scl_d1 == 1'b1);
 # I1 O3 A9 V) _- V9 y            // I2C STOP:  SDA rising while SCL is high
 ) u3 C0 j8 W6 B6 w% t            stop_detected <= sda_rising  && (scl_d1 == 1'b1);+ T$ w- c4 A8 M4 {
 end5 k* e) g& t0 }
 end
 $ `& O5 e" L, _1 _3 i* m7 H3 r; C' Z/ s+ Q+ r3 J
 
 4 f% z) K0 X) u- Y1 O, fendmodule$ ~- O4 \  f, z- C. b6 R
 5 ~! [7 @! L, g" R2 c% J
 
  9 x- d0 e0 q  H% A
 : d6 Z1 U; q+ M8 {1 t' }# G
 | 
 |