SPI Engine: Fixed delay behaviour on Chip-Select and Sleep instructions (#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>main
parent
365933542d
commit
becc035ba9
|
@ -65,11 +65,12 @@ specified delay. The length of the delay depends on the module clock frequency,
|
|||
the setting of the prescaler register and the t parameter of the instruction.
|
||||
This delay is inserted before and after the update of the chip-select signal,
|
||||
so the total execution time of the chip-select
|
||||
instruction is twice the delay.
|
||||
instruction is twice the delay, plus a fixed 2 clock cycles (fast clock, not prescaled)
|
||||
for the internal logic.
|
||||
|
||||
.. math::
|
||||
|
||||
delay = t * \frac{div + 1}{f_{clk}}
|
||||
delay = t * \frac{(div + 1)*2}{f_{clk}}
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 15 75
|
||||
|
@ -152,11 +153,12 @@ Sleep Instruction
|
|||
The sleep instruction stops the execution of the command stream for the
|
||||
specified amount of time. The time is based on the external clock frequency the
|
||||
configuration value of the prescaler register and the time parameter of the
|
||||
instruction.
|
||||
instruction. A fixed delay of two clock cycles (fast, not affected by the prescaler)
|
||||
is the minimum, needed by the internal logic.
|
||||
|
||||
.. math::
|
||||
|
||||
sleep\_time = \frac{(t + 1) * ((div + 1) * 2)}{f_{clk}}
|
||||
sleep\_time = \frac{2+(t) * ((div + 1) * 2)}{f_{clk}}
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 15 75
|
||||
|
|
|
@ -157,6 +157,8 @@ module spi_engine_execution #(
|
|||
|
||||
wire sleep_counter_compare;
|
||||
wire cs_sleep_counter_compare;
|
||||
wire cs_sleep_early_exit;
|
||||
reg cs_sleep_repeat;
|
||||
|
||||
wire io_ready1;
|
||||
wire io_ready2;
|
||||
|
@ -167,7 +169,10 @@ module spi_engine_execution #(
|
|||
|
||||
(* direct_enable = "yes" *) wire cs_gen;
|
||||
|
||||
assign cs_gen = inst_d1 == CMD_CHIPSELECT && cs_sleep_counter_compare == 1'b1;
|
||||
assign cs_gen = inst_d1 == CMD_CHIPSELECT
|
||||
&& ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit)
|
||||
&& (cs_sleep_repeat == 1'b0)
|
||||
&& (idle == 1'b0);
|
||||
assign cmd_ready = idle;
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
@ -239,17 +244,30 @@ module spi_engine_execution #(
|
|||
assign trigger_tx = trigger == 1'b1 && ntx_rx == 1'b0;
|
||||
assign trigger_rx = trigger == 1'b1 && ntx_rx == 1'b1;
|
||||
|
||||
assign sleep_counter_compare = sleep_counter == cmd_d1[7:0] && clk_div_last == 1'b1;
|
||||
assign cs_sleep_counter_compare = cs_sleep_counter == cmd_d1[9:8] && clk_div_last == 1'b1;
|
||||
assign sleep_counter_compare = sleep_counter == cmd_d1[7:0];
|
||||
assign cs_sleep_counter_compare = cs_sleep_counter == cmd_d1[9:8];
|
||||
assign cs_sleep_early_exit = (cmd_d1[9:8] == 2'b00);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (idle == 1'b1) begin
|
||||
if (resetn == 1'b0) begin
|
||||
cs_sleep_repeat <= 1'b0;
|
||||
end else begin
|
||||
if (idle) begin
|
||||
cs_sleep_repeat <= 1'b0;
|
||||
end else if (cs_sleep_counter_compare && (inst_d1 == CMD_CHIPSELECT)) begin
|
||||
cs_sleep_repeat <= !cs_sleep_repeat;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (idle == 1'b1 || (cs_sleep_counter_compare && !cs_sleep_repeat && inst_d1 == CMD_CHIPSELECT)) begin
|
||||
counter <= 'h00;
|
||||
end else if (clk_div_last == 1'b1 && wait_for_io == 1'b0) begin
|
||||
if (bit_counter == word_length) begin
|
||||
counter <= (counter & BIT_COUNTER_CLEAR) + (transfer_active ? 'h1 : 'h10) + BIT_COUNTER_CARRY;
|
||||
counter <= (counter & BIT_COUNTER_CLEAR) + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH)) + BIT_COUNTER_CARRY;
|
||||
end else begin
|
||||
counter <= counter + (transfer_active ? 'h1 : 'h10);
|
||||
counter <= counter + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -267,7 +285,7 @@ module spi_engine_execution #(
|
|||
idle <= 1'b1;
|
||||
end
|
||||
CMD_CHIPSELECT: begin
|
||||
if (cs_sleep_counter_compare)
|
||||
if ((cs_sleep_counter_compare && cs_sleep_repeat) || cs_sleep_early_exit)
|
||||
idle <= 1'b1;
|
||||
end
|
||||
CMD_MISC: begin
|
||||
|
|
Loading…
Reference in New Issue