Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI Engine: Fixed delay behaviour on Chip-Select and Sleep instructions #1200

Merged
merged 4 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/library/spi_engine/instruction-format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ instruction is twice the delay.

LBFFilho marked this conversation as resolved.
Show resolved Hide resolved
.. math::

delay = t * \frac{div + 1}{f_{clk}}
delay = t * \frac{(div + 1)*2}{f_{clk}}

.. list-table::
:widths: 10 15 75
Expand Down
28 changes: 23 additions & 5 deletions library/spi_engine/spi_engine_execution/spi_engine_execution.v
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -167,7 +169,9 @@ 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_repeat == 1'b0)
&& (idle == 1'b0);
assign cmd_ready = idle;

always @(posedge clk) begin
Expand Down Expand Up @@ -241,15 +245,29 @@ module spi_engine_execution #(

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 cs_sleep_early_exit = (cmd_d1[9:8] == 0);
LBFFilho marked this conversation as resolved.
Show resolved Hide resolved

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

LBFFilho marked this conversation as resolved.
Show resolved Hide resolved
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;
LBFFilho marked this conversation as resolved.
Show resolved Hide resolved
end else begin
counter <= counter + (transfer_active ? 'h1 : 'h10);
counter <= counter + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH));
end
end
end
Expand All @@ -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
Expand Down