I2C Verilog的实现(一)

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

I2C程序

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