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 35bf015e5..9e5980110 100644 --- a/library/spi_engine/axi_spi_engine/axi_spi_engine.v +++ b/library/spi_engine/axi_spi_engine/axi_spi_engine.v @@ -42,7 +42,7 @@ module axi_spi_engine ( output sdi_data_ready, input sdi_data_valid, - input [7:0] sdi_data, + input [(SDI_DATA_WIDTH-1):0] sdi_data, output sync_ready, input sync_valid, @@ -72,7 +72,9 @@ parameter OFFLOAD0_CMD_MEM_ADDRESS_WIDTH = 4; parameter OFFLOAD0_SDO_MEM_ADDRESS_WIDTH = 4; parameter ID = 'h00; -localparam PCORE_VERSION = 'h010061; +parameter SDI_DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 + +localparam PCORE_VERSION = 'h010071; wire [CMD_FIFO_ADDRESS_WIDTH:0] cmd_fifo_room; wire cmd_fifo_almost_empty; @@ -307,7 +309,7 @@ assign sdi_fifo_almost_full = `axi_spi_engine_check_watermark(sdi_fifo_level, SDI_FIFO_ADDRESS_WIDTH); util_axis_fifo #( - .DATA_WIDTH(8), + .DATA_WIDTH(SDI_DATA_WIDTH), .ASYNC_CLK(ASYNC_SPI_CLK), .ADDRESS_WIDTH(SDI_FIFO_ADDRESS_WIDTH), .S_AXIS_REGISTERED(0) 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 12173a6e7..223cadabc 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -1,39 +1,45 @@ module spi_engine_execution ( - input clk, - input resetn, + input clk, + input resetn, - output reg active, + output reg active, - output cmd_ready, - input cmd_valid, - input [15:0] cmd, + output cmd_ready, + input cmd_valid, + input [15:0] cmd, - input sdo_data_valid, - output reg sdo_data_ready, - input [7:0] sdo_data, + input sdo_data_valid, + output reg sdo_data_ready, + input [7:0] sdo_data, - input sdi_data_ready, - output reg sdi_data_valid, - output [7:0] sdi_data, + input sdi_data_ready, + output reg sdi_data_valid, + output [(SDI_DATA_WIDTH-1):0] sdi_data, - input sync_ready, - output reg sync_valid, - output [7:0] sync, + input sync_ready, + output reg sync_valid, + output [7:0] sync, - output reg sclk, - output sdo, - output reg sdo_t, - input sdi, - output reg [NUM_OF_CS-1:0] cs, - output reg three_wire + output reg sclk, + output sdo, + output reg sdo_t, + input sdi, + input sdi_1, + input sdi_2, + input sdi_3, + output reg [NUM_OF_CS-1:0] cs, + output reg three_wire ); parameter NUM_OF_CS = 1; parameter DEFAULT_SPI_CFG = 0; parameter DEFAULT_CLK_DIV = 0; +parameter SDI_DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 -localparam CMD_TRANSFER = 2'b00; + +localparam NUM_OF_SDI = SDI_DATA_WIDTH >> 3; +localparam CMD_TRANSFER = 2'b00; localparam CMD_CHIPSELECT = 2'b01; localparam CMD_WRITE = 2'b10; localparam CMD_MISC = 2'b11; @@ -83,6 +89,9 @@ wire sdo_enabled = cmd_d1[8]; wire sdi_enabled = cmd_d1[9]; reg [8:0] data_shift = 'h0; +reg [8:0] data_shift_1 = 'h0; +reg [8:0] data_shift_2 = 'h0; +reg [8:0] data_shift_3 = 'h0; wire [1:0] inst = cmd[13:12]; wire [1:0] inst_d1 = cmd_d1[13:12]; @@ -97,54 +106,54 @@ wire exec_sync_cmd = exec_misc_cmd && cmd[8] == MISC_SYNC; assign cmd_ready = idle; always @(posedge clk) begin - if (cmd_ready) - cmd_d1 <= cmd; + if (cmd_ready) + cmd_d1 <= cmd; end always @(posedge clk) begin - if (resetn == 1'b0) begin - active <= 1'b0; - end else begin - if (exec_cmd == 1'b1) - active <= 1'b1; - else if (sync_ready == 1'b1 && sync_valid == 1'b1) - active <= 1'b0; - end + if (resetn == 1'b0) begin + active <= 1'b0; + end else begin + if (exec_cmd == 1'b1) + active <= 1'b1; + else if (sync_ready == 1'b1 && sync_valid == 1'b1) + active <= 1'b0; + end end always @(posedge clk) begin - if (resetn == 1'b0) begin - cpha <= DEFAULT_SPI_CFG[0]; - cpol <= DEFAULT_SPI_CFG[1]; - three_wire <= DEFAULT_SPI_CFG[2]; - clk_div <= DEFAULT_CLK_DIV; - end else if (exec_write_cmd == 1'b1) begin - if (cmd[8] == REG_CONFIG) begin - cpha <= cmd[0]; - cpol <= cmd[1]; - three_wire <= cmd[2]; - end else if (cmd[8] == REG_CLK_DIV) begin - clk_div <= cmd[7:0]; - end - end + if (resetn == 1'b0) begin + cpha <= DEFAULT_SPI_CFG[0]; + cpol <= DEFAULT_SPI_CFG[1]; + three_wire <= DEFAULT_SPI_CFG[2]; + clk_div <= DEFAULT_CLK_DIV; + end else if (exec_write_cmd == 1'b1) begin + if (cmd[8] == REG_CONFIG) begin + cpha <= cmd[0]; + cpol <= cmd[1]; + three_wire <= cmd[2]; + end else if (cmd[8] == REG_CLK_DIV) begin + clk_div <= cmd[7:0]; + end + end end always @(posedge clk) begin - if ((clk_div_last == 1'b0 && idle == 1'b0 && wait_for_io == 1'b0 && - clk_div_counter == 'h01) || clk_div == 'h00) - clk_div_last <= 1'b1; - else - clk_div_last <= 1'b0; + if ((clk_div_last == 1'b0 && idle == 1'b0 && wait_for_io == 1'b0 && + clk_div_counter == 'h01) || clk_div == 'h00) + clk_div_last <= 1'b1; + else + clk_div_last <= 1'b0; end always @(posedge clk) begin - if (clk_div_last == 1'b1 || idle == 1'b1 || wait_for_io == 1'b1) begin - clk_div_counter <= clk_div; - trigger <= 1'b1; - end else begin - clk_div_counter <= clk_div_counter - 1'b1; - trigger <= 1'b0; - end + if (clk_div_last == 1'b1 || idle == 1'b1 || wait_for_io == 1'b1) begin + clk_div_counter <= clk_div; + trigger <= 1'b1; + end else begin + clk_div_counter <= clk_div_counter - 1'b1; + trigger <= 1'b0; + end end wire trigger_tx = trigger == 1'b1 && ntx_rx == 1'b0; @@ -155,159 +164,169 @@ wire cs_sleep_counter_compare = cs_sleep_counter == cmd_d1[9:8] && clk_div_last wire cs_sleep_counter_compare2 = cs_sleep_counter2 == {cmd_d1[9:8],1'b1} && clk_div_last == 1'b1; always @(posedge clk) begin - if (idle == 1'b1) - counter <= 'h00; - else if (clk_div_last == 1'b1 && wait_for_io == 1'b0) - counter <= counter + (transfer_active ? 'h1 : 'h10); + if (idle == 1'b1) + counter <= 'h00; + else if (clk_div_last == 1'b1 && wait_for_io == 1'b0) + counter <= counter + (transfer_active ? 'h1 : 'h10); end always @(posedge clk) begin - if (resetn == 1'b0) begin - idle <= 1'b1; - end else begin - if (exec_transfer_cmd || exec_chipselect_cmd || exec_misc_cmd) begin - idle <= 1'b0; - end else begin - case (inst_d1) - CMD_TRANSFER: begin - if (transfer_active == 1'b0 && wait_for_io == 1'b0) - idle <= 1'b1; - end - CMD_CHIPSELECT: begin - if (cs_sleep_counter_compare2) - idle <= 1'b1; - end - CMD_MISC: begin - case (cmd_d1[8]) - MISC_SLEEP: begin - if (sleep_counter_compare) - idle <= 1'b1; - end - MISC_SYNC: begin - if (sync_ready) - idle <= 1'b1; - end - endcase - end - endcase - end - end + if (resetn == 1'b0) begin + idle <= 1'b1; + end else begin + if (exec_transfer_cmd || exec_chipselect_cmd || exec_misc_cmd) begin + idle <= 1'b0; + end else begin + case (inst_d1) + CMD_TRANSFER: begin + if (transfer_active == 1'b0 && wait_for_io == 1'b0) + idle <= 1'b1; + end + CMD_CHIPSELECT: begin + if (cs_sleep_counter_compare2) + idle <= 1'b1; + end + CMD_MISC: begin + case (cmd_d1[8]) + MISC_SLEEP: begin + if (sleep_counter_compare) + idle <= 1'b1; + end + MISC_SYNC: begin + if (sync_ready) + idle <= 1'b1; + end + endcase + end + endcase + end + end end always @(posedge clk) begin - if (resetn == 1'b0) begin - cs <= 'hff; - end else if (inst_d1 == CMD_CHIPSELECT && cs_sleep_counter_compare == 1'b1) begin - cs <= cmd_d1[NUM_OF_CS-1:0]; - end + if (resetn == 1'b0) begin + cs <= 'hff; + end else if (inst_d1 == CMD_CHIPSELECT && cs_sleep_counter_compare == 1'b1) begin + cs <= cmd_d1[NUM_OF_CS-1:0]; + end end always @(posedge clk) begin - if (resetn == 1'b0) begin - sync_valid <= 1'b0; - end else begin - if (exec_sync_cmd == 1'b1) begin - sync_valid <= 1'b1; - end else if (sync_ready == 1'b1) begin - sync_valid <= 1'b0; - end - end + if (resetn == 1'b0) begin + sync_valid <= 1'b0; + end else begin + if (exec_sync_cmd == 1'b1) begin + sync_valid <= 1'b1; + end else if (sync_ready == 1'b1) begin + sync_valid <= 1'b0; + end + end end 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; + 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 always @(posedge clk) begin - if (resetn == 1'b0) - sdi_data_valid <= 1'b0; - else if (sdi_enabled == 1'b1 && last_bit == 1'b1 && trigger_rx == 1'b1 && - transfer_active == 1'b1) - sdi_data_valid <= 1'b1; - else if (sdi_data_ready == 1'b1) - sdi_data_valid <= 1'b0; + if (resetn == 1'b0) + sdi_data_valid <= 1'b0; + else if (sdi_enabled == 1'b1 && last_bit == 1'b1 && trigger_rx == 1'b1 && + transfer_active == 1'b1) + sdi_data_valid <= 1'b1; + else if (sdi_data_ready == 1'b1) + sdi_data_valid <= 1'b0; end wire 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_data_valid == 1'b1); wire 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 == 1'b0 || last_transfer == 1'b1 || sdo_data_valid == 1'b1); always @(posedge clk) begin - if (idle == 1'b1) begin - last_transfer <= 1'b0; - end else if (trigger_tx == 1'b1 && transfer_active == 1'b1) begin - if (transfer_counter == cmd_d1[7:0]) - last_transfer <= 1'b1; - else - last_transfer <= 1'b0; - end + if (idle == 1'b1) begin + last_transfer <= 1'b0; + end else if (trigger_tx == 1'b1 && transfer_active == 1'b1) begin + if (transfer_counter == cmd_d1[7:0]) + last_transfer <= 1'b1; + else + last_transfer <= 1'b0; + end end always @(posedge clk) begin - if (resetn == 1'b0) begin - transfer_active <= 1'b0; - wait_for_io <= 1'b0; - end else begin - if (exec_transfer_cmd == 1'b1) begin - wait_for_io <= 1'b1; - transfer_active <= 1'b0; - 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; - 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; - if (io_ready2 == 1'b0) - wait_for_io <= 1'b1; - end - end + if (resetn == 1'b0) begin + transfer_active <= 1'b0; + wait_for_io <= 1'b0; + end else begin + if (exec_transfer_cmd == 1'b1) begin + wait_for_io <= 1'b1; + transfer_active <= 1'b0; + 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; + 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; + if (io_ready2 == 1'b0) + wait_for_io <= 1'b1; + end + end end always @(posedge clk) begin - if (transfer_active == 1'b1 || wait_for_io == 1'b1) - begin - sdo_t <= ~sdo_enabled; - end else begin - sdo_t <= 1'b1; - end + if (transfer_active == 1'b1 || wait_for_io == 1'b1) + begin + sdo_t <= ~sdo_enabled; + end else begin + sdo_t <= 1'b1; + end end always @(posedge clk) begin - if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin - if (first_bit == 1'b1) - data_shift[8:1] <= sdo_data; - else - data_shift[8:1] <= data_shift[7:0]; - end + if (transfer_active == 1'b1 && trigger_tx == 1'b1) begin + if (first_bit == 1'b1) + data_shift[8:1] <= sdo_data; + else + data_shift[8:1] <= data_shift[7:0]; + data_shift_1[8:1] <= data_shift_1[7:0]; + data_shift_2[8:1] <= data_shift_2[7:0]; + data_shift_3[8:1] <= data_shift_3[7:0]; + end end assign sdo = data_shift[8]; -assign sdi_data = data_shift[7:0]; +assign sdi_data = (NUM_OF_SDI == 1) ? data_shift[7:0] : + (NUM_OF_SDI == 2) ? {data_shift_1[7:0], data_shift[7:0]} : + (NUM_OF_SDI == 3) ? {data_shift_2[7:0], data_shift_1[7:0], data_shift[7:0]} : + (NUM_OF_SDI == 4) ? {data_shift_3[7:0], data_shift_2[7:0], data_shift_1[7:0], data_shift[7:0]} : + data_shift[7:0]; always @(posedge clk) begin - if (trigger_rx == 1'b1) begin - data_shift[0] <= sdi; - end + if (trigger_rx == 1'b1) begin + data_shift[0] <= sdi; + data_shift_1[0] <= sdi_1; + data_shift_2[0] <= sdi_2; + data_shift_3[0] <= sdi_3; + end end always @(posedge clk) begin - if (transfer_active == 1'b1) begin - sclk <= cpol ^ cpha ^ ntx_rx; - end else begin - sclk <= cpol; - end + if (transfer_active == 1'b1) begin + sclk <= cpol ^ cpha ^ ntx_rx; + end else begin + sclk <= cpol; + end end endmodule diff --git a/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v b/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v index 463073955..14cf70aeb 100644 --- a/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v +++ b/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v @@ -14,7 +14,7 @@ module spi_engine_interconnect ( input m_sdi_valid, output m_sdi_ready, - input [7:0] m_sdi_data, + input [(SDI_DATA_WIDTH-1):0] m_sdi_data, input m_sync_valid, output m_sync_ready, @@ -31,7 +31,7 @@ module spi_engine_interconnect ( output s0_sdi_valid, input s0_sdi_ready, - output [7:0] s0_sdi_data, + output [(SDI_DATA_WIDTH-1):0] s0_sdi_data, output s0_sync_valid, input s0_sync_ready, @@ -48,13 +48,15 @@ module spi_engine_interconnect ( output s1_sdi_valid, input s1_sdi_ready, - output [7:0] s1_sdi_data, + output [(SDI_DATA_WIDTH-1):0] s1_sdi_data, output s1_sync_valid, input s1_sync_ready, output [7:0] s1_sync ); +parameter SDI_DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 + reg s_active = 1'b0; reg idle = 1'b1; 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 862b869b1..0082bec04 100644 --- a/library/spi_engine/spi_engine_offload/spi_engine_offload.v +++ b/library/spi_engine/spi_engine_offload/spi_engine_offload.v @@ -27,7 +27,7 @@ module spi_engine_offload ( input sdi_data_valid, output sdi_data_ready, - input [7:0] sdi_data, + input [(SDI_DATA_WIDTH-1):0] sdi_data, input sync_valid, output sync_ready, @@ -35,12 +35,13 @@ module spi_engine_offload ( output offload_sdi_valid, input offload_sdi_ready, - output [7:0] offload_sdi_data + output [(SDI_DATA_WIDTH-1):0] offload_sdi_data ); parameter ASYNC_SPI_CLK = 0; parameter CMD_MEM_ADDRESS_WIDTH = 4; parameter SDO_MEM_ADDRESS_WIDTH = 4; +parameter SDI_DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 reg spi_active = 1'b0; @@ -92,7 +93,7 @@ end assign ctrl_enabled = ctrl_is_enabled | ctrl_do_enable; always @(posedge spi_clk) begin - spi_enabled <= spi_enable | spi_active; + spi_enabled <= spi_enable | spi_active; end sync_bits # (