前言
spi从机接口程序,数据位8bit,sck空闲时低电平,工作时第一个沿数据传输。只有一个从机,cs低电平片选,slaver开始工作。
流程:
接口定义:
编码实现:(版权所有,请勿用于商业用途,仅供学习使用)
1 //************************************************ 2 // Filename : spi_sm.v 3 // Author : Kingstacker 4 // Company : School 5 // Email : kingstacker_work@163.com 6 // Device : Altera cyclone4 ep4ce6f17c8 7 // Description : spi slaver module,mode is 0 ;data 8bit; 8 //************************************************ 9 module spi_sm #(parameter WIDTH = 8)( 10 //input; 11 input wire clk, 12 input wire rst_n, 13 input wire cs, //slave select; 14 input wire sck, //data exchange clock; 15 input wire [WIDTH-1:0] slaver_din, //the data you want send; 16 input wire mosi, //the data form master; 17 //output; 18 output reg miso, //slaver out; 19 output reg [WIDTH-1:0] slaver_dout //the data you received; 20 ); 21 localparam MISO_CNT_MAX = 3'd7; 22 reg cs_reg1; 23 reg cs_reg2; 24 reg sck_reg1; 25 reg sck_reg2; 26 wire cs_p; //posedge cs; 27 wire cs_n; //negedge cs; 28 wire sck_p; //posedge sck; 29 wire sck_n; //negedge sck; 30 reg [WIDTH-1:0] slaver_din_reg; 31 reg [WIDTH-1:0] slaver_dout_reg; 32 reg [2:0] miso_cnt; 33 //produce cs_p and cs_n; 34 always @(posedge clk or negedge rst_n) begin 35 if (~rst_n) begin 36 cs_reg1 <= 1'b0; 37 cs_reg2 <= 1'b0; 38 end //if 39 else begin 40 cs_reg1 <= cs; 41 cs_reg2 <= cs_reg1; 42 end //else 43 end //always 44 assign cs_p = (cs_reg1 & (~cs_reg2)); //cs posedge; 45 assign cs_n = ((~cs_reg1) & cs_reg2); //cs negedge; 46 //produce sck_p and sck_n; 47 always @(posedge clk or negedge rst_n) begin 48 if (~rst_n) begin 49 sck_reg1 <= 1'b0; 50 sck_reg2 <= 1'b0; 51 end //if 52 else begin 53 sck_reg1 <= sck; 54 sck_reg2 <= sck_reg1; 55 end //else 56 end //always 57 assign sck_p = (sck_reg1 & (~sck_reg2)); //sck posedge; 58 assign sck_n = ((~sck_reg1) & sck_reg2); //sck negedge; 59 //you want send data registed; 60 always @(posedge clk or negedge rst_n) begin 61 if (~rst_n) begin 62 slaver_din_reg <= 0; 63 end //if 64 else begin 65 slaver_din_reg <= (cs_n) ? slaver_din :slaver_din_reg; 66 end //else 67 end //always 68 //recieved data ; 69 always @(posedge clk or negedge rst_n) begin 70 if (~rst_n) begin 71 slaver_dout <= 0; 72 end //if 73 else begin 74 slaver_dout <= (cs_p) ? slaver_dout_reg : slaver_dout; 75 end //else 76 end //always 77 //sck negedge sample mosi; 78 always @(posedge clk or negedge rst_n) begin 79 if (~rst_n) begin 80 slaver_dout_reg <= 0; 81 end //if 82 else begin 83 slaver_dout_reg <= (sck_n) ? {slaver_dout_reg[6:0],mosi} : slaver_dout_reg; 84 end //else 85 end //always 86 //miso cnt; 87 always @(posedge clk or negedge rst_n) begin 88 if (~rst_n) begin 89 miso_cnt <= 0; 90 end 91 else begin 92 if (sck_p) begin 93 if (miso_cnt == MISO_CNT_MAX) begin 94 miso_cnt <= 0; 95 end 96 else begin 97 miso_cnt <= miso_cnt + 1'b1; 98 end 99 end 100 else begin 101 miso_cnt <= miso_cnt; 102 end 103 end 104 end 105 //sck posedge output the miso; 106 always @(posedge clk or negedge rst_n) begin 107 if (~rst_n) begin 108 miso <= 0; 109 end //if 110 else begin 111 miso <= (sck_p) ? slaver_din_reg[MISO_CNT_MAX-miso_cnt] : miso; 112 end //else 113 end //always 114 115 endmodule
以上。