spi slaver接口的fpga实现

前言

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

 

以上。

 

posted @ 2017-09-07 20:17  小翁同学  阅读(1901)  评论(0编辑  收藏  举报