From 1d7ebb892387f4632c30485416f6fb3140e81b26 Mon Sep 17 00:00:00 2001
From: Laez Barbosa <laez.barbosa@analog.com>
Date: Tue, 10 Oct 2023 19:26:51 -0300
Subject: [PATCH 1/4] 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>
---
 .../spi_engine_execution.v                    | 28 +++++++++++++++----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/library/spi_engine/spi_engine_execution/spi_engine_execution.v b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
index cb9ded90689..181c936c8ab 100644
--- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v
+++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
@@ -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,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
@@ -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);
 
   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

From f31d408295c76545e1286bc41a8ef0c3d657183f Mon Sep 17 00:00:00 2001
From: Laez Barbosa <laez.barbosa@analog.com>
Date: Tue, 17 Oct 2023 16:01:10 -0300
Subject: [PATCH 2/4] Fixed documentation on delay from chip-select instruction
 to match hw behaviour.

Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
---
 docs/library/spi_engine/instruction-format.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/library/spi_engine/instruction-format.rst b/docs/library/spi_engine/instruction-format.rst
index 152e6f9555e..6f0bc564cbc 100644
--- a/docs/library/spi_engine/instruction-format.rst
+++ b/docs/library/spi_engine/instruction-format.rst
@@ -69,7 +69,7 @@ instruction is twice the delay.
 
 .. math::
 
-   delay = t * \frac{div + 1}{f_{clk}}
+   delay = t * \frac{(div + 1)*2}{f_{clk}}
 
 .. list-table::
    :widths: 10 15 75

From b0d0039c025b67fa80ec8743420cafb98c7dbfc2 Mon Sep 17 00:00:00 2001
From: Laez Barbosa <laez.barbosa@analog.com>
Date: Mon, 23 Oct 2023 10:18:59 -0300
Subject: [PATCH 3/4] Fixed CS and Sleep instructions to work with prescaler
 values other than 0. Updated delay documentation to match behavior.

Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
---
 docs/library/spi_engine/instruction-format.rst       |  8 +++++---
 .../spi_engine_execution/spi_engine_execution.v      | 12 ++++++------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/docs/library/spi_engine/instruction-format.rst b/docs/library/spi_engine/instruction-format.rst
index 6f0bc564cbc..fdf05340c8b 100644
--- a/docs/library/spi_engine/instruction-format.rst
+++ b/docs/library/spi_engine/instruction-format.rst
@@ -65,7 +65,8 @@ 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::
 
@@ -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
diff --git a/library/spi_engine/spi_engine_execution/spi_engine_execution.v b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
index 181c936c8ab..217a5e0e9ff 100644
--- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v
+++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
@@ -169,7 +169,8 @@ 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;
@@ -243,9 +244,9 @@ 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 cs_sleep_early_exit = (cmd_d1[9:8] == 0);
+  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 (resetn == 1'b0) begin
@@ -257,7 +258,6 @@ module spi_engine_execution #(
         cs_sleep_repeat <= !cs_sleep_repeat;
       end
     end
-    
   end
 
   always @(posedge clk) begin
@@ -265,7 +265,7 @@ module spi_engine_execution #(
       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 : (2**BIT_COUNTER_WIDTH)) + 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 : (2**BIT_COUNTER_WIDTH));
       end

From 18eda1bdcd63071656062cfe63f36def26b2692d Mon Sep 17 00:00:00 2001
From: Laez Barbosa <laez.barbosa@analog.com>
Date: Mon, 23 Oct 2023 11:31:40 -0300
Subject: [PATCH 4/4] Removed trailing whitespace

Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>
---
 library/spi_engine/spi_engine_execution/spi_engine_execution.v | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/spi_engine/spi_engine_execution/spi_engine_execution.v b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
index 217a5e0e9ff..418d2f01c41 100644
--- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v
+++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v
@@ -169,7 +169,7 @@ module spi_engine_execution #(
 
   (* direct_enable = "yes" *) wire cs_gen;
 
-  assign cs_gen = inst_d1 == CMD_CHIPSELECT 
+  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);