最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界新动态:通用8位SPI接口模块——verilog实现

来源:博客园


(相关资料图)

本次设计一个八位的SPI的接口模块,可以修改输出的频率,也可以通过修改参数来设置通信模式。本模块是设定生成一个目标输出频率的二倍计数器,然后通关计数的值来输出响应的信号,从而进行SPI通信。本模块既可以发送数据也可以接收数据,给Send_en信号使开始发送数据,在接收到8位数据后会生成Read_en信号。片选信号只设定了1位,但是可以通过简单的修改位宽来设置多位。

一、模块代码

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: Lclone// // Create Date: 2023/01/23 00:56:52// Design Name: SPI_Interface// Module Name: SPI_Interface// Project Name: // Target Devices: // Tool Versions: // Description: //      SPI接口模块//      可修改分频参数来生成目标频率,最低分频系数为2;//      可以置位CPOL、CPHA可以来设置通信模式;//      本模块只有1位,但是可以简单修改位宽来设置多位片选信号// Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module SPI_Interface#   (           parameter         Value_divide = 2)//分频系数(最低为2)    (        //-----------------内部接口------------------        input              Clk,             //时钟        input              Rst_n,           //复位信号        input              CPOL,            //时钟极性        input              CPHA,            //时钟相位        input              CS_input,        //片选信号        input              Send_en,         //发送使能        input       [7:0]  Data_send,       //待发送数据        output  reg        Read_en,        //接收数据读使能        output  reg [7:0]  Data_recive,    //接收到的数据        //------------------外部接口------------------        output  reg        Spi_clk,        //输出时钟端        output  reg        Spi_mosi,       //主输出从接收端        input              Spi_miso,      //主接收从输出端        output             Cs_output      //片选信号输出    );    reg         act_flag;                  //活动状态寄存器    reg [9:0]   cnt_divide;                //分频计数器    reg [7:0]   Data_send_reg;             //带发送数据寄存器    reg [4:0]   cnt_pulse;                 //脉冲计数器            always @(posedge Clk or negedge Rst_n) begin         if(Rst_n == 0)            act_flag <= 0;        else if(Send_en == 1)            act_flag <= 1;        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1 & cnt_pulse == 16)            act_flag <= 0;        else            act_flag <= act_flag;    end        always @(posedge Clk or negedge Rst_n) begin        if(Rst_n == 0)            Read_en <= 0;        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1 & cnt_pulse == 16)            Read_en <= 1;        else            Read_en <= 0;    end        always @(posedge Clk or negedge Rst_n) begin        if(Rst_n == 0)            Data_send_reg <= 0;        else if(Send_en == 1)            Data_send_reg <= Data_send;        else            cnt_divide <= 0;    end        always @(posedge Clk or negedge Rst_n) begin         if(Rst_n == 0)            cnt_divide <= 0;        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1)            cnt_divide <= 0;        else if(act_flag == 1)            cnt_divide <= cnt_divide + 1"b1;        else            cnt_divide <= 0;    end        always @(posedge Clk or negedge Rst_n) begin//生成目标时钟两倍频率的的cnt_pulse        if(Rst_n == 0)            cnt_pulse <= 0;        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1 & cnt_pulse == 16)            cnt_pulse <= 0;        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1)            cnt_pulse <= cnt_pulse + 1"b1;        else if(act_flag == 1)            cnt_pulse <= cnt_pulse;        else            cnt_pulse <= 0;    end        always @(posedge Clk or negedge Rst_n) begin        if(Rst_n == 0)            begin                if(CPOL == 1)                    begin                        Spi_clk <= 1;                        Spi_mosi <= 1;                        Data_recive <= 0;                    end                else                    begin                        Spi_clk <= 0;                        Spi_mosi <= 1;                        Data_recive <= 0;                    end            end        else if(cnt_divide == Value_divide/2 - 1 & act_flag == 1)            begin                if(CPHA == 0)                    case(cnt_pulse)                        0:begin                              Spi_clk <= Spi_clk;                            Spi_mosi <= Data_send_reg[7];                            Data_recive <= Data_recive;                          end                        1:begin                            Spi_clk <= ~Spi_clk;                            Spi_mosi <= Spi_mosi;                            Data_recive[7] <= Spi_miso;                          end                        2:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[6];                              Data_recive <= Data_recive;                              end                                    3:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[6] <= Spi_miso;                            end                                    4:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[5];                              Data_recive <= Data_recive;                              end                                    5:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[5] <= Spi_miso;                            end                                    6:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[4];                              Data_recive <= Data_recive;                              end                                    7:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[4] <= Spi_miso;                            end                                    8:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[3];                              Data_recive <= Data_recive;                              end                                    9:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[3] <= Spi_miso;                            end                                    10:begin                                      Spi_clk <= ~Spi_clk;                                       Spi_mosi <= Data_send_reg[2];                             Data_recive <= Data_recive;                             end                                    11:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[2] <= Spi_miso;                            end                                    12:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[1];                              Data_recive <= Data_recive;                              end                                    13:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[1] <= Spi_miso;                            end                                    14:begin                                      Spi_clk <= ~Spi_clk;                                        Spi_mosi <= Data_send_reg[0];                              Data_recive <= Data_recive;                              end                                    15:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[0] <= Spi_miso;                            end                        16:begin                            Spi_clk <= ~Spi_clk;                                   Spi_mosi <= 1;                                  Data_recive <= Data_recive;                         end                        default:;                    endcase                else                    case(cnt_pulse)                        0:begin                              Spi_clk <= ~Spi_clk;                            Spi_mosi <= Data_send_reg[7];                            Data_recive <= Data_recive;                          end                        1:begin                            Spi_clk <= ~Spi_clk;                            Spi_mosi <= Spi_mosi;                            Data_recive[7] <= Spi_miso;                          end                        2:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[6];                            Data_recive <= Data_recive;                            end                                    3:begin                            Spi_clk <= ~Spi_clk;                                   Spi_mosi <= Spi_mosi;                                  Data_recive[6] <= Spi_miso;                          end                                    4:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[5];                            Data_recive <= Data_recive;                            end                                    5:begin                                      Spi_clk <= ~Spi_clk;                                   Spi_mosi <= Spi_mosi;                                  Data_recive[5] <= Spi_miso;                          end                                    6:begin                                      Spi_clk <= ~Spi_clk;                                       Spi_mosi <= Data_send_reg[4];                              Data_recive <= Data_recive;                              end                                    7:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[4] <= Spi_miso;                            end                                    8:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[3];                            Data_recive <= Data_recive;                            end                                    9:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Spi_mosi;                                    Data_recive[3] <= Spi_miso;                           end                                    10:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[2];                            Data_recive <= Data_recive;                            end                                    11:begin                                      Spi_clk <= ~Spi_clk;                                   Spi_mosi <= Spi_mosi;                                  Data_recive[2] <= Spi_miso;                          end                                    12:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[1];                            Data_recive <= Data_recive;                            end                                    13:begin                                      Spi_clk <= ~Spi_clk;                                   Spi_mosi <= Spi_mosi;                                  Data_recive[1] <= Spi_miso;                          end                                    14:begin                                      Spi_clk <= ~Spi_clk;                                     Spi_mosi <= Data_send_reg[0];                            Data_recive <= Data_recive;                            end                                    15:begin                                      Spi_clk <= ~Spi_clk;                                   Spi_mosi <= Spi_mosi;                                  Data_recive[0] <= Spi_miso;                          end                        16:begin                                                   Spi_clk <= Spi_clk;                                   Spi_mosi <= 1;                                  Data_recive <= Data_recive;                          end                                                  default:;                    endcase                    end    end        assign Cs_output = CS_input;    endmodule

二、仿真

1、仿真激励

`timescale 1ns / 1psmodule SPI_tb();reg clk_50m;initial clk_50m <= 1;always #10 clk_50m <= ~clk_50m;reg rst_n;initial begin    rst_n <= 0;    #200    rst_n <= 1;endreg          Send_en;reg     [7:0]Data_send;wire         Read_en;wire    [7:0]Data_recive;wire         Spi_clk;wire         Spi_mosi;wire         Spi_miso;wire         Cs_output;SPI_Interface#   (           .Value_divide                   (4))SPI_inst    (        //-----------------内部接口------------------        .Clk                            (clk_50m),        .Rst_n                          (rst_n),        .CPOL                           (1),        .CPHA                           (0),        .CS_input                       (1),        .Send_en                        (Send_en),        .Data_send                      (Data_send),        .Read_en                        (Read_en),                .Data_recive                    (Data_recive),        //------------------外部接口------------------        .Spi_clk                        (Spi_clk),        .Spi_mosi                       (Spi_mosi),        .Spi_miso                       (Spi_miso),        .Cs_output                      (Cs_output)    );assign Spi_miso = Spi_mosi;initial begin    Send_en <= 0;    Data_send <= 0;    #400;    Send_en <= 1;    Data_send <= 8"haf;    #20    Send_en <= 0;    #800;    Send_en <= 1;    Data_send <= 8"h55;    #20    Send_en <= 0;endendmodule

2、仿真结果

两倍分频:

四倍分频:

八倍分频:

CPOL=1、CPHA=1;

CPOL=1、CPHA=0;

CPOL=0、CPHA=0;

CPOL=0、CPHA=1;

结论:仿真实验初步成功,能够满足SPI通信的基本要求。

关键词: 发送数据 接口模块 外部接口