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] - Blame information for rev 135

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 135 jt_eaton
module spi_slave(
2
 
3
 
4
                 input  wire        clk,
5
                 input  wire        reset,
6
                 input  wire        SCK,
7
                 input  wire        MOSI,
8
                 output wire        MISO,
9
                 input  wire        SSEL,
10
                 output reg   [15:0] rx_data,
11
                 input  wire  [15:0] tx_data
12
);
13
 
14
 
15
 
16
 
17
 
18
// sync SCK to the FPGA clock using a 3-bits shift register
19
reg [2:0] SCKr;  always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
20
 
21
wire SCK_risingedge  = (SCKr[2:1]==2'b01);  // now we can detect SCK rising edges
22
 
23
// same thing for SSEL
24
reg [2:0] SSELr;  always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
25
wire SSEL_active = ~SSELr[1];  // SSEL is active low
26
 
27
 
28
 
29
// and for MOSI
30
reg [1:0] MOSIr;  always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
31
wire MOSI_data = MOSIr[1];
32
// we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
33
reg [3:0] bitcnt;
34
 
35
reg byte_received;  // high when a byte has been received
36
reg [31:0] byte_data_received;
37
reg [15:0] byte_data_sent;
38
 
39
 
40
always @(posedge clk)
41
begin
42
  if(~SSEL_active)
43
    bitcnt <= 4'b0000;
44
  else
45
  if(SCK_risingedge)
46
  begin
47
    bitcnt <= bitcnt + 4'b0001;
48
  end
49
end
50
 
51
 
52
 
53
always @(posedge clk)
54
begin
55
  if(reset)
56
    byte_data_received <= 32'h00000000;
57
  else
58
  if(SCK_risingedge)
59
  begin
60
    // implement a shift-left register (since we receive the data MSB first)
61
    byte_data_received <= {byte_data_received[30:0], MOSI_data};
62
  end
63
  else
64
  begin
65
    // implement a shift-left register (since we receive the data MSB first)
66
    byte_data_received <= byte_data_received;
67
  end
68
end
69
 
70
 
71
 
72
 
73
 
74
 
75
 
76
 
77
 
78
 
79
always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==4'b1111);
80
 
81
// we use the LSB of the data received to control an LED
82
 
83
always @(posedge clk)
84
  if(reset )         rx_data <= 16'h0000;
85
 
86
  else
87
    begin
88
   if(byte_received) rx_data <= byte_data_received[15:0];
89
   else              rx_data <= rx_data;
90
   end
91
 
92
 
93
 
94
 
95
always @(posedge clk)
96
begin
97
  if(reset)
98
    byte_data_sent <= 16'h0000;
99
  else
100
  if(SCK_risingedge)
101
  begin
102
    // implement a shift-left register (since we receive the data MSB first)
103
    byte_data_sent <= {byte_data_sent[14:0], 1'b0};
104
  end
105
  else
106
    begin
107
 if(bitcnt == 4'b0000)
108
 
109
 
110
  begin
111
    // implement a shift-left register (since we receive the data MSB first)
112
    byte_data_sent <= tx_data;
113
  end
114
  else
115
 
116
  begin
117
    // implement a shift-left register (since we receive the data MSB first)
118
    byte_data_sent <= byte_data_sent;
119
  end
120
 
121
 end
122
 
123
end
124
 
125
 
126
 
127
 
128
 
129
 
130
 
131
assign MISO = byte_data_sent[15];  // send MSB first
132
 
133
// we assume that there is only one slave on the SPI bus
134
// so we don't bother with a tri-state buffer for MISO
135
// otherwise we would need to tri-state MISO when SSEL is inactive
136
 
137
endmodule

powered by: WebSVN 2.1.0

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