summaryrefslogtreecommitdiff
path: root/spi_controller.v
diff options
context:
space:
mode:
Diffstat (limited to 'spi_controller.v')
-rw-r--r--spi_controller.v61
1 files changed, 61 insertions, 0 deletions
diff --git a/spi_controller.v b/spi_controller.v
new file mode 100644
index 0000000..33ad80a
--- /dev/null
+++ b/spi_controller.v
@@ -0,0 +1,61 @@
+`default_nettype none
+
+module spi_controller
+#(parameter CPOL = 0,
+ parameter CPHA = 0)
+ (input wire clk,
+ input wire rst,
+ input wire go,
+ input wire [7:0] i_data,
+ output reg [7:0] o_data = 8'h00,
+ output wire busy,
+
+ output wire spi_clk,
+ output wire spi_mosi,
+ input wire spi_miso);
+
+ reg [3:0] state = 4'h0;
+ reg [7:0] shift_o = 8'h00;
+ reg [7:0] shift_i = 8'h00;
+
+ wire [7:0] shifted_o = {shift_o[6:0], 1'b0};
+ wire [7:0] shifted_i = {shift_i[6:0], spi_miso};
+
+ assign busy = |state;
+ assign spi_mosi = shift_o[7];
+
+ wire spi_clk_v;
+ generate
+ if (CPOL) assign spi_clk_v = ~(busy && state[0]);
+ else assign spi_clk_v = (busy && state[0]);
+ endgenerate
+
+ generate
+ if (CPHA) assign spi_clk = spi_clk_v;
+ else begin
+ reg spi_clk_d = CPOL;
+ assign spi_clk = spi_clk_d;
+ always @(posedge clk)
+ spi_clk_d <= rst? CPOL : spi_clk_v;
+ end
+ endgenerate
+
+ always @(posedge clk) begin
+ if (rst) begin
+ shift_i <= 8'h00;
+ shift_o <= 8'h00;
+ o_data <= 8'h00;
+ state <= 4'h0;
+
+ end else if (state) begin
+ state <= state - 4'h1;
+ if (~state[0]) shift_o <= shifted_o;
+ if ( state[0]) shift_i <= shifted_i;
+ if (state == 4'h1) o_data <= shifted_i;
+
+ end else if (go) begin
+ state <= 4'hF;
+ shift_o <= i_data;
+ end
+ end
+endmodule