OpenCores
URL https://opencores.org/ocsvn/socgen/socgen/trunk

Subversion Repositories socgen

[/] [socgen/] [trunk/] [Projects/] [opencores.org/] [logic/] [ip/] [spi_interface/] [rtl/] [verilog/] [spi_slave.v] - Rev 135

Compare with Previous | Blame | View Log

module spi_slave(
 
 
		 input  wire 	    clk,
		 input  wire 	    reset,
		 input  wire 	    SCK,
		 input  wire 	    MOSI,
		 output wire 	    MISO, 
		 input  wire 	    SSEL,
		 output reg   [15:0] rx_data,
		 input  wire  [15:0] tx_data
);
 
 
 
 
 
// 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
 
// 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
 
 
 
// and for MOSI
reg [1:0] MOSIr;  always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
wire MOSI_data = MOSIr[1];
// we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
reg [3:0] bitcnt;
 
reg byte_received;  // high when a byte has been received
reg [31:0] byte_data_received;
reg [15:0] byte_data_sent;
 
 
always @(posedge clk)
begin
  if(~SSEL_active)
    bitcnt <= 4'b0000;
  else
  if(SCK_risingedge)
  begin
    bitcnt <= bitcnt + 4'b0001;
  end
end
 
 
 
always @(posedge clk)
begin
  if(reset)
    byte_data_received <= 32'h00000000;
  else
  if(SCK_risingedge)
  begin
    // implement a shift-left register (since we receive the data MSB first)
    byte_data_received <= {byte_data_received[30:0], MOSI_data};
  end
  else
  begin
    // implement a shift-left register (since we receive the data MSB first)
    byte_data_received <= byte_data_received;
  end
end
 
 
 
 
 
 
 
 
 
 
always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==4'b1111);
 
// we use the LSB of the data received to control an LED
 
always @(posedge clk)
  if(reset )         rx_data <= 16'h0000;
 
  else
    begin
   if(byte_received) rx_data <= byte_data_received[15:0];
   else              rx_data <= rx_data;
   end
 
 
 
 
always @(posedge clk)
begin
  if(reset)
    byte_data_sent <= 16'h0000;
  else
  if(SCK_risingedge)
  begin
    // implement a shift-left register (since we receive the data MSB first)
    byte_data_sent <= {byte_data_sent[14:0], 1'b0};
  end
  else
    begin
 if(bitcnt == 4'b0000)
 
 
  begin
    // implement a shift-left register (since we receive the data MSB first)
    byte_data_sent <= tx_data;
  end
  else
 
  begin
    // implement a shift-left register (since we receive the data MSB first)
    byte_data_sent <= byte_data_sent;
  end
 
 end
 
end
 
 
 
 
 
 
 
assign MISO = byte_data_sent[15];  // send MSB first
 
// we assume that there is only one slave on the SPI bus
// so we don't bother with a tri-state buffer for MISO
// otherwise we would need to tri-state MISO when SSEL is inactive
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.