从站spi通信,实现32位数据的读写

近期写了篇spi通讯,fpga作为从站:仿真后信号正确性是可行的;
数据位宽32位,正在测试长期运行的效果!

/*
**************************************************************************
*                           spi 
* Filename  : spi.v
* Describel : spi总线,数据移位处理模块;
*               发送,接收均为32位数据;
*               接收时,上升沿移入数据;
*               发送时,上升沿来之前放上数据
*               用于SPI从动模式
*
**************************************************************************
*/ 
//use SPI 1 mode,CHOL = 0,CHAL = 0
module spi(         clk,                                
                    rst_n,                                      
                    CS_N,                                           
                    SCK,                                            
                    MOSI,                                                                                   
                    MISO,
                    data_o,
                    data_in 
                    );
                input clk;                                      //主频时钟25M
                input rst_n;                                    //复位信号
                input CS_N;                                     // spi拉低cs使能
                input SCK;                                      // spi数据发送接收时钟
                input MOSI;                                     // spi输入缓存数据
                input [31:0] data_in;
                //reg [7:0] txd_data;                           // spi发送数据
                output wire MISO;                               // spi输出缓存数据
                output reg[31:0] data_o;

/*
*********************************************************************
* 滤波
*********************************************************************
*/  
wire sck_o,cs_n_o,mosi_o;
reg MISO_O;
filter     u_sck  (.clk_i(clk),.s_i(SCK), .s_o(sck_o));
filter     u_cs_n  (.clk_i(clk),.s_i(CS_N), .s_o(cs_n_o));
filter     u_mosi  (.clk_i(clk),.s_i(MOSI), .s_o(mosi_o));
filter     u_miso  (.clk_i(clk),.s_i(MISO_O), .s_o(MISO));
/*
*********************************************************************
* cpld作为从机读取数据,SPI接收部分使用有限状态机 
*********************************************************************
*/
reg [5:0] rxd_state;                                           //SPI接收部分状态机
reg [31:0] rec_data;                                           //16位接收数据寄存器
always@(negedge sck_o )                                    //每次sck上升沿都会接收数据,spi的顶端模块状态机决定是否取用
begin
    if(!rst_n)                                                 //复位
        begin                                                  //初始个状态值
            rxd_state <= 6'b0;
        end
        else if(!cs_n_o)                                        //片选信号置低,移入数据 
        begin
            case(rxd_state)                                     //SPI接收部分使用有限状态机
                6'd0:begin                                      //SPI接收状态0
                        rec_data[31] <= mosi_o;             //MOSI的数据移入移位寄存器rec_data[15]
                        rxd_state <= 6'd1;                      //接收状态进入下一步
                      end                                               
                6'd1:begin                                      //SPI接收状态1
                        rec_data[30] <= mosi_o;             //MOSI的数据移入移位寄存器rec_data[14]
                        rxd_state <= 6'd2;                      //接收状态进入下一步
                      end
                6'd2:begin                                      //SPI接收状态2
                        rec_data[29] <= mosi_o;
                        rxd_state <= 6'd3;
                      end
                6'd3:begin                                      //SPI接收状态3
                        rec_data[28] <= mosi_o;
                        rxd_state <= 6'd4;
                      end
                6'd4:begin                                      //SPI接收状态4
                        rec_data[27] <= mosi_o;
                        rxd_state <= 6'd5;
                      end
                6'd5:begin                                      //SPI接收状态5
                        rec_data[26] <= mosi_o;
                        rxd_state <= 6'd6;
                      end
                6'd6:begin                                      //SPI接收状态6
                        rec_data[25] <= mosi_o;
                        rxd_state <= 6'd7;
                      end
                6'd7:begin                                      //SPI接收状态7
                        rec_data[24] <= mosi_o;
                        rxd_state <= 6'd8;                      //接收状态进入下一步                                                 
                        end
                6'd8:begin                                      //SPI接收状态8
                        rec_data[23] <= mosi_o;                 //MOSI的数据移入移位寄存器rxd_data[7]
                        rxd_state <= 6'd9;                      //接收状态进入下一步
                      end                                               
                6'd9:begin                                      //SPI接收状态9
                        rec_data[22] <= mosi_o;                 //MOSI的数据移入移位寄存器rxd_data[6]
                        rxd_state <= 6'd10;                     //接收状态进入下一步
                      end
                6'd10:begin                                     //SPI接收状态10
                        rec_data[21] <= mosi_o;
                        rxd_state <= 6'd11;
                      end
                6'd11:begin                                     //SPI接收状态11
                        rec_data[20] <= mosi_o;
                        rxd_state <= 6'd12;
                      end
                6'd12:begin                                     //SPI接收状态12
                        rec_data[19] <= mosi_o;
                        rxd_state <= 6'd13;
                      end
                6'd13:begin                                     //SPI接收状态13
                        rec_data[18] <= mosi_o;
                        rxd_state <= 6'd14;
                      end
                6'd14:begin                                     //SPI接收状态14
                        rec_data[17] <= mosi_o;
                        rxd_state <= 6'd15;
                      end
                6'd15:begin                                     //SPI接收状态15
                        rec_data[16] <= mosi_o;
                        rxd_state <= 6'd16;
                        end
                6'd16:begin                                     //SPI接收状态16
                        rec_data[15] <= mosi_o;
                        rxd_state <= 6'd17;
                      end
                6'd17:begin                                     //SPI接收状态17
                        rec_data[14] <= mosi_o;
                        rxd_state <= 6'd18;
                      end
                6'd18:begin                                     //SPI接收状态18
                        rec_data[13] <= mosi_o;
                        rxd_state <= 6'd19;
                      end
                6'd19:begin                                     //SPI接收状态19
                        rec_data[12] <= mosi_o;
                        rxd_state <= 6'd20;
                      end   
                6'd20:begin                                     //SPI接收状态20
                        rec_data[11] <= mosi_o;
                        rxd_state <= 6'd21;
                      end
                6'd21:begin                                     //SPI接收状态21
                        rec_data[10] <= mosi_o;
                        rxd_state <= 6'd22;
                      end
                6'd22:begin                                     //SPI接收状态22
                        rec_data[9] <= mosi_o;
                        rxd_state <= 6'd23;
                      end
                6'd23:begin                                     //SPI接收状态23
                        rec_data[8] <= mosi_o;
                        rxd_state <= 6'd24;
                      end
                6'd24:begin                                     //SPI接收状态24
                        rec_data[7] <= mosi_o;
                        rxd_state <= 6'd25;
                      end   
                6'd25:begin                                     //SPI接收状态25
                        rec_data[6] <= mosi_o;
                        rxd_state <= 6'd26;
                      end
                6'd26:begin                                     //SPI接收状态26
                        rec_data[5] <= mosi_o;
                        rxd_state <= 6'd27;
                      end
                6'd27:begin                                     //SPI接收状态27
                        rec_data[4] <= mosi_o;
                        rxd_state <= 6'd28;
                      end
                6'd28:begin                                     //SPI接收状态28
                        rec_data[3] <= mosi_o;
                        rxd_state <= 6'd29;
                      end    
                6'd29:begin                                     //SPI接收状态29
                        rec_data[2] <= mosi_o;
                        rxd_state <= 6'd30;
                      end
                6'd30:begin                                     //SPI接收状态30
                        rec_data[1] <= mosi_o;
                        rxd_state <= 6'd31;
                      end
                6'd31:begin                                     //SPI接收状态31
                        rec_data[0] <= mosi_o;
                        rxd_state <= 6'd0;
                        end
                default: ;
            endcase 
    end
end

always @(negedge clk)
    begin
        if(!rst_n)                          
            data_o<=32'd0;                                          
        else if(cs_n_o)
            data_o<=rec_data;                                       
    end
reg [31:0] data_reg;    
always @(negedge clk)
    begin
        if(!rst_n)                          
            data_reg<=32'd0;                                            
        else 
            data_reg<= cs_n_o ? data_in :data_reg;                                      
    end
reg [5:0]   rxd_state1;
always@(posedge sck_o )                                   
begin
    if(!rst_n)                                                 
        begin                                                  
            rxd_state1 <= 6'b0;
        end
        else if(!cs_n_o)                                        
        begin
            case(rxd_state1)                                        //SPI接收部分使用有限状态机
                6'd0:begin                                      //SPI发送状态0
                        MISO_O <=data_reg[31];              
                        rxd_state1 <= 6'd1;                     //发送状态进入下一步
                      end                                               
                6'd1:begin                                      //SPI发送状态1
                        MISO_O <=data_reg[30];              
                        rxd_state1 <= 6'd2;                     //发送状态进入下一步
                      end
                6'd2:begin                                      //SPI发送状态2
                        MISO_O <=data_reg[29];
                        rxd_state1 <= 6'd3;
                      end
                6'd3:begin                                      //SPI发送状态3
                        MISO_O <=data_reg[28];
                        rxd_state1 <= 6'd4;
                      end
                6'd4:begin                                      //SPI发送状态4
                        MISO_O <=data_reg[27];
                        rxd_state1 <= 6'd5;
                      end
                6'd5:begin                                      //SPI发送状态5
                        MISO_O <=data_reg[26];
                        rxd_state1 <= 6'd6;
                      end
                6'd6:begin                                      //SPI发送状态6
                        MISO_O <=data_reg[25];
                        rxd_state1 <= 6'd7;
                      end
                6'd7:begin                                      //SPI发送状态7
                        MISO_O <=data_reg[24];
                        rxd_state1 <= 6'd8;                     //发送状态进入下一步                                                 
                        end
                6'd8:begin                                      //SPI发送状态8
                        MISO_O <=data_reg[23];                  
                        rxd_state1 <= 6'd9;                     //发送状态进入下一步
                      end                                               
                6'd9:begin                                      //SPI发送状态9
                        MISO_O <=data_reg[22];                  
                        rxd_state1 <= 6'd10;                        //发送状态进入下一步
                      end
                6'd10:begin                                     //SPI发送状态10
                        MISO_O <=data_reg[21];
                        rxd_state1 <= 6'd11;
                      end
                6'd11:begin                                     //SPI发送状态11
                        MISO_O <=data_reg[20];
                        rxd_state1 <= 6'd12;
                      end
                6'd12:begin                                     //SPI发送状态12
                        MISO_O <=data_reg[19];
                        rxd_state1 <= 6'd13;
                      end
                6'd13:begin                                     //SPI发送状态13
                        MISO_O <=data_reg[18];
                        rxd_state1 <= 6'd14;
                      end
                6'd14:begin                                     //SPI发送状态14
                        MISO_O <=data_reg[17];
                        rxd_state1 <= 6'd15;
                      end
                6'd15:begin                                     //SPI发送状态15
                        MISO_O <=data_reg[16];
                        rxd_state1 <= 6'd16;
                        end
                6'd16:begin                                     //SPI发送状态16
                        MISO_O <=data_reg[15];
                        rxd_state1 <= 6'd17;
                      end
                6'd17:begin                                     //SPI发送状态17
                        MISO_O <=data_reg[14];
                        rxd_state1 <= 6'd18;
                      end
                6'd18:begin                                     //SPI发送状态18
                        MISO_O <=data_reg[13];
                        rxd_state1 <= 6'd19;
                      end
                6'd19:begin                                     //SPI发送状态19
                        MISO_O <=data_reg[12];
                        rxd_state1 <= 6'd20;
                      end   
                6'd20:begin                                     //SPI发送状态20
                        MISO_O <=data_reg[11];
                        rxd_state1 <= 6'd21;
                      end
                6'd21:begin                                     //SPI发送状态21
                        MISO_O <=data_reg[10];
                        rxd_state1 <= 6'd22;
                      end
                6'd22:begin                                     //SPI发送状态22
                        MISO_O <=data_reg[9];
                        rxd_state1 <= 6'd23;
                      end
                6'd23:begin                                     //SPI发送状态23
                        MISO_O <=data_reg[8];
                        rxd_state1 <= 6'd24;
                      end
                6'd24:begin                                     //SPI发送状态24
                        MISO_O <=data_reg[7];
                        rxd_state1 <= 6'd25;
                      end   
                6'd25:begin                                     //SPI发送状态25
                        MISO_O <=data_reg[6];
                        rxd_state1 <= 6'd26;
                      end
                6'd26:begin                                     //SPI发送状态26
                        MISO_O <=data_reg[5];
                        rxd_state1 <= 6'd27;
                      end
                6'd27:begin                                     //SPI发送状态27
                        MISO_O <=data_reg[4];
                        rxd_state1 <= 6'd28;
                      end
                6'd28:begin                                     //SPI发送状态28
                        MISO_O <=data_reg[3];
                        rxd_state1 <= 6'd29;
                      end    
                6'd29:begin                                     //SPI发送状态29
                        MISO_O <=data_reg[2];
                        rxd_state1 <= 6'd30;
                      end
                6'd30:begin                                     //SPI发送状态30
                        MISO_O <=data_reg[1];
                        rxd_state1 <= 6'd31;
                      end
                6'd31:begin                                     //SPI发送状态31
                        MISO_O <=data_reg[0];
                        rxd_state1 <= 6'd0;
                        end
                default: ;
            endcase 
    end
end 

endmodule


该写法过于繁琐,改进:通过移位寄存器将数据存储发送。

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值