[spi_device] Move modules inside fwmode Move FwMode related modules inside fwmode submodules to be self-contained and to increase readability. Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/hw/ip/spi_device/rtl/spi_device.sv b/hw/ip/spi_device/rtl/spi_device.sv index f15b54d..55e0f9b 100644 --- a/hw/ip/spi_device/rtl/spi_device.sv +++ b/hw/ip/spi_device/rtl/spi_device.sv
@@ -78,6 +78,24 @@ logic [SramDw-1:0] mem_b_rdata; logic [1:0] mem_b_rerror; + // Request from FwMode: peri clock domain when active + logic fwm_req; + logic fwm_write; + logic [SramAw-1:0] fwm_addr; + logic [SramDw-1:0] fwm_wdata; + logic fwm_rvalid; + logic [SramDw-1:0] fwm_rdata; + logic [1:0] fwm_rerror; + + // TODO: Add real mux for FlashMode & PassThrough + assign mem_b_req = fwm_req ; + assign mem_b_write = fwm_write ; + assign mem_b_addr = fwm_addr ; + assign mem_b_wdata = fwm_wdata ; + assign fwm_rvalid = mem_b_rvalid; + assign fwm_rdata = mem_b_rdata ; + assign fwm_rerror = mem_b_rerror; + ///////////////////// // Control signals // ///////////////////// @@ -104,31 +122,8 @@ logic intr_fwm_rxlvl, rxlvl, rxlvl_d, intr_fwm_txlvl, txlvl, txlvl_d; logic intr_fwm_rxoverflow, intr_fwm_txunderflow; - // RX Async FIFO Signals - // Write: SCK positive edge - logic rxf_wvalid, rxf_wready; - spi_byte_t rxf_wdata; - logic rxf_overflow; - // Read: Main clock - logic rxf_rvalid, rxf_rready; - spi_byte_t rxf_rdata; - logic rxf_full_syncd; + logic rxf_overflow, txf_underflow; - // TX Async FIFO Signals - // Read: SCK negative edge - logic txf_rvalid, txf_rready; - spi_byte_t txf_rdata; - logic txf_underflow; - // Write: Main clock - logic txf_wvalid, txf_wready; - spi_byte_t txf_wdata; - logic txf_empty_syncd; - - // SRAM FIFO control - typedef enum int { - FwModeRxFifo = 0, - FwModeTxFifo = 1 - } fwm_fifo_e; logic [7:0] timer_v; // Wait timer inside rxf control logic [PtrW-1:0] sram_rxf_rptr, sram_rxf_wptr; logic [PtrW-1:0] sram_txf_rptr, sram_txf_wptr; @@ -136,17 +131,12 @@ logic [SramAw-1:0] sram_rxf_bindex, sram_txf_bindex; logic [SramAw-1:0] sram_rxf_lindex, sram_txf_lindex; - logic [1:0] fwm_sram_req; - logic [SramAw-1:0] fwm_sram_addr [2]; - logic fwm_sram_write [2]; - logic [SramDw-1:0] fwm_sram_wdata [2]; - logic [1:0] fwm_sram_gnt; - logic [1:0] fwm_sram_rvalid; // RXF doesn't use - logic [SramDw-1:0] fwm_sram_rdata [2]; // RXF doesn't use - logic [1:0] fwm_sram_error [2]; logic [AsFifoDepthW-1:0] as_txfifo_depth, as_rxfifo_depth; + logic rxf_empty, rxf_full, txf_empty, txf_full; + logic rxf_full_syncd, txf_empty_syncd; // sync signals + // SPI S2P signals // io_mode: Determine s2p/p2s behavior. As of now, only fwmode exists. // TODO: Add FlashMode IO, passthrough IO @@ -191,8 +181,8 @@ assign abort = reg2hw.control.abort.q; assign hw2reg.status.abort_done.d = 1'b1; - assign hw2reg.status.rxf_empty.d = ~rxf_rvalid; - assign hw2reg.status.txf_full.d = ~txf_wready; + assign hw2reg.status.rxf_empty.d = rxf_empty; + assign hw2reg.status.txf_full.d = txf_full; // SYNC logic required assign hw2reg.status.rxf_full.d = rxf_full_syncd; @@ -210,11 +200,11 @@ logic rxf_full_q, txf_empty_q; always_ff @(posedge clk_spi_in_buf or negedge rst_ni) begin if (!rst_ni) rxf_full_q <= 1'b0; - else rxf_full_q <= ~rxf_wready; + else rxf_full_q <= rxf_full; end always_ff @(posedge clk_spi_out_buf or negedge rst_ni) begin if (!rst_ni) txf_empty_q <= 1'b1; - else txf_empty_q <= ~txf_rvalid; + else txf_empty_q <= txf_empty; end prim_flop_2sync #(.Width(1)) u_sync_rxf ( .clk_i, @@ -545,19 +535,31 @@ ///////////// // FW Mode // ///////////// - spi_fwmode u_fwmode ( + spi_fwmode #( + .FifoWidth (FifoWidth), + .FifoDepth (FifoDepth) + ) u_fwmode ( + .clk_i, + .rst_ni, + + .clk_spi_in_i (clk_spi_in_buf), + .rst_rxfifo_ni (rst_rxfifo_n), + .clk_spi_out_i (clk_spi_out_buf), + .rst_txfifo_ni (rst_txfifo_n), + .mode_i (spi_mode), - .rx_wvalid_o (rxf_wvalid), - .rx_wready_i (rxf_wready), - .rx_data_o (rxf_wdata), + .rxf_overflow_o (rxf_overflow), + .txf_underflow_o (txf_underflow), - .tx_rvalid_i (txf_rvalid), - .tx_rready_o (txf_rready), - .tx_data_i (txf_rdata), - - .rx_overflow_o (rxf_overflow), - .tx_underflow_o (txf_underflow), + // SRAM interface + .fwm_req_o (fwm_req ), + .fwm_write_o (fwm_write ), + .fwm_addr_o (fwm_addr ), + .fwm_wdata_o (fwm_wdata ), + .fwm_rvalid_i (fwm_rvalid ), + .fwm_rdata_i (fwm_rdata ), + .fwm_rerror_i (fwm_rerror ), // Input from S2P .rx_data_valid_i (s2p_data_valid), @@ -569,143 +571,33 @@ // P2S .tx_wvalid_o (p2s_valid), .tx_data_o (p2s_data), - .tx_wready_i (p2s_sent) - ); + .tx_wready_i (p2s_sent), - // FIFO: Connecting FwMode to SRAM CTRLs - prim_fifo_async #( - .Width (FifoWidth), - .Depth (FifoDepth) - ) u_rx_fifo ( - .clk_wr_i (clk_spi_in_buf), - .rst_wr_ni (rst_rxfifo_n), + // CSRs + .timer_v_i (timer_v), + .sram_rxf_bindex_i (sram_rxf_bindex), + .sram_txf_bindex_i (sram_txf_bindex), + .sram_rxf_lindex_i (sram_rxf_lindex), + .sram_txf_lindex_i (sram_txf_lindex), - .clk_rd_i (clk_i), - .rst_rd_ni (rst_rxfifo_n), + .abort_i (abort), - .wvalid_i (rxf_wvalid), - .wready_o (rxf_wready), - .wdata_i (rxf_wdata), + .sram_rxf_rptr_i (sram_rxf_rptr ), + .sram_rxf_wptr_o (sram_rxf_wptr ), + .sram_txf_rptr_o (sram_txf_rptr ), + .sram_txf_wptr_i (sram_txf_wptr ), + .sram_rxf_depth_o (sram_rxf_depth), + .sram_txf_depth_o (sram_txf_depth), + .sram_rxf_full_o (sram_rxf_full ), - .rvalid_o (rxf_rvalid), - .rready_i (rxf_rready), - .rdata_o (rxf_rdata), + .as_txfifo_depth_o (as_txfifo_depth), + .as_rxfifo_depth_o (as_rxfifo_depth), - .wdepth_o (), - .rdepth_o (as_rxfifo_depth) - ); + .rxf_empty_o (rxf_empty), + .rxf_full_o (rxf_full), + .txf_empty_o (txf_empty), + .txf_full_o (txf_full) - prim_fifo_async #( - .Width (FifoWidth), - .Depth (FifoDepth) - ) u_tx_fifo ( - .clk_wr_i (clk_i), - .rst_wr_ni (rst_txfifo_n), - - .clk_rd_i (clk_spi_out_buf), - .rst_rd_ni (rst_txfifo_n), - - .wvalid_i (txf_wvalid), - .wready_o (txf_wready), - .wdata_i (txf_wdata), - - .rvalid_o (txf_rvalid), - .rready_i (txf_rready), - .rdata_o (txf_rdata), - - .wdepth_o (as_txfifo_depth), - .rdepth_o () - ); - - // RX Fifo control (FIFO Read port --> SRAM request) - spi_fwm_rxf_ctrl #( - .FifoDw (FifoWidth), - .SramAw (SramAw), - .SramDw (SramDw) - ) u_rxf_ctrl ( - .clk_i, - .rst_ni, - - .base_index_i (sram_rxf_bindex), - .limit_index_i (sram_rxf_lindex), - .timer_v (timer_v), - .rptr (sram_rxf_rptr), // Given by FW - .wptr (sram_rxf_wptr), // to Register interface - .depth (sram_rxf_depth), - .full (sram_rxf_full), - - .fifo_valid (rxf_rvalid), - .fifo_ready (rxf_rready), - .fifo_rdata (rxf_rdata), - - .sram_req (fwm_sram_req [FwModeRxFifo]), - .sram_write (fwm_sram_write [FwModeRxFifo]), - .sram_addr (fwm_sram_addr [FwModeRxFifo]), - .sram_wdata (fwm_sram_wdata [FwModeRxFifo]), - .sram_gnt (fwm_sram_gnt [FwModeRxFifo]), - .sram_rvalid (fwm_sram_rvalid[FwModeRxFifo]), - .sram_rdata (fwm_sram_rdata [FwModeRxFifo]), - .sram_error (fwm_sram_error [FwModeRxFifo]) - ); - - // TX Fifo control (SRAM read request --> FIFO write) - spi_fwm_txf_ctrl #( - .FifoDw (FifoWidth), - .SramAw (SramAw), - .SramDw (SramDw) - ) u_txf_ctrl ( - .clk_i, - .rst_ni, - - .base_index_i (sram_txf_bindex), - .limit_index_i (sram_txf_lindex), - - .abort (abort), - .rptr (sram_txf_rptr), // Given by FW - .wptr (sram_txf_wptr), // to Register interface - .depth (sram_txf_depth), - - .fifo_valid (txf_wvalid), - .fifo_ready (txf_wready), - .fifo_wdata (txf_wdata), - - .sram_req (fwm_sram_req [FwModeTxFifo]), - .sram_write (fwm_sram_write [FwModeTxFifo]), - .sram_addr (fwm_sram_addr [FwModeTxFifo]), - .sram_wdata (fwm_sram_wdata [FwModeTxFifo]), - .sram_gnt (fwm_sram_gnt [FwModeTxFifo]), - .sram_rvalid (fwm_sram_rvalid[FwModeTxFifo]), - .sram_rdata (fwm_sram_rdata [FwModeTxFifo]), - .sram_error (fwm_sram_error [FwModeTxFifo]) - ); - - // Arbiter for FIFOs : Connecting between SRAM Ctrls and SRAM interface - prim_sram_arbiter #( - .N (2), // RXF, TXF - .SramDw (SramDw), - .SramAw (SramAw) // 2kB - ) u_fwmode_arb ( - .clk_i, - .rst_ni, - - .req_i (fwm_sram_req), - .req_addr_i (fwm_sram_addr), - .req_write_i (fwm_sram_write), - .req_wdata_i (fwm_sram_wdata), - .gnt_o (fwm_sram_gnt), - - .rsp_rvalid_o (fwm_sram_rvalid), - .rsp_rdata_o (fwm_sram_rdata), - .rsp_error_o (fwm_sram_error), - - .sram_req_o (mem_b_req), - .sram_addr_o (mem_b_addr), - .sram_write_o (mem_b_write), - .sram_wdata_o (mem_b_wdata), - - .sram_rvalid_i(mem_b_rvalid), - .sram_rdata_i (mem_b_rdata), - .sram_rerror_i(mem_b_rerror) ); tlul_adapter_sram #(
diff --git a/hw/ip/spi_device/rtl/spi_fwmode.sv b/hw/ip/spi_device/rtl/spi_fwmode.sv index ef9534f..79b4a5b 100644 --- a/hw/ip/spi_device/rtl/spi_fwmode.sv +++ b/hw/ip/spi_device/rtl/spi_fwmode.sv
@@ -7,22 +7,38 @@ module spi_fwmode import spi_device_pkg::*; -( +#( + parameter int FifoWidth = $bits(spi_byte_t), + parameter int FifoDepth = 8, + localparam int SDW = $clog2(SramDw/FifoWidth), + localparam int PtrW = SramAw + 1 + SDW, + localparam int AsFifoDepthW = $clog2(FifoDepth+1) +) ( + // clk + input clk_i, // main peripheral clock + input rst_ni, + + input clk_spi_in_i, + input rst_rxfifo_ni, + + input clk_spi_out_i, + input rst_txfifo_ni, + // Configurations // No sync logic. Configuration should be static when SPI operating input spi_mode_e mode_i, // Only works at mode_i == FwMode - // RX, TX FIFO interface - output logic rx_wvalid_o, - input rx_wready_i, - output spi_byte_t rx_data_o, + output logic rxf_overflow_o, + output logic txf_underflow_o, - input tx_rvalid_i, - output logic tx_rready_o, - input spi_byte_t tx_data_i, - - output logic rx_overflow_o, - output logic tx_underflow_o, + // SRAM interface + output logic fwm_req_o, + output logic fwm_write_o, + output logic [SramAw-1:0] fwm_addr_o, + output logic [SramDw-1:0] fwm_wdata_o, + input fwm_rvalid_i, + input [SramDw-1:0] fwm_rdata_i, + input [1:0] fwm_rerror_i, // Serial to Parallel input rx_data_valid_i, @@ -32,18 +48,81 @@ // Parallel to SPI output logic tx_wvalid_o, output spi_byte_t tx_data_o, - input tx_wready_i + input tx_wready_i, + + // CSRs + input [7:0] timer_v_i, // Wait timer inside rxf control + input [SramAw-1:0] sram_rxf_bindex_i, + input [SramAw-1:0] sram_txf_bindex_i, + input [SramAw-1:0] sram_rxf_lindex_i, + input [SramAw-1:0] sram_txf_lindex_i, + + input abort_i, + + // pointers + input [PtrW-1:0] sram_rxf_rptr_i, + output logic [PtrW-1:0] sram_rxf_wptr_o, + output logic [PtrW-1:0] sram_txf_rptr_o, + input [PtrW-1:0] sram_txf_wptr_i, + output logic [PtrW-1:0] sram_rxf_depth_o, + output logic [PtrW-1:0] sram_txf_depth_o, + output logic sram_rxf_full_o, + + output logic [AsFifoDepthW-1:0] as_txfifo_depth_o, + output logic [AsFifoDepthW-1:0] as_rxfifo_depth_o, + + // FIFO Status + output logic rxf_empty_o, + output logic rxf_full_o, + output logic txf_empty_o, + output logic txf_full_o ); import spi_device_pkg::*; - assign rx_wvalid_o = rx_data_valid_i; - assign rx_data_o = rx_data_i; + ///////////// + // Signals // + ///////////// + // RX Async FIFO Signals + // Write: SCK positive edge + logic rxf_wvalid, rxf_wready; + spi_byte_t rxf_wdata; + // Read: Main clock + logic rxf_rvalid, rxf_rready; + spi_byte_t rxf_rdata; + + // TX Async FIFO Signals + // Read: SCK negative edge + logic txf_rvalid, txf_rready; + spi_byte_t txf_rdata; + // Write: Main clock + logic txf_wvalid, txf_wready; + spi_byte_t txf_wdata; + + // SRAM FIFO control + typedef enum int { + FwModeRxFifo = 0, + FwModeTxFifo = 1 + } fwm_fifo_e; + + logic [1:0] fwm_sram_req; + logic [SramAw-1:0] fwm_sram_addr [2]; + logic fwm_sram_write [2]; + logic [SramDw-1:0] fwm_sram_wdata [2]; + logic [1:0] fwm_sram_gnt; + logic [1:0] fwm_sram_rvalid; // RXF doesn't use + logic [SramDw-1:0] fwm_sram_rdata [2]; // RXF doesn't use + logic [1:0] fwm_sram_error [2]; + + + + assign rxf_wvalid = rx_data_valid_i; + assign rxf_wdata = rx_data_i; assign tx_wvalid_o = 1'b 1; - assign tx_rready_o = tx_wready_i; - assign tx_data_o = tx_data_i; + assign txf_rready = tx_wready_i; + assign tx_data_o = txf_rdata; // Generic Mode only uses SingleIO. s_i[0] is MOSI, s_o[1] is MISO. assign io_mode_o = SingleIO; @@ -56,7 +135,152 @@ // // For these events to be propagated to the main clock domain, it needds // one more clock edge to creates toggle signal in the pulse synchronizer. - assign rx_overflow_o = rx_wvalid_o & ~rx_wready_i; - assign tx_underflow_o = tx_rready_o & ~tx_rvalid_i; + assign rxf_overflow_o = rxf_wvalid & ~rxf_wready; + assign txf_underflow_o = txf_rready & ~txf_rvalid; + + assign rxf_empty_o = ~rxf_rvalid; + assign rxf_full_o = ~rxf_wready; + assign txf_empty_o = ~txf_rvalid; + assign txf_full_o = ~txf_wready; + /////////////// + // Instances // + /////////////// + + // FIFO: Connecting FwMode to SRAM CTRLs + prim_fifo_async #( + .Width (FifoWidth), + .Depth (FifoDepth) + ) u_rx_fifo ( + .clk_wr_i (clk_spi_in_i), + .rst_wr_ni (rst_rxfifo_ni), + + .clk_rd_i (clk_i), + .rst_rd_ni (rst_rxfifo_ni), + + .wvalid_i (rxf_wvalid), + .wready_o (rxf_wready), + .wdata_i (rxf_wdata), + + .rvalid_o (rxf_rvalid), + .rready_i (rxf_rready), + .rdata_o (rxf_rdata), + + .wdepth_o (), + .rdepth_o (as_rxfifo_depth_o) + ); + + prim_fifo_async #( + .Width (FifoWidth), + .Depth (FifoDepth) + ) u_tx_fifo ( + .clk_wr_i (clk_i), + .rst_wr_ni (rst_txfifo_ni), + + .clk_rd_i (clk_spi_out_i), + .rst_rd_ni (rst_txfifo_ni), + + .wvalid_i (txf_wvalid), + .wready_o (txf_wready), + .wdata_i (txf_wdata), + + .rvalid_o (txf_rvalid), + .rready_i (txf_rready), + .rdata_o (txf_rdata), + + .wdepth_o (as_txfifo_depth_o), + .rdepth_o () + ); + + // RX Fifo control (FIFO Read port --> SRAM request) + spi_fwm_rxf_ctrl #( + .FifoDw (FifoWidth), + .SramAw (SramAw), + .SramDw (SramDw) + ) u_rxf_ctrl ( + .clk_i, + .rst_ni, + + .base_index_i (sram_rxf_bindex_i), + .limit_index_i (sram_rxf_lindex_i), + .timer_v (timer_v_i), + .rptr (sram_rxf_rptr_i), // Given by FW + .wptr (sram_rxf_wptr_o), // to Register interface + .depth (sram_rxf_depth_o), + .full (sram_rxf_full_o), + + .fifo_valid (rxf_rvalid), + .fifo_ready (rxf_rready), + .fifo_rdata (rxf_rdata), + + .sram_req (fwm_sram_req [FwModeRxFifo]), + .sram_write (fwm_sram_write [FwModeRxFifo]), + .sram_addr (fwm_sram_addr [FwModeRxFifo]), + .sram_wdata (fwm_sram_wdata [FwModeRxFifo]), + .sram_gnt (fwm_sram_gnt [FwModeRxFifo]), + .sram_rvalid (fwm_sram_rvalid[FwModeRxFifo]), + .sram_rdata (fwm_sram_rdata [FwModeRxFifo]), + .sram_error (fwm_sram_error [FwModeRxFifo]) + ); + + // TX Fifo control (SRAM read request --> FIFO write) + spi_fwm_txf_ctrl #( + .FifoDw (FifoWidth), + .SramAw (SramAw), + .SramDw (SramDw) + ) u_txf_ctrl ( + .clk_i, + .rst_ni, + + .base_index_i (sram_txf_bindex_i), + .limit_index_i (sram_txf_lindex_i), + + .abort (abort_i), + .rptr (sram_txf_rptr_o), + .wptr (sram_txf_wptr_i), + .depth (sram_txf_depth_o), + + .fifo_valid (txf_wvalid), + .fifo_ready (txf_wready), + .fifo_wdata (txf_wdata), + + .sram_req (fwm_sram_req [FwModeTxFifo]), + .sram_write (fwm_sram_write [FwModeTxFifo]), + .sram_addr (fwm_sram_addr [FwModeTxFifo]), + .sram_wdata (fwm_sram_wdata [FwModeTxFifo]), + .sram_gnt (fwm_sram_gnt [FwModeTxFifo]), + .sram_rvalid (fwm_sram_rvalid[FwModeTxFifo]), + .sram_rdata (fwm_sram_rdata [FwModeTxFifo]), + .sram_error (fwm_sram_error [FwModeTxFifo]) + ); + + // Arbiter for FIFOs : Connecting between SRAM Ctrls and SRAM interface + prim_sram_arbiter #( + .N (2), // RXF, TXF + .SramDw (SramDw), + .SramAw (SramAw) // 2kB + ) u_fwmode_arb ( + .clk_i, + .rst_ni, + + .req_i (fwm_sram_req), + .req_addr_i (fwm_sram_addr), + .req_write_i (fwm_sram_write), + .req_wdata_i (fwm_sram_wdata), + .gnt_o (fwm_sram_gnt), + + .rsp_rvalid_o (fwm_sram_rvalid), + .rsp_rdata_o (fwm_sram_rdata), + .rsp_error_o (fwm_sram_error), + + .sram_req_o (fwm_req_o), + .sram_addr_o (fwm_addr_o), + .sram_write_o (fwm_write_o), + .sram_wdata_o (fwm_wdata_o), + + .sram_rvalid_i(fwm_rvalid_i), + .sram_rdata_i (fwm_rdata_i), + .sram_rerror_i(fwm_rerror_i) + ); + endmodule