FPGA——spi代码篇

一、FPGA 开发SPI基础

        为了避免每次SPI驱动重写,直接参数化,尽量一劳永逸。SPI master有啥用呢,你发现各种外围芯片的配置一般都是通过SPI配置的,只不过有三线和四线。SPI slave有什么用呢,当外部主机(cpu)要读取FPGA内部寄存器值,那就很有用了,FPGA寄存器就相当于RAM,cpu通过SPI寻址读写数据。代码仅供参考,勿做商业用途。

二、SPI三线,四线区别

        三线制指的是CS,CLK,MOMI,是半双工方式;四线制指的是 CS,CLK,MOSI和MISO,是全双工方式。

三、SPI代码构思      

      1. SPI salve

                1.支持三线SPI或者四线SPI。通过define切换。                                 

                2.支持指令长度、帧长自定义。                               

                3.工作时钟可自定义,大于SPI clk的2倍。

        用户只需修改:(1)几线SPI。(2)单帧长度。(3)指令长度。(4)寄存器开辟。

        注意:指令最高bit表示读写,低写高读,其余bit表示地址。指令接着为数据端,两者位宽之和即为SPI单帧长。

//`define SPI_LINE  //是否是三线SPI
`define SPI_FRAME_WIDTH 16 //SPI一帧长度为16
`define SPI_INS_WIDTH 8    //SPI指令长
`timescale 1ns/1ps
////
module spi_slave 
(
    input     i_clk               , //work clk
    input     i_rst_n             ,  
  
    input     i_spi_clk           , //SPI clk
    input     i_spi_cs            , //SPI cs

    `ifdef SPI_LINE                 //条件编译
    inout     io_spi_sdio          
    `else
    input     i_spi_mosi          , //SPI mosi
    output    o_spi_miso            //SPI miso
    `endif          
);
//位宽计算函数
function integer clogb2 (input integer depth);
begin
    for (clogb2=0; depth>0; clogb2=clogb2+1) 
        depth = depth >>1;                          
end
endfunction
reg r_cs = 1'b1; //打一拍
always @(posedge i_clk)
begin
    r_cs <= i_spi_cs;
end
reg [1:0] r_spi_clk_edge = 2'b00; //SPI clk边沿检测
always @(posedge i_clk)
begin
    r_spi_clk_edge <= {r_spi_clk_edge[0],i_spi_clk};
end //always
reg [clogb2(`SPI_FRAME_WIDTH-1)-1:0] r_spi_cnt = 'd0;
always @(posedge i_clk)
begin
    if (r_cs) //cs为高则归零
        r_spi_cnt <= 'd0;
    else if (r_spi_clk_edge == 2'b10) //下降沿才计数
        r_spi_cnt <= r_spi_cnt + 'd1;
end
////指令锁存
reg [`SPI_INS_WIDTH-1:0] r_ins = 'd0;
always @(posedge i_clk)
begin
    if ((~r_cs) && (r_spi_clk_edge == 2'b01)) //上升沿锁存数据
    begin
        if ((r_spi_cnt >= 0) && (r_spi_cnt <= `SPI_INS_WIDTH-1))
        `ifdef SPI_LINE                 //条件编译
            r_ins <= {r_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我来挖坑啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值