[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