11/*
22
3- Copyright (c) 2015-2017 Alex Forencich
3+ Copyright (c) 2015-2021 Alex Forencich
44
55Permission is hereby granted, free of charge, to any person obtaining a copy
66of this software and associated documentation files (the "Software"), to deal
@@ -69,13 +69,13 @@ general-purpose processor.
6969
7070Copy this file and change init_data and INIT_DATA_LEN as needed.
7171
72- This module can be used in two modes: simple device initalization , or multiple
72+ This module can be used in two modes: simple device initialization , or multiple
7373device initialization. In multiple device mode, the same initialization sequence
74- can be performed on multiple different device addresses.
74+ can be performed on multiple different device addresses.
7575
7676To use single device mode, only use the start write to address and write data commands.
7777The module will generate the I2C commands in sequential order. Terminate the list
78- with a 0 entry.
78+ with a 0 entry.
7979
8080To use the multiple device mode, use the start data and start address block commands
8181to set up lists of initialization data and device addresses. The module enters
@@ -97,6 +97,7 @@ Commands:
979700 0000011 : start write to current address
989800 0001000 : start address block
999900 0001001 : start data block
100+ 00 001dddd : delay 2**(16+d) cycles
10010100 1000001 : send I2C stop
10110201 aaaaaaa : start write to address
1021031 dddddddd : write 8-bit data
@@ -184,6 +185,8 @@ reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next;
184185
185186reg [6 :0 ] cur_address_reg = 7'd0 , cur_address_next;
186187
188+ reg [31 :0 ] delay_counter_reg = 32'd0 , delay_counter_next;
189+
187190reg [6 :0 ] m_axis_cmd_address_reg = 7'd0 , m_axis_cmd_address_next;
188191reg m_axis_cmd_start_reg = 1'b0 , m_axis_cmd_start_next;
189192reg m_axis_cmd_write_reg = 1'b0 , m_axis_cmd_write_next;
@@ -220,6 +223,8 @@ always @* begin
220223
221224 cur_address_next = cur_address_reg;
222225
226+ delay_counter_next = delay_counter_reg;
227+
223228 m_axis_cmd_address_next = m_axis_cmd_address_reg;
224229 m_axis_cmd_start_next = m_axis_cmd_start_reg & ~ (m_axis_cmd_valid & m_axis_cmd_ready);
225230 m_axis_cmd_write_next = m_axis_cmd_write_reg & ~ (m_axis_cmd_valid & m_axis_cmd_ready);
@@ -234,6 +239,10 @@ always @* begin
234239 if (m_axis_cmd_valid | m_axis_data_tvalid) begin
235240 // wait for output registers to clear
236241 state_next = state_reg;
242+ end else if (delay_counter_reg != 0 ) begin
243+ // delay
244+ delay_counter_next = delay_counter_reg - 1 ;
245+ state_next = state_reg;
237246 end else begin
238247 case (state_reg)
239248 STATE_IDLE: begin
@@ -256,17 +265,24 @@ always @* begin
256265
257266 m_axis_data_tdata_next = init_data_reg[7 :0 ];
258267 m_axis_data_tvalid_next = 1'b1 ;
259-
268+
260269 address_next = address_reg + 1 ;
261-
270+
262271 state_next = STATE_RUN;
263272 end else if (init_data_reg[8 :7 ] == 2'b01 ) begin
264273 // write address
265274 m_axis_cmd_address_next = init_data_reg[6 :0 ];
266275 m_axis_cmd_start_next = 1'b1 ;
267276
268277 address_next = address_reg + 1 ;
269-
278+
279+ state_next = STATE_RUN;
280+ end else if (init_data_reg[8 :4 ] == 5'b00001 ) begin
281+ // delay
282+ delay_counter_next = 32'd1 << (init_data_reg[3 :0 ]+ 16 );
283+
284+ address_next = address_reg + 1 ;
285+
270286 state_next = STATE_RUN;
271287 end else if (init_data_reg == 9'b001000001 ) begin
272288 // send stop
@@ -442,6 +458,8 @@ always @(posedge clk) begin
442458
443459 cur_address_reg <= cur_address_next;
444460
461+ delay_counter_reg <= delay_counter_next;
462+
445463 m_axis_cmd_address_reg <= m_axis_cmd_address_next;
446464 m_axis_cmd_start_reg <= m_axis_cmd_start_next;
447465 m_axis_cmd_write_reg <= m_axis_cmd_write_next;
@@ -466,6 +484,8 @@ always @(posedge clk) begin
466484
467485 cur_address_reg <= 7'd0 ;
468486
487+ delay_counter_reg <= 32'd0 ;
488+
469489 m_axis_cmd_valid_reg <= 1'b0 ;
470490
471491 m_axis_data_tvalid_reg <= 1'b0 ;
0 commit comments