Verilog HDL编写SPI Slave通信

来源:互联网 发布:淘宝客佣金查看 编辑:程序博客网 时间:2024/04/30 09:55

module SPI_Slave(
                 clk,   //system clock 50MHz
                 SCK, SSEL, MOSI,MISO//SPI communication pin   

                 );
 input SCK, SSEL, MOSI;
 output MISO;
 
 // sync SCK to the FPGA clock using a 3-bits shift register
 reg [2:0] SCKr; 
 always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
 wire SCK_risingedge = (SCKr[2:1]==2'b01);  // now we can detect SCK rising edges
 wire SCK_fallingedge = (SCKr[2:1]==2'b10);  // and falling edges

 // same thing for SSEL
 reg [2:0] SSELr; 
 always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
 wire SSEL_active = ~SSELr[1];  // SSEL is active low
 wire SSEL_startmessage = (SSELr[2:1]==2'b10);  // message starts at falling edge
 wire SSEL_endmessage = (SSELr[2:1]==2'b01);  // message stops at rising edge

 // and for MOSI
 reg [1:0] MOSIr; 
 always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
 wire MOSI_data = MOSIr[1];
 reg [2:0] bitcnt;  // we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
//-------------------receive data-------------------------------------------------

 reg byte_received;  // high when a byte has been received
 reg [7:0] byte_data_received,rev_data;

 reg [7:0] byte_data_sent,sent_data;

  always @(posedge clk)
  begin
   if( SSEL_active )
   begin
    if(SSEL_startmessage)
     byte_data_sent <= sent_data;
   end  
    if(~SSEL_active)
   begin
    bitcnt <= 3'b000;
    byte_data_sent <= 8'h00;  // after that, we send 0s///////////
   end
    else
   if(SCK_risingedge)
     begin
    bitcnt <= bitcnt + 3'b001;
    byte_data_received <= {byte_data_received[6:0], MOSI_data};  // implement a shift-left

                                                  //register (since we receive the data MSB first)
    byte_data_sent <= {byte_data_sent[6:0], 1'b0};///////////

     end
  end
 always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);

//-----------------------receive data---------------------

 always @(posedge clk)
   if(byte_received)
   begin
     rev_data <= byte_data_received;

   end

 //-----------------------send data----------------------
 assign MISO = byte_data_sent[7];  // send MSB first
endmodule

0 0
原创粉丝点击