From ed1483adee271dc6650b44c122e5b195857c0588 Mon Sep 17 00:00:00 2001 From: Laez Barbosa Date: Thu, 15 Aug 2024 14:29:23 -0300 Subject: [PATCH 1/4] SPI Engine Execution: split counters Split up the different counters for better readability. Might synthesize down to slightly larger logic. Signed-off-by: Laez Barbosa --- .../spi_engine_execution.v | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 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 e759da3ea4..ce5fd58053 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -105,13 +105,12 @@ module spi_engine_execution #( reg [7:0] clk_div_counter_next = 'h00; reg clk_div_last; - reg [(BIT_COUNTER_WIDTH+8):0] counter = 'h00; - - wire [7:0] sleep_counter = counter[(BIT_COUNTER_WIDTH+8):(BIT_COUNTER_WIDTH+1)]; - wire [1:0] cs_sleep_counter = counter[(BIT_COUNTER_WIDTH+2):(BIT_COUNTER_WIDTH+1)]; - wire [(BIT_COUNTER_WIDTH-1):0] bit_counter = counter[BIT_COUNTER_WIDTH:1]; - wire [7:0] transfer_counter = counter[(BIT_COUNTER_WIDTH+8):(BIT_COUNTER_WIDTH+1)]; - wire ntx_rx = counter[0]; + reg [7:0] sleep_counter; + wire [1:0] cs_sleep_counter = sleep_counter[1:0]; + reg [(BIT_COUNTER_WIDTH-1):0] bit_counter; + reg [7:0] transfer_counter; + reg ntx_rx; + reg sleep_counter_increment; reg trigger = 1'b0; reg trigger_next = 1'b0; @@ -269,12 +268,24 @@ module spi_engine_execution #( always @(posedge clk) begin if (idle == 1'b1 || (cs_sleep_counter_compare && !cs_sleep_repeat && inst_d1 == CMD_CHIPSELECT)) begin - counter <= 'h00; + bit_counter <= 'h0; + transfer_counter <= 'h0; + sleep_counter <= 'h0; + ntx_rx <= 1'b0; + sleep_counter_increment <= 1'b0; end else if (clk_div_last == 1'b1 && wait_for_io == 1'b0) begin if (bit_counter == word_length && transfer_active) begin - counter <= (counter & BIT_COUNTER_CLEAR) + 'h1 + BIT_COUNTER_CARRY; + bit_counter <= 'h0; + transfer_counter <= transfer_counter + 1; + ntx_rx <= ~ntx_rx; end else begin - counter <= counter + (transfer_active ? 'h1 : (2**BIT_COUNTER_WIDTH)); + if (transfer_active) begin + bit_counter <= bit_counter + ntx_rx; + ntx_rx <= ~ntx_rx; + end else begin + sleep_counter_increment <= ~sleep_counter_increment; + sleep_counter <= sleep_counter + sleep_counter_increment; + end end end end From 3c56531d5057a1e1c70cad0af9fd06afd12a8981 Mon Sep 17 00:00:00 2001 From: Laez Barbosa Date: Thu, 15 Aug 2024 16:11:24 -0300 Subject: [PATCH 2/4] SPI Engine Execution: split shift register logic Moved shift register logic to separate module Signed-off-by: Laez Barbosa --- .../spi_engine/spi_engine_execution/Makefile | 1 + .../spi_engine_execution.v | 258 ++------------- .../spi_engine_execution_hw.tcl | 3 +- .../spi_engine_execution_ip.tcl | 57 ++-- .../spi_engine_execution_shiftreg.v | 295 ++++++++++++++++++ 5 files changed, 361 insertions(+), 253 deletions(-) create mode 100644 library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v diff --git a/library/spi_engine/spi_engine_execution/Makefile b/library/spi_engine/spi_engine_execution/Makefile index 30f20717be..dd5ed79796 100644 --- a/library/spi_engine/spi_engine_execution/Makefile +++ b/library/spi_engine/spi_engine_execution/Makefile @@ -7,6 +7,7 @@ LIBRARY_NAME := spi_engine_execution GENERIC_DEPS += spi_engine_execution.v +GENERIC_DEPS += spi_engine_execution_shiftreg.v XILINX_DEPS += spi_engine_execution_constr.ttcl XILINX_DEPS += spi_engine_execution_ip.tcl 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 ce5fd58053..12876729f4 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -56,11 +56,11 @@ module spi_engine_execution #( input [15:0] cmd, input sdo_data_valid, - output reg sdo_data_ready, + output sdo_data_ready, input [(DATA_WIDTH-1):0] sdo_data, input sdi_data_ready, - output reg sdi_data_valid, + output sdi_data_valid, output [(NUM_OF_SDI * DATA_WIDTH)-1:0] sdi_data, input sync_ready, @@ -124,8 +124,6 @@ module spi_engine_execution #( reg [7:0] left_aligned = 8'b0; wire end_of_word; - reg [7:0] sdi_counter = 8'b0; - assign first_bit = ((bit_counter == 'h0) || (bit_counter == word_length)); reg [15:0] cmd_d1; @@ -140,10 +138,6 @@ module spi_engine_execution #( reg sdo_enabled = 1'b0; reg sdi_enabled = 1'b0; - reg [(DATA_WIDTH-1):0] data_sdo_shift = 'h0; - - reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}}; - wire [2:0] inst = cmd[14:12]; wire [2:0] inst_d1 = cmd_d1[14:12]; @@ -166,13 +160,43 @@ module spi_engine_execution #( wire io_ready1; wire io_ready2; - wire trigger_rx_s; - wire last_sdi_bit; wire end_of_sdi_latch; (* direct_enable = "yes" *) wire cs_gen; + spi_engine_execution_shiftreg #( + .DEFAULT_SPI_CFG(DEFAULT_SPI_CFG), + .DATA_WIDTH(DATA_WIDTH), // Valid data widths values are 8/16/24/32 + .NUM_OF_SDI(NUM_OF_SDI), + .SDI_DELAY(SDI_DELAY), + .ECHO_SCLK(ECHO_SCLK), + .CMD_TRANSFER(CMD_TRANSFER) + ) shiftreg ( + .clk(clk), + .resetn(resetn), + .sdi(sdi), + .sdo_int(sdo_int_s), + .echo_sclk(echo_sclk), + .sdo_data(sdo_data), + .sdo_data_valid(sdo_data_valid), + .sdo_data_ready(sdo_data_ready), + .sdi_data(sdi_data), + .sdi_data_valid(sdi_data_valid), + .sdi_data_ready(sdi_data_ready), + .sdo_enabled(sdo_enabled), + .sdi_enabled(sdi_enabled), + .current_instr(inst_d1), + .sdo_idle_state(sdo_idle_state), + .left_aligned(left_aligned), + .word_length(word_length), + .transfer_active(transfer_active), + .trigger_tx(trigger_tx), + .trigger_rx(trigger_rx), + .first_bit(first_bit), + .cs_activate(cs_activate), + .end_of_sdi_latch(end_of_sdi_latch)); + assign cs_gen = inst_d1 == CMD_CHIPSELECT && ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit) && (cs_sleep_repeat == 1'b0) @@ -355,15 +379,6 @@ module spi_engine_execution #( assign sync = cmd_d1[7:0]; - always @(posedge clk) begin - if (resetn == 1'b0) - sdo_data_ready <= 1'b0; - else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1) - sdo_data_ready <= 1'b1; - else if (sdo_data_valid == 1'b1) - sdo_data_ready <= 1'b0; - end - assign io_ready1 = (sdi_data_valid == 1'b0 || sdi_data_ready == 1'b1) && (sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1); assign io_ready2 = (sdi_enabled == 1'b0 || sdi_data_ready == 1'b1) && @@ -412,42 +427,6 @@ module spi_engine_execution #( end end - // Load the SDO parallel data into the SDO shift register. In case of a custom - // data width, additional bit shifting must done at load. - always @(posedge clk) begin - if (!sdo_enabled || (inst_d1 != CMD_TRANSFER)) begin - data_sdo_shift <= {DATA_WIDTH{sdo_idle_state}}; - end else if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin - if (first_bit == 1'b1) - data_sdo_shift <= sdo_data << left_aligned; - else - data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0}; - end - end - - assign sdo_int_s = data_sdo_shift[DATA_WIDTH-1]; - - // In case of an interface with high clock rate (SCLK > 50MHz), the latch of - // the SDI line can be delayed with 1, 2 or 3 SPI core clock cycle. - // Taking the fact that in high SCLK frequencies the pre-scaler most likely will - // be set to 0, to reduce the core clock's speed, this delay will mean that SDI will - // be latched at one of the next consecutive SCLK edge. - - always @(posedge clk) begin - trigger_rx_d <= {trigger_rx_d, trigger_rx}; - end - - assign trigger_rx_s = trigger_rx_d[SDI_DELAY+1]; - - // Load the serial data into SDI shift register(s), then link it to the output - // register of the module - // NOTE: ECHO_SCLK mode can be used when the SCLK line is looped back to the FPGA - // through an other level shifter, in order to remove the round-trip timing delays - // introduced by the level shifters. This can improve the timing significantly - // on higher SCLK rates. Devices like ad4630 have an echod SCLK, which can be - // used to latch the MISO lines, improving the overall timing margin of the - // interface. - always @(posedge clk) begin if (!resetn) begin // set cs_activate during reset for a cycle to clear shift reg cs_activate <= 1; @@ -456,175 +435,6 @@ module spi_engine_execution #( end end - genvar i; - - // NOTE: SPI configuration (CPOL/PHA) is only hardware configurable at this point - 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 [(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 - - // MISO shift register runs on negative echo_sclk - for (i=0; i +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module spi_engine_execution_shiftreg #( + + parameter DEFAULT_SPI_CFG = 0, + parameter DATA_WIDTH = 8, // Valid data widths values are 8/16/24/32 + parameter NUM_OF_SDI = 1, + parameter [1:0] SDI_DELAY = 2'b00, + parameter ECHO_SCLK = 0, + parameter [2:0]CMD_TRANSFER = 3'b000 +) ( + input clk, + input resetn, + + // spi io + input sdi, + output sdo_int, + input echo_sclk, + + // spi data + input [(DATA_WIDTH-1):0] sdo_data, + input sdo_data_valid, + output reg sdo_data_ready, + output [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, + output reg sdi_data_valid, + input sdi_data_ready, + + // cfg and status + input sdo_enabled, + input sdi_enabled, + input [2:0] current_instr, + input sdo_idle_state, + input [7:0] left_aligned, + input [7:0] word_length, + + // timing from main fsm + input transfer_active, + input trigger_tx, + input trigger_rx, + input first_bit, + input cs_activate, + output end_of_sdi_latch +); + + reg [7:0] sdi_counter = 8'b0; + reg [(DATA_WIDTH-1):0] data_sdo_shift = 'h0; + wire last_sdi_bit; + reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}}; + wire trigger_rx_s; + + always @(posedge clk) begin + if (resetn == 1'b0) + sdo_data_ready <= 1'b0; + else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1) + sdo_data_ready <= 1'b1; + else if (sdo_data_valid == 1'b1) + sdo_data_ready <= 1'b0; + end + + // Load the SDO parallel data into the SDO shift register. In case of a custom + // data width, additional bit shifting must done at load. + always @(posedge clk) begin + if (!sdo_enabled || (current_instr != CMD_TRANSFER)) begin + data_sdo_shift <= {DATA_WIDTH{sdo_idle_state}}; + end else if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin + if (first_bit == 1'b1) + data_sdo_shift <= sdo_data << left_aligned; //TODO: check if this could/should be pipelined + else + data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0}; + end + end + assign sdo_int = data_sdo_shift[DATA_WIDTH-1]; + + // In case of an interface with high clock rate (SCLK > 50MHz), the latch of + // the SDI line can be delayed with 1, 2 or 3 SPI core clock cycle. + // Taking the fact that in high SCLK frequencies the pre-scaler most likely will + // be set to 0, to reduce the core clock's speed, this delay will mean that SDI will + // be latched at one of the next consecutive SCLK edge. + always @(posedge clk) begin + trigger_rx_d <= {trigger_rx_d, trigger_rx}; + end + assign trigger_rx_s = trigger_rx_d[SDI_DELAY+1]; + + // Load the serial data into SDI shift register(s), then link it to the output + // register of the module + // NOTE: ECHO_SCLK mode can be used when the SCLK line is looped back to the FPGA + // through an other level shifter, in order to remove the round-trip timing delays + // introduced by the level shifters. This can improve the timing significantly + // on higher SCLK rates. Devices like ad4630 have an echod SCLK, which can be + // used to latch the MISO lines, improving the overall timing margin of the + // interface. + + genvar i; + // NOTE: SPI configuration (CPOL/PHA) is only hardware configurable at this point, unless ECHO_SCLK=0 + 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 [(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 + + // MISO shift register runs on negative echo_sclk + for (i=0; i Date: Thu, 15 Aug 2024 16:52:17 -0300 Subject: [PATCH 3/4] SPI Engine Execution: pipeline sdo alignment Split path between sdo data input and sdo shift register, which includes a barrel shifter. Signed-off-by: Laez Barbosa --- docs/regmap/adi_regmap_spi_engine.txt | 4 +- .../axi_spi_engine/axi_spi_engine.v | 2 +- .../spi_engine_execution.v | 10 +++- .../spi_engine_execution_shiftreg.v | 49 ++++++++++++++----- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/docs/regmap/adi_regmap_spi_engine.txt b/docs/regmap/adi_regmap_spi_engine.txt index 681c37d45d..908b04bf33 100644 --- a/docs/regmap/adi_regmap_spi_engine.txt +++ b/docs/regmap/adi_regmap_spi_engine.txt @@ -9,7 +9,7 @@ ENDTITLE REG 0x00 VERSION -Version of the peripheral. Follows semantic versioning. Current version 1.03.00. +Version of the peripheral. Follows semantic versioning. Current version 1.03.01. ENDREG FIELD @@ -25,7 +25,7 @@ RO ENDFIELD FIELD -[7:0] 0x00000000 +[7:0] 0x00000001 VERSION_PATCH RO ENDFIELD diff --git a/library/spi_engine/axi_spi_engine/axi_spi_engine.v b/library/spi_engine/axi_spi_engine/axi_spi_engine.v index f91e00eb26..2c0a9f37c9 100644 --- a/library/spi_engine/axi_spi_engine/axi_spi_engine.v +++ b/library/spi_engine/axi_spi_engine/axi_spi_engine.v @@ -133,7 +133,7 @@ module axi_spi_engine #( input [7:0] offload_sync_data ); - localparam PCORE_VERSION = 'h010300; + localparam PCORE_VERSION = 'h010301; localparam S_AXI = 0; localparam UP_FIFO = 1; 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 12876729f4..f0a58bcc93 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -163,6 +163,8 @@ module spi_engine_execution #( wire end_of_sdi_latch; + wire sample_sdo; + (* direct_enable = "yes" *) wire cs_gen; spi_engine_execution_shiftreg #( @@ -186,10 +188,12 @@ module spi_engine_execution #( .sdi_data_ready(sdi_data_ready), .sdo_enabled(sdo_enabled), .sdi_enabled(sdi_enabled), - .current_instr(inst_d1), + .current_cmd(cmd_d1), .sdo_idle_state(sdo_idle_state), .left_aligned(left_aligned), .word_length(word_length), + .sample_sdo(sample_sdo), + .sdo_io_ready(sdo_io_ready), .transfer_active(transfer_active), .trigger_tx(trigger_tx), .trigger_rx(trigger_rx), @@ -197,6 +201,8 @@ module spi_engine_execution #( .cs_activate(cs_activate), .end_of_sdi_latch(end_of_sdi_latch)); + assign sample_sdo = sdo_data_valid && ((trigger_tx && last_bit) || (wait_for_io || exec_transfer_cmd)); + assign cs_gen = inst_d1 == CMD_CHIPSELECT && ((cs_sleep_counter_compare == 1'b1) || cs_sleep_early_exit) && (cs_sleep_repeat == 1'b0) @@ -380,7 +386,7 @@ module spi_engine_execution #( assign sync = cmd_d1[7:0]; assign io_ready1 = (sdi_data_valid == 1'b0 || sdi_data_ready == 1'b1) && - (sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1); + (sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_io_ready == 1'b1); assign io_ready2 = (sdi_enabled == 1'b0 || sdi_data_ready == 1'b1) && (sdo_enabled == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1); diff --git a/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v b/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v index 6f3e999177..428c09797d 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v @@ -48,7 +48,7 @@ module spi_engine_execution_shiftreg #( input resetn, // spi io - input sdi, + input [NUM_OF_SDI-1:0] sdi, output sdo_int, input echo_sclk, @@ -63,12 +63,14 @@ module spi_engine_execution_shiftreg #( // cfg and status input sdo_enabled, input sdi_enabled, - input [2:0] current_instr, + input [15:0] current_cmd, input sdo_idle_state, input [7:0] left_aligned, input [7:0] word_length, // timing from main fsm + input sample_sdo, + output reg sdo_io_ready, input transfer_active, input trigger_tx, input trigger_rx, @@ -79,17 +81,37 @@ module spi_engine_execution_shiftreg #( reg [7:0] sdi_counter = 8'b0; reg [(DATA_WIDTH-1):0] data_sdo_shift = 'h0; + reg [(DATA_WIDTH-1):0] aligned_sdo_data, sdo_data_d; wire last_sdi_bit; reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}}; wire trigger_rx_s; + wire [2:0] current_instr = current_cmd[14:12]; always @(posedge clk) begin - if (resetn == 1'b0) + if (resetn == 1'b0) begin sdo_data_ready <= 1'b0; - else if (sdo_enabled == 1'b1 && first_bit == 1'b1 && trigger_tx == 1'b1 && transfer_active == 1'b1) + end else if (sdo_toshiftreg) begin sdo_data_ready <= 1'b1; - else if (sdo_data_valid == 1'b1) + end else if (sdo_data_valid == 1'b1) begin sdo_data_ready <= 1'b0; + end + end + + // pipelined shifter for sdo_data + always @(posedge clk ) begin + if (resetn == 1'b0) begin + aligned_sdo_data <= 0; + sdo_io_ready <= 1'b0; + end else begin + if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin + sdo_io_ready <= 1'b0; + end + if (sample_sdo) begin + sdo_data_d <= sdo_data; + sdo_io_ready <= 1'b1; + end + aligned_sdo_data <= sdo_data_d << left_aligned; + end end // Load the SDO parallel data into the SDO shift register. In case of a custom @@ -98,13 +120,16 @@ module spi_engine_execution_shiftreg #( if (!sdo_enabled || (current_instr != CMD_TRANSFER)) begin data_sdo_shift <= {DATA_WIDTH{sdo_idle_state}}; end else if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin - if (first_bit == 1'b1) - data_sdo_shift <= sdo_data << left_aligned; //TODO: check if this could/should be pipelined - else - data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0}; + if (first_bit == 1'b1) begin + data_sdo_shift <= aligned_sdo_data; + end else begin + data_sdo_shift <= {data_sdo_shift[(DATA_WIDTH-2):0], 1'b0}; + end end end assign sdo_int = data_sdo_shift[DATA_WIDTH-1]; + assign sdo_toshiftreg = (transfer_active && trigger_tx && first_bit && sdo_enabled); + // In case of an interface with high clock rate (SCLK > 50MHz), the latch of // the SDI line can be delayed with 1, 2 or 3 SPI core clock cycle. @@ -203,7 +228,7 @@ module spi_engine_execution_shiftreg #( // sdi_data_valid is synchronous to SPI clock, so synchronize the // last_sdi_bit to SPI clock - reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: bad synchronizer (cs_activate shouldn't be connected here), also why not just use sync_bits? + reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: why not just use sync_bits? always @(posedge clk) begin if (cs_activate) begin last_sdi_bit_m <= 4'b0; @@ -228,8 +253,8 @@ module spi_engine_execution_shiftreg #( if (cs_activate) begin num_of_transfers <= 8'b0; end else begin - if (cmd_d1[15:12] == 4'b0) begin - num_of_transfers <= cmd_d1[7:0] + 1'b1; // cmd_d1 contains the NUM_OF_TRANSFERS - 1 + if (current_instr == CMD_TRANSFER) begin + num_of_transfers <= current_cmd[7:0] + 1'b1; // current_cmd contains the NUM_OF_TRANSFERS - 1 end end end From 831e115143fb58ce34bbb40a2cebd22ad911c233 Mon Sep 17 00:00:00 2001 From: Laez Barbosa Date: Mon, 11 Nov 2024 14:50:46 -0300 Subject: [PATCH 4/4] Guidelines fix Signed-off-by: Laez Barbosa --- .../spi_engine_execution.v | 14 ++-- .../spi_engine_execution_shiftreg.v | 72 ++++++++++--------- 2 files changed, 45 insertions(+), 41 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 f0a58bcc93..4dd61f6732 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -96,7 +96,6 @@ module spi_engine_execution #( localparam BIT_COUNTER_CLEAR = {{8{1'b1}}, {BIT_COUNTER_WIDTH{1'b0}}, 1'b1}; reg sclk_int = 1'b0; - wire sdo_int_s; reg sdo_t_int = 1'b0; reg idle; @@ -106,7 +105,6 @@ module spi_engine_execution #( reg clk_div_last; reg [7:0] sleep_counter; - wire [1:0] cs_sleep_counter = sleep_counter[1:0]; reg [(BIT_COUNTER_WIDTH-1):0] bit_counter; reg [7:0] transfer_counter; reg ntx_rx; @@ -117,12 +115,9 @@ module spi_engine_execution #( reg wait_for_io = 1'b0; reg transfer_active = 1'b0; - wire last_bit; - wire first_bit; reg last_transfer; reg [7:0] word_length = DATA_WIDTH; reg [7:0] left_aligned = 8'b0; - wire end_of_word; assign first_bit = ((bit_counter == 'h0) || (bit_counter == word_length)); @@ -138,6 +133,12 @@ module spi_engine_execution #( reg sdo_enabled = 1'b0; reg sdi_enabled = 1'b0; + wire sdo_int_s; + + wire last_bit; + wire first_bit; + wire end_of_word; + wire [2:0] inst = cmd[14:12]; wire [2:0] inst_d1 = cmd_d1[14:12]; @@ -152,6 +153,7 @@ module spi_engine_execution #( wire trigger_tx; wire trigger_rx; + wire [1:0] cs_sleep_counter = sleep_counter[1:0]; wire sleep_counter_compare; wire cs_sleep_counter_compare; wire cs_sleep_early_exit; @@ -169,7 +171,7 @@ module spi_engine_execution #( spi_engine_execution_shiftreg #( .DEFAULT_SPI_CFG(DEFAULT_SPI_CFG), - .DATA_WIDTH(DATA_WIDTH), // Valid data widths values are 8/16/24/32 + .DATA_WIDTH(DATA_WIDTH), .NUM_OF_SDI(NUM_OF_SDI), .SDI_DELAY(SDI_DELAY), .ECHO_SCLK(ECHO_SCLK), diff --git a/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v b/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v index 428c09797d..2298a20861 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution_shiftreg.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2015-2024 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2024 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -38,54 +38,56 @@ module spi_engine_execution_shiftreg #( parameter DEFAULT_SPI_CFG = 0, - parameter DATA_WIDTH = 8, // Valid data widths values are 8/16/24/32 + parameter DATA_WIDTH = 8, parameter NUM_OF_SDI = 1, parameter [1:0] SDI_DELAY = 2'b00, parameter ECHO_SCLK = 0, parameter [2:0]CMD_TRANSFER = 3'b000 ) ( - input clk, - input resetn, + input clk, + input resetn, // spi io - input [NUM_OF_SDI-1:0] sdi, - output sdo_int, - input echo_sclk, + input [NUM_OF_SDI-1:0] sdi, + output sdo_int, + input echo_sclk, // spi data - input [(DATA_WIDTH-1):0] sdo_data, - input sdo_data_valid, - output reg sdo_data_ready, - output [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, - output reg sdi_data_valid, - input sdi_data_ready, + input [(DATA_WIDTH-1):0] sdo_data, + input sdo_data_valid, + output reg sdo_data_ready, + + output [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, + output reg sdi_data_valid, + input sdi_data_ready, // cfg and status - input sdo_enabled, - input sdi_enabled, - input [15:0] current_cmd, - input sdo_idle_state, - input [7:0] left_aligned, - input [7:0] word_length, + input sdo_enabled, + input sdi_enabled, + input [15:0] current_cmd, + input sdo_idle_state, + input [ 7:0] left_aligned, + input [ 7:0] word_length, // timing from main fsm - input sample_sdo, - output reg sdo_io_ready, - input transfer_active, - input trigger_tx, - input trigger_rx, - input first_bit, - input cs_activate, - output end_of_sdi_latch + input sample_sdo, + output reg sdo_io_ready, + input transfer_active, + input trigger_tx, + input trigger_rx, + input first_bit, + input cs_activate, + output end_of_sdi_latch ); - reg [7:0] sdi_counter = 8'b0; + reg [ 7:0] sdi_counter = 8'b0; reg [(DATA_WIDTH-1):0] data_sdo_shift = 'h0; + reg [ SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}}; reg [(DATA_WIDTH-1):0] aligned_sdo_data, sdo_data_d; - wire last_sdi_bit; - reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}}; - wire trigger_rx_s; - wire [2:0] current_instr = current_cmd[14:12]; + + wire trigger_rx_s; + wire [2:0] current_instr = current_cmd[14:12]; + wire last_sdi_bit; always @(posedge clk) begin if (resetn == 1'b0) begin @@ -130,7 +132,6 @@ module spi_engine_execution_shiftreg #( assign sdo_int = data_sdo_shift[DATA_WIDTH-1]; assign sdo_toshiftreg = (transfer_active && trigger_tx && first_bit && sdo_enabled); - // In case of an interface with high clock rate (SCLK > 50MHz), the latch of // the SDI line can be delayed with 1, 2 or 3 SPI core clock cycle. // Taking the fact that in high SCLK frequencies the pre-scaler most likely will @@ -228,7 +229,7 @@ module spi_engine_execution_shiftreg #( // sdi_data_valid is synchronous to SPI clock, so synchronize the // last_sdi_bit to SPI clock - reg [3:0] last_sdi_bit_m = 4'b0; //FIXME: why not just use sync_bits? + reg [3:0] last_sdi_bit_m = 4'b0; always @(posedge clk) begin if (cs_activate) begin last_sdi_bit_m <= 4'b0; @@ -254,7 +255,8 @@ module spi_engine_execution_shiftreg #( num_of_transfers <= 8'b0; end else begin if (current_instr == CMD_TRANSFER) begin - num_of_transfers <= current_cmd[7:0] + 1'b1; // current_cmd contains the NUM_OF_TRANSFERS - 1 + // current_cmd contains the NUM_OF_TRANSFERS - 1 + num_of_transfers <= current_cmd[7:0] + 1'b1; end end end