From 4e57170384273907267ec514634ad9ef9189673d Mon Sep 17 00:00:00 2001 From: Istvan Csomortani Date: Mon, 14 Dec 2015 15:57:54 +0200 Subject: [PATCH] spi_engine: Update SPI Engine frame work + data width and number of SDI lines are configurable + axi_spi_engine module can have two different type of memory map interface (S_AXI or UP) --- .../axi_spi_engine/axi_spi_engine.v | 495 ++++++++++-------- .../spi_engine_execution.v | 54 +- .../spi_engine_interconnect.v | 15 +- .../spi_engine_offload/spi_engine_offload.v | 13 +- 4 files changed, 318 insertions(+), 259 deletions(-) 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 793c5fa01..9cff99264 100644 --- a/library/spi_engine/axi_spi_engine/axi_spi_engine.v +++ b/library/spi_engine/axi_spi_engine/axi_spi_engine.v @@ -1,68 +1,82 @@ module axi_spi_engine ( - // Slave AXI interface - input s_axi_aclk, - input s_axi_aresetn, + // Slave AXI interface - input s_axi_awvalid, - input [31:0] s_axi_awaddr, - output s_axi_awready, - input [2:0] s_axi_awprot, - input s_axi_wvalid, - input [31:0] s_axi_wdata, - input [ 3:0] s_axi_wstrb, - output s_axi_wready, - output s_axi_bvalid, - output [ 1:0] s_axi_bresp, - input s_axi_bready, - input s_axi_arvalid, - input [31:0] s_axi_araddr, - output s_axi_arready, - input [2:0] s_axi_arprot, - output s_axi_rvalid, - input s_axi_rready, - output [ 1:0] s_axi_rresp, - output [31:0] s_axi_rdata, + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [31:0] s_axi_awaddr, + output s_axi_awready, + input [2:0] s_axi_awprot, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [31:0] s_axi_araddr, + output s_axi_arready, + input [2:0] s_axi_arprot, + output s_axi_rvalid, + input s_axi_rready, + output [ 1:0] s_axi_rresp, + output [31:0] s_axi_rdata, - output reg irq, + // up interface + input up_clk, + input up_rstn, + input up_wreq, + input [(UP_ADDRESS_WIDTH-1):0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [(UP_ADDRESS_WIDTH-1):0] up_raddr, + output [31:0] up_rdata, + output up_rack, - // SPI signals - input spi_clk, + output reg irq, - output spi_resetn, + // SPI signals + input spi_clk, - input cmd_ready, - output cmd_valid, - output [15:0] cmd_data, + output spi_resetn, - input sdo_data_ready, - output sdo_data_valid, - output [7:0] sdo_data, + input cmd_ready, + output cmd_valid, + output [15:0] cmd_data, - output sdi_data_ready, - input sdi_data_valid, - input [(SDI_DATA_WIDTH-1):0] sdi_data, + input sdo_data_ready, + output sdo_data_valid, + output [(DATA_WIDTH-1):0] sdo_data, - output sync_ready, - input sync_valid, - input [7:0] sync_data, + output sdi_data_ready, + input sdi_data_valid, + input [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, - // Offload ctrl signals - output offload0_cmd_wr_en, - output [15:0] offload0_cmd_wr_data, + output sync_ready, + input sync_valid, + input [7:0] sync_data, - output offload0_sdo_wr_en, - output [7:0] offload0_sdo_wr_data, + // Offload ctrl signals + output offload0_cmd_wr_en, + output [15:0] offload0_cmd_wr_data, - output reg offload0_mem_reset, - output reg offload0_enable, - input offload0_enabled + output offload0_sdo_wr_en, + output [(DATA_WIDTH-1):0] offload0_sdo_wr_data, + + output reg offload0_mem_reset, + output reg offload0_enable, + input offload0_enabled ); parameter CMD_FIFO_ADDRESS_WIDTH = 4; parameter SDO_FIFO_ADDRESS_WIDTH = 5; parameter SDI_FIFO_ADDRESS_WIDTH = 5; +parameter MM_IF_TYPE = 0; +parameter UP_ADDRESS_WIDTH = 14; parameter ASYNC_SPI_CLK = 0; @@ -72,9 +86,15 @@ parameter OFFLOAD0_CMD_MEM_ADDRESS_WIDTH = 4; parameter OFFLOAD0_SDO_MEM_ADDRESS_WIDTH = 4; parameter ID = 'h00; -parameter SDI_DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 +parameter DATA_WIDTH = 8; +parameter NUM_OF_SDI = 1; localparam PCORE_VERSION = 'h010071; +localparam S_AXI = 0; +localparam UP_FIFO = 1; + +wire clk; +wire rstn; wire [CMD_FIFO_ADDRESS_WIDTH:0] cmd_fifo_room; wire cmd_fifo_almost_empty; @@ -86,66 +106,103 @@ wire cmd_fifo_in_valid; wire [SDO_FIFO_ADDRESS_WIDTH:0] sdo_fifo_room; wire sdo_fifo_almost_empty; -wire [7:0] sdo_fifo_in_data; +wire [(DATA_WIDTH-1):0] sdo_fifo_in_data; wire sdo_fifo_in_ready; wire sdo_fifo_in_valid; wire [SDI_FIFO_ADDRESS_WIDTH:0] sdi_fifo_level; wire sdi_fifo_almost_full; -wire [31:0] sdi_fifo_out_data; +wire [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_fifo_out_data; wire sdi_fifo_out_ready; wire sdi_fifo_out_valid; -reg up_reset = 1'b1; -wire up_resetn = ~up_reset; +reg up_sw_reset = 1'b1; +wire up_sw_resetn = ~up_sw_reset; -reg [31:0] up_rdata = 'd0; -reg up_wack = 1'b0; -reg up_rack = 1'b0; -wire up_wreq; -wire up_rreq; -wire [31:0] up_wdata; -wire [ 7:0] up_waddr; -wire [ 7:0] up_raddr; +reg [31:0] up_rdata_ff = 'd0; +reg up_wack_ff = 1'b0; +reg up_rack_ff = 1'b0; +wire up_wreq_s; +wire up_rreq_s; +wire [31:0] up_wdata_s; +wire [(UP_ADDRESS_WIDTH-1):0] up_waddr_s; +wire [(UP_ADDRESS_WIDTH-1):0] up_raddr_s; // Scratch register reg [31:0] up_scratch = 'h00; reg [7:0] sync_id = 'h00; -reg sync_id_pending = 1'b0; +reg sync_id_pending = 1'b0; + +generate if (MM_IF_TYPE == S_AXI) begin + + // assign clock and reset + + assign clk = s_axi_aclk; + assign rstn = s_axi_aresetn; + + // interface wrapper + + up_axi #( + .ADDRESS_WIDTH (UP_ADDRESS_WIDTH) + ) i_up_axi ( + .up_rstn(rstn), + .up_clk(clk), + .up_axi_awvalid(s_axi_awvalid), + .up_axi_awaddr(s_axi_awaddr), + .up_axi_awready(s_axi_awready), + .up_axi_wvalid(s_axi_wvalid), + .up_axi_wdata(s_axi_wdata), + .up_axi_wstrb(s_axi_wstrb), + .up_axi_wready(s_axi_wready), + .up_axi_bvalid(s_axi_bvalid), + .up_axi_bresp(s_axi_bresp), + .up_axi_bready(s_axi_bready), + .up_axi_arvalid(s_axi_arvalid), + .up_axi_araddr(s_axi_araddr), + .up_axi_arready(s_axi_arready), + .up_axi_rvalid(s_axi_rvalid), + .up_axi_rresp(s_axi_rresp), + .up_axi_rdata(s_axi_rdata), + .up_axi_rready(s_axi_rready), + .up_wreq(up_wreq_s), + .up_waddr(up_waddr_s), + .up_wdata(up_wdata_s), + .up_wack(up_wack_ff), + .up_rreq(up_rreq_s), + .up_raddr(up_raddr_s), + .up_rdata(up_rdata_ff), + .up_rack(up_rack_ff) + ); + + assign up_rdata = 32'b0; + assign up_rack = 1'b0; + assign up_wack = 1'b0; + +end +endgenerate + +generate if (MM_IF_TYPE == UP_FIFO) begin + + // assign clock and reset + + assign clk = up_clk; + assign rstn = up_rstn; + + assign up_wreq_s = up_wreq; + assign up_waddr_s = up_waddr; + assign up_wdata_s = up_wdata; + assign up_wack = up_wack_ff; + assign up_rreq_s = up_rreq; + assign up_raddr_s = up_raddr; + assign up_rdata = up_rdata_ff; + assign up_rack = up_rack_ff; + +end +endgenerate + -up_axi #( - .ADDRESS_WIDTH (8) -) i_up_axi ( - .up_rstn(s_axi_aresetn), - .up_clk(s_axi_aclk), - .up_axi_awvalid(s_axi_awvalid), - .up_axi_awaddr(s_axi_awaddr), - .up_axi_awready(s_axi_awready), - .up_axi_wvalid(s_axi_wvalid), - .up_axi_wdata(s_axi_wdata), - .up_axi_wstrb(s_axi_wstrb), - .up_axi_wready(s_axi_wready), - .up_axi_bvalid(s_axi_bvalid), - .up_axi_bresp(s_axi_bresp), - .up_axi_bready(s_axi_bready), - .up_axi_arvalid(s_axi_arvalid), - .up_axi_araddr(s_axi_araddr), - .up_axi_arready(s_axi_arready), - .up_axi_rvalid(s_axi_rvalid), - .up_axi_rresp(s_axi_rresp), - .up_axi_rdata(s_axi_rdata), - .up_axi_rready(s_axi_rready), - .up_wreq(up_wreq), - .up_waddr(up_waddr), - .up_wdata(up_wdata), - .up_wack(up_wack), - .up_rreq(up_rreq), - .up_raddr(up_raddr), - .up_rdata(up_rdata), - .up_rack(up_rack) -); // IRQ handling reg [3:0] up_irq_mask = 'h0; @@ -153,85 +210,85 @@ wire [3:0] up_irq_source; wire [3:0] up_irq_pending; assign up_irq_source = { - sync_id_pending, - sdi_fifo_almost_full, - sdo_fifo_almost_empty, - cmd_fifo_almost_empty + sync_id_pending, + sdi_fifo_almost_full, + sdo_fifo_almost_empty, + cmd_fifo_almost_empty }; assign up_irq_pending = up_irq_mask & up_irq_source; -always @(posedge s_axi_aclk) begin - if (s_axi_aresetn == 1'b0) - irq <= 1'b0; - else - irq <= |up_irq_pending; +always @(posedge clk) begin + if (rstn == 1'b0) + irq <= 1'b0; + else + irq <= |up_irq_pending; end -always @(posedge s_axi_aclk) begin - if (s_axi_aresetn == 1'b0) begin - up_wack <= 1'b0; - up_scratch <= 'h00; - up_reset <= 1'b1; - up_irq_mask <= 'h00; - offload0_enable <= 1'b0; - offload0_mem_reset <= 1'b0; - end else begin - up_wack <= up_wreq; - offload0_mem_reset <= 1'b0; - if (up_wreq) begin - case (up_waddr) - 8'h02: up_scratch <= up_wdata; - 8'h10: up_reset <= up_wdata; - 8'h20: up_irq_mask <= up_wdata; - 8'h40: offload0_enable <= up_wdata[0]; - 8'h42: offload0_mem_reset <= up_wdata[0]; - endcase - end - end +always @(posedge clk) begin + if (rstn == 1'b0) begin + up_wack_ff <= 1'b0; + up_scratch <= 'h00; + up_sw_reset <= 1'b1; + up_irq_mask <= 'h00; + offload0_enable <= 1'b0; + offload0_mem_reset <= 1'b0; + end else begin + up_wack_ff <= up_wreq_s; + offload0_mem_reset <= 1'b0; + if (up_wreq_s) begin + case (up_waddr_s) + 8'h02: up_scratch <= up_wdata_s; + 8'h10: up_sw_reset <= up_wdata_s; + 8'h20: up_irq_mask <= up_wdata_s; + 8'h40: offload0_enable <= up_wdata_s[0]; + 8'h42: offload0_mem_reset <= up_wdata_s[0]; + endcase + end + end end -always @(posedge s_axi_aclk) begin - if (s_axi_aresetn == 1'b0) begin - up_rack <= 'd0; - end else begin - up_rack <= up_rreq; - end +always @(posedge clk) begin + if (rstn == 1'b0) begin + up_rack_ff <= 'd0; + end else begin + up_rack_ff <= up_rreq_s; + end end -always @(posedge s_axi_aclk) begin - case (up_raddr) - 8'h00: up_rdata <= PCORE_VERSION; - 8'h01: up_rdata <= ID; - 8'h02: up_rdata <= up_scratch; - 8'h10: up_rdata <= up_reset; - 8'h20: up_rdata <= up_irq_mask; - 8'h21: up_rdata <= up_irq_pending; - 8'h22: up_rdata <= up_irq_source; - 8'h30: up_rdata <= sync_id; - 8'h34: up_rdata <= cmd_fifo_room; - 8'h35: up_rdata <= sdo_fifo_room; - 8'h36: up_rdata <= sdi_fifo_level; - 8'h3a: up_rdata <= sdi_fifo_out_data; - 8'h3c: up_rdata <= sdi_fifo_out_data; /* PEEK register */ - 8'h40: up_rdata <= {offload0_enable}; - 8'h41: up_rdata <= {offload0_enabled}; - default: up_rdata <= 'h00; - endcase +always @(posedge clk) begin + case (up_raddr_s) + 8'h00: up_rdata_ff <= PCORE_VERSION; + 8'h01: up_rdata_ff <= ID; + 8'h02: up_rdata_ff <= up_scratch; + 8'h10: up_rdata_ff <= up_sw_reset; + 8'h20: up_rdata_ff <= up_irq_mask; + 8'h21: up_rdata_ff <= up_irq_pending; + 8'h22: up_rdata_ff <= up_irq_source; + 8'h30: up_rdata_ff <= sync_id; + 8'h34: up_rdata_ff <= cmd_fifo_room; + 8'h35: up_rdata_ff <= sdo_fifo_room; + 8'h36: up_rdata_ff <= sdi_fifo_level; + 8'h3a: up_rdata_ff <= sdi_fifo_out_data; + 8'h3c: up_rdata_ff <= sdi_fifo_out_data; /* PEEK register */ + 8'h40: up_rdata_ff <= {offload0_enable}; + 8'h41: up_rdata_ff <= {offload0_enabled}; + default: up_rdata_ff <= 'h00; + endcase end -always @(posedge s_axi_aclk) begin - if (up_resetn == 1'b0) begin - sync_id <= 'h00; - sync_id_pending <= 1'b0; - end else begin - if (sync_valid == 1'b1) begin - sync_id <= sync_data; - sync_id_pending <= 1'b1; - end else if (up_wreq == 1'b1 && up_waddr == 8'h21 && up_wdata[3] == 1'b1) begin - sync_id_pending <= 1'b0; - end - end +always @(posedge clk) begin + if (up_sw_resetn == 1'b0) begin + sync_id <= 'h00; + sync_id_pending <= 1'b0; + end else begin + if (sync_valid == 1'b1) begin + sync_id <= sync_data; + sync_id_pending <= 1'b1; + end else if (up_wreq_s == 1'b1 && up_waddr_s == 8'h21 && up_wdata_s[3] == 1'b1) begin + sync_id_pending <= 1'b0; + end + end end assign sync_ready = 1'b1; @@ -240,98 +297,98 @@ generate if (ASYNC_SPI_CLK) begin wire spi_reset; ad_rst i_spi_resetn ( - .preset(up_reset), - .clk(spi_clk), - .rst(spi_reset) + .preset(up_sw_reset), + .clk(spi_clk), + .rst(spi_reset) ); assign spi_resetn = ~spi_reset; end else begin -assign spi_resetn = ~up_reset; +assign spi_resetn = ~up_sw_reset; end endgenerate /* Evaluates to true if FIFO level/room is 3/4 or above */ `define axi_spi_engine_check_watermark(x, n) \ - (x[n] == 1'b1 || x[n-1:n-2] == 2'b11) + (x[n] == 1'b1 || x[n-1:n-2] == 2'b11) assign cmd_fifo_in_valid = up_wreq == 1'b1 && up_waddr == 8'h38; -assign cmd_fifo_in_data = up_wdata[15:0]; +assign cmd_fifo_in_data = up_wdata_s[15:0]; assign cmd_fifo_almost_empty = - `axi_spi_engine_check_watermark(cmd_fifo_room, CMD_FIFO_ADDRESS_WIDTH); + `axi_spi_engine_check_watermark(cmd_fifo_room, CMD_FIFO_ADDRESS_WIDTH); util_axis_fifo #( - .DATA_WIDTH(16), - .ASYNC_CLK(ASYNC_SPI_CLK), - .ADDRESS_WIDTH(CMD_FIFO_ADDRESS_WIDTH), - .S_AXIS_REGISTERED(0) + .DATA_WIDTH(16), + .ASYNC_CLK(ASYNC_SPI_CLK), + .ADDRESS_WIDTH(CMD_FIFO_ADDRESS_WIDTH), + .S_AXIS_REGISTERED(0) ) i_cmd_fifo ( - .s_axis_aclk(s_axi_aclk), - .s_axis_aresetn(up_resetn), - .s_axis_ready(cmd_fifo_in_ready), - .s_axis_valid(cmd_fifo_in_valid), - .s_axis_data(cmd_fifo_in_data), - .s_axis_room(cmd_fifo_room), + .s_axis_aclk(clk), + .s_axis_aresetn(up_sw_resetn), + .s_axis_ready(cmd_fifo_in_ready), + .s_axis_valid(cmd_fifo_in_valid), + .s_axis_data(cmd_fifo_in_data), + .s_axis_room(cmd_fifo_room), - .m_axis_aclk(spi_clk), - .m_axis_aresetn(spi_resetn), - .m_axis_ready(cmd_ready), - .m_axis_valid(cmd_valid), - .m_axis_data(cmd_data) + .m_axis_aclk(spi_clk), + .m_axis_aresetn(spi_resetn), + .m_axis_ready(cmd_ready), + .m_axis_valid(cmd_valid), + .m_axis_data(cmd_data) ); -assign sdo_fifo_in_valid = up_wreq == 1'b1 && up_waddr == 8'h39; -assign sdo_fifo_in_data = up_wdata[7:0]; +assign sdo_fifo_in_valid = up_wreq_s == 1'b1 && up_waddr_s == 8'h39; +assign sdo_fifo_in_data = up_wdata_s[(DATA_WIDTH-1):0]; assign sdo_fifo_almost_empty = - `axi_spi_engine_check_watermark(sdo_fifo_room, SDO_FIFO_ADDRESS_WIDTH); + `axi_spi_engine_check_watermark(sdo_fifo_room, SDO_FIFO_ADDRESS_WIDTH); util_axis_fifo #( - .DATA_WIDTH(8), - .ASYNC_CLK(ASYNC_SPI_CLK), - .ADDRESS_WIDTH(SDO_FIFO_ADDRESS_WIDTH), - .S_AXIS_REGISTERED(0) + .DATA_WIDTH(DATA_WIDTH), + .ASYNC_CLK(ASYNC_SPI_CLK), + .ADDRESS_WIDTH(SDO_FIFO_ADDRESS_WIDTH), + .S_AXIS_REGISTERED(0) ) i_sdo_fifo ( - .s_axis_aclk(s_axi_aclk), - .s_axis_aresetn(up_resetn), - .s_axis_ready(sdo_fifo_in_ready), - .s_axis_valid(sdo_fifo_in_valid), - .s_axis_data(sdo_fifo_in_data), - .s_axis_room(sdo_fifo_room), + .s_axis_aclk(clk), + .s_axis_aresetn(up_sw_resetn), + .s_axis_ready(sdo_fifo_in_ready), + .s_axis_valid(sdo_fifo_in_valid), + .s_axis_data(sdo_fifo_in_data), + .s_axis_room(sdo_fifo_room), - .m_axis_aclk(spi_clk), - .m_axis_aresetn(spi_resetn), - .m_axis_ready(sdo_data_ready), - .m_axis_valid(sdo_data_valid), - .m_axis_data(sdo_data) + .m_axis_aclk(spi_clk), + .m_axis_aresetn(spi_resetn), + .m_axis_ready(sdo_data_ready), + .m_axis_valid(sdo_data_valid), + .m_axis_data(sdo_data) ); -assign sdi_fifo_out_ready = up_rreq == 1'b1 && up_raddr == 8'h3a; +assign sdi_fifo_out_ready = up_rreq_s == 1'b1 && up_raddr_s == 8'h3a; assign sdi_fifo_almost_full = - `axi_spi_engine_check_watermark(sdi_fifo_level, SDI_FIFO_ADDRESS_WIDTH); + `axi_spi_engine_check_watermark(sdi_fifo_level, SDI_FIFO_ADDRESS_WIDTH); util_axis_fifo #( - .DATA_WIDTH(SDI_DATA_WIDTH), - .ASYNC_CLK(ASYNC_SPI_CLK), - .ADDRESS_WIDTH(SDI_FIFO_ADDRESS_WIDTH), - .S_AXIS_REGISTERED(0) + .DATA_WIDTH(NUM_OF_SDI * DATA_WIDTH), + .ASYNC_CLK(ASYNC_SPI_CLK), + .ADDRESS_WIDTH(SDI_FIFO_ADDRESS_WIDTH), + .S_AXIS_REGISTERED(0) ) i_sdi_fifo ( - .s_axis_aclk(spi_clk), - .s_axis_aresetn(spi_resetn), - .s_axis_ready(sdi_data_ready), - .s_axis_valid(sdi_data_valid), - .s_axis_data(sdi_data), + .s_axis_aclk(spi_clk), + .s_axis_aresetn(spi_resetn), + .s_axis_ready(sdi_data_ready), + .s_axis_valid(sdi_data_valid), + .s_axis_data(sdi_data), - .m_axis_aclk(s_axi_aclk), - .m_axis_aresetn(up_resetn), - .m_axis_ready(sdi_fifo_out_ready), - .m_axis_valid(sdi_fifo_out_valid), - .m_axis_data(sdi_fifo_out_data), - .m_axis_level(sdi_fifo_level) + .m_axis_aclk(clk), + .m_axis_aresetn(up_sw_resetn), + .m_axis_ready(sdi_fifo_out_ready), + .m_axis_valid(sdi_fifo_out_valid), + .m_axis_data(sdi_fifo_out_data), + .m_axis_level(sdi_fifo_level) ); -assign offload0_cmd_wr_en = up_wreq == 1'b1 && up_waddr == 8'h44; -assign offload0_cmd_wr_data = up_wdata[15:0]; +assign offload0_cmd_wr_en = up_wreq_s == 1'b1 && up_waddr_s == 8'h44; +assign offload0_cmd_wr_data = up_wdata_s[15:0]; -assign offload0_sdo_wr_en = up_wreq == 1'b1 && up_waddr == 8'h45; -assign offload0_sdo_wr_data = up_wdata[7:0]; +assign offload0_sdo_wr_en = up_wreq_s == 1'b1 && up_waddr_s == 8'h45; +assign offload0_sdo_wr_data = up_wdata_s[7:0]; endmodule 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 223cadabc..b3a092bef 100644 --- a/library/spi_engine/spi_engine_execution/spi_engine_execution.v +++ b/library/spi_engine/spi_engine_execution/spi_engine_execution.v @@ -11,11 +11,12 @@ module spi_engine_execution ( input sdo_data_valid, output reg sdo_data_ready, - input [7:0] sdo_data, + input [(DATA_WIDTH-1):0] sdo_data, + input sdi_data_ready, output reg sdi_data_valid, - output [(SDI_DATA_WIDTH-1):0] sdi_data, + output [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, input sync_ready, output reg sync_valid, @@ -35,10 +36,9 @@ module spi_engine_execution ( 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 +parameter DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 +parameter NUM_OF_SDI = 1; - -localparam NUM_OF_SDI = SDI_DATA_WIDTH >> 3; localparam CMD_TRANSFER = 2'b00; localparam CMD_CHIPSELECT = 2'b01; localparam CMD_WRITE = 2'b10; @@ -88,10 +88,10 @@ reg [7:0] clk_div = DEFAULT_CLK_DIV; 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; +reg [(DATA_WIDTH):0] data_shift = 'h0; +reg [(DATA_WIDTH):0] data_shift_1 = 'h0; +reg [(DATA_WIDTH):0] data_shift_2 = 'h0; +reg [(DATA_WIDTH):0] data_shift_3 = 'h0; wire [1:0] inst = cmd[13:12]; wire [1:0] inst_d1 = cmd_d1[13:12]; @@ -287,45 +287,45 @@ end always @(posedge clk) begin if (transfer_active == 1'b1 || wait_for_io == 1'b1) begin - sdo_t <= ~sdo_enabled; + sdo_t <= ~sdo_enabled; end else begin - sdo_t <= 1'b1; + 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; + data_shift[DATA_WIDTH: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]; + data_shift[DATA_WIDTH:1] <= data_shift[(DATA_WIDTH-1):0]; + data_shift_1[DATA_WIDTH:1] <= data_shift_1[(DATA_WIDTH-1):0]; + data_shift_2[DATA_WIDTH:1] <= data_shift_2[(DATA_WIDTH-1):0]; + data_shift_3[DATA_WIDTH:1] <= data_shift_3[(DATA_WIDTH-1):0]; end end -assign sdo = data_shift[8]; -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]} : +assign sdo = data_shift[DATA_WIDTH]; +assign sdi_data = (NUM_OF_SDI == 1) ? data_shift[(DATA_WIDTH-1):0] : + (NUM_OF_SDI == 2) ? {data_shift_1[(DATA_WIDTH-1):0], data_shift[(DATA_WIDTH-1):0]} : + (NUM_OF_SDI == 3) ? {data_shift_2[(DATA_WIDTH-1):0], data_shift_1[(DATA_WIDTH-1):0], data_shift[(DATA_WIDTH-1):0]} : + (NUM_OF_SDI == 4) ? {data_shift_3[(DATA_WIDTH-1):0], data_shift_2[(DATA_WIDTH-1):0], data_shift_1[(DATA_WIDTH-1):0], data_shift[(DATA_WIDTH-1):0]} : data_shift[7:0]; always @(posedge clk) begin 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; + 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; + sclk <= cpol ^ cpha ^ ntx_rx; end else begin - sclk <= cpol; + sclk <= cpol; end end 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 14cf70aeb..bd8cc6c48 100644 --- a/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v +++ b/library/spi_engine/spi_engine_interconnect/spi_engine_interconnect.v @@ -10,11 +10,11 @@ module spi_engine_interconnect ( output m_sdo_valid, input m_sdo_ready, - output [7:0] m_sdo_data, + output [(DATA_WIDTH-1):0] m_sdo_data, input m_sdi_valid, output m_sdi_ready, - input [(SDI_DATA_WIDTH-1):0] m_sdi_data, + input [(NUM_OF_SDI * DATA_WIDTH-1):0] m_sdi_data, input m_sync_valid, output m_sync_ready, @@ -27,11 +27,11 @@ module spi_engine_interconnect ( input s0_sdo_valid, output s0_sdo_ready, - input [7:0] s0_sdo_data, + input [(DATA_WIDTH-1):0] s0_sdo_data, output s0_sdi_valid, input s0_sdi_ready, - output [(SDI_DATA_WIDTH-1):0] s0_sdi_data, + output [(NUM_OF_SDI * DATA_WIDTH-1):0] s0_sdi_data, output s0_sync_valid, input s0_sync_ready, @@ -44,18 +44,19 @@ module spi_engine_interconnect ( input s1_sdo_valid, output s1_sdo_ready, - input [7:0] s1_sdo_data, + input [(DATA_WIDTH-1):0] s1_sdo_data, output s1_sdi_valid, input s1_sdi_ready, - output [(SDI_DATA_WIDTH-1):0] s1_sdi_data, + output [(NUM_OF_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 +parameter DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 +parameter NUM_OF_SDI = 1; reg s_active = 1'b0; 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 0082bec04..80563a17f 100644 --- a/library/spi_engine/spi_engine_offload/spi_engine_offload.v +++ b/library/spi_engine/spi_engine_offload/spi_engine_offload.v @@ -6,7 +6,7 @@ module spi_engine_offload ( input [15:0] ctrl_cmd_wr_data, input ctrl_sdo_wr_en, - input [7:0] ctrl_sdo_wr_data, + input [(DATA_WIDTH-1):0] ctrl_sdo_wr_data, input ctrl_enable, output ctrl_enabled, @@ -23,11 +23,11 @@ module spi_engine_offload ( output sdo_data_valid, input sdo_data_ready, - output [7:0] sdo_data, + output [(DATA_WIDTH-1):0] sdo_data, input sdi_data_valid, output sdi_data_ready, - input [(SDI_DATA_WIDTH-1):0] sdi_data, + input [(NUM_OF_SDI * DATA_WIDTH-1):0] sdi_data, input sync_valid, output sync_ready, @@ -35,13 +35,14 @@ module spi_engine_offload ( output offload_sdi_valid, input offload_sdi_ready, - output [(SDI_DATA_WIDTH-1):0] offload_sdi_data + output [(NUM_OF_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 +parameter DATA_WIDTH = 8; // Valid data widths values are 8/16/24/32 +parameter NUM_OF_SDI = 1; reg spi_active = 1'b0; @@ -51,7 +52,7 @@ reg [SDO_MEM_ADDRESS_WIDTH-1:0] ctrl_sdo_wr_addr = 'h00; reg [SDO_MEM_ADDRESS_WIDTH-1:0] spi_sdo_rd_addr = 'h00; reg [15:0] cmd_mem[0:2**CMD_MEM_ADDRESS_WIDTH-1]; -reg [7:0] sdo_mem[0:2**SDO_MEM_ADDRESS_WIDTH-1]; +reg [(DATA_WIDTH-1):0] sdo_mem[0:2**SDO_MEM_ADDRESS_WIDTH-1]; wire [CMD_MEM_ADDRESS_WIDTH-1:0] spi_cmd_rd_addr_next; wire spi_enable;