NVMe控制器之指令控制设计
0赞指令控制模块由一个指令信息缓存, 一个指令组装状态机和一个 ID 池组成。 指令信息缓存中存放着由系统控制模块写入的待处理指令信息; 指令组装状态机获取缓存的指令信息, 将其组装成提交队列条目写入提交队列中; ID 池则用于存放可使用的指令 ID。

图1 指令控制状态转移图
指令组装状态机状态转移如图1所示。 系统复位后, 首先进入 IDLE 状态。 在IDLE 状态下, 当检测到指令信息缓存非空时, 表示有新的指令信息需要处理, 跳转到 GET_CMD 状态; 当指令信息缓存为空时, 保持 IDLE 状态。
在 GET_CMD 状态下, 读取一条缓存中的指令信息, 同时从 ID 池中获取一个 ID,进入 SEL_SQ 状态; 如果 ID 池中的 ID 全部都在被使用, 则保持 GET_CMD 状态。
在 SEL_SQ 状态下, 根据读取的指令信息的指令类型选择提交条目将要放入的提交队列。 当指令类型为 Admin 指令时, 选择 Admin 提交队列, 当指令类型为 I/O 指令时, 使用轮询仲裁选择将要放入的队列。 然后跳转到 WR_SQ 状态。
在 WR_SQ 状态下, 将获取的 ID 和指令信息组装成为提交条目, 写入 SEL_SQ状态下选择的队列。 如果指令涉及数据传输, 在该状态下还要将 ID 和对应的 PRP 写入 PRP 控制模块。 完成指令的写入后, 如果指令信息缓存非空, 跳转到 GET_CMD获取新的指令信息, 否则回到 IDLE 状态。
ID 池在复位时被写入位宽为 16 比特的连续 ID, 由于实际应用中 SSD 处理任务的性能有限, 所以将 ID 池深度设置为 1024, 足以满足常见 SSD 的并发性能。 在有新的指令信息被组装成提交条目时, ID 池中的 ID 被读出; 在接收到新的完成条目时,将完成条目中返回的指令 ID 写入 ID 池。
对相关视频感兴趣者,请搜B站用户名 专注与守望

