FPGA学习之路——SPI详解及Verilog源码分析

概述

SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。

  • 优点
    支持全双工
    支持高速
    协议支持字长不限于8bit,可以根据应用灵活选择消息字长。
    硬件连接简单
  • 缺点
    相比I2C多两条线
    没有寻址机制,只能靠片选选择不同的设备
    没有回应ACK机制,主设备不知道消息发送是否成功
    典型应用仅支持单主控

硬件结构

  • 信号定义
    SCK:Serial Clock,时钟信号,由主设备产生。
    MOSI:Master Output,Slave Input 主发从收信号。在片选信号有效时,数据由高位到低位,在时钟的上升沿依次发送给从设备。
    MISO:Master Input,Slave Output 主收从发信号,在片选信号有效时,数据由高位到低位,在时钟的上升沿依次发送给主设备。
    SS/CS:Slave Select 片选信号,低有效,由主设备控制。即只有片选信号为预先规定的使能信号时,对应的芯片操作才有效,这使得在同一总线上连接多个SPI设备成为可能。
  • 电路连接
    单个主设备和单个从设备:

    单个主设备和多个从设备,通过用多个片选信号或者菊花链的形式完成。
  • 传输模式
    通过设置相关控制寄存器,SPI可以有四种传输模式。
    1、时钟空闲时的电平为高或低。
    2、数据采样发生在时钟(SCK)的上/下边沿。
    将以上两种情况两两组合,即可得四种传输模式。
    数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取,完成一位数据传输,输入与输出原理相近。这样通过至少8次时钟信号的改变(上升沿和下降沿为一次),就可以完成8位数据的传输。如下图所示。
  • 标准SPI读

    片选→读指令→地址→数据读出
  • 标准SPI写

    片选→写指令→地址→数据写入

Verilog代码解析

本文以SPI Master控制器为例来对Verilog源码进行分析,参考资料为《VERILOG HDL应用程序设计实例精讲》,仅供学习参考,项目在文章末尾给出下载链接。
1、时钟分频模块,将原始时钟进行四分频,过程较为简单,不再详述。

module clkdiv(clk,clkout);
input clk;
output clkout;reg [1:0]cnt=2'd0;
reg clkout=1'b0;always @(posedge clk)beginif(cnt==2'd1)beginclkout<=1'b1;cnt<=cnt+2'd1;endelse if(cnt == 2'd3)beginclkout<=1'b0;cnt<=2'd0;endelse begincnt<=cnt+2'd1;end
end
endmodule

2、SPI发送数据部分,在spiclk的上升沿完成数据的传输。spics为片选信号,低有效;spido为输出的数据;dstate为FSM变量。dsend为待传送数据,其中部分数据过程重复,代码中仅保留首尾数据的传输过程。

begincase (dstate)8'd0:beginspics <= 1'b0;spiclk <= 1'b1;spido <= 1'b1;dstate <= 8'd1;end8'd1:beginspics <= 1'b0;spiclk <= 1'b1;spido <= 1'b1;dstate <= 8'd2;end8'd2:beginspics <= 1'b0;spiclk <= 1'b0;spido <= 1'b1;dstate <= 8'd3;end8'd3:beginspics <= 1'b0;spiclk <= 1'b1;spido <= dsend[7];dstate <= 8'd4;end8'd4:beginspics <= 1'b0;spiclk <= 1'b0;spido <= dsend[7];dstate <= 8'd5;end……8'd17:beginspics <= 1'b0;spiclk <= 1'b1;spido <= dsend[0];dstate <= 8'd18;end8'd18:beginspics <= 1'b0;spiclk <= 1'b0;spido <= dsend[0];dstate <= 8'd19;end8'd19:beginspics <= 1'b0;spiclk <= 1'b1;spido <= 1'b1;dstate <= 8'd20;end8'd20:beginspics <= 1'b0;spiclk <= 1'b1;spido <= 1'b1;dstate <= 8'd0;spistate <= idle;endendcaseenddefault:beginspics <= 1'b1;spiclk <= 1'b1;spido <= 1'b1;spistate <= 2'b00;endendcaseend


可以看到当片选信号spics为低有效时,数据在spiclk的上升沿按顺序被发送至SPI总线上,数据信号spido与输入数据相对应,SPI Master发送时序得到验证。
3、SPI接收数据部分,参数定义与2一样,其中部分数据过程重复,代码中仅保留首尾数据的传输过程。在时钟的下降沿进行数据的接收。

begincase (dstate)8'd0:beginspics <= 1'b0;spiclk <= 1'b1;dstate <= 8'd1;end8'd1:beginspics <= 1'b0;spiclk <= 1'b1;dstate <= 8'd2;end8'd2:beginspics <= 1'b0;spiclk <= 1'b0;dstate <= 8'd3;end8'd3:beginspics <= 1'b0;spiclk <= 1'b1;              dstate <= 8'd4;end8'd4:beginspics <= 1'b0;spiclk <= 1'b0;dreceive[7] <= spidi;dstate <= 8'd5;end8'd5:beginspics <= 1'b0;spiclk <= 1'b1;             dstate <= 8'd6;end……8'd18:beginspics <= 1'b0;spiclk <= 1'b0;dreceive[0] <= spidi;dstate <= 8'd19;end8'd19:beginspics <= 1'b0;spiclk <= 1'b1;dstate <= 8'd20;dataout <= dreceive;end8'd20:beginspics <= 1'b0;spiclk <= 1'b1;dstate <= 8'd0;spistate <= 2'b00;endendcaseend


由上图分析看出,收到的数据与SPI传输的数据相对应,SPI接收数据部分得到正确验证。

实验项目框图:

实验心得
1、在给复位信号低电平时时间过短,分频后时钟上升沿还未到复位信号就拉高了,导致未进行有效复位。
2、进行发送/接收状态检测时设置的计数子过大,如下图,每过40个时钟周期进行一次检测,当仿真时间过短时,容易看不到结果。

if(cnt == 8'd40)begincnt <= 8'd0;if((wr == 1'b0) && (rd == 1'b1))beginspistate <= send_data;dstate <= 8'd0;dsend <= datain;endelse if((wr == 1'b1) && (rd == 1'b0))beginspistate <= receive_data;dstate <= 8'd0;endendelsebegincnt <= cnt + 8'd1;end

3、若结果出现问题,将相关控制信号添加至窗口,观察其状态,分析程序存在的问题。

项目下载链接

参考资料:https://blog.csdn.net/weixin_42509369/article/details/83096349
《VERILOG HDL应用程序设计实例精讲》

FPGA学习之路—接口(3)—SPI详解及Verilog源码分析相关推荐

  1. 【Swagger】配置信息详解(涉及源码分析)

    先来说说 Swagger 有什么用,相较于使用 markdown 或者 word 写接口文档,Swagger 自动生成 API 文档,然后在 web 端暴露,并且 API 文档与 API 定义同步更新 ...

  2. 详解JSP——从源码分析

    何为JSP Java Server Pages:java服务器端页面 和Servlet一样 用于动态web技术 特点: 跟在写HTML一样 区别: HTML只给用户提供静态的数据 JSP页面中可以嵌入 ...

  3. 【Java 代码实例 14】BeanUtils用法详解,附源码分析

    目录 一.org.apache.commons.beanutils.BeanUtils简介 二.使用的前置条件 三.添加pom 四.org.apache.commons.beanutils.BeanU ...

  4. @AliasFor注解详解(结合源码分析)

    一. 概述 网上关于该注解的描述大都抄来抄去,没有涉及到最本质的源码问题, 下面是笔者结合注解源码, 以及其他常用的注解源码, 来分析@AliasFor注解的主要功能以及展示实际使用场景 描述:@Al ...

  5. FPGA学习之路—接口(2)—I2C协议详解+Verilog源码分析

    FPGA学习之路--I2C协议详解+Verilog源码分析 定义 I2C Bus(Inter-Integrated Circuit Bus) 最早是由Philips半导体(现被NXP收购)开发的两线时 ...

  6. 生成对抗网络入门详解及TensorFlow源码实现--深度学习笔记

    生成对抗网络入门详解及TensorFlow源码实现–深度学习笔记 一.生成对抗网络(GANs) 生成对抗网络是一种生成模型(Generative Model),其背后最基本的思想就是从训练库里获取很多 ...

  7. CNN入门详解及TensorFlow源码实现--深度学习笔记

    CNN入门详解及TensorFlow源码实现–深度学习笔记 ##一.卷积神经网络 ###1.简介 卷积神经网络是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出 ...

  8. 【Python】基金/股票 最大回撤率计算与绘图详解(附源码和数据)

    如果你想找的是求最大回撤的算法,请跳转:[Python] 使用动态规划求解最大回撤详解 [Python]基金/股票 最大回撤率计算与绘图详解(附源码和数据) 0. 起因 1. 大成沪深300指数A 5 ...

  9. JAVA文件上传详解(附源码)

    文章目录 JAVA文件上传详解(附源码) 1.准备工作 2.使用类介绍 FileItem类 ServletFileUpload类 3.代码编写 JAVA文件上传详解(附源码) 在web应用中,文件上传 ...

最新文章

  1. python客户价值分析_Python数据分析与应用航空公司客户价值分析.ppt
  2. kalman 滤波 演示与opencv代码
  3. python私有方法应用场景_Python私有属性私有方法应用实例解析
  4. 虚拟现实大会ChinaVR2015报告之-电子试衣和三维人体建模
  5. 前端学习(3058):vue+element今日头条管理-回顾
  6. 回顾一下Unix哲学
  7. uboot的readme导读(转)
  8. java线性数据结构_Java实现数据结构之线性结构
  9. 微信分身版电脑版_电脑版营销wetool电脑版-网站
  10. Codeforces Round #215 (Div. 2) B. Sereja and Suffixes map
  11. c51语言跑马灯键盘程序,单片机按键控制跑马灯程序
  12. 了不起的GIS:GIS相关软件、框架、代码、资源等的合集
  13. 解决客户一例:使用域超级管理员打开Exchange 2010发现没有权限
  14. 锐捷计算机教室排顺序,大学四年说话最多的一堂课是在锐捷智慧教室
  15. 南极大冒险/零下八度/南极物语/8只雪橇犬
  16. python3 绘制盖尔圆
  17. 前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)...
  18. 如何提升企业网络曝光率?
  19. Android的ADB
  20. 漫反射实现 - UnityShader

热门文章

  1. HANA report transaction data retrieve in QHD/504
  2. How is ABAP keyword highlight implemented in Chrome
  3. variable not availabe in Chrome debugger
  4. why we need a undefined parameter in function signature
  5. 基于微服务架构的token生成和使用
  6. SAP Marketing 和SAP marketing Cloud的区别
  7. workflow initialization in webclient ui - Remote call case
  8. 使用SAP ABAP BSP应用实现一个环状的进度条
  9. 如何使用SAP Gigya的登录服务和您的网站集成
  10. SAP C4C和Gigya(Customer Data Cloud)的客户报表