x393  1.0
FPGAcodeforElphelNC393camera
sensor_i2c_prot.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  parameter SENSI2C_TBL_RAH = 0, // high byte of the register address
43  parameter SENSI2C_TBL_RAH_BITS = 8,
44  parameter SENSI2C_TBL_RNWREG = 8, // read register (when 0 - write register
45  parameter SENSI2C_TBL_SA = 9, // Slave address in write mode
46  parameter SENSI2C_TBL_SA_BITS = 7,
47  parameter SENSI2C_TBL_NBWR = 16, // number of bytes to write (1..10)
48  parameter SENSI2C_TBL_NBWR_BITS = 4,
49  parameter SENSI2C_TBL_NBRD = 16, // number of bytes to read (1 - 8) "0" means "8"
50  parameter SENSI2C_TBL_NBRD_BITS = 3,
51  parameter SENSI2C_TBL_NABRD = 19, // number of address bytes for read (0 - 1 byte, 1 - 2 bytes)
52  parameter SENSI2C_TBL_DLY = 20, // bit delay (number of mclk periods in 1/4 of SCL period)
53  parameter SENSI2C_TBL_DLY_BITS= 8
54 )(
55  input mrst, // @ posedge mclk
56  input mclk, // global clock
57  input i2c_rst,
58  input i2c_start,
59  input active_sda, // global config bit: active pull SDA
60  input early_release_0,// global config bit: release SDA immediately after end of SCL if next bit is 1 (for ACKN). Data hold time by slow 0->1
61  // setup LUT to translate address page into SA, actual address MSB and number of bytes to write (second word bypasses translation)
62  input tand, // table address/not data
63  input [27:0] td, // table address/data in
64  input twe, // table write enable
65  input sda_in, // data from sda pad
66  output sda,
67  output sda_en,
68  output scl,
69  output reg i2c_run, // released as soon as the last command (usually STOP) gets to the i2c start/stop/shift module
70  output reg i2c_busy, // released when !i2c_run and all i2c activity is over
71  output reg [1:0] seq_mem_ra, // number of byte to read from the sequencer memory
72  output [ 1:0] seq_mem_re, // [0] - re, [1] - regen to the sequencer memory
73  input [ 7:0] seq_rd, // data from the sequencer memory
74  output [ 7:0] rdata,
75  output rvalid
76 );
77 /*
78  Sequencer provides 4 bytes per command, read one byte at a time as seq_rd[7:0] with byte address provided by seq_mem_ra[1:0],
79  seq_mem_re[0] external memory re, seq_mem_re[1] - regen
80  MSB (byte 3) is used as index in the table that provides for register writes (tdout[8] == 0):
81  high byte of the register address (if used) - tdout[7:0]
82  slave address - tdout[15:9],
83  number of bytes to send after SA - tdout[19:16] (includes both adderss and data bytes, aligned to the MSB)
84  bit delay - tdout[27:20] (periods of mclk for 1/4 of the SCL period), should be >2(?)
85 
86  if number of bytes to send (including address) >4, there will be no stop and the next command will bypass MSB decoding through table
87  and be sent out as data bytes (MSB first, aligned to the LSB (byte[0]), so if only one byte is to be sent bytes[3:1] will be skipped.
88  In read mode (tdout[8] == 1) it is possible to use 1 or 2 byte register address and read 1..8 bytes
89  bit delay - tdout[27:20] (same as for register writes - see above)
90  Slave address in the read mode is provided as byte[2], register adderss in bytes[1:0] (byte[1] is skipped for 1-byte addresses)
91  Number of data bytes to read is provided as tdout[18:16], with 0 meaning 8 bytes
92  Nuber of register address bytes is defined by tdout[19]: 0 - one byte, 1 - 2 bytes address
93  "active_sda" (configuration bit enables active pull-up on SDA line by the master for faster communication, it is active during second
94  half of the SCL=0 for the data bits and also for the first interval of the RESTART sequence and for the last of the STOP one.
95  "early_release_0" - when sending data bit "0" over the SDA line, release SDA=0 immediately after SCL: 1->0 if the next bit to send is "1".
96  This is OK as the SDA 0->1 transition will be slower than SCL 1->0 (only pulled up by a resistor), so there will be positive hold time
97  on SDA line. This is done so for communications with 10359 (or similar) board where FPGA can also actively drive SDA line for faster
98  communication.
99  Active driving of the SDA line increases only master send communication, so ACKN may be missed, but it is not used in this implementation.
100  Reading registers is less used operation than write and can use slower communication spped (provided through the table)
101 */
102  reg [ 7:0] twa;
103  wire [31:0] tdout;
104  reg [ 7:0] reg_ah; // MSB of the register address (instead of the byte 2)
105  reg [ 7:0] slave_a_rah; // 8-bit slave address , used instead of the byte 3, later replaced with reg_ah
106  reg [ 3:0] num_bytes_send; // number of bytes to send (if more than 4 will skip stop and continue with next data
107  reg [ 7:0] i2c_dly; // bit duration-1 (>=2?), 1 unit - 4 mclk periods
108 
109 
110  reg [ 3:0] bytes_left_send; // Number of bytes left in register write sequence (not counting sa?)
111  reg [ 6:0] run_reg_wr; // run register write [6] - start, [5] - send sa, [4] - send high byte (from table),..[0] - send stop
112  reg [ 4:0] run_extra_wr; // continue register write (if more than sa + 4bytes) [4] - byte 3, .. [1]- byte0, [0] - stop
113  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
114  reg run_extra_wr_d; // any of run_extra_wr bits, delayed by 1
115  reg run_any_d; // any of command states, delayed by 1
116  reg [1:0] pre_cmd; // from i2c_start until run_any_d will be active
118 // reg i2c_done;
119 // wire i2c_next_byte;
120  reg [ 2:0] mem_re;
122  reg [ 2:0] table_re;
123 
124 // reg read_mem_msb;
125 // wire decode_reg_rd = &seq_rd[7:4];
126 // wire start_wr_seq_w = !run_extra_wr_d && !decode_reg_rd && read_mem_msb;
130 
131  // wire snd_start_w = run_reg_wr[6] || 1'b0; // add start & restart of read
132  // wire snd_stop_w = run_reg_wr[0] || 1'b0; // add stop of read
133  // wire snd9_w = (|run_reg_wr[5:1]) || 1'b0; // add for read and extra write;
134 
136  reg snd_stop;
137  reg snd9;
138  // the following signals are mutually exclusive, can be encoded to 2 bits. Invaluid during next_cmd_d
139  reg send_seq_data; // including first SA for read
140  reg send_rd_sa; // from the table
141  reg send_sa_rah; // send slave address/ high address from the table
142  reg send_rd; // send 1fe/1ff to read data
143  reg [6:0] rd_sa; // 7-bit slave address for reading
144  wire [1:0] sel_sr_in = { // select source for the shift register
146  send_rd_sa | send_rd};
147  reg [8:0] sr_in; // input data for the shift register
148  wire bus_busy; // i2c bus is active
149  wire bus_open; // i2c bus is "open" (START-ed but not STOP-ed) - between multi-byte write if it spans >1 32-bit comands
150 
151  wire i2c_rdy;
152  reg next_cmd; // i2c command (start/stop/data) accepted, proceed to the next stage
153  reg next_cmd_d; // next cycle after next_cmd (first at new state)
156 
157  reg read_address_bytes; // 0 - single-byte register adderss, 1 - two-byte register address
158  reg [ 2:0] read_data_bytes; // 1..8 bytes to read from the i2c slave (0 is 8!)
159 
160  reg [ 1:0] initial_address; // initial data byte to read: usually 3 but for extra write may be different
161  wire [ 3:0] initial_address_w = bytes_left_send - 1; // if bytes left to send == 0 - will be 3
162  wire unused; // unused ackn signal SuppressThisWarning VEditor
163 
165  reg rnw; // last command was read (not write) - do not increment bytes_left_send
166 
167 // wire dout_stb; // rvalid
168 
169  assign seq_mem_re = mem_re[1:0];
170 // assign rvalid = dout_stb && run_reg_rd[1];
171  always @ (posedge mclk) begin
172  if (mrst || i2c_rst || start_wr_seq_w) rnw <= 0;
173  else if (start_rd_seq_w) rnw <= 1;
175 
176  run_any_d <= (|run_reg_wr) || (|run_extra_wr) || (|run_reg_rd);
177 
178  if (mrst || i2c_rst) first_mem_re <= 0;
179  else if (i2c_start) first_mem_re <= 1;
180  else if (mem_re[2]) first_mem_re <= 0;
181 
182  if (mrst || i2c_rst) pre_cmd <= 0;
183  else if (i2c_start) pre_cmd <= 1;
184  else if (run_any_d) pre_cmd <= 0;
185 
186  if (mrst || i2c_rst) i2c_run <= 0;
187  else i2c_run <= i2c_start || pre_cmd || run_any_d;
188 
189  if (mrst || i2c_rst) i2c_busy <= 0;
190  else i2c_busy <= i2c_start || pre_cmd || run_any_d || bus_busy || bus_open;
191 
192 
193  table_re <= {table_re[1:0], pre_table_re}; // start_wr_seq_w};
194 
195  if (table_re[2]) begin
196  reg_ah <= tdout[SENSI2C_TBL_RAH +: SENSI2C_TBL_RAH_BITS]; //[ 7:0]; // MSB of the register address (instead of the byte 2)
197  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
199  end
200  if (table_re[2]) slave_a_rah <= {tdout[SENSI2C_TBL_SA +: SENSI2C_TBL_SA_BITS], 1'b0}; // {tdout[15:9], 1'b0};
201  else if (next_cmd && run_reg_wr[5]) slave_a_rah <= reg_ah; // will copy even if not used
202  // wire pre_next_cmd = (snd_start || snd_stop || snd9) && i2c_rdy;
204 
205  next_cmd_d <= next_cmd;
206 
207  next_byte_wr <= snd9 && i2c_rdy && !run_reg_wr[5] && !rnw; // (|run_reg_rd); // same time as next_cmd, no pulse when sending SA during write
208 
209 // snd_start <= snd_start_w; // add & i2c_ready? Not really needed as any i2c stage will be busy for long enough
210 // snd_stop <= snd_stop_w;
211 // snd9 <= snd9_w;
212 
213  if (mrst || i2c_rst) bytes_left_send <= 0;
214  else if (start_wr_seq_w) bytes_left_send <= tdout[SENSI2C_TBL_NBWR +: SENSI2C_TBL_NBWR_BITS]; // num_bytes_send;
216 
217  // calculate stages for each type of commands
218  // start and write sa and some bytes, stop if number of bytes <= 4 at the end
219  if (mrst || i2c_rst) run_reg_wr <= 0;
220  else if (start_wr_seq_w) run_reg_wr <= 7'h40;
221  else if (next_cmd) run_reg_wr <= {1'b0, // first "start"
222  run_reg_wr[6], // slave_addr - always after start
223  run_reg_wr[5] & (|num_bytes_send[3:2]), // MSB (from the table)
224  run_reg_wr[4] | (run_reg_wr[5] & (num_bytes_send == 4'h3)), // byte 2 (from input)
225  run_reg_wr[3] | (run_reg_wr[5] & (num_bytes_send == 4'h2)), // byte 1 (from input)
226  run_reg_wr[2] | (run_reg_wr[5] & (num_bytes_send == 4'h1)), // byte 0 (from input)
227  run_reg_wr[1] & (bytes_left_send == 4'h1)
228  };
229  // send just bytes (up to 4), stop if nothing left
230  if (mrst || i2c_rst) run_extra_wr <= 0;
231  else if (start_extra_seq_w) run_extra_wr <= {
232  |bytes_left_send[3:2], // >= 4 bytes left
233  (bytes_left_send == 3), // exactly 3 bytes left
234  (bytes_left_send == 2), // exactly 2 bytes left
235  (bytes_left_send == 1), // exactly 1 bytes left (zero should never be left)
236  1'b0
237  };
238  else if (next_cmd) run_extra_wr <= {
239  1'b0,
240  run_extra_wr[4],
241  run_extra_wr[3],
242  run_extra_wr[2],
243  run_extra_wr[1] & (bytes_left_send == 4'h1)
244  };
245 
246 // 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
247 
248 // if (table_re[2] && tdout[8]) read_address_bytes <= tdout[19];
250 
251 // if (table_re[2] && tdout[8]) read_data_bytes <= tdout[18:16];
253  else if (run_reg_rd[1] && next_cmd) read_data_bytes <= read_data_bytes - 1;
254 
255  // read i2c data
256  if (mrst || i2c_rst) run_reg_rd <= 0;
257 // else if (!run_extra_wr_d && decode_reg_rd && read_mem_msb) run_reg_rd <= 8'h80;
258  else if (start_rd_seq_w) run_reg_rd <= 8'h80;
259  else if (next_cmd) run_reg_rd <= {1'b0, // first "start"
260  run_reg_rd[7], // slave_addr - always after start (bit0 = 0)
261  run_reg_rd[6] & read_address_bytes, // optional MSB of the register address
262  run_reg_rd[5] | (run_reg_rd[6] & ~read_address_bytes), // LSB of the register address
263  run_reg_rd[4], // restart
264  run_reg_rd[3], // send slave address with 1 in bit[0]
265  run_reg_rd[2] | (run_reg_rd[1] & (read_data_bytes != 3'h1)), // repeat reading bytes
266  run_reg_rd[1] & (read_data_bytes == 3'h1)
267  };
268  // read sequencer memory byte (for the current word)
269  mem_re <= {mem_re[1:0], i2c_start | next_cmd_d & (
270  (|run_reg_wr[3:1]) |
271  (|run_extra_wr[4:1]) |
272  (|run_reg_rd[6:4]))};
273  initial_address <= initial_address_w[1:0]; // if bytes left to send is 0 mod 4 - will be 3 (read MSB)
274  seq_mem_ra <= i2c_start ? initial_address : { // run_extra_wr[4] is not needed - it will be read by i2c_start
275  run_reg_wr[3] | run_extra_wr[3] | run_reg_rd[6],
276  run_reg_wr[2] | run_extra_wr[2] | run_reg_rd[5]
277  };
278  if (mrst || i2c_rst || i2c_start || next_cmd ) mem_valid <= 0;
279  else if (mem_re[2]) mem_valid <= 1;
280 
281  // calculate snd9 and delay it if waiting for memory using mem_valid, set din[8:0]
282  if (run_reg_rd[6] && mem_re[2]) rd_sa <= seq_rd[7:1]; // store sa to use with read
283 
284  send_seq_data <= !next_cmd && mem_valid && ((|run_reg_wr[3:1]) || (|run_extra_wr[4:1]) || (|run_reg_rd[6:4]));
285  send_rd_sa <= !next_cmd && run_reg_rd[2];
286  send_sa_rah <= !next_cmd && (|run_reg_wr[5:4]);
287  send_rd <= !next_cmd && run_reg_rd[1];
288 
289  if (mrst || i2c_rst || next_cmd) snd9 <= 0;
290  else snd9 <= snd9 ? (!i2c_rdy) : ((send_seq_data || send_rd_sa || send_sa_rah || send_rd) && !next_cmd);
291 
292  if (mrst || i2c_rst || next_cmd) snd_start <= 0;
293  else snd_start <= snd_start? (!i2c_rdy) : (run_reg_wr[6] || run_reg_rd[7] || run_reg_rd[3]);
294 
295  if (mrst || i2c_rst || next_cmd) snd_stop <= 0;
296  else snd_stop <= snd_stop? (!i2c_rdy) : (run_reg_wr[0] || run_extra_wr[0] || run_reg_rd[0]);
297 
298  case (sel_sr_in)
299  2'h0: sr_in <= {seq_rd, 1'b1};
300  2'h1: sr_in <= {rd_sa, 2'b11};
301  2'h2: sr_in <= {slave_a_rah, 1'b1};
302  2'h3: sr_in <= {8'hff,(read_data_bytes == 3'h1)};
303  endcase
304 
305  end
306 
307  sensor_i2c_scl_sda sensor_i2c_scl_sda_i (
308  .mrst (mrst), // input
309  .mclk (mclk), // input
310  .i2c_rst (i2c_rst), // input
311  .i2c_dly (i2c_dly), // input[7:0]
312  .active_sda (active_sda), // input
313  .early_release_0 (early_release_0), // input
314  .snd_start (snd_start), // input
315  .snd_stop (snd_stop), // input
316  .snd9 (snd9), // input
317  .rcv (run_reg_rd[1]), // input
318  .din (sr_in), // input[8:0]
319  .dout ({rdata,unused}),// output[8:0]
320  .dout_stb (rvalid), // output reg
321  .scl (scl), // output reg
322  .sda_in (sda_in), // input
323  .sda (sda), // output reg
324  .sda_en (sda_en), // output reg
325  .ready (i2c_rdy), // output register
326  .bus_busy (bus_busy), // output reg
327  .is_open (bus_open) // output
328  );
329 
330  // table write
331  always @ (posedge mclk) begin
332  if (mrst) twa <= 0;
333  else if (twe) twa <= tand ? td[7:0] : (twa + 1);
334  end
335 
337  .REGISTERS (1),
338  .LOG2WIDTH_WR (5),
339  .LOG2WIDTH_RD (5),
340  .DUMMY (0)
341  ) ram18_var_w_var_r_i (
342  .rclk (mclk), // input
343  .raddr ({1'b0, seq_rd}), // input[8:0]
344  .ren (table_re[0]), // input
345  .regen (table_re[1]), // input
346  .data_out (tdout), // output[31:0]
347  .wclk (mclk), // input
348  .waddr ({1'b0, twa}), // input[8:0]
349  .we (twe && !tand), // input
350  .web (4'hf), // input[3:0]
351  .data_in ({4'b0, td}) // input[31:0]
352  );
353 
354 
355 endmodule
356 
8386read_data_bytesreg[2:0]
[ 1:0] 8344seq_mem_re
[1 << LOG2WIDTH_WR-1:0] 11597data_in
8349tdoutwire[31:0]
8354bytes_left_sendreg[3:0]
[1 << LOG2WIDTH_RD-1:0] 11592data_out
[13-LOG2WIDTH_RD:0] 11589raddr
8356run_extra_wrreg[4:0]
8355run_reg_wrreg[6:0]
8357run_reg_rdreg[7:0]
8351slave_a_rahreg[7:0]
ram18_var_w_var_r_i ram18_var_w_var_r
sensor_i2c_scl_sda_i sensor_i2c_scl_sda
[13-LOG2WIDTH_WR:0] 11594waddr
8352num_bytes_sendreg[3:0]
reg [1:0] 8343seq_mem_ra
8376sel_sr_inwire[1:0]
8387initial_addressreg[1:0]
8388initial_address_wwire[3:0]