OpenCores
URL https://opencores.org/ocsvn/i2c_to_wb/i2c_to_wb/trunk

Subversion Repositories i2c_to_wb

[/] [i2c_to_wb/] [trunk/] [src/] [i2c_to_wb_fsm.v] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
 
`include "timescale.v"
 
 
module
  i2c_to_wb_fsm
  (
    input         i2c_data,
    input         i2c_data_rise,
    input         i2c_data_fall,
 
    input         i2c_clk,
    input         i2c_clk_rise,
    input         i2c_clk_fall,
 
    input         i2c_bit_7,
    output        i2c_ack_done, 
 
    output        tip_addr_byte, 
//     output        tip_byte, 
    output        tip_read_byte, 
    output        tip_write_byte, 
    output        tip_wr_ack, 
    output        tip_rd_ack, 
    output        tip_addr_ack, 
//     output        tip_ack, 
//     output        tip_write, 
//     output        tip_read, 
 
    output  [7:0] state_out,
 
    input         wb_clk_i, 
    input         wb_rst_i  
  );
 
  // --------------------------------------------------------------------
  //  wires
  wire xmt_byte_done;
 
//   wire i2c_read  = 1'b0;
//   wire i2c_ack_done;
  wire i2c_address_hit = 1'b1;
 
  wire tip_ack;
 
 
  // --------------------------------------------------------------------
  //  start & stop 
 
  wire start_detected = i2c_data_fall & i2c_clk;
  wire stop_detected  = i2c_data_rise & i2c_clk;
 
 
  // --------------------------------------------------------------------
  //  state machine
 
  localparam   STATE_IDLE       = 8'b00000001;
  localparam   STATE_ADDR_BYTE  = 8'b00000010;
  localparam   STATE_ADDR_ACK   = 8'b00000100;
  localparam   STATE_WRITE      = 8'b00001000;
  localparam   STATE_WR_ACK     = 8'b00010000;
  localparam   STATE_READ       = 8'b00100000;
  localparam   STATE_RD_ACK     = 8'b01000000;
  localparam   STATE_ERROR      = 8'b10000000;
 
  reg [7:0] state;
  reg [7:0] next_state;
 
  always @(posedge wb_clk_i or posedge wb_rst_i)
    if(wb_rst_i)
      state <= STATE_IDLE;
    else
      state <= next_state;
 
  always @(*)
    case( state )
      STATE_IDLE:       if( start_detected )
                          next_state = STATE_ADDR_BYTE;
                        else
                          next_state = STATE_IDLE;                              
 
      STATE_ADDR_BYTE:  if( xmt_byte_done )
                          if( i2c_address_hit )
                            next_state = STATE_ADDR_ACK;
                          else
                            next_state = STATE_IDLE;
                        else if( start_detected | stop_detected )
                          next_state = STATE_ERROR;
                        else  
                          next_state = STATE_ADDR_BYTE;
 
      STATE_ADDR_ACK:   if( i2c_ack_done )
                          if( i2c_bit_7 )
                            next_state = STATE_READ;
                          else
                            next_state = STATE_WRITE;
                        else if( start_detected | stop_detected )
                          next_state = STATE_ERROR;
                        else
                          next_state = STATE_ADDR_ACK;
 
      STATE_WRITE:      if( xmt_byte_done )
                          next_state = STATE_WR_ACK;
                        else if( start_detected )
                          next_state = STATE_ADDR_BYTE;
                        else if( stop_detected )
                          next_state = STATE_IDLE;
                        else
                          next_state = STATE_WRITE;
 
      STATE_WR_ACK:     if( i2c_ack_done )
                          next_state = STATE_WRITE;  
                        else if( start_detected | stop_detected )
                          next_state = STATE_ERROR;
                        else
                          next_state = STATE_WR_ACK;
 
      STATE_READ:       if( xmt_byte_done )
                          next_state = STATE_RD_ACK;
                        else if( start_detected )
                          next_state = STATE_ADDR_BYTE;
                        else if( stop_detected )
                          next_state = STATE_IDLE;
                        else
                          next_state = STATE_READ;
 
      STATE_RD_ACK:     if( i2c_ack_done )
                          next_state = STATE_READ;  
                        else if( start_detected | stop_detected )
                          next_state = STATE_ERROR;
                        else
                          next_state = STATE_RD_ACK;
 
      STATE_ERROR:      next_state = STATE_IDLE;
 
      default:          next_state = STATE_ERROR;
    endcase
 
 
  // --------------------------------------------------------------------
  //  bit counter 
  reg [3:0] bit_count;
 
  assign  xmt_byte_done = (bit_count == 4'h7) & i2c_clk_rise; 
  assign  tip_ack       = (bit_count == 4'h8);
  assign  i2c_ack_done  = tip_ack & i2c_clk_rise;
 
  always @(posedge wb_clk_i)
    if( wb_rst_i | i2c_ack_done | start_detected )
      bit_count <= 4'hf;
    else if( i2c_clk_fall )
      bit_count <= bit_count + 1;
 
 
// --------------------------------------------------------------------
//  outputs
 
  assign state_out = state;
 
  assign  tip_addr_byte   = (state == STATE_ADDR_BYTE);
  assign  tip_addr_ack    = (state == STATE_ADDR_ACK);
  assign  tip_read_byte   = (state == STATE_READ);
  assign  tip_write_byte  = tip_addr_byte               | (state == STATE_WRITE);
  assign  tip_wr_ack      = tip_addr_ack                | (state == STATE_WR_ACK);
  assign  tip_rd_ack      = (state == STATE_RD_ACK);
//   assign  tip_byte        = tip_write_byte              | tip_read_byte;
//   assign  tip_write       = tip_write_byte              | tip_wr_ack;
//   assign  tip_read        = tip_read_byte               | tip_rd_ack;
 
endmodule
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.