aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/e31x/spi_slave.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/e31x/spi_slave.v')
-rw-r--r--fpga/usrp3/top/e31x/spi_slave.v107
1 files changed, 107 insertions, 0 deletions
diff --git a/fpga/usrp3/top/e31x/spi_slave.v b/fpga/usrp3/top/e31x/spi_slave.v
new file mode 100644
index 000000000..d8d48115d
--- /dev/null
+++ b/fpga/usrp3/top/e31x/spi_slave.v
@@ -0,0 +1,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