spi master接口的fpga实现

前言

当你器件的引脚贼少的时候,需要主机和从机通信,spi就派上了用场,它可以一对多,但只是片选到的从机能和主机通信,其他的挂机。

spi:serial peripheral interface 串行外围接口

大致了解:

spi是个同步协议,数据在master和slaver间交换通过时钟sck,由于它是同步协议,时钟速率就可以各种变换。

sck:主机提供,从机不能操控,从器件由主机产生的时钟控制。数据只有在sck来了的上升沿或者下降沿才传输。

高级一点的spi芯片有配置寄存器,高级一点的工作有四种模式,采样相位和sck空闲电平可配置。

当然在这里我们主要实现简单的spi协议:sck是系统时钟的四分频,wr请求信号有效时,主机开始工作,数据位8bit,sck空闲时低电平,工作时第一个沿数据传输。只有一个从机,cs低电平片选。

看下结构:

接口定义:

编码实现:(版权所有,请勿用于商业用途,仅供学习使用)

  1 //************************************************
  2 //  Filename      : spi_ms_test1.v
  3 //  Author        : Kingstacker
  4 //  Company       : School
  5 //  Email         : [email protected]
  6 //  Device        : Altera cyclone4 ep4ce6f17c8
  7 //  Description   : spi master module;data 8bit;sck is 4 div of the clk;
  8 //************************************************
  9 module  spi_ms #(parameter WIDTH = 8)(
 10     //input;
 11     input    wire    clk,
 12     input    wire    rst_n,
 13     input    wire    wr, //send request;
 14     input    wire    [WIDTH-1:0]    master_din, //the data you want send;
 15     input    wire    miso, //the data form slave;
 16     //output;
 17     output   reg     cs, //slave select;
 18     output   reg     sck, //data exchange clock;
 19     output   reg     mosi,    //master out;
 20     output   reg     [WIDTH-1:0]    master_dout //the data you received;
 21 );
 22 localparam [2:0] DIV_NUMBER = 4;      //div number,you can change;
 23 localparam       CNT_MAX = (DIV_NUMBER >>1) - 1‘b1;  //max cnt number,6/2 -1 ;
 24 reg cnt; //sck cnt;
 25 reg sck_en; //enable sck;
 26 reg data_cnt_en;
 27 reg sck_reg1;
 28 reg sck_reg2;
 29 wire sck_p; //posedge sck;
 30 wire sck_n; //negedge sck;
 31 wire send_over;
 32 localparam IDEL = 2‘b00;
 33 localparam SEND = 2‘b01;
 34 localparam FINISH = 2‘b10;
 35 reg [1:0] cstate;
 36 reg [4:0] data_cnt; //cnt the send data;
 37 reg [7:0] master_din_reg;
 38 reg [7:0] master_dout_reg;
 39 reg [2:0] mosi_cnt;
 40 //produce sck;
 41 always @(posedge clk or negedge rst_n) begin
 42     if (~rst_n) begin
 43         cnt <= 0;
 44         sck <= 1‘b0;
 45     end //if
 46     else begin
 47         if (sck_en == 1‘b1) begin
 48             if (cnt == CNT_MAX) begin
 49                 cnt <= 0;
 50                 sck <= ~sck;
 51             end
 52             else begin
 53                 cnt <= cnt + 1‘b1;
 54                 sck <= sck;
 55             end
 56         end
 57         else begin
 58             cnt <= 0;
 59             sck <= 1‘b0;
 60         end
 61     end //else
 62 end //always
 63 //produce sck_p and sck_n;
 64 always @(posedge clk or negedge rst_n) begin
 65     if (~rst_n) begin
 66         sck_reg1 <= 1‘b0;
 67         sck_reg2 <= 1‘b0;
 68     end //if
 69     else begin
 70         sck_reg1 <= sck;
 71         sck_reg2 <= sck_reg1;
 72     end //else
 73 end //always
 74 assign sck_p = (sck_reg1 & (~sck_reg2)); //sck posedge;
 75 assign sck_n = ((~sck_reg1) & sck_reg2); //sck negedge;
 76 //fsm;hot code;
 77 always @(posedge clk or negedge rst_n) begin
 78     if (~rst_n) begin
 79         cstate <= IDEL;
 80     end
 81     else begin
 82         case (cstate)
 83             IDEL:    cstate <= (wr)? SEND : IDEL;
 84             SEND:    cstate <= (send_over) ? FINISH : SEND;
 85             FINISH:  cstate <= IDEL;
 86             default: cstate <= IDEL;
 87         endcase //case
 88     end
 89 end
 90 always @(posedge clk or negedge rst_n) begin
 91     if (~rst_n) begin
 92         cs <= 1‘b1;
 93         data_cnt_en <= 1‘b0;
 94         sck_en <= 1‘b0;
 95         master_din_reg <= 0;
 96         master_dout <= 0;
 97     end
 98     else begin
 99         case (cstate)
100             IDEL: begin
101             data_cnt_en <= 1‘b0;
102             master_din_reg <= (wr) ? master_din : master_din_reg; //load the data you want send to slaver;
103             end
104             SEND: begin
105                 data_cnt_en <= 1‘b1;
106                 cs <= 1‘b0;
107                 sck_en <= 1‘b1;
108                 master_dout <= (send_over) ? master_dout_reg : master_dout; //master receiverd data;
109             end
110             FINISH: begin                  //send and load ok;
111                 sck_en <= 1‘b0;
112                 cs <= 1‘b1;
113                 data_cnt_en <= 1‘b0;
114             end
115             default: begin
116                 cs <= 1‘b1;
117                 sck_en <= 1‘b0;
118                 data_cnt_en <= 1‘b0;
119             end
120         endcase //case
121     end
122 end
123 always @(posedge clk or negedge rst_n) begin
124     if (~rst_n) begin
125         data_cnt <= 0;
126     end
127     else begin
128         data_cnt <= (data_cnt_en) ? (data_cnt + 1‘b1) : 5‘d0; //4 div * 8bit = 32 cnt;
129     end
130 end
131 assign send_over = (data_cnt == 5‘d31) ? 1‘b1 : 1‘b0;
132 //rising edge miso;
133 always @(posedge clk or negedge rst_n) begin
134     if (~rst_n) begin
135         master_dout_reg <= 0;
136     end
137     else begin
138         master_dout_reg <= (sck_p) ? {master_dout_reg[6:0],miso} : master_dout_reg;
139     end
140 end
141 //miso;
142 always @(posedge clk or negedge rst_n) begin
143     if (~rst_n) begin
144         mosi_cnt <= 0;
145     end
146     else begin
147         if (sck_n) begin
148             if (mosi_cnt == 3‘d7) begin
149                 mosi_cnt <= 0;
150             end
151             else begin
152                 mosi_cnt <= mosi_cnt + 1‘b1;
153             end
154         end
155         else begin
156             mosi_cnt <= mosi_cnt;
157         end
158     end
159 end
160 always @(posedge clk or negedge rst_n) begin
161     if (~rst_n) begin
162         mosi <= 1‘b0;
163     end
164     else begin
165         mosi <= (sck_n) ? master_din_reg[3‘d7-mosi_cnt] : mosi;
166     end
167 end
168 endmodule

仿真:

综合资源使用:

Fmax:

以上。

时间: 2024-10-10 22:28:26

spi master接口的fpga实现的相关文章

spi slaver接口的fpga实现

前言 spi从机接口程序,数据位8bit,sck空闲时低电平,工作时第一个沿数据传输.只有一个从机,cs低电平片选,slaver开始工作. 流程: 接口定义: 编码实现:(版权所有,请勿用于商业用途,仅供学习使用) 1 //************************************************ 2 // Filename : spi_sm.v 3 // Author : Kingstacker 4 // Company : School 5 // Email : [em

Linux SPI总线和设备驱动架构之二:SPI通用接口层

通过上一篇文章的介绍,我们知道,SPI通用接口层用于把具体SPI设备的协议驱动和SPI控制器驱动联接在一起,通用接口层除了为协议驱动和控制器驱动提供一系列的标准接口API,同时还为这些接口API定义了相应的数据结构,这些数据结构一部分是SPI设备.SPI协议驱动和SPI控制器的数据抽象,一部分是为了协助数据传输而定义的数据结构.另外,通用接口层还负责SPI系统与Linux设备模型相关的初始化工作.本章的我们就通过这些数据结构和API的讨论来对整个通用接口层进行深入的了解. /**********

SPI通信实验---verilog(FPGA作为从机,使用可读可写)

本实验讲究实用性,故设计思想为:主机先向从机发送地址,若是向从机写入数据,则向从机发送数据,若是读取从机数据,则向从机发送时钟,然后在时钟下降沿读取数据即可.cs信号上升沿作为SPI通信的结束信号.rom程序只是做测试使用. 每次发送16个时钟信号,前八个是地址和命令,后八个是数据.其中:前8个时钟接受的数据的最高位决定着这次通信是读取数据还是写入数据,最高位为1,则是读取数据,为0则是写入数据. 程序: /********************************Copyright***

BMP280 driver对接单片机I2C或者SPI总线接口

1:登录github网站搜BMP280,找到 BoschSensortec/BMP280_driver 2:gitclone或者download zip都可以,把驱动下载到本地,记得fork哦! 3:阅读驱动的readme文件 4:readme前面分别是目录.概要.和版本介绍,略过 5:我们关注的焦点也是重点是:传感器初始化即:Initializing the sensor,以I2C为例讲解如下: 咱们按照要求先定义一个结构体 struct bmp280_dev bmp; 这个结构体最重要的是实

VC709E 增强版 基于FMC接口的Xilinx Vertex-7 FPGA V7 XC7VX690T PCIeX8 接口卡

VC709E 增强版 基于FMC接口的Xilinx Vertex-7 FPGA V7 XC7VX690T PCIeX8 接口卡 一.板卡概述       本板卡基于Xilinx公司的FPGA XC7VX690T-FFG1761 芯片,支持PCIeX8.64bit DDR3容量2GByte,HPC的FMC连接器,板卡支持各种接口输入,软件支持windows. 二.功能和技术指标:     1.标准PCI-E接口,支持PCI-E 8x,支持PCI-E 3.0.    2.标准FMC-HPC接口,VA

SPI、I2C、UART三种串行总线协议的区别和SPI接口介绍(转)

SPI.I2C.UART三种串行总线协议的区别 第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART(Universal Asynchronous Receiver Transmitter:通用异步收发器) 第二,区别在电气信号线上: SPI总线由三条信号线组成:串行时钟(SCLK).串行数据输出(SDO).串行数据输入(SDI).SPI总线可以实现多个SPI设备互相连接.提供SPI串行时钟的SPI

FPGA设计——SPI Flash启动之MC8051设计

1. 概述 本设计采用FPGA技术,在FPGA中实现8051单片机的软核,将外部SPI Flash中的代码数据加载到FPGA内部ram,然后复位MC8051,实现外部flash启动MC8051. 2. 系统框图 8051采用Oregano Systems公司开源的MC8051软核.SPI Flash采用W25Q16芯片存储8051的代码程序.系统框图如下: 3. MC8051简介 Oregano Systems的8051单片机采用VHDL语言开发,具有如下特点: 采用完全同步设计 指令集和标准

270-VC709E 增强版 基于FMC接口的Xilinx Vertex-7 FPGA V7 XC7VX690T PCIeX8 接口卡

VC709E 增强版 基于FMC接口的Xilinx Vertex-7 FPGA V7 XC7VX690T PCIeX8 接口卡 一.板卡概述       本板卡基于Xilinx公司的FPGA XC7VX690T-FFG1761I 芯片,支持PCIeX8.64bit DDR3容量2GByte,HPC的FMC连接器,板卡支持各种接口输入,软件支持windows. 二.功能和技术指标:     1.标准PCI-E接口,支持PCI-E 8x,支持PCI-E 3.0.    2.标准FMC-HPC接口,V

总线接口与计算机通信(二)SPI总线

[SPI基础知识简介] SPI总线是Motorola公司推出的三线同步接口,用于 CPU与各种外围器件进行全双工.同步串行通讯. 同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO; SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等. SPI总线有四种工作方式(SP0, SP1, SP2, SP3),其中使用的最为广泛的是SPI0和SPI3方式. ? ? 源文档 <htt