Verilog I2C Master Acknowledment on Spartixed
The Spartixed board has a I2C EEPROM hooked to the Spartan 6. The section of the schematics is shown below
In this section we will write a small code, that will try to detect the presence of the CAT24C08YI-GT3 EEPROM but looking for the acknowledgement signal. If we get an acknowledgement signal when trying to send the I2C address of the EEPRPOM, it will glow an LED, otherwise now. We will test this by sending a wrong I2C device address to make sure that the LED indeed does not glow when the wrong I2C address is sent.
So here is the code that initiates Spartan6 in master mode and looks for ack signal
// i2c Bus Master // This will verify the i2c bus acknowledgement on spartixed board // For details please see referencedesigner.com module i2c (input clk, reset, button_sw3 , output scl, led2,i2c_wp , inout sda ); reg start; reg [7:0] data; reg led_output; reg clk_track; // For simulation use below //reg [2:0] counter; // Actual for division by 1024 reg [9:0] counter; always @(posedge clk, negedge reset ) //always @(posedge clk ) begin if (~reset) begin counter <= 0; end else begin counter <= counter +1; // Use this for simulation // clk_track<= counter[2]; // Division by 8 clk_track <= counter[9]; // Division by 1024 end end wire serclock = (counter ==256); wire sernegclock =(counter ==768); assign scl = ~clk_track; assign i2c_wp= 1'b0; reg [3:0] state; always @(posedge clk) begin case (state) 4'b0000: if (start) state <= 4'b0001; 4'b0001: if (serclock) state <= 4'b0010; // Start bit 4'b0010: if (sernegclock) state <= 4'b0011; // Bit 7 4'b0011: if (sernegclock) state <= 4'b0100; // Bit 6 4'b0100: if (sernegclock) state <= 4'b0101; // Bit 5 4'b0101: if (sernegclock) state <= 4'b0110; // Bit 4 4'b0110: if (sernegclock) state <= 4'b0111; // Bit 3 4'b0111: if (sernegclock) state <= 4'b1000; // Bit 2 4'b1000: if (sernegclock) state <= 4'b1001; // Bit 1 4'b1001: if (sernegclock) state <= 4'b1010; // Bit 0 4'b1010: if (serclock) state <= 4'b1011; // Release Bus 4'b1011: if (sernegclock) state <= 4'b1100; // Read Acknowledgement 4'b1100: if (serclock) state <= 4'b0000; // default: state <= 4'b0000; // Undefined, skip to stop endcase end reg outbit; always @(posedge clk) begin case (state) 4'b0000: outbit <= 1'bz; // idle - May be assign like this outbit <= 1'bz; 4'b0001: outbit <= 1'bz; // 4'b0010: outbit <= 1'b0; // Start Bit 4'b0011: outbit <= data[7]; // Bit 7 4'b0100: outbit <= data[6]; // Bit 6 4'b0101: outbit <= data[5]; // Bit 5 4'b0110: outbit <= data[4]; // Bit 4 4'b0111: outbit <= data[3]; // Bit 3 4'b1000: outbit <= data[2]; // Bit 2 4'b1001: outbit <= data[1]; // Bit 1 4'b1010: outbit <= data[0]; // Bit 0 4'b1011: outbit <= 1'bz; // Release Bus 4'b1100: led_output<= sda; // Read the SDA line default: outbit <= 1'bz; // Bad state output idle better outbit <= 1'bz; endcase end // Output register to pin assign sda = outbit; assign led2 = ~led_output; reg delay_reg ; always @(posedge clk, negedge reset) //always @(posedge clk_track, negedge reset) if ( reset == 0) begin // Correct Address for the I2C EEPROM data <= 8'b10100001; // 1010 is device address, last is 0 means write operation, 1 means read operation // Wrong Address to test // data <= 8'b10101101; // 1010 is device address, last is 0 means write operation, 1 means read operation delay_reg <= 0; //start <=0; start <=1; end else begin delay_reg <= button_sw3 ; start <= (delay_reg) & (~button_sw3); end endmodule |
The image shows the screen shot captured on the Spartixed board.
The video about this post is coming soon.
Following ucf file is used.
NET "scl" LOC = P78; NET "sda" LOC = P79; NET "led2" LOC = P131; NET "reset" LOC = P88; // Moved to new Pin as the original not working NET "clk" LOC = P55; NET "button_sw3" LOC = P126; NET "i2c_wp" LOC = P75; |
Suggested Exercises
1. Try to write a byte and then read the byte and then displat it on 7 segment display.