spi 发送与接收 移位写法

spi _tx 发送模块 片选信号cs可以在top顶层控制模块产生

verilog 复制代码
`timescale 1ns / 1ps


module spi_rom#(
    parameter SIZE =  8     
)(
    input      wire                  clk  ,
    input      wire                  rst_n,
    input      wire      [SIZE-1:0]  data ,
    input      wire                  valid,
    output     reg                   sck  ,
    output     wire                  busy ,
    output     reg                   mosi 
    );
parameter CUNT_MAX = 100   ;
parameter BUSY     = 2'b10 ;
parameter IDEL     = 2'b01 ;



reg             fin      ;
reg  [1:0]      state    ;
reg  [10:0]     cunt     ;
reg  [10:0]     cunt_b   ;
reg  [SIZE-1:0] data_r   ; 
assign busy=(state==BUSY)?1'b1:1'b0;
//状态
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
    state<=IDEL;
    else case (state)
        IDEL:begin
            if(valid==1)
            state<=BUSY;
            else
            state<=state;
            end
        BUSY:begin
            if(fin==1)
            state<=IDEL;
            else
            state<=state;
        end
        default: ;
    endcase
end
//计数器
always @(posedge clk) begin
    if(state==IDEL)
    cunt<=11'd0;
    else begin
        if(cunt==CUNT_MAX-1)
        cunt<=11'd0;
        else
        cunt<=cunt+1'b1;
    end
end
//cunt_b
always @(posedge clk ) begin
    if(state==IDEL)
    cunt_b<=11'd0;
    else begin
        if(cunt==CUNT_MAX-1)
        cunt_b<=cunt_b+1;
        else
        cunt_b<=cunt_b;
    end    
end
//fin结束信号
always @(posedge clk ) begin
    if((cunt_b==SIZE-1)&&(cunt==CUNT_MAX-1))
    fin<=1'b1;
    else
    fin<=1'b0;
end
//数据的缓存
always @(posedge clk ) begin
    if(state==IDEL&&valid==1)
    data_r<=data;
    else if(state==BUSY&&cunt==CUNT_MAX-2)
    data_r<=(data_r<<1);
    else
    data_r<=data_r;
end
//sck的产生
always @(posedge clk ) begin
    if(state==IDEL)
    sck<=1'b0;
    else begin
        if(cunt_b==SIZE)  //防止sck出现末尾的毛刺
        sck<=1'b0;
        else if(cunt<50)
        sck<=1'b1;
        else
        sck<=1'b0;
    end
end
//tx的输出
always @(posedge clk ) begin
    if(state==IDEL)
    mosi<=1'b0;
    else begin
        if(cunt==0)
        mosi<=data_r[SIZE-1];
        else
        mosi<=mosi;
    end
end
endmodule

spi_rx

verilog 复制代码
`timescale 1ns / 1ps

module spi_rx#(
    parameter SIZE  =  8 
)(
    input                         clk   ,
    input                         rst_n ,
    input                         miso  ,
    input                         sck   ,
    input                         cs    ,
    output     reg    [SIZE-1:0]  data  ,
    output                        vlid  
    );
reg  [8:0]   cunt_b;
reg  [1:0]   rx_t  ;

assign vlid=(cunt_b==SIZE)?1'b1:1'b0;

always @(posedge clk ) begin
    if(!rst_n)
    rx_t<=2'b00;
    else 
    rx_t<={rx_t[0],sck};
end
//对下降沿计数
always @(posedge clk ) begin
    if(!rst_n)
    cunt_b<=0;
    else if(cs==0)begin 
    if(vlid==1)
    cunt_b<=0;
    else if(rx_t==2'b10)
    cunt_b<=cunt_b+1'b1;
    else
    cunt_b<=cunt_b;
    end
    else
    cunt_b<=0;
end
//data
always @(posedge clk ) begin
    if(cs==0&&rx_t==2'b10)
    data[0]<=miso;
    else if(cs==0&&rx_t==2'b01) //先移位再赋值相当于是
    data<=(data<<1);
    else
    data<=data;
end


endmodule
相关推荐
坏孩子的诺亚方舟8 天前
FPGA系统架构设计实践15_高云Arora V系列时钟体系
fpga开发·系统架构
FPGA小徐9 天前
入门 CNN 结构全解析|从流程图理论到 FPGA Verilog 硬件实现(含习题带讲解)
fpga开发
FPGA小徐9 天前
FPGA 数字信号处理:并行 FIR 与串行滤波器设计原理、对比与完整 Verilog 实现
fpga开发
Saniffer_SH10 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
zlinear数据采集卡10 天前
双核架构深度解析:ARM+FPGA如何让数据采集卡实现500Ksps高性能?
arm开发·fpga开发·架构
9527华安10 天前
FPGA实现GTH Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·gth·aurora 8b10b·transceivers
FPGA小徐11 天前
FPGA 数字信号处理(二):并行 FIR 滤波器的 Verilog 全流程设计与实现
fpga开发
国科安芯11 天前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
ALINX技术博客11 天前
【黑金云课堂】FPGA技术教程FPGA基础:I2C 总线通信技术
fpga开发·i2c
Hello-FPGA11 天前
Xilinx KU040 FPGA Camera Link 图像采集
c++·fpga开发