Commit f8eca99e authored by Andrey Filippov's avatar Andrey Filippov

simulating/debugging modified i2c sequencer

parent 74db68c1
......@@ -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,
......
......@@ -72,6 +72,20 @@ module sensor_channel#(
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,
......@@ -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),
......
......@@ -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
......
......@@ -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
......
......@@ -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,10 +154,14 @@ 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;
if (mrst || i2c_rst) i2c_run <= 0;
else i2c_run <= i2c_start || pre_cmd || run_any_d;
......@@ -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_data_bytes <= tdout[18:16];
// 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[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;
else snd9 <= snd9 ? (!i2c_rdy) : ((send_seq_data || send_rd_sa || send_sa_rah || send_rd) && !next_cmd);
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
......
......@@ -30,7 +30,7 @@ module sensor_i2c_scl_sda(
input snd_start,
input snd_stop,
input snd9,
// input rcv, // recieve mode (valid with snd9) - master receives, slave - sends
input rcv, // receive mode (valid with snd9) - master receives, slave - sends
input [ 8:0] din,
output [ 8:0] dout, //
output reg dout_stb, // dout contains valid data
......@@ -47,12 +47,13 @@ module sensor_i2c_scl_sda(
reg [8:0] sr;
reg [7:0] dly_cntr;
reg busy_r;
wire snd_start_w = snd_start && !busy_r;
wire snd_stop_w = snd_stop && !busy_r;
wire snd9_w = snd9 && !busy_r;
wire start_w = (snd_start || snd_stop || snd9_w) && !busy_r;
wire snd_start_w = snd_start && ready; //!busy_r;
wire snd_stop_w = snd_stop && ready; // !busy_r;
wire snd9_w = snd9 && ready; //!busy_r;
wire start_w = (snd_start || snd_stop || snd9_w) && ready; //!busy_r;
reg pre_dly_over;
reg dly_over;
// reg dly_over_d;
reg [3:0] seq_start_restart;
reg [2:0] seq_stop;
reg [3:0] seq_bit;
......@@ -60,48 +61,66 @@ module sensor_i2c_scl_sda(
reg done_r;
reg sda_r;
reg first_cyc; // first clock cycle for the delay interval - update SCL/SDA outputs
assign ready = !busy_r;
reg active_sda_r; // registered @ snd9, disable in rcv mode
reg active_sda_was_0; // only use active SDA if previous bit was 0 or it is receive mode
reg rcv_r;
wire busy_w = busy_r && ! done_r;
// assign ready = !busy_r;
assign ready = !busy_w;
assign is_open = is_open_r;
assign dout = sr;
always @ (posedge mclk) begin
active_sda_was_0 <= !sda || rcv_r;
if (snd9_w) rcv_r <= rcv;
// disable active_sda in send messages for the last (ACKN) bit, for the receive - all but ACKN
if (snd9_w) active_sda_r <= active_sda && !rcv;
else if (snd_start_w || snd_stop_w) active_sda_r <= active_sda;
else if (dly_over && seq_bit[0]) active_sda_r <= active_sda && ((bits_left != 1) ^ rcv_r);
//active_sda_r && !sda
if (rst) seq_start_restart <= 0;
else if (snd_start_w) seq_start_restart <= is_open_r ? 4'h8 : 4'h4;
else if (snd_start_w) seq_start_restart <= (is_open_r && !seq_stop[0]) ? 4'h8 : 4'h4;
else if (dly_over) seq_start_restart <= {1'b0,seq_start_restart[3:1]};
if (rst) seq_stop <= 0;
else if (snd_stop_w) seq_stop <= 3'h4;
else if (dly_over) seq_stop <= {1'b0,seq_stop[2:1]};
if (rst) seq_bit <= 0;
else if (snd_start_w || (seq_bit[0] && (bits_left != 0))) seq_bit <= 4'h8;
else if (dly_over) seq_bit <= {1'b0,seq_bit[3:1]};
if (rst) seq_bit <= 0;
else if (snd9_w || (seq_bit[0] && (bits_left != 0) && dly_over)) seq_bit <= 4'h8;
else if (dly_over) seq_bit <= {1'b0,seq_bit[3:1]};
if (rst) bits_left <= 0;
if (rst) bits_left <= 4'h0;
else if (snd9_w) bits_left <= 4'h8;
else if (dly_over && seq_bit[0]) bits_left <= bits_left - 1;
else if (dly_over && seq_bit[0] && (|bits_left)) bits_left <= bits_left - 1;
if (rst) busy_r <= 0;
else if (start_w) busy_r <= 1;
else if (done_r) busy_r <= 0;
// pre_dly_over <= (dly_cntr == 3);
pre_dly_over <= (dly_cntr == 2);
dly_over <= pre_dly_over;
// dly_over_d <= dly_over;
if (rst) done_r <= 0;
else done_r <= pre_dly_over &&
(bits_left == 0) &&
(seq_start_restart[3:1] == 0) &&
(seq_stop[2:1] == 0) &&
(bits_left[3:1] == 0);
(seq_bit[3:1] == 0);
if (!busy_r || dly_over) dly_cntr <= i2c_dly;
// if (!busy_r || dly_over_d) dly_cntr <= i2c_dly;
// else dly_cntr <= dly_cntr - 1;
if (!busy_w || dly_over) dly_cntr <= i2c_dly;
else dly_cntr <= dly_cntr - 1;
if (dly_over && seq_bit[1]) sda_r <= sda_in; // just before the end of SCL pulse - delay it by a few clocks to match external latencies?
if (snd_start_w) sr <= din;
if (snd9_w) sr <= din;
else if (dly_over && seq_bit[0]) sr <= {sr[7:0], sda_r};
dout_stb <= dly_over && seq_bit[0] && (bits_left == 0);
......@@ -113,20 +132,24 @@ module sensor_i2c_scl_sda(
first_cyc <= start_w || dly_over;
if (rst) scl <= 1;
else if (first_cyc) scl <= !busy_r ||
// else if (first_cyc) scl <= !busy_r || // Wrong whe "open"?
else if (first_cyc) scl <= (scl && !busy_w) || // Wrong whe "open"?
seq_start_restart[2] || seq_start_restart[1] ||
seq_stop[1] || seq_stop[0] ||
seq_bit[2] || seq_bit[1];
if (rst) sda <= 1;
else if (first_cyc) sda <= !busy_r ||
// else if (first_cyc) sda <= !busy_r ||
else if (first_cyc) sda <= (sda && !busy_w) ||
seq_start_restart[3] || seq_start_restart[2] ||
seq_stop[0] ||
(sr[8] && (|seq_bit));
if (rst) sda_en <= 1;
else if (first_cyc) sda_en <= busy_r && (
(active_sda && (seq_start_restart[3] || seq_stop[0] || (sr[8] && seq_bit[3]))) ||
// else if (first_cyc) sda_en <= busy_r && (
// TODO: no active SDA if previous SDA was 1
else if (first_cyc) sda_en <= busy_w && (
(active_sda_r && active_sda_was_0 && (seq_start_restart[3] || seq_stop[0] || (sr[8] && seq_bit[3]))) || // !sda uses output reg
(|seq_start_restart[1:0]) ||
(|seq_stop[2:1]) ||
(!sr[8] && (|seq_bit[3:1])) ||
......
......@@ -64,6 +64,20 @@ module sensors393 #(
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_SYNC_RADDR = 'h4,
......@@ -386,6 +400,18 @@ module sensors393 #(
.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_STATUS (SENSI2C_STATUS),
.SENS_GAMMA_RADDR (SENS_GAMMA_RADDR),
.SENS_GAMMA_ADDR_MASK (SENS_GAMMA_ADDR_MASK),
......
......@@ -1410,7 +1410,7 @@ assign axi_grst = axi_rst_pre;
.SENSIO_STATUS_REG_REL (SENSIO_STATUS_REG_REL),
.SENSOR_NUM_HISTOGRAM (SENSOR_NUM_HISTOGRAM),
.HISTOGRAM_RAM_MODE (HISTOGRAM_RAM_MODE),
.SENS_NUM_SUBCHN (SENS_NUM_SUBCHN),
.SENS_NUM_SUBCHN (SENS_NUM_SUBCHN),
.SENS_GAMMA_BUFFER (SENS_GAMMA_BUFFER),
.SENSOR_CTRL_RADDR (SENSOR_CTRL_RADDR),
.SENSOR_CTRL_ADDR_MASK (SENSOR_CTRL_ADDR_MASK),
......@@ -1431,6 +1431,18 @@ assign axi_grst = axi_rst_pre;
.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_STATUS (SENSI2C_STATUS),
.SENS_SYNC_RADDR (SENS_SYNC_RADDR),
.SENS_SYNC_MASK (SENS_SYNC_MASK),
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment