-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspi_slave.v
79 lines (70 loc) · 1.56 KB
/
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
module spi_slave(
input clk,
input rst,
input ss,
input mosi,
output miso,
input sck,
output done,
input [7:0] din,
output [7:0] dout
);
reg mosi_d, mosi_q;
reg ss_d, ss_q;
reg sck_d, sck_q;
reg sck_old_d, sck_old_q;
reg [7:0] data_d, data_q;
reg done_d, done_q;
reg [2:0] bit_ct_d, bit_ct_q;
reg [7:0] dout_d, dout_q;
reg miso_d, miso_q;
assign miso = miso_q;
assign done = done_q;
assign dout = dout_q;
always @(*) begin
ss_d = ss;
mosi_d = mosi;
miso_d = miso_q;
sck_d = sck;
sck_old_d = sck_q;
data_d = data_q;
done_d = 1'b0;
bit_ct_d = bit_ct_q;
dout_d = dout_q;
if (ss_q) begin
bit_ct_d = 3'b0;
data_d = din;
miso_d = data_q[7];
end else begin
if (!sck_old_q && sck_q) begin // rising edge
data_d = {data_q[6:0], mosi_q};
bit_ct_d = bit_ct_q + 1'b1;
if (bit_ct_q == 3'b111) begin
dout_d = {data_q[6:0], mosi_q};
done_d = 1'b1;
data_d = din;
end
end else if (sck_old_q && !sck_q) begin // falling edge
miso_d = data_q[7];
end
end
end
always @(posedge clk) begin
if (rst) begin
done_q <= 1'b0;
bit_ct_q <= 3'b0;
dout_q <= 8'b0;
miso_q <= 1'b1;
end else begin
done_q <= done_d;
bit_ct_q <= bit_ct_d;
dout_q <= dout_d;
miso_q <= miso_d;
end
sck_q <= sck_d;
mosi_q <= mosi_d;
ss_q <= ss_d;
data_q <= data_d;
sck_old_q <= sck_old_d;
end
endmodule