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: fix segmented transfers with echo_sclk #1532

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions library/spi_engine/spi_engine_execution/spi_engine_execution.v
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ module spi_engine_execution #(

reg last_transfer;
reg [7:0] word_length = DATA_WIDTH;
reg [7:0] last_bit_count = DATA_WIDTH-1;
reg [7:0] left_aligned = 8'b0;

assign first_bit = ((bit_counter == 'h0) || (bit_counter == word_length));
Expand Down Expand Up @@ -163,8 +164,6 @@ module spi_engine_execution #(
wire io_ready1;
wire io_ready2;

wire end_of_sdi_latch;

wire sample_sdo;

(* direct_enable = "yes" *) wire cs_gen;
Expand Down Expand Up @@ -200,8 +199,7 @@ module spi_engine_execution #(
.trigger_tx(trigger_tx),
.trigger_rx(trigger_rx),
.first_bit(first_bit),
.cs_activate(cs_activate),
.end_of_sdi_latch(end_of_sdi_latch));
.cs_activate(cs_activate));

assign sample_sdo = sdo_data_valid && ((trigger_tx && last_bit) || (wait_for_io || exec_transfer_cmd));

Expand Down Expand Up @@ -244,6 +242,7 @@ module spi_engine_execution #(
sdo_idle_state <= SDO_DEFAULT;
clk_div <= DEFAULT_CLK_DIV;
word_length <= DATA_WIDTH;
last_bit_count <= DATA_WIDTH-1;
left_aligned <= 8'b0;
end else if (exec_write_cmd == 1'b1) begin
if (cmd[9:8] == REG_CONFIG) begin
Expand All @@ -256,6 +255,7 @@ module spi_engine_execution #(
end else if (cmd[9:8] == REG_WORD_LENGTH) begin
// the max value of this reg must be DATA_WIDTH
word_length <= cmd[7:0];
last_bit_count <= cmd[7:0] - 1;
left_aligned <= DATA_WIDTH - cmd[7:0];
end
end
Expand Down Expand Up @@ -331,7 +331,7 @@ module spi_engine_execution #(
end else begin
case (inst_d1)
CMD_TRANSFER: begin
if (transfer_active == 1'b0 && wait_for_io == 1'b0 && end_of_sdi_latch == 1'b1)
if (transfer_active == 1'b0 && wait_for_io == 1'b0)
idle <= 1'b1;
end
CMD_CHIPSELECT: begin
Expand Down Expand Up @@ -446,7 +446,7 @@ module spi_engine_execution #(
// end_of_word will signal the end of a transaction, pushing the command
// stream execution to the next command. end_of_word in normal mode can be
// generated using the global bit_counter
assign last_bit = bit_counter == word_length - 1;
assign last_bit = (bit_counter == last_bit_count);
assign end_of_word = last_bit == 1'b1 && ntx_rx == 1'b1 && clk_div_last == 1'b1;

always @(posedge clk) begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ module spi_engine_execution_shiftreg #(
input trigger_tx,
input trigger_rx,
input first_bit,
input cs_activate,
output end_of_sdi_latch
input cs_activate
);

reg [ 7:0] sdi_counter = 8'b0;
Expand Down Expand Up @@ -156,9 +155,7 @@ module spi_engine_execution_shiftreg #(
generate
if (ECHO_SCLK == 1) begin : g_echo_sclk_miso_latch

reg [7:0] sdi_counter_d = 8'b0;
reg [7:0] sdi_transfer_counter = 8'b0;
reg [7:0] num_of_transfers = 8'b0;
reg last_sdi_bit_r;
reg [(NUM_OF_SDI * DATA_WIDTH)-1:0] sdi_data_latch = {(NUM_OF_SDI * DATA_WIDTH){1'b0}};

if ((DEFAULT_SPI_CFG[1:0] == 2'b01) || (DEFAULT_SPI_CFG[1:0] == 2'b10)) begin : g_echo_miso_nshift_reg
Expand All @@ -185,10 +182,10 @@ module spi_engine_execution_shiftreg #(
always @(posedge echo_sclk or posedge cs_activate) begin
if (cs_activate) begin
sdi_counter <= 8'b0;
sdi_counter_d <= 8'b0;
last_sdi_bit_r <= 1'b0;
end else begin
sdi_counter <= (sdi_counter == word_length-1) ? 8'b0 : sdi_counter + 1'b1;
sdi_counter_d <= sdi_counter;
last_sdi_bit_r <= (sdi_counter == word_length - 1); // FIXME: potentially unsafe path: what are the guarantees of settling time between changing word_length and first echo_sclk edge?
sdi_counter <= (sdi_counter == word_length - 1) ? 8'b0 : sdi_counter + 1'b1;
end
end

Expand All @@ -214,17 +211,17 @@ module spi_engine_execution_shiftreg #(
always @(posedge echo_sclk or posedge cs_activate) begin
if (cs_activate) begin
sdi_counter <= 8'b0;
sdi_counter_d <= 8'b0;
last_sdi_bit_r <= 1'b0;
end else begin
sdi_counter <= (sdi_counter == word_length-1) ? 8'b0 : sdi_counter + 1'b1;
sdi_counter_d <= sdi_counter;
last_sdi_bit_r <= (sdi_counter == word_length - 1); // FIXME: potentially unsafe path: what are the guarantees of settling time between changing word_length and first echo_sclk edge?
sdi_counter <= (sdi_counter == word_length - 1) ? 8'b0 : sdi_counter + 1'b1;
end
end

end

assign sdi_data = sdi_data_latch;
assign last_sdi_bit = (sdi_counter == 0) && (sdi_counter_d == word_length-1);
assign last_sdi_bit = last_sdi_bit_r;

// sdi_data_valid is synchronous to SPI clock, so synchronize the
// last_sdi_bit to SPI clock
Expand All @@ -250,34 +247,10 @@ module spi_engine_execution_shiftreg #(
end
end

always @(posedge clk) begin
if (cs_activate) begin
num_of_transfers <= 8'b0;
end else begin
if (current_instr == CMD_TRANSFER) begin
// current_cmd contains the NUM_OF_TRANSFERS - 1
num_of_transfers <= current_cmd[7:0] + 1'b1;
end
end
end

always @(posedge clk) begin
if (cs_activate) begin
sdi_transfer_counter <= 0;
end else if (last_sdi_bit_m[2] == 1'b0 &&
last_sdi_bit_m[1] == 1'b1) begin
sdi_transfer_counter <= sdi_transfer_counter + 1'b1;
end
end

assign end_of_sdi_latch = last_sdi_bit_m[2] & (sdi_transfer_counter == num_of_transfers);

end /* g_echo_sclk_miso_latch */
else
begin : g_sclk_miso_latch

assign end_of_sdi_latch = 1'b1;

for (i=0; i<NUM_OF_SDI; i=i+1) begin: g_sdi_shift_reg

reg [DATA_WIDTH-1:0] data_sdi_shift;
Expand Down
Loading