Skip to content

Commit becc035

Browse files
authored
SPI Engine: Fixed delay behaviour on Chip-Select and Sleep instructions (analogdevicesinc#1200)
Fixed wrong behaviour on chip select instruction: - previously, a sleep time happened before the chip select change - the intended behaviour was for another sleep time, of equal amount, to happen after the chip select change as well - additionally, the counter logic implementation was creating an additional factor of 2 on the sleep time All of the above points were fixed. The changes introduced also fix another issue where the sleep instruction was likewise happening with a duration larger than intended by a factor of 2 Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
1 parent 3659335 commit becc035

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

docs/library/spi_engine/instruction-format.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ specified delay. The length of the delay depends on the module clock frequency,
6565
the setting of the prescaler register and the t parameter of the instruction.
6666
This delay is inserted before and after the update of the chip-select signal,
6767
so the total execution time of the chip-select
68-
instruction is twice the delay.
68+
instruction is twice the delay, plus a fixed 2 clock cycles (fast clock, not prescaled)
69+
for the internal logic.
6970

7071
.. math::
7172
72-
delay = t * \frac{div + 1}{f_{clk}}
73+
delay = t * \frac{(div + 1)*2}{f_{clk}}
7374
7475
.. list-table::
7576
:widths: 10 15 75
@@ -152,11 +153,12 @@ Sleep Instruction
152153
The sleep instruction stops the execution of the command stream for the
153154
specified amount of time. The time is based on the external clock frequency the
154155
configuration value of the prescaler register and the time parameter of the
155-
instruction.
156+
instruction. A fixed delay of two clock cycles (fast, not affected by the prescaler)
157+
is the minimum, needed by the internal logic.
156158

157159
.. math::
158160
159-
sleep\_time = \frac{(t + 1) * ((div + 1) * 2)}{f_{clk}}
161+
sleep\_time = \frac{2+(t) * ((div + 1) * 2)}{f_{clk}}
160162
161163
.. list-table::
162164
:widths: 10 15 75

library/spi_engine/spi_engine_execution/spi_engine_execution.v

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ module spi_engine_execution #(
157157

158158
wire sleep_counter_compare;
159159
wire cs_sleep_counter_compare;
160+
wire cs_sleep_early_exit;
161+
reg cs_sleep_repeat;
160162

161163
wire io_ready1;
162164
wire io_ready2;
@@ -167,7 +169,10 @@ module spi_engine_execution #(
167169

168170
(* direct_enable = "yes" *) wire cs_gen;
169171

170-
assign cs_gen = inst_d1 == CMD_CHIPSELECT && cs_sleep_counter_compare == 1'b1;
172+
assign cs_gen = inst_d1 == CMD_CHIPSELECT
173+
&& ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit)
174+
&& (cs_sleep_repeat == 1'b0)
175+
&& (idle == 1'b0);
171176
assign cmd_ready = idle;
172177

173178
always @(posedge clk) begin
@@ -239,17 +244,30 @@ module spi_engine_execution #(
239244
assign trigger_tx = trigger == 1'b1 && ntx_rx == 1'b0;
240245
assign trigger_rx = trigger == 1'b1 && ntx_rx == 1'b1;
241246

242-
assign sleep_counter_compare = sleep_counter == cmd_d1[7:0] && clk_div_last == 1'b1;
243-
assign cs_sleep_counter_compare = cs_sleep_counter == cmd_d1[9:8] && clk_div_last == 1'b1;
247+
assign sleep_counter_compare = sleep_counter == cmd_d1[7:0];
248+
assign cs_sleep_counter_compare = cs_sleep_counter == cmd_d1[9:8];
249+
assign cs_sleep_early_exit = (cmd_d1[9:8] == 2'b00);
244250

245251
always @(posedge clk) begin
246-
if (idle == 1'b1) begin
252+
if (resetn == 1'b0) begin
253+
cs_sleep_repeat <= 1'b0;
254+
end else begin
255+
if (idle) begin
256+
cs_sleep_repeat <= 1'b0;
257+
end else if (cs_sleep_counter_compare && (inst_d1 == CMD_CHIPSELECT)) begin
258+
cs_sleep_repeat <= !cs_sleep_repeat;
259+
end
260+
end
261+
end
262+
263+
always @(posedge clk) begin
264+
if (idle == 1'b1 || (cs_sleep_counter_compare && !cs_sleep_repeat && inst_d1 == CMD_CHIPSELECT)) begin
247265
counter <= 'h00;
248266
end else if (clk_div_last == 1'b1 && wait_for_io == 1'b0) begin
249267
if (bit_counter == word_length) begin
250-
counter <= (counter & BIT_COUNTER_CLEAR) + (transfer_active ? 'h1 : 'h10) + BIT_COUNTER_CARRY;
268+
counter <= (counter & BIT_COUNTER_CLEAR) + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH)) + BIT_COUNTER_CARRY;
251269
end else begin
252-
counter <= counter + (transfer_active ? 'h1 : 'h10);
270+
counter <= counter + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH));
253271
end
254272
end
255273
end
@@ -267,7 +285,7 @@ module spi_engine_execution #(
267285
idle <= 1'b1;
268286
end
269287
CMD_CHIPSELECT: begin
270-
if (cs_sleep_counter_compare)
288+
if ((cs_sleep_counter_compare && cs_sleep_repeat) || cs_sleep_early_exit)
271289
idle <= 1'b1;
272290
end
273291
CMD_MISC: begin

0 commit comments

Comments
 (0)