前言

上一篇文章介绍了SPI的四种工作模式及其时序特性,相信各位同学已经掌握了SPI通信的核心原理。

本文用纯Verilog设计了功能完整的4线SPI主机,并详细说明了模块编码思路和使用注意事项,最后分享了源码。

一、模块功能

本Verilog功能模块——SPI主机实现了SPI协议要求的完整时序控制,具体功能如下:

  1. 支持所有4种SPI工作模式

  2. 支持任意数据位宽

  3. 支持任意串行时钟频率fsclk

  4. 支持指定CS下降沿到第一个SCLK边沿的延时

  5. 支持指定最后SCLK边沿到CS上升沿的延时

  6. 支持指定CS高电平持续时间

二、模块框图

三、信号接口

3.1 参数列表

参数名类型默认值说明
SPI_MODEinteger3SPI模式, 可选0, 1, 2, 3 (默认)
DATA_WIDTHinteger16单次通信发送或接收数据的位宽, 最小为2, 常见8/16
SCLK_PERIOD_CLK_NUMinteger4fSCLK, SCLK周期对应CLK数, 必须为偶数, 最小为2
CS_EDGE_TO_SCLK_EDGE_CLK_NUMinteger1TCC, CS_N下降沿到SCLK的第一个边沿对应CLK数, 最小为1
SCLK_EDGE_TO_CS_EDGE_CLK_NUMinteger3TCCH, 最后一个SCLK边沿到CS_N上升沿对应CLK数, 最小为3
CS_KEEP_HIGH_CLK_NUMinteger2TCWH, CS_N低电平后保持高电平的时间对应CLK数, 最小为2
CLK_FREQ_MHZinteger100模块工作时钟, 常用100/120

3.2 接口信号列表

信号分组信号名方向说明
外部控制SPI信号spi_begininputSPI单次通信开始, 高电平有效, 仅在spi_is_busy为低时起作用
spi_endoutputSPI单次通信结束, 高电平有效, 只会持续一个时钟周期
spi_is_busyoutputSPI繁忙指示, 高电平表示SPI正在工作
spi_master_tx_data[DATA_WIDTH-1:0]inputSPI发送数据, 数据总是高位先发
spi_master_rx_data[DATA_WIDTH-1:0]outputSPI接收数据, 最先读出的数据在最高位
spi_master_rx_data_validoutputSPI接收数据有效指示,高电平有效
SPI硬线链接spi_cs_noutput片选, 低电平有效
spi_sclkoutputSPI时钟, 主机提供
spi_mosioutput主机输出从机输入
spi_misoinput主机输入从机输出
时钟与复位clkinput模块工作时钟
rstninput模块复位, 低电平有效

四、编码思路

  1. 通过参数控制SPI模式、数据位宽、时钟频率与三种时序参数

    parameter integer SPI_MODE                     = 3,  // SPI模式, 可选0, 1, 2, 3 (默认)
    parameter integer DATA_WIDTH                   = 16// 单次通信发送或接收数据的位宽, 最小为2, 常见8/16
    parameter integer SCLK_PERIOD_CLK_NUM          = 4,  // fSCLK, SCLK周期对应CLK数, 必须为偶数, 最小为2
    parameter integer CS_EDGE_TO_SCLK_EDGE_CLK_NUM = 1,  // TCC, CS_N下降沿到SCLK的第一个边沿对应CLK数, 最小为1
    parameter integer SCLK_EDGE_TO_CS_EDGE_CLK_NUM = 3,  // TCCH, 最后一个SCLK边沿到CS_N上升沿对应CLK数, 最小为3
    parameter integer CS_KEEP_HIGH_CLK_NUM         = 2,  // TCWH, CS_N低电平后保持高电平的时间对应CLK数, 最小为2
    parameter integer CLK_FREQ_MHZ                 = 100 // 模块工作时钟, 常用100/120

    注意这里的时延并不是真实值,而是以模块时钟CLK为单位的相对值,且因为三段式状态机输出时序逻辑的限制,时延参数并不能到0,有最小值的限制。这对于实际应用是没有影响的,实际应用中这些参数也不可能为0,且即使延时略长(如TCCH=30ns)同样可以正常工作。

  2. 对参数进行有效性检查,限制参数赋值

    //++ 参数有效性检查 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    initial begin
      if (SPI_MODE != 0 && SPI_MODE != 1 && SPI_MODE != 2 && SPI_MODE != 3)
        $error("SPI_MODE must be 0, 1, 2, 3");
      if (DATA_WIDTH < 2)
        $error("DATA_WIDTH must be >= 2");
      if (SCLK_PERIOD_CLK_NUM < 2 || (SCLK_PERIOD_CLK_NUM % 2 != 0))
        $error("SCLK_PERIOD_CLK_NUM must even and >= 2");
      if (CS_EDGE_TO_SCLK_EDGE_CLK_NUM < 1)
        $error("CS_EDGE_TO_SCLK_EDGE_CLK_NUM must >= 1");
      if (SCLK_EDGE_TO_CS_EDGE_CLK_NUM < 3)
        $error("SCLK_EDGE_TO_CS_EDGE_CLK_NUM must >= 3");
      if (CS_KEEP_HIGH_CLK_NUM < 2)
        $error("CS_KEEP_HIGH_CLK_NUM must >= 2");
    end
    //-- 参数有效性检查 ------------------------------------------------------------
  3. 使用三段式状态机控制整个SPI传输过程,状态机如下图所示

五、使用说明

// 外部控制SPI信号
input  wire spi_begin,   // SPI单次通信开始, 高电平有效, 仅在spi_is_busy为低时起作用
output wire spi_end,     // SPI单次通信结束, 高电平有效, 只会持续一个时钟周期
output wire spi_is_busy, // SPI繁忙指示, 高电平表示SPI正在工作
input  wire [DATA_WIDTH-1:0] spi_master_tx_data, // SPI发送数据, 数据总是高位先发
output reg  [DATA_WIDTH-1:0] spi_master_rx_data, // SPI接收数据, 最先读出的数据在最高位
output reg                   spi_master_rx_data_valid, // SPI接收数据有效,高电平有效

外部模块通过以上信号控制SPI读写,相关说明如下:

  1. spi_is_busy为高时,此SPI主机模块不响应任何外部信号,所以,外部模块需要监测spi_is_busy信号,在它为低电平时,发送spi_begin控制spi控制开始

  2. SPI主机模块在会在spi_begin高电平且spi_is_busy低电平时,锁存spi_master_tx_data,作为待发送数据

此接口和AXI Stream接口用法基本一致。

六、仿真验证

见本系列文章——Verilog功能模块--SPI主机和从机(04)--SPI主机从机回环仿真与实测。

七、源码分享

源码在Gitee与Github开源,两平台同步:

Gitee:[Verilog功能模块--SPI主机和从机](https://gitee.com/xuxiaokang/verilog-function-module--SPI-Master-Slave)

Github:[zhengzhideakang/Verilog--SPI-Master-Slave](https://github.com/zhengzhideakang/Verilog--SPI-Master-Slave)


如果本文对你有所帮助,欢迎点赞、转发、收藏、评论让更多人看到,赞赏支持就更好了。

如果对文章内容有疑问,请务必清楚描述问题,留言评论或私信告知我,我看到会回复。


徐晓康的博客持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93203.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93203.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/93203.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Decoder模型 向量模长表示什么

Decoder模型 向量模长表示什么 词和其他词的关系的强弱和关联程度;生僻词模长小 从实验结果来看,Qwen2-7B-Instruct的向量模长规律与之前的预期(“模长与语义丰富度、确定性正相关”)完全相反,这反映了Decoder-only模型(尤其是指令微调模型)的表征特性与Encoder-only模…

STL容器及其算法

C 标准库容器详解&#xff1a;特性、用法与场景选型容器是 C 标准库&#xff08;STL&#xff09;的核心组件&#xff0c;用于存储和管理数据。不同容器因底层实现不同&#xff0c;在性能、功能和适用场景上差异显著。本文系统梳理vector、list、set、map等常用容器&#xff0c;…

MySQL ZIP安装教程:从解压到启动

金金金上线&#xff01; 话不多&#xff0c;只讲你能听懂的前端知识 前言 我这里不能下载安装程序的mysql&#xff0c;由于电脑安全限制&#xff0c;安装时会弹出需要管理员账号密码权限&#xff0c;此路行不通&#xff0c;所以琢磨着免安装版本怎么个流程&#xff0c;好&#…

p2p打洞

p2p网络穿透库,它的C++版本目前只支持linux,不支持win,它最新版本的穿透用的tcp,老版本支持tcp/udp: https://libp2p.io/ P2P-udp的穿透教程: https://edu.51cto.com/lesson/731596.html 目前打洞机制最好的库是webrtc,其次是libnice,它是轻量级的专门打洞的库。 libni…

『“无恙心宽”,梗痛不常』——爱上古中医(12)(健康生活是coder抒写优质代码的前提条件——《黄帝内经》伴读学习纪要)

养心护心气血通&#xff0c;无痛无梗全身松。 笔记模板由python脚本于2025-08-10 15:54:46创建&#xff0c;本篇笔记适合至少通晓一门语言&#xff0c;熟悉基本编程范式的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅…

Spark 运行流程核心组件(一)作业提交

1、Job启动流程1、Client触发 SparkContext 初始化 2、SparkContext 向 Master 注册应用 3、Master 调度 Worker 启动 Executor 4、Worker 进程启动 Executor 5、DAGScheduler 将作业分解为 Stage&#xff1a; 6、TaskScheduler 分配 Task 到 Executor 2、核心组件组件职责Spar…

MySQL 临时表与复制表

一、MySQL 临时表临时表是会话级别的临时数据载体&#xff0c;其设计初衷是为了满足短期数据处理需求&#xff0c;以下从技术细节展开说明。&#xff08;一&#xff09;核心特性拓展1.生命周期与会话绑定会话结束的判定&#xff1a;包括正常断开连接&#xff08;exit/quit&…

从配置到调试:WinCC与S7-1200/200SMT无线Modbus TCP通讯方案

测试设备与参数l 西门子PLC型号&#xff1a;S7-1200 1台l 西门子PLC型号&#xff1a;S7-200Smart 1台l 上位机&#xff1a;WinCC7.4 1台l 无线通讯终端——DTD418MB 3块l 主从关系&#xff1a;1主2从l 通讯接口&#xff1a;RJ45接口l 供电&#xff1a;12-24VDCl 通讯协议&a…

Android沉浸式全屏显示与隐藏导航栏的实现

1. 总体流程以下是实现沉浸式全屏显示和隐藏导航栏的流程&#xff1a;步骤描述步骤1创建一个新的Android项目步骤2在布局文件中定义需要展示的界面步骤3在Activity中设置沉浸式全屏显示步骤4处理系统UI的显示与隐藏步骤5运行应用并测试效果2. 详细步骤步骤1&#xff1a;创建一个…

EN 62368消费电子、信息技术设备和办公设备安全要求标准

EN 62368认证标准是一项全球性的电子产品安全标准&#xff0c;用于评估和认证消费电子、信息技术设备和办公设备的安全性。该标准由国际电工委员会(IEC)制定&#xff0c;取代了传统的EN60065和EN 60950两个标准&#xff0c;成为国际电子产品安全领域的新指导。IEC /EN 62368-1是…

【unity实战】使用Splines+DOTween制作弯曲手牌和抽牌动画效果

最终效果 文章目录最终效果前言实战1、Splines的使用2、绘制样条线3、DOTween安装和使用4、基于样条曲线&#xff08;Spline&#xff09;的手牌管理系统4.1 代码实现4.2 解释&#xff1a;&#xff08;1&#xff09;计算第一张卡牌的位置&#xff08;居中排列&#xff09;&#…

Flask模板注入梳理

从模板开始介绍&#xff1a;Flask中有许多不同功能的模板&#xff0c;他们之间是相互隔离的地带&#xff0c;可供引入和使用。Flask中的模块&#xff1a;flask 主模块&#xff1a;包含框架的核心类和函数&#xff0c;如 Flask&#xff08;应用实例&#xff09;、request&#x…

企业级的即时通讯平台怎么保护敏感行业通讯安全?

聊天记录存在第三方服务器、敏感文件被误发至外部群组、离职员工仍能查看历史消息.对于金融、医疗、政务等对数据安全高度敏感的行业而言&#xff0c;“沟通效率与”信息安全”的矛盾&#xff0c;从未像今天这样尖锐。企业即时通讯怎么保护敏感行业通讯安全&#xff1f;这个问题…

Java Spring框架最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡

Java Spring框架最新版本及发展史详解&#xff08;截至2025年8月&#xff09;-优雅草卓伊凡引言今天有个新项目 客户问我为什么不用spring 4版本&#xff0c;卓伊凡我今天刚做完项目方案&#xff0c;我被客户这一句问了有点愣住&#xff0c;Java Spring框架最新版本及发展史详解…

Android实现Glide/Coil样式图/视频加载框架,Kotlin

Android实现Glide/Coil样式图/视频加载框架&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permiss…

【k8s】pvc 配置的两种方式volumeClaimTemplates 和 PersistentVolumeClaim

pvc配置实例 实例1在Deployment中配置 template:xxxxxxvolumeClaimTemplates:- metadata:name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: nfsdev-storageclass (创建好的storageClassName)实例2#先创建一个pvc 然后在 Deploym…

Logistic Loss Function|逻辑回归代价函数

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

计算机网络技术-知识篇(Day.1)

一、网络概述 1、网络的概念 两个不在同一地理位置的主机&#xff0c;通过传输介质和通信协议&#xff0c;实现通信和资源共享。 2、网络发展史 第一阶段&#xff08;20世纪60年代&#xff09; 标志性事件&#xff1a;ARPANET的诞生关键技术&#xff1a;分组交换技术 第二…

工业元宇宙:迈向星辰大海的“玄奘之路”

一、从认知革命到工业革命&#xff1a;文明跃迁的底层逻辑1.1 认知革命&#xff1a;人类协作的基石时间线&#xff1a;约7万年前&#xff0c;智人通过语言和想象力构建共同虚拟现实&#xff0c;形成部落协作模式。核心突破&#xff1a;虚构能力&#xff1a;创造神、国家、法律等…

9. React组件生命周期

2. React组件生命周期 2.1. 认识生命周期 2.1.1. 很多事物都有从创建到销毁的整个过程&#xff0c;这个过程称之为生命周期&#xff1b;2.1.2. React组件也有自己的生命周期&#xff0c;了解生命周期可以让我们在最合适的地方完成想要的功能2.1.3. 生命周期和生命周期函数的关系…