From 3808a6eed88e339ca6a080adfc0ba7282ef93359 Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Sun, 10 May 2020 16:40:40 -0500 Subject: [PATCH] Add word transfer mode to SPI core in quad SPI mode Switch main sequencer to use word transfer for firmware reads. --- main.v | 283 +++++++++++++++++++++------------------------------ spi_master.v | 41 ++++++-- 2 files changed, 148 insertions(+), 176 deletions(-) diff --git a/main.v b/main.v index e7e9cdd..79a4ef5 100644 --- a/main.v +++ b/main.v @@ -600,8 +600,8 @@ module lpc_bridge_top( ); // Instantiate SPI external master interface - wire [7:0] spi_external_master_rx_data; - reg [7:0] spi_external_master_tx_data = 0; + wire [31:0] spi_external_master_rx_data; + reg [31:0] spi_external_master_tx_data = 0; reg [7:0] spi_external_master_dummy_cycle_count = 0; reg spi_external_master_cycle_start = 0; reg spi_external_master_hold_ss_active = 0; @@ -611,6 +611,7 @@ module lpc_bridge_top( reg spi_external_master_reset_n_buffered = 0; reg spi_external_master_qspi_mode_active = 0; + reg spi_external_master_qspi_transfer_mode = 0; reg spi_external_master_qspi_transfer_direction = 0; wire spi_external_master_data_direction; wire spi_external_master_quad_mode_pin_enable; @@ -634,6 +635,7 @@ module lpc_bridge_top( .rx_data(spi_external_master_rx_data), .dummy_cycle_count(spi_external_master_dummy_cycle_count), .qspi_mode_active(spi_external_master_qspi_mode_active), + .qspi_transfer_mode(spi_external_master_qspi_transfer_mode), .qspi_transfer_direction(spi_external_master_qspi_transfer_direction), .hold_ss_active(spi_external_master_hold_ss_active), .cycle_start(spi_external_master_cycle_start), @@ -965,11 +967,6 @@ module lpc_bridge_top( parameter LPC_BRIDGE_TRANSFER_STATE_RD09 = 200; parameter LPC_BRIDGE_TRANSFER_STATE_RD10 = 201; parameter LPC_BRIDGE_TRANSFER_STATE_RD11 = 202; - parameter LPC_BRIDGE_TRANSFER_STATE_RD12 = 203; - parameter LPC_BRIDGE_TRANSFER_STATE_RD13 = 204; - parameter LPC_BRIDGE_TRANSFER_STATE_RD14 = 205; - parameter LPC_BRIDGE_TRANSFER_STATE_RD15 = 206; - parameter LPC_BRIDGE_TRANSFER_STATE_RD16 = 207; parameter LPC_BRIDGE_TRANSFER_STATE_RC01 = 224; parameter LPC_BRIDGE_TRANSFER_STATE_RC02 = 225; parameter LPC_BRIDGE_TRANSFER_STATE_RC03 = 226; @@ -985,11 +982,6 @@ module lpc_bridge_top( parameter BLOCK_CACHE_TRANSFER_STATE_RD07 = 22; parameter BLOCK_CACHE_TRANSFER_STATE_RD08 = 23; parameter BLOCK_CACHE_TRANSFER_STATE_RD09 = 24; - parameter BLOCK_CACHE_TRANSFER_STATE_RD10 = 25; - parameter BLOCK_CACHE_TRANSFER_STATE_RD11 = 26; - parameter BLOCK_CACHE_TRANSFER_STATE_RD12 = 27; - parameter BLOCK_CACHE_TRANSFER_STATE_RD13 = 28; - parameter BLOCK_CACHE_TRANSFER_STATE_RD14 = 29; parameter BLOCK_CACHE_TRANSFER_STATE_EW01 = 64; parameter BLOCK_CACHE_TRANSFER_STATE_EW02 = 65; parameter BLOCK_CACHE_TRANSFER_STATE_EW03 = 66; @@ -1106,7 +1098,7 @@ module lpc_bridge_top( // Uncacheable request use_flash_sector_cache <= 0; ipmi_bt_hiomap_new_window_ack <= 1; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD14; + cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD09; end end if (ipmi_bt_hiomap_flush_req) begin @@ -1172,13 +1164,16 @@ module lpc_bridge_top( end end BLOCK_CACHE_TRANSFER_STATE_RD03: begin - // Address byte 1 + // Address (4 bytes / 1 word) if (!spi_external_master_transaction_complete) begin - spi_external_master_tx_data <= {4'b0000, hiomap_active_window_start_address[27:24]}; + spi_external_master_tx_data <= {4'b0000, hiomap_active_window_start_address[27:0]}; spi_external_master_qspi_mode_active <= 1; + spi_external_master_qspi_transfer_mode <= 1; spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= 0; + spi_external_master_dummy_cycle_count <= SPI_FAST_READ_DUMMY_CLOCK_CYCLES; spi_external_master_cycle_start <= 1; + + spi_byte_read_count <= 0; cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD04; end end @@ -1190,97 +1185,65 @@ module lpc_bridge_top( end BLOCK_CACHE_TRANSFER_STATE_RD05: begin if (!spi_external_master_transaction_complete) begin - // Address byte 2 - spi_external_master_tx_data <= hiomap_active_window_start_address[23:16]; + // Data words + spi_external_master_tx_data <= 0; // Not used spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; + spi_external_master_qspi_transfer_mode <= 1; + spi_external_master_qspi_transfer_direction <= 0; spi_external_master_dummy_cycle_count <= 0; spi_external_master_cycle_start <= 1; cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD06; - end - end - BLOCK_CACHE_TRANSFER_STATE_RD06: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD07; - end - end - BLOCK_CACHE_TRANSFER_STATE_RD07: begin - if (!spi_external_master_transaction_complete) begin - // Address byte 3 - spi_external_master_tx_data <= hiomap_active_window_start_address[15:8]; - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= 0; - spi_external_master_cycle_start <= 1; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD08; - end - end - BLOCK_CACHE_TRANSFER_STATE_RD08: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD09; - end - end - BLOCK_CACHE_TRANSFER_STATE_RD09: begin - if (!spi_external_master_transaction_complete) begin - // Address byte 4 - spi_external_master_tx_data <= hiomap_active_window_start_address[7:0]; - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= SPI_FAST_READ_DUMMY_CLOCK_CYCLES; - spi_external_master_cycle_start <= 1; - spi_byte_read_count <= 0; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD10; + flash_cache_wren_port_b <= 0; + flash_cache_addr_port_b <= spi_byte_read_count; end end - BLOCK_CACHE_TRANSFER_STATE_RD10: begin + BLOCK_CACHE_TRANSFER_STATE_RD06: begin if (spi_external_master_transaction_complete) begin spi_external_master_cycle_start <= 0; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD11; - end - end - BLOCK_CACHE_TRANSFER_STATE_RD11: begin - if (!spi_external_master_transaction_complete) begin - // Data bytes - spi_external_master_tx_data <= 0; // Don't care, but have to clock /something/ in to get data out over SPI - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 0; - spi_external_master_dummy_cycle_count <= 0; - spi_external_master_cycle_start <= 1; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD12; - flash_cache_wren_port_b <= 0; + // Start first memory write as early as possible + flash_cache_write_data_port_b <= spi_external_master_rx_data[31:24]; flash_cache_addr_port_b <= spi_byte_read_count; + flash_cache_wren_port_b <= 1; spi_byte_read_count <= spi_byte_read_count + 1; + + cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD07; end end - BLOCK_CACHE_TRANSFER_STATE_RD12: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - - flash_cache_write_data_port_b <= spi_external_master_rx_data; - flash_cache_wren_port_b <= 1; + BLOCK_CACHE_TRANSFER_STATE_RD07: begin + // Write remaining bytes + case (spi_byte_read_count[1:0]) + 2'b01: flash_cache_write_data_port_b <= spi_external_master_rx_data[23:16]; + 2'b10: flash_cache_write_data_port_b <= spi_external_master_rx_data[15:8]; + 2'b11: flash_cache_write_data_port_b <= spi_external_master_rx_data[7:0]; + endcase + flash_cache_addr_port_b <= spi_byte_read_count; + flash_cache_wren_port_b <= 1; + spi_byte_read_count <= spi_byte_read_count + 1; - if (spi_byte_read_count >= hiomap_active_window_size_bytes) begin - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD13; + if (spi_byte_read_count[1:0] == 2'b11) begin + // Word fully written to cache RAM + // Determine if we need more words from Flash or if the transfer is complete + if ((spi_byte_read_count + 1) >= hiomap_active_window_size_bytes) begin + cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD08; end else begin - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD11; + cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD05; end end end - BLOCK_CACHE_TRANSFER_STATE_RD13: begin + BLOCK_CACHE_TRANSFER_STATE_RD08: begin if (!spi_external_master_transaction_complete) begin // Release CS and prepare the SPI device for the next command spi_external_master_hold_ss_active <= 0; + spi_external_master_qspi_transfer_mode <= 0; spi_external_master_qspi_mode_active <= 0; ipmi_bt_hiomap_new_window_ack <= 1; flash_cache_wren_port_b <= 0; - cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD14; + cache_load_state <= BLOCK_CACHE_TRANSFER_STATE_RD09; end end - BLOCK_CACHE_TRANSFER_STATE_RD14: begin + BLOCK_CACHE_TRANSFER_STATE_RD09: begin if (!ipmi_bt_hiomap_new_window_req) begin ipmi_bt_hiomap_new_window_ack <= 0; if (ipmi_bt_hiomap_flush_req) begin @@ -2132,13 +2095,16 @@ module lpc_bridge_top( end end LPC_BRIDGE_TRANSFER_STATE_RD03: begin - // Address byte 1 + // Address (4 bytes / 1 word) if (!spi_external_master_transaction_complete) begin - spi_external_master_tx_data <= {4'b0000, lpc_slave_address_reg[27:24]}; + spi_external_master_tx_data <= {4'b0000, lpc_slave_address_reg[27:0]}; spi_external_master_qspi_mode_active <= 1; + spi_external_master_qspi_transfer_mode <= 1; spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= 0; + spi_external_master_dummy_cycle_count <= SPI_FAST_READ_DUMMY_CLOCK_CYCLES; spi_external_master_cycle_start <= 1; + + spi_byte_read_count <= 0; fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD04; end end @@ -2150,136 +2116,119 @@ module lpc_bridge_top( end LPC_BRIDGE_TRANSFER_STATE_RD05: begin if (!spi_external_master_transaction_complete) begin - // Address byte 2 - spi_external_master_tx_data <= lpc_slave_address_reg[23:16]; - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= 0; - spi_external_master_cycle_start <= 1; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD06; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD06: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD07; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD07: begin - if (!spi_external_master_transaction_complete) begin - // Address byte 3 - spi_external_master_tx_data <= lpc_slave_address_reg[15:8]; - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= 0; - spi_external_master_cycle_start <= 1; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD08; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD08: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD09; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD09: begin - if (!spi_external_master_transaction_complete) begin - // Address byte 4 - spi_external_master_tx_data <= lpc_slave_address_reg[7:0]; - spi_external_master_qspi_mode_active <= 1; - spi_external_master_qspi_transfer_direction <= 1; - spi_external_master_dummy_cycle_count <= SPI_FAST_READ_DUMMY_CLOCK_CYCLES; - spi_external_master_cycle_start <= 1; - - spi_byte_read_count <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD10; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD10: begin - if (spi_external_master_transaction_complete) begin - spi_external_master_cycle_start <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; - end - end - LPC_BRIDGE_TRANSFER_STATE_RD11: begin - if (!spi_external_master_transaction_complete) begin - // Data bytes - spi_external_master_tx_data <= 0; // Don't care, but have to clock /something/ in to get data out over SPI + // Data words + spi_external_master_tx_data <= 0; // Not used spi_external_master_qspi_mode_active <= 1; + if (lpc_slave_fw_msize == 4'b0001) begin + spi_external_master_qspi_transfer_mode <= 0; + end else begin + spi_external_master_qspi_transfer_mode <= 1; + end spi_external_master_qspi_transfer_direction <= 0; spi_external_master_dummy_cycle_count <= 0; spi_external_master_cycle_start <= 1; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD12; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD06; lpc_fw_input_xfer_write_wren <= 0; lpc_fw_input_xfer_write_addr <= spi_byte_read_count; - spi_byte_read_count <= spi_byte_read_count + 1; end end - LPC_BRIDGE_TRANSFER_STATE_RD12: begin + LPC_BRIDGE_TRANSFER_STATE_RD06: begin if (spi_external_master_transaction_complete) begin spi_external_master_cycle_start <= 0; - lpc_fw_input_xfer_write_data <= spi_external_master_rx_data; + // Start first memory write as early as possible + if (lpc_slave_fw_msize == 4'b0001) begin + lpc_fw_input_xfer_write_data <= spi_external_master_rx_data[7:0]; + end else begin + lpc_fw_input_xfer_write_data <= spi_external_master_rx_data[31:24]; + end lpc_fw_input_xfer_write_wren <= 1; + spi_byte_read_count <= spi_byte_read_count + 1; case (lpc_slave_fw_msize) - 4'b0000: begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_IDLE; - end 4'b0001: begin - if (spi_byte_read_count >= 1) begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD13; - end else begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; - end + // Only needed that one byte + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD08; end 4'b0010: begin - if (spi_byte_read_count >= 4) begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD13; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD07; + end + 4'b0100: begin + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD07; + end + 4'b0111: begin + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD07; + end + default: begin + // Invalid MSIZE + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_IDLE; + end + endcase + end + end + LPC_BRIDGE_TRANSFER_STATE_RD07: begin + // Write remaining bytes + case (spi_byte_read_count[1:0]) + 2'b01: lpc_fw_input_xfer_write_data <= spi_external_master_rx_data[23:16]; + 2'b10: lpc_fw_input_xfer_write_data <= spi_external_master_rx_data[15:8]; + 2'b11: lpc_fw_input_xfer_write_data <= spi_external_master_rx_data[7:0]; + endcase + lpc_fw_input_xfer_write_addr <= spi_byte_read_count; + lpc_fw_input_xfer_write_wren <= 1; + spi_byte_read_count <= spi_byte_read_count + 1; + + if (spi_byte_read_count[1:0] == 2'b11) begin + // Word fully written to LPC transfer RAM + // Determine if we need more words from Flash or if the transfer is complete + case (lpc_slave_fw_msize) + 4'b0010: begin + if (spi_byte_read_count >= (4-1)) begin + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD08; end else begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD05; end end 4'b0100: begin - if (spi_byte_read_count >= 16) begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD13; + if (spi_byte_read_count >= (16-1)) begin + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD08; end else begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD05; end end 4'b0111: begin - if (spi_byte_read_count >= 128) begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD13; + if (spi_byte_read_count >= (128-1)) begin + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD08; end else begin - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD05; end end endcase end end - LPC_BRIDGE_TRANSFER_STATE_RD13: begin + LPC_BRIDGE_TRANSFER_STATE_RD08: begin if (!spi_external_master_transaction_complete) begin // Release CS and prepare the SPI device for the next command spi_external_master_hold_ss_active <= 0; spi_external_master_qspi_mode_active <= 0; + spi_external_master_qspi_transfer_mode <= 0; lpc_fw_input_xfer_write_wren <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD14; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD09; end end - LPC_BRIDGE_TRANSFER_STATE_RD14: begin + LPC_BRIDGE_TRANSFER_STATE_RD09: begin lpc_slave_continue <= 1; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD15; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD10; lpc_done_pulse_counter <= 0; end - LPC_BRIDGE_TRANSFER_STATE_RD15: begin + LPC_BRIDGE_TRANSFER_STATE_RD10: begin if (lpc_done_pulse_counter > 2) begin lpc_slave_continue <= 0; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD16; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD11; end lpc_done_pulse_counter <= lpc_done_pulse_counter + 1; end - LPC_BRIDGE_TRANSFER_STATE_RD16: begin + LPC_BRIDGE_TRANSFER_STATE_RD11: begin if (!lpc_slave_address_ready_reg) begin fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_IDLE; end @@ -2338,7 +2287,7 @@ module lpc_bridge_top( LPC_BRIDGE_TRANSFER_STATE_RC03: begin lpc_fw_input_xfer_write_wren <= 0; lpc_slave_continue <= 1; - fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD15; + fw_transfer_state <= LPC_BRIDGE_TRANSFER_STATE_RD10; lpc_done_pulse_counter <= 0; end default: begin diff --git a/spi_master.v b/spi_master.v index a5a2666..cbe73cc 100644 --- a/spi_master.v +++ b/spi_master.v @@ -125,11 +125,12 @@ endmodule module spi_master_interface_quad( input wire platform_clock, input wire reset, - input wire [7:0] tx_data, - output reg [7:0] rx_data, + input wire [31:0] tx_data, + output reg [31:0] rx_data, input wire [7:0] dummy_cycle_count, input wire hold_ss_active, input wire qspi_mode_active, + input wire qspi_transfer_mode, // 0 == byte transfer, 1 == word transfer input wire qspi_transfer_direction, // 0 == read (input), 1 == write (output) input wire cycle_start, output reg transaction_complete, @@ -149,7 +150,7 @@ module spi_master_interface_quad( ); reg [3:0] transfer_state = 0; - reg [7:0] data_shift_out = 0; + reg [31:0] data_shift_out = 0; reg [7:0] state_iteration = 0; reg ss_state_at_idle = 1'b1; @@ -157,6 +158,9 @@ module spi_master_interface_quad( reg [7:0] dummy_cycle_count_reg = 0; reg [7:0] dummy_cycle_ctr = 0; + reg qspi_transfer_mode_reg = 0; + reg [3:0] qspi_transfer_cycle_stop_value = 1; + always @(posedge platform_clock) begin if (reset) begin transfer_state <= 0; @@ -188,6 +192,14 @@ module spi_master_interface_quad( data_shift_out <= tx_data; spi_quad_mode_pin_enable <= qspi_mode_active; spi_data_direction <= qspi_transfer_direction; + qspi_transfer_mode_reg <= qspi_transfer_mode; + if (qspi_transfer_mode == 0) begin + // Byte transfer (2 nibbles per word) + qspi_transfer_cycle_stop_value <= 1; + end else begin + // Word transfer (4 bytes / 8 nibbles per word) + qspi_transfer_cycle_stop_value <= 7; + end // Drive frame start spi_clock <= 1'b1; @@ -207,10 +219,17 @@ module spi_master_interface_quad( spi_clock <= 1'b0; spi_ss_n <= 1'b0; if (spi_quad_mode_pin_enable) begin - spi_d3_out <= data_shift_out[7]; - spi_d2_out <= data_shift_out[6]; - spi_d1_out <= data_shift_out[5]; - spi_d0_out <= data_shift_out[4]; + if (qspi_transfer_mode_reg) begin + spi_d3_out <= data_shift_out[31]; + spi_d2_out <= data_shift_out[30]; + spi_d1_out <= data_shift_out[29]; + spi_d0_out <= data_shift_out[28]; + end else begin + spi_d3_out <= data_shift_out[7]; + spi_d2_out <= data_shift_out[6]; + spi_d1_out <= data_shift_out[5]; + spi_d0_out <= data_shift_out[4]; + end data_shift_out <= data_shift_out << 4; end else begin spi_d0_out <= data_shift_out[7]; @@ -224,8 +243,12 @@ module spi_master_interface_quad( spi_ss_n <= 1'b0; state_iteration <= state_iteration + 1; if (spi_quad_mode_pin_enable) begin - rx_data <= {rx_data[3:0], spi_d3_in, spi_d2_in, spi_d1_in, spi_d0_in}; - if (state_iteration >= 1) begin + if (qspi_transfer_mode_reg) begin + rx_data <= {rx_data[27:0], spi_d3_in, spi_d2_in, spi_d1_in, spi_d0_in}; + end else begin + rx_data <= {rx_data[3:0], spi_d3_in, spi_d2_in, spi_d1_in, spi_d0_in}; + end + if (state_iteration >= qspi_transfer_cycle_stop_value) begin if (hold_ss_active) begin ss_state_at_idle <= 1'b0; end else begin -- 2.30.2