Commit f8eca99e authored by Andrey Filippov's avatar Andrey Filippov
Browse files

simulating/debugging modified i2c sequencer

parent 74db68c1
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -352,10 +352,24 @@
        parameter SENSI2C_CMD_RESET =       14, // [14]   reset all FIFO (takes 16 clock pulses), also - stops i2c until run command
        parameter SENSI2C_CMD_RUN =         13, // [13:12]3 - run i2c, 2 - stop i2c (needed before software i2c), 1,0 - no change to run state
        parameter SENSI2C_CMD_RUN_PBITS =    1,
        parameter SENSI2C_CMD_FIFO_RD =      3, // advane I2C read data FIFO by 1  
        parameter SENSI2C_CMD_FIFO_RD =      3, // advance I2C read data FIFO by 1  
        parameter SENSI2C_CMD_ACIVE =        2, // [2] - SENSI2C_CMD_ACIVE_EARLY0, SENSI2C_CMD_ACIVE_SDA
        parameter SENSI2C_CMD_ACIVE_EARLY0 = 1, // release SDA==0 early if next bit ==1
        parameter SENSI2C_CMD_ACIVE_SDA =    0,  // drive SDA=1 during the second half of SCL=1
    //i2c page table bit fields
        parameter SENSI2C_TBL_RAH =          0, // high byte of the register address 
        parameter SENSI2C_TBL_RAH_BITS =     8,
        parameter SENSI2C_TBL_RNWREG =       8, // read register (when 0 - write register
        parameter SENSI2C_TBL_SA =           9, // Slave address in write mode
        parameter SENSI2C_TBL_SA_BITS =      7,
        parameter SENSI2C_TBL_NBWR =        16, // number of bytes to write (1..10)
        parameter SENSI2C_TBL_NBWR_BITS =    4,
        parameter SENSI2C_TBL_NBRD =        16, // number of bytes to read (1 - 8) "0" means "8"
        parameter SENSI2C_TBL_NBRD_BITS =    3,
        parameter SENSI2C_TBL_NABRD =       19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
        parameter SENSI2C_TBL_DLY =         20, // bit delay (number of mclk periods in 1/4 of SCL period)
        parameter SENSI2C_TBL_DLY_BITS=      8,
        
      
      parameter SENSI2C_STATUS =        'h1,
    
+26 −0
Original line number Diff line number Diff line
@@ -73,6 +73,20 @@ module sensor_channel#(
        parameter SENSI2C_CMD_ACIVE_EARLY0 = 1, // release SDA==0 early if next bit ==1
        parameter SENSI2C_CMD_ACIVE_SDA =    0,  // drive SDA=1 during the second half of SCL=1
        
    //i2c page table bit fields
        parameter SENSI2C_TBL_RAH =          0, // high byte of the register address 
        parameter SENSI2C_TBL_RAH_BITS =     8,
        parameter SENSI2C_TBL_RNWREG =       8, // read register (when 0 - write register
        parameter SENSI2C_TBL_SA =           9, // Slave address in write mode
        parameter SENSI2C_TBL_SA_BITS =      7,
        parameter SENSI2C_TBL_NBWR =        16, // number of bytes to write (1..10)
        parameter SENSI2C_TBL_NBWR_BITS =    4,
        parameter SENSI2C_TBL_NBRD =        16, // number of bytes to read (1 - 8) "0" means "8"
        parameter SENSI2C_TBL_NBRD_BITS =    3,
        parameter SENSI2C_TBL_NABRD =       19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
        parameter SENSI2C_TBL_DLY =         20, // bit delay (number of mclk periods in 1/4 of SCL period)
        parameter SENSI2C_TBL_DLY_BITS=      8,
      
      parameter SENSI2C_STATUS =        'h1,
    
    parameter SENS_GAMMA_RADDR =       'h38, //4,  'h38..'h3b
@@ -493,6 +507,18 @@ module sensor_channel#(
        .SENSI2C_CMD_ACIVE       (SENSI2C_CMD_ACIVE),
        .SENSI2C_CMD_ACIVE_EARLY0(SENSI2C_CMD_ACIVE_EARLY0),
        .SENSI2C_CMD_ACIVE_SDA   (SENSI2C_CMD_ACIVE_SDA),
        .SENSI2C_TBL_RAH         (SENSI2C_TBL_RAH), // high byte of the register address 
        .SENSI2C_TBL_RAH_BITS    (SENSI2C_TBL_RAH_BITS),
        .SENSI2C_TBL_RNWREG      (SENSI2C_TBL_RNWREG), // read register (when 0 - write register
        .SENSI2C_TBL_SA          (SENSI2C_TBL_SA), // Slave address in write mode
        .SENSI2C_TBL_SA_BITS     (SENSI2C_TBL_SA_BITS),
        .SENSI2C_TBL_NBWR        (SENSI2C_TBL_NBWR), // number of bytes to write (1..10)
        .SENSI2C_TBL_NBWR_BITS   (SENSI2C_TBL_NBWR_BITS),
        .SENSI2C_TBL_NBRD        (SENSI2C_TBL_NBRD), // number of bytes to read (1 - 8) "0" means "8"
        .SENSI2C_TBL_NBRD_BITS   (SENSI2C_TBL_NBRD_BITS),
        .SENSI2C_TBL_NABRD       (SENSI2C_TBL_NABRD), // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
        .SENSI2C_TBL_DLY         (SENSI2C_TBL_DLY),   // bit delay (number of mclk periods in 1/4 of SCL period)
        .SENSI2C_TBL_DLY_BITS    (SENSI2C_TBL_DLY_BITS),
        .SENSI2C_DRIVE           (SENSI2C_DRIVE),
        .SENSI2C_IBUF_LOW_PWR    (SENSI2C_IBUF_LOW_PWR),
        .SENSI2C_IOSTANDARD      (SENSI2C_IOSTANDARD),
+30 −3
Original line number Diff line number Diff line
@@ -39,7 +39,21 @@ module sensor_i2c#(
    parameter SENSI2C_CMD_FIFO_RD =      3, // advane I2C read data FIFO by 1  
    parameter SENSI2C_CMD_ACIVE =        2, // [2] - SENSI2C_CMD_ACIVE_EARLY0, SENSI2C_CMD_ACIVE_SDA
    parameter SENSI2C_CMD_ACIVE_EARLY0 = 1, // release SDA==0 early if next bit ==1
    parameter SENSI2C_CMD_ACIVE_SDA =    0  // drive SDA=1 during the second half of SCL=1
    parameter SENSI2C_CMD_ACIVE_SDA =    0,  // drive SDA=1 during the second half of SCL=1

    //i2c page table bit fields
    parameter SENSI2C_TBL_RAH =          0, // high byte of the register address 
    parameter SENSI2C_TBL_RAH_BITS =     8,
    parameter SENSI2C_TBL_RNWREG =       8, // read register (when 0 - write register
    parameter SENSI2C_TBL_SA =           9, // Slave address in write mode
    parameter SENSI2C_TBL_SA_BITS =      7,
    parameter SENSI2C_TBL_NBWR =        16, // number of bytes to write (1..10)
    parameter SENSI2C_TBL_NBWR_BITS =    4,
    parameter SENSI2C_TBL_NBRD =        16, // number of bytes to read (1 - 8) "0" means "8"
    parameter SENSI2C_TBL_NBRD_BITS =    3,
    parameter SENSI2C_TBL_NABRD =       19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
    parameter SENSI2C_TBL_DLY =         20, // bit delay (number of mclk periods in 1/4 of SCL period)
    parameter SENSI2C_TBL_DLY_BITS=      8
)(
    input         mrst,         // @ posedge mclk
    input         mclk,         // global clock, half DDR3 clock, synchronizes all I/O through the command port
@@ -304,7 +318,7 @@ module sensor_i2c#(
      if      (reset_cmd || page_r_inc[0])  rpointer[5:0] <= 6'h0;
      else if (i2c_run_d && ! i2c_run)      rpointer[5:0] <= rpointer[5:0] + 1;

      i2c_start <= i2c_enrun && !i2c_run && !i2c_start && (rpointer[5:0]!= fifo_wr_pointers_outr_r[5:0]) && !(|page_r_inc);
      i2c_start <= i2c_enrun && !i2c_run && !i2c_run_d && !i2c_start && (rpointer[5:0]!= fifo_wr_pointers_outr_r[5:0]) && !(|page_r_inc);
      page_r_inc[1:0] <= {page_r_inc[0],
                           !i2c_run &&                              // not i2c in progress
                           !page_r_inc[0] &&                        // was not incrementing in previous cycle
@@ -326,7 +340,20 @@ module sensor_i2c#(
     
    end
    
    sensor_i2c_prot sensor_i2c_prot_i (
    sensor_i2c_prot  #(
        .SENSI2C_TBL_RAH         (SENSI2C_TBL_RAH), // high byte of the register address 
        .SENSI2C_TBL_RAH_BITS    (SENSI2C_TBL_RAH_BITS),
        .SENSI2C_TBL_RNWREG      (SENSI2C_TBL_RNWREG), // read register (when 0 - write register
        .SENSI2C_TBL_SA          (SENSI2C_TBL_SA), // Slave address in write mode
        .SENSI2C_TBL_SA_BITS     (SENSI2C_TBL_SA_BITS),
        .SENSI2C_TBL_NBWR        (SENSI2C_TBL_NBWR), // number of bytes to write (1..10)
        .SENSI2C_TBL_NBWR_BITS   (SENSI2C_TBL_NBWR_BITS),
        .SENSI2C_TBL_NBRD        (SENSI2C_TBL_NBRD), // number of bytes to read (1 - 8) "0" means "8"
        .SENSI2C_TBL_NBRD_BITS   (SENSI2C_TBL_NBRD_BITS),
        .SENSI2C_TBL_NABRD       (SENSI2C_TBL_NABRD), // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
        .SENSI2C_TBL_DLY         (SENSI2C_TBL_DLY),   // bit delay (number of mclk periods in 1/4 of SCL period)
        .SENSI2C_TBL_DLY_BITS    (SENSI2C_TBL_DLY_BITS)
    ) sensor_i2c_prot_i(
        .mrst            (mrst),            // input
        .mclk            (mclk),            // input
        .i2c_rst         (reset_cmd),       // input
+26 −2
Original line number Diff line number Diff line
@@ -40,6 +40,19 @@ module sensor_i2c_io#(
    parameter SENSI2C_CMD_ACIVE =        2, // [2] - SENSI2C_CMD_ACIVE_EARLY0, SENSI2C_CMD_ACIVE_SDA
    parameter SENSI2C_CMD_ACIVE_EARLY0 = 1, // release SDA==0 early if next bit ==1
    parameter SENSI2C_CMD_ACIVE_SDA =    0,  // drive SDA=1 during the second half of SCL=1
    //i2c page table bit fields
    parameter SENSI2C_TBL_RAH =          0, // high byte of the register address 
    parameter SENSI2C_TBL_RAH_BITS =     8,
    parameter SENSI2C_TBL_RNWREG =       8, // read register (when 0 - write register
    parameter SENSI2C_TBL_SA =           9, // Slave address in write mode
    parameter SENSI2C_TBL_SA_BITS =      7,
    parameter SENSI2C_TBL_NBWR =        16, // number of bytes to write (1..10)
    parameter SENSI2C_TBL_NBWR_BITS =    4,
    parameter SENSI2C_TBL_NBRD =        16, // number of bytes to read (1 - 8) "0" means "8"
    parameter SENSI2C_TBL_NBRD_BITS =    3,
    parameter SENSI2C_TBL_NABRD =       19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
    parameter SENSI2C_TBL_DLY =         20, // bit delay (number of mclk periods in 1/4 of SCL period)
    parameter SENSI2C_TBL_DLY_BITS=      8,
// I/O parameters   
    parameter integer SENSI2C_DRIVE = 12,
    parameter SENSI2C_IBUF_LOW_PWR = "TRUE",
@@ -81,8 +94,19 @@ module sensor_i2c_io#(
        .SENSI2C_CMD_FIFO_RD     (SENSI2C_CMD_FIFO_RD),
        .SENSI2C_CMD_ACIVE       (SENSI2C_CMD_ACIVE),
        .SENSI2C_CMD_ACIVE_EARLY0(SENSI2C_CMD_ACIVE_EARLY0),
        .SENSI2C_CMD_ACIVE_SDA   (SENSI2C_CMD_ACIVE_SDA)
        
        .SENSI2C_CMD_ACIVE_SDA   (SENSI2C_CMD_ACIVE_SDA),
        .SENSI2C_TBL_RAH         (SENSI2C_TBL_RAH), // high byte of the register address 
        .SENSI2C_TBL_RAH_BITS    (SENSI2C_TBL_RAH_BITS),
        .SENSI2C_TBL_RNWREG      (SENSI2C_TBL_RNWREG), // read register (when 0 - write register
        .SENSI2C_TBL_SA          (SENSI2C_TBL_SA), // Slave address in write mode
        .SENSI2C_TBL_SA_BITS     (SENSI2C_TBL_SA_BITS),
        .SENSI2C_TBL_NBWR        (SENSI2C_TBL_NBWR), // number of bytes to write (1..10)
        .SENSI2C_TBL_NBWR_BITS   (SENSI2C_TBL_NBWR_BITS),
        .SENSI2C_TBL_NBRD        (SENSI2C_TBL_NBRD), // number of bytes to read (1 - 8) "0" means "8"
        .SENSI2C_TBL_NBRD_BITS   (SENSI2C_TBL_NBRD_BITS),
        .SENSI2C_TBL_NABRD       (SENSI2C_TBL_NABRD), // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
        .SENSI2C_TBL_DLY         (SENSI2C_TBL_DLY),   // bit delay (number of mclk periods in 1/4 of SCL period)
        .SENSI2C_TBL_DLY_BITS    (SENSI2C_TBL_DLY_BITS)
    ) sensor_i2c_i (
        .mrst          (mrst),         // input
        .mclk          (mclk),         // input
+52 −27
Original line number Diff line number Diff line
@@ -20,7 +20,20 @@
 *******************************************************************************/
`timescale 1ns/1ps

module  sensor_i2c_prot(
module  sensor_i2c_prot#(
    parameter SENSI2C_TBL_RAH =          0, // high byte of the register address 
    parameter SENSI2C_TBL_RAH_BITS =     8,
    parameter SENSI2C_TBL_RNWREG =       8, // read register (when 0 - write register
    parameter SENSI2C_TBL_SA =           9, // Slave address in write mode
    parameter SENSI2C_TBL_SA_BITS =      7,
    parameter SENSI2C_TBL_NBWR =        16, // number of bytes to write (1..10)
    parameter SENSI2C_TBL_NBWR_BITS =    4,
    parameter SENSI2C_TBL_NBRD =        16, // number of bytes to read (1 - 8) "0" means "8"
    parameter SENSI2C_TBL_NBRD_BITS =    3,
    parameter SENSI2C_TBL_NABRD =       19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
    parameter SENSI2C_TBL_DLY =         20, // bit delay (number of mclk periods in 1/4 of SCL period)
    parameter SENSI2C_TBL_DLY_BITS=      8
)(
    input            mrst,         // @ posedge mclk
    input            mclk,         // global clock
    input            i2c_rst,
@@ -83,6 +96,7 @@ module sensor_i2c_prot(
    reg           run_extra_wr_d;  // any of run_extra_wr bits, delayed by 1
    reg           run_any_d;       // any of command states, delayed by 1
    reg    [1:0]  pre_cmd;         // from i2c_start until run_any_d will be active
    reg           first_mem_re;
//    reg           i2c_done;
//    wire          i2c_next_byte;
    reg    [ 2:0] mem_re;
@@ -92,13 +106,13 @@ module sensor_i2c_prot(
//    reg           read_mem_msb;
//    wire          decode_reg_rd = &seq_rd[7:4];
//    wire          start_wr_seq_w = !run_extra_wr_d && !decode_reg_rd && read_mem_msb;
    wire          start_wr_seq_w = table_re[2] && !tdout[8];
    wire          start_rd_seq_w = table_re[2] &&  tdout[8];
    wire          start_wr_seq_w = table_re[2] && !tdout[SENSI2C_TBL_RNWREG];
    wire          start_rd_seq_w = table_re[2] &&  tdout[SENSI2C_TBL_RNWREG];
    wire          start_extra_seq_w = i2c_start && (bytes_left_send !=0);
    
    wire          snd_start_w = run_reg_wr[6] || 1'b0; // add start & restart of read
    wire          snd_stop_w =  run_reg_wr[0] || 1'b0; // add stop of read
    wire          snd9_w     =  (|run_reg_wr[5:1]) || 1'b0; // add for read and extra write;
 //   wire          snd_start_w = run_reg_wr[6] || 1'b0; // add start & restart of read
 //   wire          snd_stop_w =  run_reg_wr[0] || 1'b0; // add stop of read
 //   wire          snd9_w     =  (|run_reg_wr[5:1]) || 1'b0; // add for read and extra write;

    reg           snd_start;
    reg           snd_stop;
@@ -129,7 +143,7 @@ module sensor_i2c_prot(
    wire   [ 3:0] initial_address_w =  bytes_left_send - 1; // if bytes left to send == 0 - will be 3                      
    wire          unused;            // unused ackn signal SuppressThisWarning VEditor
    
    wire          pre_table_re = !run_extra_wr_d && (&seq_mem_ra[1:0]) && mem_re[1];
    wire          pre_table_re = !run_extra_wr_d && first_mem_re && mem_re[1];
    
    
      
@@ -140,6 +154,10 @@ module sensor_i2c_prot(
        
        run_any_d <= (|run_reg_wr) || (|run_extra_wr) || (|run_reg_rd);
        
        if (mrst || i2c_rst)  first_mem_re <= 0;
        else if (i2c_start)   first_mem_re <= 1;
        else if (mem_re[2])   first_mem_re <= 0;
        
        if (mrst || i2c_rst) pre_cmd <= 0;
        else if (i2c_start)  pre_cmd <= 1;
        else if (run_any_d)  pre_cmd <= 0;
@@ -154,25 +172,25 @@ module sensor_i2c_prot(
        table_re <= {table_re[2:0], pre_table_re}; // start_wr_seq_w};
        
        if (table_re[2]) begin
            reg_ah <=         tdout[7:0];   // MSB of the register address (instead of the byte 2)
            num_bytes_send <= tdout[19:16]; // number of bytes to send (if more than 4 will skip stop and continue with next data
            i2c_dly <=        tdout[27:20];
            reg_ah <=         tdout[SENSI2C_TBL_RAH +: SENSI2C_TBL_RAH_BITS]; //[ 7:0];   // MSB of the register address (instead of the byte 2)
            num_bytes_send <= tdout[SENSI2C_TBL_NBWR +: SENSI2C_TBL_NBWR_BITS] ; // [19:16]; // number of bytes to send (if more than 4 will skip stop and continue with next data
            i2c_dly <=        tdout[SENSI2C_TBL_DLY +: SENSI2C_TBL_DLY_BITS]; //[27:20];
        end
        if      (table_re[2])               slave_a_rah <= {tdout[15:9], 1'b0};
        else if (next_cmd && run_reg_wr[6]) slave_a_rah <= reg_ah; // will copy even if not used
        if      (table_re[2])               slave_a_rah <= {tdout[SENSI2C_TBL_SA +: SENSI2C_TBL_SA_BITS], 1'b0}; // {tdout[15:9], 1'b0};
        else if (next_cmd && run_reg_wr[5]) slave_a_rah <= reg_ah; // will copy even if not used
        
        next_cmd <= pre_next_cmd;
        
        next_cmd_d <= next_cmd;
        
        next_byte_wr <= snd9 && i2c_rdy; // same time as next_cmd
        next_byte_wr <= snd9 && i2c_rdy && !run_reg_wr[5]; // same time as next_cmd, no pulse when sending SA during write

        snd_start <= snd_start_w; // add & i2c_ready? Not really needed as any i2c stage will be busy for long enough
        snd_stop <=  snd_stop_w;
        snd9 <=      snd9_w;
//        snd_start <= snd_start_w; // add & i2c_ready? Not really needed as any i2c stage will be busy for long enough
//        snd_stop <=  snd_stop_w;
//        snd9 <=      snd9_w;
        
        if     (mrst || i2c_rst) bytes_left_send <= 0;
        else if (start_wr_seq_w) bytes_left_send <= num_bytes_send;
        else if (start_wr_seq_w) bytes_left_send <= tdout[SENSI2C_TBL_NBWR +: SENSI2C_TBL_NBWR_BITS]; // num_bytes_send;
        else if (next_byte_wr)   bytes_left_send <= bytes_left_send - 1;

        // calculate stages for each type of commands
@@ -206,12 +224,11 @@ module sensor_i2c_prot(

//     reg    [ 7:0] run_reg_rd; // [7] - start, [6] SA (byte 3), [5] (optional) - RA_msb, [4] - RA_lsb, [3] - restart, [2] - SA, [1] - read bytes, [0] - stop

//        if (!run_extra_wr &&  decode_reg_rd && read_mem_msb) read_address_bytes <= seq_rd[3];
//        if (!run_extra_wr &&  decode_reg_rd && read_mem_msb) read_data_bytes <= seq_rd[2:0];

        if      (table_re[2] &&  tdout[8])  read_address_bytes <= tdout[19];
//        if      (table_re[2] &&  tdout[8])  read_address_bytes <= tdout[19];
        if      (table_re[2] &&  tdout[SENSI2C_TBL_RNWREG])  read_address_bytes <= tdout[SENSI2C_TBL_NABRD]; // [19];
        
        if      (table_re[2] &&  tdout[8])  read_data_bytes <= tdout[18:16];
//        if      (table_re[2] &&  tdout[8])  read_data_bytes <= tdout[18:16];
        if      (table_re[2] &&  tdout[SENSI2C_TBL_RNWREG])  read_data_bytes <= tdout[SENSI2C_TBL_NBRD +: SENSI2C_TBL_NBRD_BITS];
        else if (run_reg_rd[1] && next_cmd) read_data_bytes <= read_data_bytes - 1;
        
        // read i2c data
@@ -245,11 +262,18 @@ module sensor_i2c_prot(
        
        send_seq_data <= !next_cmd && mem_valid && ((|run_reg_wr[3:1]) || (|run_extra_wr[4:1]) || (|run_reg_rd[6:4])); 
        send_rd_sa <=    !next_cmd && run_reg_rd[2];
        send_sa_rah <=   !next_cmd && (|run_reg_wr[6:5]);
        send_sa_rah <=   !next_cmd && (|run_reg_wr[5:4]);
        send_rd <=       !next_cmd && run_reg_rd[1];
        
        if (mrst || i2c_rst) snd9 <= 0;
        if (mrst || i2c_rst || next_cmd) snd9 <= 0;
        else                             snd9 <= snd9 ? (!i2c_rdy) : ((send_seq_data || send_rd_sa || send_sa_rah || send_rd) && !next_cmd);

        if (mrst || i2c_rst || next_cmd) snd_start <= 0;
        else                             snd_start <= snd_start? (!i2c_rdy) : (run_reg_wr[6] || run_reg_rd[7] || run_reg_rd[3]);

        if (mrst || i2c_rst || next_cmd) snd_stop <= 0;
        else                             snd_stop <= snd_stop? (!i2c_rdy) : (run_reg_wr[0] || run_extra_wr[0] || run_reg_rd[0]);
        
        case (sel_sr_in)
            2'h0: sr_in <= {seq_rd, 1'b1};
            2'h1: sr_in <= {rd_sa, 2'b11};
@@ -269,6 +293,7 @@ module sensor_i2c_prot(
        .snd_start       (snd_start),     // input
        .snd_stop        (snd_stop),      // input
        .snd9            (snd9),          // input
        .rcv             (run_reg_rd[1]), // input       
        .din             (sr_in),         // input[8:0] 
        .dout            ({rdata,unused}),// output[8:0] 
        .dout_stb        (rvalid),        // output reg 
Loading