-
Notifications
You must be signed in to change notification settings - Fork 0
/
old_spi_slave.v
82 lines (64 loc) · 2.08 KB
/
old_spi_slave.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module old_spi_slave (
input clk,
input SCK,
input SSEL,
input MOSI,
output MISO,
output byte_avilable,
output [7:0] data_received,
output start_message,
output end_message,
output active,
input [7:0] byte_to_send
);
// 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];
// we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
reg [2:0] bitcnt;
reg byte_received; // high when a byte has been received
reg [7:0] byte_data_received;
assign byte_avilable = byte_received;
assign data_received = byte_data_received;
assign start_message = SSEL_startmessage;
assign end_message = SSEL_endmessage;
assign active = SSEL_active;
always @(posedge clk)
begin
if(~SSEL_active)
bitcnt <= 3'b000;
else
if(SCK_risingedge)
begin
bitcnt <= bitcnt + 3'b001;
// implement a shift-left register (since we receive the data MSB first)
byte_data_received <= {byte_data_received[6:0], MOSI_data};
end
end
always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
reg [7:0] byte_data_sent;
always @(posedge clk)
if(SSEL_active)
begin
if(SSEL_startmessage)
byte_data_sent <= byte_to_send; // first byte sent in a message is the message count
else
if(SCK_fallingedge)
begin
if(bitcnt==3'b000)
byte_data_sent <= 8'h00; // after that, we send 0s
else
byte_data_sent <= {byte_data_sent[6:0], 1'b0};
end
end
assign MISO = byte_data_sent[7]; // send MSB first
endmodule