首页IT科技spi多少位(通用8位SPI接口模块——verilog实现)

spi多少位(通用8位SPI接口模块——verilog实现)

时间2025-05-04 07:52:56分类IT科技浏览3828
导读:本次设计一个八位的SPI的接口模块,可以修改输出的频率,也可以通过修改参数来设置通信模式。...

本次设计一个八位的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 + 1b1; 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 + 1b1; 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 / 1ps module 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; end reg 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 <= 8haf; #20 Send_en <= 0; #800; Send_en <= 1; Data_send <= 8h55; #20 Send_en <= 0; end endmodule

2                  、仿真结果

两倍分频:

四倍分频:

八倍分频:

CPOL=1      、CPHA=1;

CPOL=1      、CPHA=0;

CPOL=0                  、CPHA=0;

CPOL=0            、CPHA=1;

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

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
dayone的中文意思是(day08-AOP-01) system license violation蓝屏无法开机(System)