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

Subversion Repositories i2c

[/] [i2c/] [tags/] [rel_1/] [rtl/] [verilog/] [i2c_master_bit_ctrl.v] - Diff between revs 24 and 27

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 24 Rev 27
Line 35... Line 35...
////                                                             ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
 
 
//  CVS Log
//  CVS Log
//
//
//  $Id: i2c_master_bit_ctrl.v,v 1.4 2002-10-30 18:10:07 rherveille Exp $
//  $Id: i2c_master_bit_ctrl.v,v 1.5 2002-11-30 22:24:40 rherveille Exp $
//
//
//  $Date: 2002-10-30 18:10:07 $
//  $Date: 2002-11-30 22:24:40 $
//  $Revision: 1.4 $
//  $Revision: 1.5 $
//  $Author: rherveille $
//  $Author: rherveille $
//  $Locker:  $
//  $Locker:  $
//  $State: Exp $
//  $State: Exp $
//
//
// Change History:
// Change History:
//               $Log: not supported by cvs2svn $
//               $Log: not supported by cvs2svn $
 
//               Revision 1.4  2002/10/30 18:10:07  rherveille
 
//               Fixed some reported minor start/stop generation timing issuess.
 
//
//               Revision 1.3  2002/06/15 07:37:03  rherveille
//               Revision 1.3  2002/06/15 07:37:03  rherveille
//               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
//               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
//
//
//               Revision 1.2  2001/11/05 11:59:25  rherveille
//               Revision 1.2  2001/11/05 11:59:25  rherveille
//               Fixed wb_ack_o generation bug.
//               Fixed wb_ack_o generation bug.
Line 195... Line 198...
        // detect stop condition => detect rising edge on SDA while SCL is high
        // detect stop condition => detect rising edge on SDA while SCL is high
        always @(posedge clk)
        always @(posedge clk)
          begin
          begin
              dSDA <= #1 sSDA; // generate a delayed version of sSDA
              dSDA <= #1 sSDA; // generate a delayed version of sSDA
 
 
              sta_condition <= #1 !sSDA &&  dSDA && sSCL;
              sta_condition <= #1 ~sSDA &  dSDA & sSCL;
              sto_condition <= #1  sSDA && !dSDA && sSCL;
              sto_condition <= #1  sSDA & ~dSDA & sSCL;
          end
          end
 
 
        // generate bus busy signal
        // generate bus busy signal
        always @(posedge clk or negedge nReset)
        always @(posedge clk or negedge nReset)
          if(!nReset)
          if(!nReset)
            busy <= #1 1'b0;
            busy <= #1 1'b0;
          else if (rst)
          else if (rst)
            busy <= #1 1'b0;
            busy <= #1 1'b0;
          else
          else
            busy <= #1 (sta_condition || busy) && !sto_condition;
            busy <= #1 (sta_condition | busy) & ~sto_condition;
 
 
 
 
        // generate statemachine
        // generate statemachine
 
 
        // nxt_state decoder
        // nxt_state decoder
Line 231... Line 234...
        parameter [16:0] wr_a    = 17'b0_0010_0000_0000_0000;
        parameter [16:0] wr_a    = 17'b0_0010_0000_0000_0000;
        parameter [16:0] wr_b    = 17'b0_0100_0000_0000_0000;
        parameter [16:0] wr_b    = 17'b0_0100_0000_0000_0000;
        parameter [16:0] wr_c    = 17'b0_1000_0000_0000_0000;
        parameter [16:0] wr_c    = 17'b0_1000_0000_0000_0000;
        parameter [16:0] wr_d    = 17'b1_0000_0000_0000_0000;
        parameter [16:0] wr_d    = 17'b1_0000_0000_0000_0000;
 
 
        reg [16:0] c_state, nxt_state; // synopsis enum_state
        reg [16:0] c_state; // synopsis enum_state
        reg icmd_ack, store_sda;
 
 
 
        always @(c_state or cmd)
 
          begin
 
              nxt_state  = c_state;
 
              icmd_ack   = 1'b0; // default no command acknowledge
 
              store_sda  = 1'b0;
 
 
 
              case (c_state) // synopsis full_case parallel_case
 
                // idle state
 
                idle:
 
                  case (cmd) // synopsis full_case parallel_case
 
                    `I2C_CMD_START:
 
                       nxt_state = start_a;
 
 
 
                    `I2C_CMD_STOP:
 
                       nxt_state = stop_a;
 
 
 
                    `I2C_CMD_WRITE:
 
                       nxt_state = wr_a;
 
 
 
                    `I2C_CMD_READ:
 
                       nxt_state = rd_a;
 
 
 
                    default:
 
                      nxt_state = idle;
 
 
 
                  endcase
 
 
 
                // start
 
                start_a:
 
                  nxt_state = start_b;
 
 
 
                start_b:
 
                  nxt_state = start_c;
 
 
 
                start_c:
 
                  nxt_state = start_d;
 
 
 
                start_d:
 
                  nxt_state = start_e;
 
 
 
                start_e:
 
                  begin
 
                      nxt_state = idle;
 
                      icmd_ack  = 1'b1;
 
                  end
 
 
 
                // stop
 
                stop_a:
 
                  nxt_state = stop_b;
 
 
 
                stop_b:
 
                  nxt_state = stop_c;
 
 
 
                stop_c:
 
                  nxt_state = stop_d;
 
 
 
                stop_d:
 
                  begin
 
                      nxt_state = idle;
 
                      icmd_ack  = 1'b1;
 
                  end
 
 
 
                // read
 
                rd_a:
 
                  nxt_state = rd_b;
 
 
 
                rd_b:
 
                  nxt_state = rd_c;
 
 
 
                rd_c:
 
                  begin
 
                      nxt_state = rd_d;
 
                      store_sda = 1'b1;
 
                  end
 
 
 
                rd_d:
 
                  begin
 
                      nxt_state = idle;
 
                      icmd_ack  = 1'b1;
 
                  end
 
 
 
                // write
 
                wr_a:
 
                  nxt_state = wr_b;
 
 
 
                wr_b:
 
                  nxt_state = wr_c;
 
 
 
                wr_c:
 
                  nxt_state = wr_d;
 
 
 
                wr_d:
 
                  begin
 
                      nxt_state = idle;
 
                      icmd_ack  = 1'b1;
 
                  end
 
 
 
              endcase
 
          end
 
 
 
 
 
        // generate registers
 
        always @(posedge clk or negedge nReset)
        always @(posedge clk or negedge nReset)
          if (!nReset)
          if (!nReset)
            begin
            begin
                c_state <= #1 idle;
                c_state <= #1 idle;
                cmd_ack <= #1 1'b0;
                cmd_ack <= #1 1'b0;
                dout    <= #1 1'b0;
                dout    <= #1 1'b0;
 
                scl_oen <= #1 1'b1;
 
                sda_oen <= #1 1'b1;
            end
            end
          else if (rst)
          else if (rst)
            begin
            begin
                c_state <= #1 idle;
                c_state <= #1 idle;
                cmd_ack <= #1 1'b0;
                cmd_ack <= #1 1'b0;
                dout    <= #1 1'b0;
                dout    <= #1 1'b0;
 
                scl_oen <= #1 1'b1;
 
                sda_oen <= #1 1'b1;
            end
            end
          else
          else
            begin
            begin
 
                cmd_ack   <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
 
 
                if (clk_en)
                if (clk_en)
 
                  case (c_state) // synopsis full_case parallel_case
 
                    // idle state
 
                    idle:
                  begin
                  begin
                      c_state <= #1 nxt_state;
                        case (cmd) // synopsis full_case parallel_case
                      if (store_sda)
                          `I2C_CMD_START:
                        dout <= #1 sSDA;
                             c_state <= #1 start_a;
                  end
 
 
 
                  cmd_ack <= #1 icmd_ack && clk_en;
                          `I2C_CMD_STOP:
            end
                             c_state <= #1 stop_a;
 
 
        //
                          `I2C_CMD_WRITE:
        // convert states to SCL and SDA signals
                             c_state <= #1 wr_a;
        //
 
 
 
        // assign scl and sda output (always gnd)
                          `I2C_CMD_READ:
        assign scl_o = 1'b0;
                             c_state <= #1 rd_a;
        assign sda_o = 1'b0;
 
 
 
        // assign scl and sda output_enables
                          default:
        always @(posedge clk or negedge nReset)
                            c_state <= #1 idle;
          if (!nReset)
                        endcase
            begin
 
                scl_oen <= #1 1'b1;
 
                sda_oen <= #1 1'b1;
 
            end
 
          else if (rst)
 
            begin
 
                scl_oen <= #1 1'b1;
 
                sda_oen <= #1 1'b1;
 
            end
 
          else if (clk_en)
 
            case (c_state) // synopsis full_case parallel_case
 
 
 
              // idle state
 
              idle:
 
                begin
 
                    scl_oen <= #1 scl_oen; // keep SCL in same state
                    scl_oen <= #1 scl_oen; // keep SCL in same state
                    sda_oen <= #1 sda_oen; // keep SDA in same state
                    sda_oen <= #1 sda_oen; // keep SDA in same state
                end
                end
 
 
              // start
              // start
              start_a:
              start_a:
                begin
                begin
 
                        c_state <= #1 start_b;
                    scl_oen <= #1 scl_oen; // keep SCL in same state
                    scl_oen <= #1 scl_oen; // keep SCL in same state
                    sda_oen <= #1 1'b1;    // set SDA high
                    sda_oen <= #1 1'b1;    // set SDA high
                end
                end
 
 
              start_b:
              start_b:
                begin
                begin
 
                        c_state <= #1 start_c;
                    scl_oen <= #1 1'b1; // set SCL high
                    scl_oen <= #1 1'b1; // set SCL high
                    sda_oen <= #1 1'b1; // keep SDA high
                    sda_oen <= #1 1'b1; // keep SDA high
                end
                end
 
 
              start_c:
              start_c:
                begin
                begin
 
                        c_state <= #1 start_d;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 1'b0; // set SDA low
                    sda_oen <= #1 1'b0; // set SDA low
                end
                end
 
 
              start_d:
              start_d:
                begin
                begin
 
                        c_state <= #1 start_e;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 1'b0; // keep SDA low
                    sda_oen <= #1 1'b0; // keep SDA low
                end
                end
 
 
              start_e:
              start_e:
                begin
                begin
 
                        c_state <= #1 idle;
 
                        cmd_ack <= #1 1'b1;
                    scl_oen <= #1 1'b0; // set SCL low
                    scl_oen <= #1 1'b0; // set SCL low
                    sda_oen <= #1 1'b0; // keep SDA low
                    sda_oen <= #1 1'b0; // keep SDA low
                end
                end
 
 
              // stop
              // stop
              stop_a:
              stop_a:
                begin
                begin
 
                        c_state <= #1 stop_b;
                    scl_oen <= #1 1'b0; // keep SCL low
                    scl_oen <= #1 1'b0; // keep SCL low
                    sda_oen <= #1 1'b0; // set SDA low
                    sda_oen <= #1 1'b0; // set SDA low
                end
                end
 
 
              stop_b:
              stop_b:
                begin
                begin
 
                        c_state <= #1 stop_c;
                    scl_oen <= #1 1'b1; // set SCL high
                    scl_oen <= #1 1'b1; // set SCL high
                    sda_oen <= #1 1'b0; // keep SDA low
                    sda_oen <= #1 1'b0; // keep SDA low
                end
                end
 
 
              stop_c:
              stop_c:
                begin
                begin
 
                        c_state <= #1 stop_d;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 1'b0; // keep SDA low
                    sda_oen <= #1 1'b0; // keep SDA low
                end
                end
 
 
              stop_d:
              stop_d:
                begin
                begin
 
                        c_state <= #1 idle;
 
                        cmd_ack <= #1 clk_en;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 1'b1; // set SDA high
                    sda_oen <= #1 1'b1; // set SDA high
                end
                end
 
 
              //write
                    // read
              wr_a:
                    rd_a:
                begin
                begin
 
                        c_state <= #1 rd_b;
                    scl_oen <= #1 1'b0; // keep SCL low
                    scl_oen <= #1 1'b0; // keep SCL low
                    sda_oen <= #1 din;  // set SDA
                        sda_oen <= #1 1'b1; // tri-state SDA
                end
                end
 
 
              wr_b:
                    rd_b:
                begin
                begin
 
                        c_state <= #1 rd_c;
                    scl_oen <= #1 1'b1; // set SCL high
                    scl_oen <= #1 1'b1; // set SCL high
                    sda_oen <= #1 din;  // keep SDA
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
                end
                end
 
 
              wr_c:
                    rd_c:
                begin
                begin
 
                        c_state <= #1 rd_d;
 
                        dout <= #1 sSDA;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 din;
                        sda_oen <= #1 1'b1;
                end
                end
 
 
              wr_d:
                    rd_d:
                begin
                begin
 
                        c_state <= #1 idle;
 
                        cmd_ack <= #1 clk_en;
                    scl_oen <= #1 1'b0; // set SCL low
                    scl_oen <= #1 1'b0; // set SCL low
                    sda_oen <= #1 din;
                        sda_oen <= #1 1'b1;
                end
                end
 
 
              // read
                    // write
              rd_a:
                    wr_a:
                begin
                begin
 
                        c_state <= #1 wr_b;
                    scl_oen <= #1 1'b0; // keep SCL low
                    scl_oen <= #1 1'b0; // keep SCL low
                    sda_oen <= #1 1'b1; // tri-state SDA
                        sda_oen <= #1 din;  // set SDA
                end
                end
 
 
              rd_b:
                    wr_b:
                begin
                begin
 
                        c_state <= #1 wr_c;
                    scl_oen <= #1 1'b1; // set SCL high
                    scl_oen <= #1 1'b1; // set SCL high
                    sda_oen <= #1 1'b1; // keep SDA tri-stated
                        sda_oen <= #1 din;  // keep SDA
                end
                end
 
 
              rd_c:
                    wr_c:
                begin
                begin
 
                        c_state <= #1 wr_d;
                    scl_oen <= #1 1'b1; // keep SCL high
                    scl_oen <= #1 1'b1; // keep SCL high
                    sda_oen <= #1 1'b1;
                        sda_oen <= #1 din;
                end
                end
 
 
              rd_d:
                    wr_d:
                begin
                begin
 
                        c_state <= #1 idle;
 
                        cmd_ack <= #1 1'b1;
                    scl_oen <= #1 1'b0; // set SCL low
                    scl_oen <= #1 1'b0; // set SCL low
                    sda_oen <= #1 1'b1;
                        sda_oen <= #1 din;
                end
                end
 
 
        endcase
        endcase
 
            end
 
 
 
 
 
        // assign scl and sda output (always gnd)
 
        assign scl_o = 1'b0;
 
        assign sda_o = 1'b0;
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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