I2C Verilog的实现(一)

  1. <span style="font-size:14px;">`timescale 1ns / 1ps  
  2. module test(  
  3. sda  
  4. );  
  5.   
  6.     reg scl;  
  7.     inout sda;  
  8.     reg sda_out;  
  9.     wire    sda_in;  
  10.     reg [7:0]   data;  
  11.       
  12.     reg start_flag, stop_flag;  
  13.       
  14.     assign sda = sda_out ? 1'bz : 1'b0;  
  15.     assign sda_in = sda;  
  16.     pullup( sda );  
  17.       
  18.       
  19.     I2CTEST testmine(.SDA(sda), .SCL(scl));  
  20.   
  21.     initial  
  22.         begin  
  23.            scl = 0;  
  24.             sda_out = 0;  
  25.             data = 8'h27;  
  26.             start_flag = 0;  
  27.             #160000;  
  28.             start ( );  
  29.         end  
  30.       
  31.     always   
  32.     begin  
  33.        #50000 scl = ~scl;  
  34.    end  
  35.       
  36.     always @ (posedge start_flag)  
  37.     begin  
  38.        repeat (8)  
  39.           begin  
  40.              wait ( scl == 0 );  
  41.                 #20000;  
  42.                 sda_out = data[7];  
  43.                 #40000;  
  44.                 data = data <1;  
  45.             end  
  46.             wait (~ scl);  
  47.             #20000;  
  48.             sda_out = 1;  
  49.             #160000;  
  50.             stop ( );  
  51.     end   
  52.       
  53.     always @ ( posedge stop_flag)  
  54.     begin  
  55. //     sda_out = 0;  
  56. //     #50000;  
  57.        sda_out = 1;  
  58.     end     
  59.   
  60.       
  61.     task start;     
  62.     begin  
  63.         wait (scl == 0);  
  64.         #20000;  
  65.         sda_out = 1;  
  66.         wait ( scl == 1 );  
  67.         #20000;  
  68.         sda_out = 0;  
  69.         start_flag = 1;  
  70.     end  
  71.     endtask  
  72.           
  73.     task stop;  
  74.     begin  
  75.         wait ( scl == 0 );  
  76.         #20000;  
  77.         sda_out = 0;  
  78.         wait ( scl ==1 );  
  79.         #20000;  
  80.         sda_out = 1;  
  81.         stop_flag = 1;  
  82.         end  
  83.     endtask  
  84.           
  85. endmodule</span>  



I2C程序

[html] view plaincopy
 
    1. <span style="font-family:Arial;">`timescale 1ns / 1ps  
    2. module I2CTEST(  
    3. SDA, SCL  
    4. );  
    5.   
    6. input SCL;  
    7. inout SDA;  
    8.   
    9. // The 7-bits address that we want for our I2C slave  
    10. parameter I2C_ADR = 7'h13;  
    11.   
    12. //---------------------------------------------  
    13. //start,stop condition judgement  
    14. //---------------------------------------------  
    15. wire start, stop;  
    16. reg sda1, sda2;  
    17. reg sda11;  
    18.   
    19. always @ ( posedge SCL )  
    20. sda1 <= SDA;  
    21.   
    22. always @ ( negedge SCL )  
    23. sda2 <= SDA;  
    24.   
    25. always @ ( negedge SCL )  
    26. sda11 <= sda1;  
    27.   
    28.   
    29. assign start = sda11 & (!sda2);  
    30. assign stop = sda2 & ( !sda11 );  
    31.   
    32.   
    33. //----------------------------------------------  
    34. //count setting  
    35. //----------------------------------------------  
    36. reg [3:0]  bitcont;  
    37. wire bit_ack = bitcont[3];  
    38.   
    39. always @ ( posedge SCL or posedge start)  
    40. begin  
    41.     if ( start )  
    42.     bitcont <=  4'h6;  
    43.     else  
    44.     begin  
    45.         if (bit_ack)  
    46.         bitcont <= 4'h6;  
    47.         else  
    48.         bitcont <= bitcont -4'h1;  
    49.     end  
    50. end  
    51.   
    52.   
    53.   
    54. //-------------------------------------  
    55. //get sda using posedge scl  
    56. //-------------------------------------  
    57.   
    58. reg sdar;  
    59.   
    60. always @ ( posedge SCL ) sdar <= SDA;  
    61.   
    62. //----------------------------------------  
    63. //address match  
    64. //----------------------------------------  
    65.   
    66. reg addr_match, op_read;  
    67.   
    68. always @ ( negedge SCL or posedge start )  
    69. begin  
    70.     if ( start )  
    71.     begin  
    72.         addr_match <= 1'h1;  
    73.         op_read <= 1'h0;  
    74.     end  
    75.     else  
    76.     begin  
    77.         if( (bitcont == 6) & (sdar != I2C_ADR[6])) addr_match <= 1'h0;  
    78.         if( (bitcont == 5) & (sdar != I2C_ADR[5])) addr_match <= 1'h0;  
    79.         if( (bitcont == 4) & (sdar != I2C_ADR[4])) addr_match <= 1'h0;  
    80.         if( (bitcont == 3) & (sdar != I2C_ADR[3])) addr_match <= 1'h0;  
    81.         if( (bitcont == 2) & (sdar != I2C_ADR[2])) addr_match <= 1'h0;  
    82.         if( (bitcont == 1) & (sdar != I2C_ADR[1])) addr_match <= 1'h0;  
    83.         if( (bitcont == 0) & (sdar != I2C_ADR[0])) addr_match <= 1'h0;  
    84.         if( bitcont == 0 ) op_read <= sdar;  
    85.     end  
    86. end  
    87.   
    88. //-----------------------------------------------------------------------  
    89. //send ack  
    90. //-----------------------------------------------------------------------  
    91.   
    92. reg ack_assert;  
    93.   
    94. always @ ( negedge SCL )  
    95. begin  
    96.     if ( bit_ack & addr_match & op_read )  
    97.     ack_assert <= 1'h1;  
    98.     else  
    99.     ack_assert <= 1'h0;  
    100. end  
    101.   
    102. //-------------------------------------------------------------------------  
    103. //control SDA line  
    104. //-------------------------------------------------------------------------  
    105.   
    106. assign SDA = ack_assert ? 1'h0 : 1'hz;  
    107. pullup ( SDA );  
    108.   
    109. endmodule
原文地址:https://www.cnblogs.com/hfyfpga/p/4281323.html