From 1d7ebb892387f4632c30485416f6fb3140e81b26 Mon Sep 17 00:00:00 2001 From: Laez Barbosa 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 --- .../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 cb9ded9068..181c936c8a 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 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 --- 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 152e6f9555..6f0bc564cb 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 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 --- 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 6f0bc564cb..fdf05340c8 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 181c936c8a..217a5e0e9f 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 Date: Mon, 23 Oct 2023 11:31:40 -0300 Subject: [PATCH 4/4] Removed trailing whitespace Signed-off-by: Laez Barbosa --- 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 217a5e0e9f..418d2f01c4 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);