// // 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