Entity: spi_p2s

Diagram

clk_i rst_ni data_valid_i spi_byte_t data_i csb_i cpha_i order_i io_mode_e io_mode_i data_sent_o [3:0] s_en_o [3:0] s_o

Description

Copyright lowRISC contributors. Licensed under the Apache License, Version 2.0, see LICENSE for details. SPDX-License-Identifier: Apache-2.0

SPI byte to SPI (Single/ Dual/ Quad)

Ports

Port name Direction Type Description
clk_i input
rst_ni input
data_valid_i input Input byte interface
data_i input spi_byte_t
data_sent_o output
csb_i input for line floating
s_en_o output [3:0]
s_o output [3:0]
cpha_i input Configuration If CPHA=1, then the first byte should be delayed. But this does not matter in SPI Flash. Only applicable to Generic mode
order_i input Control txorder: controls which bit goes out first.
io_mode_i input io_mode_e IO mode

Signals

Name Type Description
tx_state tx_state_e Only for handling CPHA
io_mode io_mode_e Latching io_mode_i when last beat is set. This guarantees cnt not abruptly changed during operation which affects last_beat again.
first_beat logic in Mode3, the logic skips first clock edge to move to next bit. This is not necessary for Flash / Passthrough mode. But Generic mode sends the data through TX line right after reset
last_beat logic in Mode3, the logic skips first clock edge to move to next bit. This is not necessary for Flash / Passthrough mode. But Generic mode sends the data through TX line right after reset
cnt count_t
out_enable logic [3:0]
out_shift spi_byte_t
out_shift_d spi_byte_t

Constants

Name Type Value Description
Bits int unsigned $bits(spi_byte_t) ////////////// Definition // //////////////
BitWidth int unsigned $clog2(Bits)

Types

Name Type Description
count_t logic [BitWidth-1:0]
tx_state_e enum logic {
TxIdle,
TxActive }

Processes

Type: always_comb

Description
Enable selection in Single mode, line 1 is for output. in Dual mode, line 0:1 are for output in Quad mode, all lines 0:3 are for output.

Type: always_comb

Description
data_sent Popping signal is a little bit tricky if p2s supports Quad IO The sent signal cannot be sent at the end of the beat, as it does not have enought time to affect the FIFO.
If the sent signal asserted at the first beat, at the very first byte of SPI has no time to assert valid signal. So the sent signal does not affect the FIFO. So the logic sends first byte twice.
This won't affect in Flash mode as in Flash/Passthrough mode, first byte is always SPI command. It does not send anything on the SPI bus.
So, the logic generating sent signal looks not straightforward. It tries assert second last beat. So, in SingleIO (right after reset always), it asserts at 7th beat. Then the mode could be changed to Dual/ Quad.

Type: always_ff

Description
data shift

Type: always_comb

Description
SPI out

Type: always_ff

Description
io_mode io_mode reset value is SingleIO (as described in assumption) Then, every byte sent, the logic updates its value to io_mode_i This makes the logic safer than direct use of io_mode_i. If io_mode_i value is changed within a byte, it affects to last_beat then, the incorrect last_beat affects cnt, which could break the data operation.
Following logic has high chance to break the rule. As there's no indication of the end of a byte. data_sent_o is not a valid indicator as the signal asserted one cycle earlier than the last beat.

Type: always_ff

Description
cnt TODO: Consider dummy cycle that is not aligned to a byte Is this valid scenario?

Type: always_comb

Description
Last beat depends on the mode

Type: always_ff

Description
///////// State // ///////// At reset, tx state sits in TxIdle. It moves to TxActive. This is to delay the first posedge in Mode 3.