支持Nor Flash读写的SPI主控制器设计、仿真和FPGA验证(含XIP模式)

支持Nor Flash读写的SPI主控制器设计、仿真和FPGA验证(含XIP模式)

文章目录


前言

提示:本文仅供个人学习,未经授权严禁转载。

一、功能

(1)支持SPI模式0和模式3(关于SPI模式的介绍网上有很多,这里不再赘述。重点注意一下:对于模式0和模式3,发送端在SPI时钟下降沿发送数据,接收端在SPI时钟上升沿采样数据);
(2)支持Standard SPI,Dual SPI,Quad SPI模式;
(3)支持XIP模式(支持W25Q、N25Q、MX25L等系列SPI Flash);
对于XIP模式的定义,每一款Flash器件的说法似乎有些细微的差异。本文的理解就是,在XIP模式下,Flash器件可以看作一块类似于sram的存储设备,只需要通过地址即可读取Flash的存储内容。不需要像SPI接口读Flash时那样,需要先发送flash专用的读命令,其次发送读地址,以及可能需要发送的dummy cycle,然后Flash才会返回读数据。本文设计的SPI主控制器的AHB path能够将AHB读操作直接转换成SPI读Flash操作,因此从AHB接口端来看,Flash就像一个普通的sram一样,通过地址即可读取Flash中的数据。
(4)SPI控制器时钟频率为50MHz时(SPI接口时钟sclk频率最高为25MHz),AHB接口地址连续读W25QXX Flash带宽最高约为12.5MB/s,随机地址读带宽约4.3MB/s;
(5)支持对AHB接口读取的数据计算CRC32校验码(目的:验证Flash Device中的数据是否被正确传输到SPI主控制器端);

二、架构设计

在这里插入图片描述

三、接口介绍

(1)AMBA3 AHB-Lite接口
(2)AMBA4 APB接口
(3)SPI接口

NameIO Typedescription
cs_noutputSPI片选信号
sclkoutputSPI时钟信号
io_0inoutSPI数据线0,MOSI
io_1inoutSPI数据线1,MISO
io_2inoutSPI数据线2
io_3inoutSPI数据线3

(4)中断电平信号
在以下情况时会产生中断:
i. 发送buffer为空;
ii. 接收buffer非空;
iii. 在AHB path检测到写操作(AHB path为XIP模式,只支持读操作);

四、寄存器介绍

在这里插入图片描述

五、APB接口读写W25Q128 Flash

APB读写Flash需要通过多次访问寄存器来实现。

5.1 APB写Flash

以W25Q128 Flash中写Flash的命令Page Program (02h)为例,只需要通过访问寄存器依次将1byte命令、3byte地址和若干待写入的数据以byte为单位发送出去即可。W25Q128的Page Program命令的sequence如下图所示:

在这里插入图片描述

5.1.1 寄存器访问具体流程(以向地址24’h123456写入8’hA0为例)

(1)向寄存器地址8’h20写入32’h02(即把命令8’h02写入tx_buf);
(2)向寄存器地址8’h0写入32’h1(即abort=0, last_byte=0, op_mode=0, rx_trig=0, tx_trig=1);
(3)循环读寄存器地址8’h10,直到读数据的bit0为1(即tx_buf_empty=1);
(4)向寄存器地址8’h20写入32’h12(即把地址的高8bit写入tx_buf);
(5)向寄存器地址8’h0写入32’h1;
(6)循环读寄存器地址8’h10,直到读数据的bit0为1;
(7)向寄存器地址8’h20写入32’h34(即把地址的中间8bit写入tx_buf);
(8)向寄存器地址8’h0写入32’h1;
(9)循环读寄存器地址8’h10,直到读数据的bit0为1;
(10)向寄存器地址8’h20写入32’h56(即把地址的低8bit写入tx_buf);
(11)向寄存器地址8’h0写入32’h1;
(12)循环读寄存器地址8’h10,直到读数据的bit0为1;
(13)向寄存器地址8’h20写入32’hA0(即把要写入Flash的数据写入tx_buf);
(14)向寄存器地址8’h0写入32’h11(即abort=0, last_byte=1, op_mode=0, rx_trig=0, tx_trig=1);
循环读寄存器地址8’h10,直到读数据的bit0为1;

5.1.2 仿真波形

在这里插入图片描述

5.2 APB读Flash状态寄存器

在5.1节中介绍了Page Program指令写Flash的流程,但是Page Program指令本身只是负责把要写入Flash的数据发送给Flash端,而数据真正写入Flash存储单元还需要一段时间,这个时间一般是需要若干毫秒。主控端可以通过定时的方式,固定延时多少毫秒后再发起下一次对Flash的读写访问;也可以通过循环读Flash中的状态寄存器,根据状态寄存器的值判断上一次的写操作或者擦除操作是否完成。本文设计的SPI控制器没有定时的功能,因此只能通过软件定时或者读Flash状态寄存器的方式判断当前Flash是否处于busy状态。

在这里插入图片描述


W25Q128的BUSY位在状态寄存器1的bit0,读状态寄存器1的sequence如下图所示:

在这里插入图片描述

5.2.1 寄存器访问具体流程(以循环读W25Q128状态寄存器1,且直到BUSY等于0为例)

(1)向寄存器地址8’h20写入32’h05(即把命令8’h05写入tx_buf);
(2)向寄存器地址8’h0写入32’h2(即abort=0, last_byte=0, op_mode=0, rx_trig=1, tx_trig=0);
(3)循环读寄存器地址8’h10,直到读数据的bit 1为1(即rx_buf_full=1);
(4)APB读寄存器地址8’h24,APB read data即为状态寄存器1的值;
(5)判断状态寄存器1的bit 0(BUSY)是否为0,若为0则表示flash处于idle状态,向寄存器地址8’h0写入32’h21/32’h22(即abort置1,rx_trig或tx_trig置1,op_mode和last_byte可以为任意值),将cs_n直接拉高,结束当前的SPI传输;否则返回步骤(2);

5.2.2 仿真波形

在这里插入图片描述


在这里插入图片描述

六、AHB接口读W25Q128 Flash(即XIP模式)

AHB读数据位宽为32bit,一次AHB读命令固定从Flash中读4byte数据,因此建议通过AHB path读Flash时,一次读32bit数据,从而提高读取速率。(AHB的narrow transfer也是支持的,支持AHB一次读1byte、2byte、4byte数据,只是AHB读操作转换成SPI读Flash操作时,都是4字节对齐的读Flahs操作)
另外,该SPI主控支持AHB读取一个地址后,在没有收到下一个AHB读命令的情况下,自动从Flash中读取下一个地址的32bit数据,节省SPI读Flash时的命令、地址和dummy的开销,从而提高AHB连续读Flash的带宽。
(1)AHB地址非连续读Flash波形如下,第一个读地址为24’h123450,第二个读地址为24’h123458。

在这里插入图片描述

(2)AHB地址连续读Flash波形如下,第一个读地址为24’h123450,第二个读地址为24’h123454。

在这里插入图片描述

七、CRC32功能使用方法

(1)向寄存器地址8’h28写入32’h3,使能CRC32计算的功能,并初始化CRC32。
(2)通过AHB接口从Flash中读数据,所有AHB接口读取的数据都会参与CRC32的计算;
(3)读取寄存器地址8’h2C,获取CRC32的计算结果。

八、SOC系统集成验证

将该SPI主控和ARM Cortex-M3核集成在一起,并编写C代码对Flash进行读写测试。从Flash中读数据的测试结果如下。(已提前将Flash中的数据初始化为0~256,即Flash地址0~255的值依次为0~255,地址256~511的值同样依次为0~255,其他地址的值以此类推)
测试的C代码:

在这里插入图片描述


串口打印结果:

在这里插入图片描述

九、资源下载

免费版verilog代码和仿真文件下载:点击下载

Read more

Copilot 的agent、ask、edit、plan模式有什么区别

Copilot 的 ask、edit、agent、plan 四种模式,核心区别在于权限范围、操作主动性、代码修改权限、适用场景,以下从定义、工作机制、核心特点、典型场景与操作流程展开,帮你快速区分并选对模式。 一、核心区别速览(表格版) 二、分模式详细解析 1. Ask 模式:纯问答与代码理解 * 工作机制:基于当前文件 / 选中代码的上下文,回答自然语言问题,不修改任何代码,仅输出文字解释、建议或思路。 * 典型用法: * 解释某段代码逻辑(如 “这段 Python 函数做了什么”); * 咨询技术方案(如 “如何在 Go 中实现重试机制”); * 调试思路(如 “这个死循环可能的原因”)。 * 关键特点:安全无风险,适合学习、快速澄清和非修改类咨询。

文心一言开源版测评:能力、易用性与价值的全面解析

文心一言开源版测评:能力、易用性与价值的全面解析

目录 * 一、实测过程记录 * 1. 环境配置详解 * 2. 安装Python环境 * 3. 安装PaddlePaddle(选择CPU版本) * 4. 安装FastDeploy推理引擎 * 5. 下载模型权重及配置文件 * 6. 环境验证脚本 * 7. 常见问题及解决 * 8. 关于GPU加速说明(重要) * 二、模型能力实测:多维度压力测试与代码实战 * 1. 通用理解能力测评(附测试代码) * 1.1 复杂逻辑推理测试 * 1.2 情感极性分析 * 2. 文本生成能力实测 * 风格化写作(带控制参数) * 商业文案生成对比 * 3. 鲁棒性压力测试 * 4. 多模态能力专项测试 * 4.1 图文关联度测评 * 4.2 视觉问答(VQA)实战

2026 AI 元年|智能体来了:Agent Native 正在取代 Copilot,定义下一代 AI 公司

2026 AI 元年|智能体来了:Agent Native 正在取代 Copilot,定义下一代 AI 公司 摘要(Summary) 如果说 2023–2025 是 “Copilot 的三年”,那么 2026 则是 “智能体(Agent)的元年”。AI 从“辅助工具”跨入“可自治协作的任务执行体”,正在重写现代公司的生产方式。过去我们认为 AI 会提升效率;到了 2026 年,我们发现 AI 正在参与 定义组织结构。 所谓 Agent Native,指不是在传统业务中补 AI,而是在 AI 的逻辑下重构产品、流程、

Android Studio集成GitHub Copilot GPT-4o:AI辅助开发实战与避坑指南

快速体验 在开始今天关于 Android Studio集成GitHub Copilot GPT-4o:AI辅助开发实战与避坑指南 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 Android Studio集成GitHub Copilot GPT-4o:AI辅助开发实战与避坑指南 传统Android开发的效率瓶颈 在传统Android开发过程中,开发者常常面临以下痛点: * 重复代码编写: