diff --git a/docs/regmap/adi_regmap_spi_engine.txt b/docs/regmap/adi_regmap_spi_engine.txt index 46833de568..371bfa6612 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.01. +Version of the peripheral. Follows semantic versioning. Current version 1.04.00. ENDREG FIELD @@ -19,13 +19,13 @@ RO ENDFIELD FIELD -[15:8] 0x00000003 +[15:8] 0x00000004 VERSION_MINOR RO ENDFIELD FIELD -[7:0] 0x00000001 +[7:0] 0x00000000 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 2c0a9f37c9..b1072f8961 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 = 'h010301; + localparam PCORE_VERSION = 'h010400; 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 4dd61f6732..9c579d7aad 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -132,6 +132,8 @@ module spi_engine_execution #( reg sdo_enabled = 1'b0; reg sdi_enabled = 1'b0; + wire sdo_enabled_io; + wire sdi_enabled_io; wire sdo_int_s; @@ -165,7 +167,7 @@ module spi_engine_execution #( wire end_of_sdi_latch; - wire sample_sdo; + wire sdo_io_ready; (* direct_enable = "yes" *) wire cs_gen; @@ -194,7 +196,6 @@ module spi_engine_execution #( .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), @@ -203,8 +204,6 @@ 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) @@ -217,6 +216,8 @@ module spi_engine_execution #( sdi_enabled <= cmd[9]; end end + assign sdo_enabled_io = (exec_transfer_cmd) ? cmd[8] : sdo_enabled; + assign sdi_enabled_io = (exec_transfer_cmd) ? cmd[9] : sdi_enabled; always @(posedge clk) begin if (cmd_ready & cmd_valid) @@ -388,9 +389,9 @@ 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_io_ready == 1'b1); + (sdo_enabled_io == 1'b0 || 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); + (sdo_enabled_io == 1'b0 || last_transfer == 1'b1 || sdo_io_ready == 1'b1); always @(posedge clk) begin if (idle == 1'b1) begin @@ -409,14 +410,11 @@ module spi_engine_execution #( wait_for_io <= 1'b0; end else begin if (exec_transfer_cmd == 1'b1) begin - wait_for_io <= 1'b1; - transfer_active <= 1'b0; + wait_for_io <= !io_ready1; + transfer_active <= io_ready1; end else if (wait_for_io == 1'b1 && io_ready1 == 1'b1) begin wait_for_io <= 1'b0; - if (last_transfer == 1'b0) - transfer_active <= 1'b1; - else - transfer_active <= 1'b0; + transfer_active <= !last_transfer; end else if (transfer_active == 1'b1 && end_of_word == 1'b1) begin if (last_transfer == 1'b1 || io_ready2 == 1'b0) transfer_active <= 1'b0; 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 2298a20861..fe52996f5c 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 @@ -55,7 +55,7 @@ module spi_engine_execution_shiftreg #( // spi data input [(DATA_WIDTH-1):0] sdo_data, input sdo_data_valid, - output reg sdo_data_ready, + output sdo_data_ready, output [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, output reg sdi_data_valid, @@ -70,8 +70,7 @@ module spi_engine_execution_shiftreg #( input [ 7:0] word_length, // timing from main fsm - input sample_sdo, - output reg sdo_io_ready, + output sdo_io_ready, input transfer_active, input trigger_tx, input trigger_rx, @@ -83,19 +82,26 @@ module spi_engine_execution_shiftreg #( 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 trigger_rx_s; - wire [2:0] current_instr = current_cmd[14:12]; - wire last_sdi_bit; - - always @(posedge clk) begin + reg [(DATA_WIDTH-1):0] aligned_sdo_data, sdo_data_reg; + reg data_sdo_v; + wire sdo_toshiftreg; + wire last_sdi_bit; + wire trigger_rx_s; + wire [2:0] current_instr = current_cmd[14:12]; + + // sdo data handshake + assign sdo_data_ready = (!data_sdo_v) || sdo_toshiftreg; + assign sdo_io_ready = data_sdo_v; + always @(posedge clk ) begin if (resetn == 1'b0) begin - sdo_data_ready <= 1'b0; - end else if (sdo_toshiftreg) begin - sdo_data_ready <= 1'b1; - end else if (sdo_data_valid == 1'b1) begin - sdo_data_ready <= 1'b0; + data_sdo_v <= 1'b0; + end else begin + if (sdo_data_ready && sdo_data_valid) begin + data_sdo_v <= 1'b1; + sdo_data_reg <= sdo_data; + end else if (sdo_toshiftreg) begin + data_sdo_v <= 1'b0; + end end end @@ -103,16 +109,8 @@ module spi_engine_execution_shiftreg #( 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; + aligned_sdo_data <= sdo_data_reg << left_aligned; end end diff --git a/library/spi_engine/spi_engine_offload/spi_engine_offload.v b/library/spi_engine/spi_engine_offload/spi_engine_offload.v index d1d294037a..f0ba5b86ad 100644 --- a/library/spi_engine/spi_engine_offload/spi_engine_offload.v +++ b/library/spi_engine/spi_engine_offload/spi_engine_offload.v @@ -95,7 +95,7 @@ module spi_engine_offload #( localparam SDO_SOURCE_MEM = 1'b0; reg spi_active = 1'b0; - reg sdo_source_select = SDO_SOURCE_MEM; + wire sdo_source_select; reg [CMD_MEM_ADDRESS_WIDTH-1:0] ctrl_cmd_wr_addr = 'h00; reg [CMD_MEM_ADDRESS_WIDTH-1:0] spi_cmd_rd_addr = 'h00; @@ -111,10 +111,12 @@ module spi_engine_offload #( wire [CMD_MEM_ADDRESS_WIDTH-1:0] spi_cmd_rd_addr_next; wire spi_enable; wire trigger_posedge; + reg sdo_mem_valid; + assign sdo_source_select = SDO_STREAMING; assign cmd_valid = spi_active; assign sdo_data_valid = (sdo_source_select == SDO_SOURCE_STREAM) ? - s_axis_sdo_valid : spi_active; + s_axis_sdo_valid : (spi_active && sdo_mem_valid); assign s_axis_sdo_ready = (sdo_source_select == SDO_SOURCE_STREAM) ? sdo_data_ready : 1'b0; assign offload_sdi_valid = sdi_data_valid; @@ -278,7 +280,7 @@ module spi_engine_offload #( if (!spi_active) begin // start offload when we have a valid trigger, offload is enabled and // the DMA is enabled - if (trigger_posedge && spi_enable && (offload_sdi_ready || (SDO_STREAMING && s_axis_sdo_valid))) + if (trigger_posedge && spi_enable) spi_active <= 1'b1; end else if (cmd_ready && (spi_cmd_rd_addr_next == ctrl_cmd_wr_addr)) begin spi_active <= 1'b0; @@ -286,26 +288,6 @@ module spi_engine_offload #( end end - always @(posedge spi_clk ) begin - if (!spi_resetn) begin - sdo_source_select <= SDO_SOURCE_MEM; - end else begin - if (SDO_STREAMING) begin - if (sdo_source_select == SDO_SOURCE_MEM) begin - // switch to streaming sdo after we're done with reading the sdo memory - if (sdo_data_valid && sdo_data_ready && (spi_sdo_rd_addr+1 == ctrl_sdo_wr_addr)|| (ctrl_sdo_wr_addr==0 && spi_active) ) begin - sdo_source_select <= SDO_SOURCE_STREAM; - end - end else begin - // switch back to sdo memory after last command accepted - if (cmd_ready && (spi_cmd_rd_addr_next == ctrl_cmd_wr_addr)) begin - sdo_source_select <= SDO_SOURCE_MEM; - end - end - end - end - end - always @(posedge spi_clk) begin if (!cmd_valid) begin spi_cmd_rd_addr <= 'h00; @@ -322,6 +304,18 @@ module spi_engine_offload #( end end + always @(posedge spi_clk ) begin + if (!spi_resetn) begin + sdo_mem_valid <= 1'b0; + end else begin + if (!spi_active && trigger_posedge && spi_enable) begin + sdo_mem_valid <= (ctrl_sdo_wr_addr != 'h00); // if ctrl_sdo_wr_addr is 0, mem is empty + end else if (sdo_data_ready && spi_active && sdo_mem_valid && (spi_sdo_rd_addr + 1'b1 == ctrl_sdo_wr_addr)) begin + sdo_mem_valid <= 1'b0; + end + end + end + always @(posedge ctrl_clk) begin if (ctrl_mem_reset) ctrl_cmd_wr_addr <= 'h00;