muNVMe IP Core Datasheet

Features 1

Applications 2

General Description. 3

Functional Description. 5

NVMe. 8

·      NVMe Host Controller 8

·      Command Parameter 9

·      Data Buffer 9

·      NVMe Data Controller 9

PCIe. 9

·      PCIe Controller 9

·      AsyncCtrl 9

User Logic. 10

Avalon-ST PCIe Hard IP. 10

Core I/O Signals 11

Initialization. 15

Control interface of dgIF typeS. 16

Data interface of dgIF typeS. 18

IdenCtrl/IdenName. 21

Shutdown. 23

SMART. 24

Flush. 26

Error 27

Verification Methods 28

Recommended Design Experience. 28

Ordering Information. 28

Revision History. 28

 

 

 

  Core Facts

Provided with Core

Documentation

Reference Design Manual

Demo Instruction Manual

Design File Formats

Encrypted File

Instantiation Templates

VHDL

Reference Designs & Application Notes

Quartus Project,

See Reference Design Manual

Additional Items

Demo on

Arria10GX development kit

Support

Support provided by Design Gateway Co., Ltd.

 

 

Design Gateway Co.,Ltd

E-mail:    ip-sales@design-gateway.com

URL:       design-gateway.com

 

Features

·     Direct NVMe Gen3 SSD access without the need for CPU or external memory

·     Include two 256-KB RAMs for data buffering

·     Simple user interfaces through dgIF typeS

·     Two user interfaces operating simultaneously

·     Command support:

·     User#0 (Main user): Identify, Shutdown, Write, Read, SMART, and Flush

·     User#1 (Sub user): Write and Read

·     Supported NVMe device

·     Base Class Code:01h (mass storage), Sub Class Code:08h (Non-volatile), Programming Interface:02h (NVMHCI)

·     MPSMIN (Memory Page Size Minimum): 0 (4KB)

·     MDTS (Maximum Data Transfer Size): At least 5 (128 KB) or 0 (no limitation)

·     MQES (Maximum Queue Entries Support): At least 8

·     Support for multiple queues

·     LBA unit: 512 or 4096 bytes

·     User clock frequency: At least the PCIe clock frequency (250MHz for Gen3)

·     PCIe Gen3 Hard IP interface: 128-bit Avalon-ST bus interface

·     Available reference design

·     Arria10 GX development board with AB18-PCIeX16 adapter board

·     Customized service for following features

·     Additional NVMe commands such as Format, Write Zeroes, and Sanitize

·     RAM size modification

·     Number of users modification

 

Table 1: Example Implementation Statistics

Family

Example Device

Fmax

(MHz)

Logic utilization (ALMs)1

Registers

Pin

Block

Memory bit

Design

Tools

Arria10 GX

10AX115S2F45I1SG

300

2833

6432

-

4,259,840

Quartus 21.3

Notes: Actual logic resource dependent on percentage of unrelated logic

 

Applications

 

Figure 1: muNVMe IP Application

 

muNVMe IP Core, integrated with PCIe Gen3 hard IP, provides an efficient solution to access an NVMe Gen3 SSD without the need for CPU or external memory, such as DDR. With a dual -user interface, both users can access an NVMe SSD in parallel, making it an ideal solution for applications that require concurrent data recording from local source, such as high-speed A/D converter, and simultaneous data retrieval from the same SSD. Furthermore, by connecting an Ethernet IP Core to the read logic, the system can facilitate host access for data retrieval and real-time monitoring via an Ethernet network, as shown in Figure 1.

General Description

 

Figure 2: muNVMe IP block diagram

 

The muNVMe IP serves as a comprehensive host controller solution, facilitating access to an NVMe SSD through the NVM express standard. This connection is established via PCIe, with the lower layer being implemented through the use of Avalon-ST Hard IP for PCIe (PCIe hard IP), a hard block available in Intel FPGA devices.

Six NVMe commands, including Identify, Shutdown, Write, Read, SMART, and Flush, are executed by the muNVMe IP, which offers dual user interfaces: User#0 I/F and User#1 I/F. As shown in Figure 2, User#0 I/F and User#1 I/F correspond to the interfaces of NVM#0 and NVMe#1 modules within the muNVMeIP. NVM#0 (Main) is capable of executing all six commands, whereas NVM#1 (Sub) exclusively handles Write and Read commands.

The User I/F utilizes two user interface groups to facilitate command and data transfer. The Control interface is responsible for transmitting commands and their associated parameters. Meanwhile, the Data interface is used when data transfer is required by the specific command. For Write/Read commands, both the Control interface and Data interface utilize dgIF typeS, our standard interface for storage IP. This Control interface of dgIF typeS includes the start address, transfer length, and request signals, while the Data interface uses the standard FIFO interface.

The SMART and Flush commands are categorized as Custom commands and utilize the Ctm Cmd I/F for control path and the Ctm RAM I/F for data path. Meanwhile, the Identify command uses its dedicated data interface, known as the Iden RAM I/F. It shares the same Control interfaces as the Write or Read command, as shown in Figure 2. These specific interfaces are integrated only in the User#0 I/F.

Due to two user interfaces, NVM#1 can execute Write or Read commands while NVM#0 concurrently handles other commands. However, there is one specification regarding parallel operation: the Shutdown command must be executed on NVMe#0 after both NVM#0 and NVM#1 return to be an idle state.

If abnormal conditions are detected during initialization or certain command operation, the muNVMe IP may assert an error signal. The error status can be read from the IP for more details. Once the error cause is resolved, both the muNVMe IP and SSD must be reset.

To ensure continuous packet transmission until the end of the packet on the user interface of the PCIe hard IP, the user logic clock frequency must be equal to or greater than the PCIe clock frequency (250 MHz for PCIe Gen3). This ensures that data remains valid during each clock cycle within the frame. Therefore, it can guarantee that the bandwidth on the user interface is equal to or greater than the PCIe hard IP.

Overall, the muNVMe IP provides a comprehensive solution for NVMe SSD access through two parallel-executing user interfaces. The IP core is accompanied by reference designs for FPGA evaluation boards, allowing users to evaluate the product’s capabilities before making a purchase. These reference designs on FPGA evaluation boards are available for evaluation before purchasing.

 

Functional Description

The operation flow of muNVMe IP is divided into three phases: Initialization, Command operation, and No operation, as shown in Figure 3. Upon de-asserting the IP reset, the initialization phase begins, and User#0 should execute the Identify command to assess device status and capacity. In the Command operation phase, both User#0 and User#1 can perform write and read operations. User#0 can also execute Custom commands such as SMART and Flush. Finally, before shutting down the system, it is recommended for User#0 to execute the Shutdown command to ensure safe operation.

 

 

Figure 3 Operation Flow of muNVMe IP

 

The Initialization phase is handled by the User#0 I/F, while the User#1 I/F remains in a waiting state until the Initialization phase completes. The Initialization step is outlined in the following steps.

1)     NVM#0 waits for PCIe to be ready, monitoring the Linkup status from the PCIe IP core.

2)     NVM#0 initiates the initialization process by configuring PCIe and NVMe registers. Upon successful completion of the initialization, it transitions to an Idle state, ready to accept new command request from user. If any errors during the initialization process are detected, the IP switches to an Inactive state, with U0Error set to 1b.

For further insights into the operational flow of each command during the Command operation phase of NVM#0, refer to Figure 4.

 

 

Figure 4: Command Operation Flow of NVM#0, controlled by User#0 I/F

1)     To initiate command execution, User#0 must first issue the Identify command (U0Cmd=000b). This command updates the LBASize (disk capacity) and LBAMode (LBA unit=512 bytes or 4 KB).

2)     Prior to powering down the system, User#0 should issue the Shutdown command (U0Cmd=001b). This command is recommended to ensure a proper sequence of power-down for the SSD. Without executing the Shutdown command, the write data in the SSD cannot be guaranteed. Following the completion of the Shutdown command, both the muNVMe IP and the SSD change to the Inactive state, and no new commands can be executed until the IP is reset.

3)     When executing a Write command by NVM#0 (U0Cmd=010b), each command can transmit a maximum data size of 128 KB. If the total data length from the user exceeds 128 KB, the IP automatically repeats the following steps, 3a) – 3b), until all data has been successfully transferred.

a)     The IP waits until the write data, sent by the user, is sufficient to form one complete command. Each command’s transfer size in the muNVMe IP is 128 KB, except for the last iteration, which may be less than 128 KB.

b)     The IP sends the Write command to the SSD and then waits for a status response from the SSD. NVM#0 returns to the Idle state only when all the data has been completely transferred. If not, NVM#0 reverts to step 3a) to issue the next Write command.

4)     Similar to the Write command, when executing a Read command by NVM#0 (U0Cmd=011b) with a transfer size exceeding 128 KB, the IP must follow these steps, 4a) – 4b).

a)     If the remaining transfer size is zero, the IP proceeds to step 4c). Otherwise, it waits for sufficient free space in Data Buffer#0 of the muNVMe IP to accommodate one complete command (either 128 KB or the remaining transfer size in the last iteration).

b)     The IP issues the Read command to the SSD and then returns to step 4a).

c)     The IP awaits completion of data transfer from Data Buffer#0 to the user logic and subsequently returns to the Idle state. Consequently, Data Buffer#0 becomes empty after the Read command is completed.

5)     When executing a SMART command (U0Cmd=100b and CtmSubmDW0-15=SMART), a 512-byte data response is generated upon successful operation.

a)     The IP sends the Get Log Page command to retrieve SMART/Health information from the SSD.

b)     The IP receives a 512-byte data response from the SSD, forwarding this data via the Custom command RAM interface (CtmRamAddr=0x000 – 0x01F).

6)     In the case of the Flush command (U0Cmd=110b), no data transfer occurs during the operation.

a)     The IP transmits the Flush command to the SSD.

b)     The IP awaits the SSD’s status response to confirm the completion of the operation.

 

For the Write command (U1Cmd=010b) and Read command (U1Cmd=011b) executed by NVM#1, the operation flow mirrors that of Write and Read commands for NVM#0, utilizing separate operation core and Data Buffer for NVM#1.

The design of muNMVe IP consists of two protocols: NVMe and PCIe. The NVMe protocol is used to interface with the user, while the PCIe protocol is used to interface with PCIe hard IP. Figure 2 shows the hardware inside the muNVMe IP which is split into two groups, NVMe and PCIe.

 

NVMe

The NVMe group supports six commands, which are split into two categories - Admin commands and NVM commands. Admin commands include Identify, Shutdown, and SMART, while NVM commands include Write, Read, and Flush. After executing a command, the status received from the SSD is latched either to U0AdmCompStatus (for status returned from Admin commands) or U0-U1IOCompStatus (for status returned from NVM commands), depending on the command type.

The parameters of Write or Read command are configured through the Control interface of dgIF typeS, while SMART or Flush command parameters are set by CtmSubmDW0-15 in the Ctm Cmd interface. The Data interface for Write or Read command is transferred using the FIFO interface, a part of dgIF typeS. The data for Write and Read commands is stored within the Data buffer inside each NVM. However, for other command types, the Data interface utilizes distinct interfaces – the Identify I/F for the Identify command and the Custom RAM I/F for the SMART command.

To implement the NVMe protocol, all NVMs are constructed with four NVMe submodules: the NVMe Host Controller, Command Parameter, Data Buffer, and NVMe Data Controller. However, the features and complexity of these submodules differ between NVM#0 and NVM#1 due to different supported user commands. Further details of each submodule are described as follows.

·       NVMe Host Controller

The NVMe host controller serves as the core controller within each NVM. It operates in two phases: the Initialization phase and the Command operation phase. The Initialization phase runs once when the system is booted up, for configuring the NVMe register within the SSD. The Initialization process is handled by NVMe Host Controller#0. Once the Initialization phase is completed, both NVMe Host Controller#0 and #1 enter the Command operation phase. Within this phase, each NVMe Host Controller controls the sequence of transmitted and received packets specific to its user command.

To initiate the execution of each command, the command parameters are stored in the Command Parameter, facilitating packet creation. Subsequently, these packets are forwarded to the AsyncCtrl for converting NVMe packets into PCIe packets. Following the execution of each command operatio, a status packet is received from the SSD. The NVMe Host Controller decodes this status value, verifying whether the operation was completed successfully or an error occurred. In cases where the command involves data transfer, such as Write or Read command, the NVMe Host Controller also manges the order of data packets, which are created and decoded by the NVMe Data Controller.

·       Command Parameter

The Command Parameter module creates the command packet sent to the SSD and decodes the status packet received from the SSD. The input and output of this module are controlled by the NVMe Host Controller. Typically, a command consists of 16 Dwords (1 Dword = 32 bits). When executing Identify, Shutdown, Write, and Read commands, all 16 Dwords are created by the Command parameter module, which are initialized by the user inputs via dgIF typeS. In case of SMART and Flush commands, all 16 Dwords are directly loaded via CtmSubmDW0-CtmSubmDW15 of Ctm Cmd interface.

·       Data Buffer

The Data buffer serves as data buffering between user logic and the SSD while executing Write and Read commands. Each Data buffer employs Embedded Memory block to provide a RAM size of 256 KB. Each muNVMe IP involves the use of two 256 KB buffers to enable concurrent data transfer through two user interfaces.

·       NVMe Data Controller

The NVMe data controller module is used when a command requires data transfer, such as Identify, SMART, Write, and Read commands. This module manages three data interfaces for transferring with the SSD.

1)     The FIFO interface is used with the Data buffer during the execution of Write or Read commands.

2)     The Custom RAM interface is used when executing SMART command.

3)     The Identify interface is used when executing Identify command.

The NVMe data controller is responsible for creating and decoding of data packets. Similar to the Command Parameter module, the input and output signals of the NVMe Data Controller module are controlled by the NVMe Host Controller.

PCIe

The PCIe protocol is the outstanding low-layer protocol for the high-speed application, and the NVMe protocol runs over it. Therefore, the NVMe layer can starts its operation once the PCIe layer has completed the initialization. Two modules have been developed to support the PCIe protocol: the PCIe controller and AsyncCtrl. Additional details of these modules are provided below.

·       PCIe Controller

During the initialization process, the PCIe controller configures the PCIe environment of the SSD using the Avalon-ST interface. Subsequently, it employs the same interface to create or decode PCIe packets. The PCIe controller converts the command and data packets into PCIe packets, and vice versa. Since NVMe#0 and NVM#1 share the same PCIe controller, the PCIe controller needs to determine the active NVM during each packet transfer.

·       AsyncCtrl

AsyncCtrl incorporates asynchronous registers and buffers designed to support clock domain crossing. The user clock frequency must match or exceed the PCIe clock frequency to ensure sufficient bandwidth for continuous packet data transmission. The majority of the logic within the muNVMe IP operates in the user clock domain, while the PCIe hard IP operates in the PCIe clock domain.

 

User Logic

This module could be designed by using small state machine to send the commands with assigning the parameters for each command. For Write/Read command, the command parameters are address and transfer size. Data interface for Write/Read command can directly connect to FIFO while data output from SMART and Identify command can directly connect to simple dual port RAM with byte enable. RAM size depends on the data size transferring in each command, but data width of all commands is 128-bit. Data size of Identify command is 8 KB while data size of SMART command is 512 bytes.

 

Avalon-ST PCIe Hard IP

 

 

Figure 5: Architecture of Avalon-ST PCIe Hard IP

 

PCIe hard IP block embeds the PCIe protocol stack into the Intel FPGA. The hard IP block includes the transceiver modules, physical layer, data link layer and transaction layer. The maximum number of SSDs that can connect to a single FPGA device is limited by the number of available PCIe hard IP blocks. Further information about the Avalon-ST PCIe hard IP can be found in following documents.

 

ArriaV Avalon-ST Interface for PCIe Solutions User Guide

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_a5_pcie_avst.pdf

Stratix V Avalon-ST Interface for PCIe Solutions User Guide

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_s5_pcie_avst.pdf

Intel Arria10 and Intel Cyclone 10 GX Avalon-ST Interface for PCIe Solutions User Guide

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_a10_pcie_avst.pdf

 

Core I/O Signals

Descriptions of the I/O signals are provided in Table 2 and Table 3.

Table 2: User logic I/O Signals (Synchronous to Clk signal)

Signal

Dir

Description

Control I/F of dgIF typeS

RstB

In

Synchronous reset signal. Active low. After the ‘Clk’ signal is stable, de-assert this signal to 1b.

Clk

In

User clock to run the muNVMe IP. The frequency of this clock must be equal to or greater than the PCIeClk frequency, which is output from the PCIe hard IP. PCIeClk frequency is equal to 250 MHz for PCIe Gen3.

U0Cmd[2:0]

In

User Command of User#0 I/F. Valid when U0Req=1b.

000b: Identify,       001b: Shutdown,

010b: Write SSD,  011b: Read SSD,

100b: SMART,      110b: Flush,            Others: Reserved

U1Cmd[2:0]

In

User Command of User#1 I/F. Valid when U1Req=1b.

010b: Write SSD,  011b: Read SSD,  Others: Reserved

U0-U1Addr[47:0]

In

The start address of User#0-#1 I/F to write/read from the SSD in 512-byte units.

Valid when U0-U1Req=1b, respectively.

If the LBA unit = 4 KB, U0-U1Addr[2:0] must be always set to 000b to align 4 KB unit.

If the LBA unit = 512 bytes, it is recommended to set U0-U1Addr[2:0]=000b to align with 4 KB size (SSD page size). The 4KB address unalignment results in reduced write/read performance for most SSDs.

U0-U1Len[47:0]

In

Data transfer size when writing or reading from the SSD in 512-byte units. The value is valid from 1 to (LBASize - U0-U1Addr). When the LBA unit = 4 KB, U0-U1Len[2:0] must be always set to 000b to align with the 4 KB unit. This parameter is applicable when U0-U1Req=1b, respectively.

U0Req

In

Set to 1b to initiate a new command request and reset to 0b after the IP starts the operation, signaling by setting U0Busy to 1b. This signal can only be asserted when the NVM#0 is Idle (U0Busy=0b). Command parameters, including U0Cmd, U0Addr, U0Len, and CtmSubmDW0-DW15, must be valid and stable when U0Req=1b. U0Addr and U0Len are inputs for Write/Read commands while CtmSubmDW0-DW15 are inputs for SMART/Flush commands.

U1Req

In

Set to 1b to initiate a new command request and reset to 0b after IP starts the operation, signaling by setting U1Busy to 1b. This signal can only be asserted when the NVM#1 is Idle

(U1Busy=0b). Command parameters, including U1Cmd, U1Addr, and U1Len, must be valid and stable when U1Req=1b.

U0-U1Busy

Out

Set to 1b when NVM#0-#1 is busy during operating the command of User#0-#1 I/F, respectively.

New request must not be sent (U0-U1Req to 1b) while NVM#0-#1 is busy.

LBASize[47:0]

Out

The total capacity of the SSD in 512-byte units. Default value is 0.

This value is valid after finishing the Identify command.

LBAMode

Out

The LBA unit size of the SSD (0b: 512 bytes, 1b: 4 KB). Default value is 0.

This value is valid after finishing the Identify command.

U0-U3Error

Out

Error flag. Asserted to 1b when U0-U1ErrorType is not equal to 0.

The flag can be de-asserted to 0b by setting RstB to 0b.

 

Signal

Dir

Description

Control I/F of dgIF typeS

U0ErrorType[31:0]

Out

Error status.

[0] – An error when PCIe class code is incorrect.

[1] – An error from Controller capabilities (CAP) register, which can occur due to various reasons.

- Memory Page Size Minimum (MPSMIN) not equal to 0.

- NVM command set flag (bit 37 of CAP register) not set to 1.

- DSTRD (Doorbell Stride) not equal 0.

- Maximum Queue Entries Supported (MQES) less than 7.

More details of each register can be found in the NVMeCAPReg signal.

[2] – An error when the Admin completion entry is not received within the specified timeout.

[3] – An error when the status register in the Admin completion entry is not 0 or when the phase tag/command ID is invalid. Further information can be found in the U0AdmCompStatus signal.

[4] – An error when the IO completion entry of NVM#0 is not received within the specified timeout.

[5] – An error when the status register in the IO completion entry of NVM#0 is not 0 or when the phase tag is invalid. More details are available in the U0IOCompStatus signal.

[6] – An error when the Completion TLP packet size is incorrect.

[7] – An error when the PCIe hard IP detects an Error correction code (ECC) error from the internal buffer.

[8] – An error from the Unsupported Request (UR) flag in the Completion TLP packet.

[9] – An error from the Completer Abort (CA) flag in the Completion TLP packet.

[15:10] – Reserved

[16] – An error due to an unsupported LBA unit (LBA unit is not equal to 512 bytes or 4 KB)

[17] – An error when the SSD does not support multiple queues.

[31:18] – Reserved

Note: Timeout period of bit[2]/[4] is set from TimeOutSet input.

U1ErrorType[31:0]

 

Out

[3:0] – Reserved

[4] – An error when the IO completion entry of NVM#1 is not received within the specified timeout.

[5] – An error when the status register in the IO completion entry of NVM#1 is not 0 or when the phase tag is invalid. More details are available in the U1IOCompStatus signal.

[31:6] – Reserved

Note: Timeout period of bit[4] is set from TimeOutSet input.

Data I/F of dgIF typeS

U0FifoWrCnt[15:0]

In

Write data counter for the Receive FIFO#0. Used to monitor the FIFO full status. When the FIFO becomes full, data transmission from the Read command temporarily halts. If the data count of FIFO is less than 16 bits, the upper bits should be padded with 1b to complete the 16-bit count.

U0FifoWrEn

Out

Asserted to 1b to write data to Receive FIFO#0 when NVM#0 executes the Read command.

U0FifoWrData[127:0]

Out

Write data bus of Receive FIFO#0. Valid when U0FifoWrEn=1b.

U0FifoRdCnt[15:0]

In

Read data counter for the Transmit FIFO#0. Used to monitor the amount of data stored in the FIFO. If the counter indicates an empty status, the transmission of data packets for the Write command temporarily pauses. When the data count of FIFO is less than 16 bits, the upper bis should be padded with 0b to complete the 16-bit count.

U0FifoEmpty

In

Unused for this IP.

 

Signal

Dir

Description

Data I/F of dgIF typeS

U0FifoRdEn

Out

Asserted to 1b to read data from the Transmit FIFO#0 when NVM#0 executes the Write command.

U0FifoRdData[127:0]

In

Read data returned from the Transmit FIFO#0.

Valid in the next clock after U0FifoRdEn is asserted to 1b.

Data I/F for User#1 uses the same description provided for User#0 I/F by referring to the signals and module of NVM#1.

User#1 Data I/F signals includes the following signals: U1FifoWrCnt[15:0], U1FifoWrEn, U1FifoWrData[127:0], U1FifoRdCnt[15:0], U1FifoEmpty, U1FifoRdEn, and U1FifoRdData[255:0].

muNVMe IP Interface

IPVesion[31:0]

Out

IP version number

U0TestPin[47:0],

U1TestPin[15:0]

Out

Reserved to be IP Test point.

TimeOutSet[31:0]

In

Timeout value to wait for completion from SSD. Time unit is equal to 1/(Clk frequency).

When TimeOutSet is equal to 0, Timeout function is disabled.

U0AdmCompStatus[15:0]

Out

Status output from Admin Completion Entry

[0] – Set to 1b when the Phase tag or Command ID in Admin Completion Entry is invalid.

[15:1] – Status field value of Admin Completion Entry

U0-U1IOCompStatus[15:0]

Out

Status output from IO Completion Entry

[0] – Set to 1b when Phase tag in IO Completion Entry of NVM#0-#1 is invalid, respectively.

[15:1] – Status field value of IO Completion Entry in NVM#0-#1, respectively.

NVMeCAPReg[31:0]

Out

The parameter value of the NVMe capability register when U0ErrorType[1] is asserted to 1b.

[15:0] – MQES (Maximum Queue Entries Supported)

[19:16] – DSTRD (Doorbell Stride)

[20] – NVM command set flag

[24:21] – MPSMIN (Memory Page Size Minimum)

[31:25] – Undefined

Identify Interface (for User#0)

IdenWrEn

Out

Asserted to 1b for sending data output from Identify command.

IdenWrDWEn[3:0]

Out

Dword (32-bit) enable of IdenWrData. Valid when IdenWrEn=1b.

1b: This Dword data is valid, 0b: This Dword data is not available.

Bit[0], [1], [2], and [3] corresponds to IdenWrData[31:0], [63:32], [95:64], and [127:96], respectively.

IdenWrAddr[8:0]

Out

Index of IdenWrData in 128-bit unit. Valid when IdenWrEn=1b.

0x000-0x0FF is 4KB Identify controller data,

0x100-0x1FF is 4KB Identify namespace data.

IdenWrData[127:0]

Out

4KB Identify controller data or Identify namespace data. Valid when IdenWrEn=1b.

Custom Interface (for User#0)

CtmSubmDW0[31:0] – CtmSubmDW15[31:0]

In

16 Dwords of Submission queue entry for SMART/Flush command.

DW0: Command Dword0, DW1: Command Dword1, …, and DW15: Command Dword15.

These inputs must be valid when U0Req=1b and U0Cmd=100b (SMART) or 110b (Flush).

CtmCompDW0[31:0] –

CtmCompDW3[31:0]

Out

4 Dwords of Completion queue entry, output from SMART/Flush command.

DW0: Completion Dword0, DW1: Completion Dword1, …, and DW3: Completion Dword3

 

Signal

Dir

Description

Custom Interface (for User#0)

CtmRamWrEn

Out

Asserted to 1b for sending data output from Custom command such as SMART command.

CtmRamWrDWEn[3:0]

Out

Dword (32-bit) enable of CtmRamWrData. Valid when CtmRamWrEn=1b.

1b: This Dword data is valid, 0b: This Dword data is not available.

Bit[0], [1], [2], and [3] correspond to CtmRamWrData[31:0], [63:32], [95:64], and [127:96], respectively.

CtmRamAddr[8:0]

Out

Index of CtmRamWrData when SMART data is received. Valid when CtmRamWrEn=1b.

(Optional) Index to request data input through CtmRamRdData for customized Custom commands.

CtmRamWrData[127:0]

Out

512-byte data output from SMART command. Valid when CtmRamWrEn=1b.

CtmRamRdData[127:0]

In

(Optional) Data input for customized Xustom commands.

 

Table 3: Physical I/O Signals for PCIe Hard IP (Synchronous to PCIeClk signal)

Signal

Dir

Description

Clock Signal

PCIeRstB

In

Synchronous reset signal. Active low.

De-assert to 1b when PCIe hard IP is not in reset state.

PCIeClk

In

Clock output from Avalon-ST PCIe Hard IP

(250 MHz for PCIe Gen3).

PCIe Hard IP Rx Interface

PCIeRxValid

In

Asserts to 1b to indicate that PCIeRxData is valid.

De-asserts to 0b within 2 clock cycles after PCIeRxReady is de-asserted to 0b.

PCIeRxEOP

In

Asserts to 1b to indicate that this is the last cycle of the TLP.

Valid when PCIeRxValid is asserted to 1b.

PCIeRxReady

Out

Asserted to 1b to indicate that muNVMe IP is ready to accept data. Data is transferred when both PCIeRxValid and PCIeRxReady are asserted in the same clock cycle.

PCIeRxError

In

Asserts to 1b to indicate that there is an uncorrectable error correction coding (ECC) in the internal RX buffer of Avalon-ST PCIe Hard IP.

PCIeRxData[127:0]

In

Receive data bus. Valid when PCIeRxValid is asserted to 1b.

PCIe Hard IP Tx Interface

PCIeTxValid

Out

Asserted to 1b to indicate that PCIeTxData is valid.

De-asserted to 0b within 2 clock cycles after PCIeTxReady is de-asserted to 0b.

PCIeTxSOP

Out

Asserted to 1b to indicate the first cycle of a TLP. Valid when PCIeTxValid is asserted to 1b.

PCIeTxEOP

Out

Asserted to 1b to indicate the last cycle of a TLP. Valid when PCIeTxValid is asserted to 1b.

PCIeTxEmpty

Out

Indicates whether the upper Qword at the end of a packet (PCIeTxEOP=1b) contains data.

0b: PCIeTxData[127:0] is valid, 1b: PCIeTxData[63:0] is valid.

PCIeTxReady

In

Asserts to 1b to indicate that Avalon-ST PCIe Hard IP is ready to accept data.

Data is transferred when both PCIeTxValid and PCIeTxReady are asserted in the same clock cycle.

PCIeTxError

Out

Asserted to 1b to indicate an error on transmitted TLP. This signal is always set to 0b.

PCIeTxData[127:0]

Out

Data for transmission. Valid when PCIeTxValid is asserted to 1b.

 

Timing Diagram

 

Initialization

 

 

Figure 6: Timing diagram during initialization process

 

The initialization process of the muNVMe IP follows the steps below as shown in timing diagram.

1)     Wait until Clk is stable and then set RstB to 1b to start the IP initialization process.

2)     After completing the PCIe reset sequence, the PCIe hard IP de-asserts PCIeRstB to 1b, indicating that it is ready to transfer data with the application layer.

3)     Assert PCIeLinkup to 1b after LTSSM state of PCIe hard IP reaches the L0 state. Since the LTSSM state operates on PCIeClk, PCIeLinkup must be generated in the Clk domain using asynchronous registers. After that, muNVMe IP starts initialization process.

4)     Once the muNVMe IP completes initialization process, U0Busy and U1Busy are de-asserted to 0b.

Note: U1Busy is de-asserted to 0b after U0Busy has been de-asserted for 2 clock cycles.

After completing all of the above steps, the muNVMe IP is ready to receive commands from the user.

 

Control interface of dgIF typeS

The dgIF typeS signals can be split into two groups: the Control interface for sending commands and monitoring status, and the Data interface for transferring data streams in both directions. Figure 7 shows an example of how to send a new command to the IP via the NVM#0 Control interface of dgIF typeS.

 

 

Figure 7: NVM#0 Control interface of dgIF typeS timing diagram

 

1)     U0Busy must be equal to 0b before sending a new command request to confirm that the NVM#0 is Idle.

2)     Command and its parameters such as U0Cmd, U0Addr, and U0Len must be valid when asserting U0Req to 1b to send the new command request.

3)     The NVM#0 asserts U0Busy to 1b after starting the new command operation.

4)     After U0Busy is asserted to 1b, U0Req is de-asserted to 0b to finish the current request. New parameters for the next command can be prepared on the bus. U0Req for the new command must not be asserted to 1b until the current command operation is finished.

5)     U0Busy is de-asserted to 0b after the command operation is completed. Next, new command request can be initiated by asserting U0Req to 1b.

Note: The number of parameters used in each command is different. More details are described below.

 

Similarly, the NVM#1 Control interface of dgIF typeS follows the same concepts as that of NVM#0, utilizing U1Busy, U1Cmd, U1Addr, and U1Len for both Write and Read commands.

 

 

Figure 8: dgIF typeS Control Interface timing diagram when running command in parallel

 

Figure 8 shows the Control interfaces for dgIF TypeS in both User#0 and User#1 when NVM#0 and NVM#1 execute commands in parallel. Each user interface possesses specific control signals to manage user command. As a result, two user commands can run concurrently, with the first command using the User#0 I/F and the second command using the User#1 I/F.

Note: The Shutdown command does not operate in parallel with other commands.

 

Data interface of dgIF typeS

The Data interface of dgIF typeS is used for transferring data stream when operating Write or Read command, and it is compatible with a general FIFO interface. Figure 9 shows the NVM#0 Data interface of dgIF typeS when transferring write data to the IP in the Write command.

 

 

Figure 9: Transmit FIFO interface for NVM#0 Write command

 

The 16-bit FIFO read data counter (U0FifoRdCnt) shows the total amount of data stored, and if the amount of data is sufficient, 512-byte data (32x128-bit) is transferred.

In the NVM#0 Write command, data is read from the Transmit FIFO#0 until the total data is transferred completely. The process details to transfer data are described as follows.

1)     Before starting a new burst transfer, NVM#0 waits until at least 512-byte data is available in the Transmit FIFO#0 by monitoring U0FifoRdCnt[15:5] that must be not equal to 0.

2)     The NVM#0 asserts U0FifoRdEn to 1b for 32 clock cycles to read 512-byte data from Transmit FIFO#0.

3)     U0FifoRdData is valid in the next clock cycle after asserting U0FifoRdEn to 1b, and 32 data are continuously transferred.

4)     Upon reading the 32th data (D31), U0FifoRdEn is de-asserted to 0b. Repeat steps 1) – 4) to transfer the next 512-byte data until total amount of data is equal to the transfer size specified in the command.

5)     After total data is completely transferred, U0Busy is de-asserted to 0b.

 

 

Figure 10: Receive FIFO interface for NVM#0 Read command

 

When NVM#0 executes the Read command, the data is transferred from the SSD to the Receive FIFO#0 until the entire data is transferred. The steps for transferring a burst of data are below.

1)     Before starting a new burst transmission, the U0FifoWrCnt[15:6] is checked to verify that there is enough free space available in the Receive FIFO#0, indicated by the condition U0FifoWrCnt[15:6] ≠ all 1 or 1023. Also, the IP waits until the amount of received data from the SSD reaches at least 512 bytes. Once both conditions are satisfied, the new burst transmission begins.

2)     The NVM#0 asserts U0FifoWrEn to 1b for 32 clock cycles to transfer 512-byte data from the Data Buffer#0 to the user logic.

3)     After finishing transferring each 512-byte data, U0FifoWrEn is de-asserted to 0b for one clock cycle. If there is additional data remaining to be transferred, repeat steps 1) – 3) until total data size matches the transfer size specified in the command.

4)     After the total data is completely transferred, U0Busy is de-asserted to 0b.

Similar to Figure 9 and Figure 10 that show User#0 I/F, the NVM#1 Data interface for dgIF typeS follows the same concept, employing Transmit FIFO#1, Receive FIFO#1, and Data Buffer#1 for data transfer during NVM#1 Write and Read commands, respectively.

As shown in Figure 8, commands are simultaneously requested on both User#0 I/F and User#1 I/F. This parallel command initiation results in parallel data on both user interfaces.

 

 

Figure 11: dgIF typeS Data interface timing diagram in parallelly

 

Figure 11 shows the NVM#0 and NVM#1 Data interface for dgIF typeS. NVM#0 executes a Write command by reading write data, and NVM#1 executes Read command by writing read data in parallel. Similarly, the parallel data interface can also be found when NVM#0 and NVM#1 execute Read/Read or Write/Read commands concurrently.

 

IdenCtrl/IdenName

To ensure proper operation of the system, it is recommended to send the Identify command to NVM#0 as the first command after the system boots up. This command updates important information about the SSD, such as its total capacity (LBASize) and LBA unit size (LBAMode), which are necessary for Write and Read commands to operate correctly. The following rules apply to the input parameters of this command.

1)     The sum of the address (U<i>Addr; i=0 or 1) and transfer length (U<i>Len; i=0 or 1), inputs of Write and Read commands, must not exceed the total capacity (LBASize) of the SSD.

2)     If LBAMode is 1b (LBA unit size is 4 KB), the three lower bits (bit[2:0]) of U0-U1Addr and U0-U1Len must be set to 0 to align with the 4 KB unit.

 

 

Figure 12: Identify command timing diagram

 

The process for executing the Identify command is described below.

1)     Send the Identify command to NVM#0 by setting U0Cmd to 000b and U0Req to 1b.

2)     Once NVM#0 receives the Identify command, it sets U0Busy to 1b.

3)     NVM#0 returns a 4KB Identify controller data to User#0 by setting IdenWrAddr to 0-255 and IdenWrEn to 1b. IdenWrData and IdenWrDWEn are valid at the same clock cycle when IdenWrEn is set to 1b.

4)     After that, NVM#0 returns a 4KB Identify namespace data to User#0 by setting IdenWrAddr to 256-511. IdenWrAddr[8] can be used to determine the data type as Identify controller data or Identify namespace data.

5)     After completing the Identify command, U0Busy is de-asserted to 0b.

6)     The LBASize and LBAMode of the SSD are updated with the values obtained from the Identify command.

 

 

Figure 13: IdenWrDWEn timing diagram

 

The signal IdenWrDWEn is a 4-bit signal used to validate a 32-bit data signal. Some SSDs return the 4KB Identify controller data and Identify namespace data one word (32-bit) at a time instead of continuously. To forward 32-bit data, one bit of IdenWrDWEn is asserted to 1b in the write cycle, as illustrated in Figure 13. Each bit of IdenWrDWEn (IdenWrDWEn[0], [1], [2], and [3]) corresponds to each 32-bit data of IdenWrData (IdenWrData[31:0], [63:32], [95:64], and [127:96]).

 

Shutdown

The Shutdown command is a command that should be sent as the last command before the system is powered down. The SSD ensures that the data from its internal cache is written to the flash memory before the shutdown process finishes. After the shutdown operation is completed, the muNVMe IP and the SSD become inactive status. If the SSD is powered down without executing the Shutdown command, the total count of unsafe shutdowns is increased, as returned data from the SMART command.

 

 

Figure 14: Shutdown command timing diagram

 

The process for executing the Shutdown command is described below.

1)     Before initiating the Shutdown command, it is crucial to verify that both NVM#0 and NVM#1 are in an Idle state, which is indicated by both U0Busy and U1Busy being set to 0b. The user sets U0Cmd=001b and U0Req=1b to request the Shutdown command.

2)     Upon the execution of the Shutdown command by the muNVMe IP, U0Busy is set to 1b.

3)     After that, the command request is cleared by setting U0Req=0b.

4)     U0Busy is de-asserted to 0b when the SSD is completely shut down. Following the completion of the shutdown process, the IP will no longer accept any further user commands.

 

SMART

The SMART command is the command to check the health of the SSD. When this command is sent, the SSD returns 512-byte health information. The SMART command parameters are loaded from the CtmSubmDW0-DW15 signals on the Custom command interface. User#0 must set the 16-Dword data which is a constant value before asserting U0Req. Once the SMART data is returned, it can be accessed via the CtmRAM port, as shown in Figure 15.

 

 

Figure 15: SMART command timing diagram

 

Below are the details of how to run the SMART command.

1)     NVM#0 must be Idle (U0Busy=0b) before sending the command request. All input parameters must be stable when U0Req is asserted to 1b for sending the request. CtmSubmDW0-DW15 is set as constant value for the SMART command by following values.

CtmSubmDW0                                         = 0x0000_0002

CtmSubmDW1                                         = 0xFFFF_FFFF

CtmSubmDW2 – CtmSubmDW5               = 0x0000_0000

CtmSubmDW6                                         = 0x8002_2000

CtmSubmDW7 – CtmSubmDW9               = 0x0000_0000

CtmSubmDW10                                       = 0x007F_0002

CtmSubmDW11 – CtmSubmDW15           = 0x0000_0000

2)     U0Busy is set to 1b after the muNVMe IP executes the SMART command.

3)     U0Req is de-asserted to 0b to clear the current request. Next, User#0 can change the input parameters for the next command request.

4)     512-byte SMART data is returned on CtmRamWrData signal with asserting CtmRamWrEn to 1b. CtmRamAddr is equal to 0-15 to be data index of 512-byte data. When CtmRamAddr=0, byte0-15 of SMART data is valid on CtmRamWrData. CtmRamWrDWEn is Dword enable for each 32-bit CtmRamWrData. If CtmRamWrDWEn=1111b, all 128 bits of CtmRamWrData are valid.

5)     U0Busy is de-asserted to 0b when finishing SMART command.

 

 

Figure 16: CtmRamWrDWEn timing diagram

 

Similar to Identify command, some SSDs returns only one Dword (32-bit) of data at a time instead of 512-byte data continuously. In such cases, one bit of CtmRamWrDWEn is asserted to 1b in the write cycle to be the valid signal of 32-bit CtmRamWrData. Each bit of CtmRamWrDWEn (bit[0], [1], [2], and [3]) corresponds to each 32 bits of CtmRamWrData (bit[31:0], [63:32], [95:64], and [127:96]).

 

Flush

The SSDs typically enhance write performance by caching write data before writing it to the flash memory. However, unexpected power loss can result data loss as cached data may not be stored in flash memory. To avoid data loss, the Flush command can be used to force the SSD controller to write cached data to the flash memory.

 

 

Figure 17: Flush command timing diagram

 

The process for executing the Flush command is described below.

1)     NVM#0 must be Idle (U0Busy=0b) before sending the command request, and all input parameters must be stable when U0Req is asserted to 1b for sending the request. The CtmSubmDW0-DW15 is set as constant value with the following value for Flush command.

CtmSubmDW0                             = 0x0000_0000

CtmSubmDW1                             = 0x0000_0001

CtmSubmDW2 – CtmSubmDW15 = 0x0000_0000

2)     U0Busy is asserted to 1b after the muNVMe IP executes the Flush command.

3)     U0Req is de-asserted to 0b to clear the current request, and User#0 can change the input parameters for the next command request.

4)     U0Busy is de-asserted to 0b when the Flush command is completed

Using the Flush command ensures that all data from the previous Write command is guaranteed to be stored in flash memory, thus preventing data loss in the event of unexpected power loss.

 

Error

 

Figure 18: Error flag timing diagram

 

If an error occurs during the initialization process or when running some commands, the U0Error or U1Error flag is set to 1b. To determine the specific error type, the user should read the U0ErrorType or U1ErrorType. For detailed error monitoring, the user can utilize the NVMeCAPReg, U0AdmCompStatus, and U0IOCompStatus signals when U0Error is set to 1b. Similarly, the U1IOCompStatus signal can be used to monitor error details when U1Error is set to 1b.

If an error occurs during the initialization process, it is recommended to read the NVMeCAPReg signal to check the capabilities of the NVMe SSD. When an error occurs while executing a command, it is recommended to read the U0AdmCompStatus and U<i>IOCompStatus (i=0-1) signals.

The U0Error and U1Error flags can only be cleared by the RstB signal. After the issue has been resolved, the user can assert RstB to 0b to clear the error flags.

 

Verification Methods

The muNVMe IP Core functionality was verified by simulation and also proved on real board design by using Arria10 GX FPGA development board.

 

Recommended Design Experience

Experience design engineers with a knowledge of Quartus Tools should easily integrate this IP into their design.

 

Ordering Information

This product is available directly from Design Gateway Co., Ltd. Please contact Design Gateway Co., Ltd. for pricing and additional information about this product using the contact information on the front page of this datasheet.

 

Revision History

Revision

Date

Description

1.0

15-Nov-23

New release