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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
//
// Copyright 2015 Ettus Research LLC
//
`ifndef LOG2
`define LOG2(N) (\
N < 2 ? 0 : \
N < 4 ? 1 : \
N < 8 ? 2 : \
N < 16 ? 3 : \
N < 32 ? 4 : \
N < 64 ? 5 : \
N < 128 ? 6 : \
N < 256 ? 7 : \
N < 512 ? 8 : \
N < 1024 ? 9 : \
10)
`endif
module spi_slave
#(
parameter DEPTH = 64
)
(
// sys connect
input clk,
input rst,
// spi slave port
input ss,
input mosi,
output miso,
input sck,
// parallel data io port
output parallel_stb,
input [DEPTH-1:0] parallel_din,
output [DEPTH-1:0] parallel_dout
);
reg mosi_d, mosi_q;
reg ss_d, ss_q;
reg sck_d, sck_q;
reg sck_old_d, sck_old_q;
reg miso_d, miso_q;
reg [DEPTH-1:0] data_d, data_q;
reg parallel_stb_d, parallel_stb_q;
reg [`LOG2(DEPTH)-1:0] bit_ct_d, bit_ct_q;
reg [DEPTH-1:0] parallel_dout_d, parallel_dout_q;
assign miso = miso_q;
assign parallel_stb = parallel_stb_q;
assign parallel_dout = parallel_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;
parallel_stb_d = 1'b0;
bit_ct_d = bit_ct_q;
parallel_dout_d = parallel_dout_q;
if (ss_q) begin
bit_ct_d = 'h0;
data_d = parallel_din;
miso_d = data_q[DEPTH-1];
end
else begin
if (!sck_old_q && sck_q) begin // rising edge
data_d = {data_q[DEPTH-1-1:0], mosi_q};
bit_ct_d = bit_ct_q + 1'b1;
if (bit_ct_q == (DEPTH - 1)) begin
parallel_dout_d = {data_q[DEPTH-1-1:0], mosi_q};
parallel_stb_d = 1'b1;
data_d = parallel_din;
end
end
else if (sck_old_q && !sck_q) begin // falling edge
miso_d = data_q[DEPTH-1];
end
end
end
always @(posedge clk) begin
if (rst) begin
parallel_stb_q <= 1'b0;
bit_ct_q <= 'h0;
parallel_dout_q <= 'h0;
miso_q <= 1'b1;
end else begin
parallel_stb_q <= parallel_stb_d;
bit_ct_q <= bit_ct_d;
parallel_dout_q <= parallel_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
|