I2C Slave Test - EDA Playground
Warning! This exercise has been opened in another tab; autosave has been disabled. Close this tab or refresh to reactivate.

 Languages & Libraries

 Tools & Simulators

 Examples

209


91
 
1
/**
2
Testing I2C Slace for reading/writing 8 bits of data only
3
*/
4
5
`timescale 1ns / 1ps
6
7
module Slave_TB ();
8
9
  reg clk;
10
  
11
  wire SDA;
12
  wire SCL;
13
  
14
  pullup(SDA);
15
  pullup(SCL);
16
  
17
  reg [6:0] addressToSend   = 7'b000_1000;  //8
18
  reg readWite              = 1'b1;         //write
19
  reg [7:0] dataToSend      = 8'b0110_0111; //103 = 0x67
20
  
21
  integer ii=0;
22
23
  initial begin
24
        clk = 0;
25
        force SCL = clk;
26
        forever begin
27
            clk = #1 ~clk;
28
            force SCL = clk;
29
        end     
30
    end
31
32
  
33
  Slave #() UUT
34
    (.SDA(SDA),
35
     .SCL(SCL));
36
37
  initial 
38
    begin
39
      $display("Starting Testbench...");
40
      
41
      clk = 0;
42
      force SCL = clk;
43
      
44
      #11
45
      
46
      // Set SDA Low to start
47
      force SDA = 0;
48
49
      // Write address
50
      for(ii=0; ii<7; ii=ii+1)
51
        begin
52
          $display("Address SDA %h to %h", SDA, addressToSend[ii]);
53
          #2 force SDA = addressToSend[ii];
54
        end
55
      
56
      // Are we wanting to read or write to/from the device?
57
      $display("Read/Write %h SDA: %h", readWite, SDA);
58
      #2 force SDA = readWite;
59
      
60
      // Next SDA will be driven by slave, so release it
61
      release SDA;
62
      
63
      $display("SDA: %h", SDA);
64
      #2; // Wait for ACK bit
65
      
66
      for(ii=0; ii<8; ii=ii+1)
67
        begin
68
          $display("Data SDA %h to %h", SDA, dataToSend[ii]);
69
          #2 force SDA = dataToSend[ii];
70
        end
71
      
72
      #2; // Wait for ACK bit
73
      
74
       // Next SDA will be driven by slave, so release it
75
      release SDA;
76
      
77
      // Force SDA high again, we are done
78
      #2 force SDA = 1;
79
80
      #100;
81
      $finish();
82
    end
83
  
84
  initial 
85
  begin
86
    // Required to dump signals to EPWave
87
    $dumpfile("dump.vcd");
88
    $dumpvars(0);
89
  end
90
  
91
endmodule
103
 
1
/**
2
I2C Slave to Read/Write 8 bits of data only
3
*/
4
5
`timescale 1ns / 1ps
6
7
module Slave(
8
    inout wire SDA,
9
    input wire SCL);
10
  
11
  reg [4:0] IDLE            = 4'b0000;
12
  reg [4:0] START           = 4'b0001;
13
  reg [4:0] READ_ADDRESS    = 4'b0010;
14
  reg [4:0] READ_WRITE      = 4'b0011;
15
  reg [4:0] DATA            = 4'b0100;
16
  reg [4:0] DATA_ACK        = 4'b0101;
17
  reg [4:0] STOP            = 4'b0110;
18
  reg [4:0] ADDRESS_ACK     = 4'b0111;
19
  
20
  reg [4:0] state           = 4'b0010;
21
  
22
  reg [6:0] slaveAddress    = 7'b000_1000;
23
  reg [6:0] addr            = 7'b000_0000;
24
  reg [6:0] addressCounter  = 7'b000_0000;
25
  
26
  reg [7:0] data            = 8'b0000_0000;
27
  reg [6:0] dataCounter     = 7'b000_0000;
28
  
29
  reg readWrite         = 1'b0;
30
  reg start             = 0;
31
  reg write_ack         = 0;
32
  
33
  assign SDA = (write_ack == 1) ? 0 : 'b1z;
34
  
35
  always @(negedge SDA) begin
36
    if ((start == 0) && (SCL == 1)) 
37
    begin
38
        start <= 1;
39
        addressCounter <= 0;
40
        dataCounter <= 0;
41
    end
42
  end
43
  
44
  always @(posedge SDA) begin
45
    if (state == DATA_ACK && SCL == 1)
46
      begin
47
        start <= 0;
48
        state <= READ_ADDRESS;
49
      end
50
    end
51
  
52
  always @(posedge SCL)
53
    begin
54
        if (start == 1)
55
        begin
56
          case (state)
57
            READ_ADDRESS: 
58
              begin
59
                addr[addressCounter] <= SDA;
60
                addressCounter <= addressCounter + 1;
61
                if (addressCounter == 6) 
62
                    begin
63
                     state <= READ_WRITE;
64
                   end
65
             end
66
           READ_WRITE:
67
             begin
68
                readWrite <= SDA;
69
                state <= ADDRESS_ACK;
70
              end
71
            ADDRESS_ACK:
72
              begin
73
                write_ack <= 1;
74
                state <= DATA;
75
              end
76
            DATA:
77
              begin
78
                write_ack <= 0;
79
                
80
                data[dataCounter] <= SDA;
81
                dataCounter <= dataCounter + 1;
82
                if (dataCounter == 8) 
83
                    begin
84
                     state <= DATA_ACK;
85
                      write_ack <= 1;
86
                   end
87
              end
88
            DATA_ACK:
89
             begin
90
               write_ack <= 0;
91
               state <= STOP;
92
              end
93
            STOP:
94
              begin
95
                start <= 0;
96
                state <= READ_ADDRESS;
97
              end
98
          endcase
99
        end
100
    end
101
    
102
  
103
endmodule
7606 views and 0 likes     
A short description will be helpful for you to remember your playground's details
 
100:0