From 916c766dab5d169b8327aeb03fbcfc76e194f52e Mon Sep 17 00:00:00 2001 From: Alexis Hovorka Date: Fri, 28 Oct 2022 11:29:28 -0600 Subject: Initial commit --- .gitignore | 2 ++ Makefile | 15 ++++++++++++++ spi_controller.v | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ spi_tb.v | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 spi_controller.v create mode 100644 spi_tb.v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0545d5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.vvp +*.vcd diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a5df170 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +TESTBENCH := spi_tb +VCDFILE := main.vcd + +.PHONY: all clean + +all: $(VCDFILE) + +clean: + rm -rf $(TESTBENCH).vvp $(VCDFILE) + +$(VCDFILE): $(TESTBENCH).vvp + vvp $(TESTBENCH).vvp + +$(TESTBENCH).vvp: $(wildcard *.v) + iverilog -o $@ $^ 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 diff --git a/spi_tb.v b/spi_tb.v new file mode 100644 index 0000000..f042f8d --- /dev/null +++ b/spi_tb.v @@ -0,0 +1,57 @@ +`timescale 1ns/1ps + +module main; + reg clk = 0; + always #1 clk = ~clk; + + reg go = 0; + reg rst = 1; + reg [7:0] i_data = 8'hAA; + wire [7:0] o_data; + wire busy; + + wire spi_clk; + wire spi_mosi; + reg spi_miso = 0; + + spi_controller dut( + .clk(clk), .rst(rst), .go(go /*& ~busy*/), + .i_data(i_data), .o_data(o_data), + .busy(busy), + + .spi_clk(spi_clk), + .spi_mosi(spi_mosi), + .spi_miso(spi_miso)); + + initial begin + $dumpfile("main.vcd"); + $dumpvars(2, main); + + //$display("Hello world!"); + //$monitor("T%03d | clk: %0d", $time, clk); + + #2 rst = 0; + go = 1; + #2 go = 0; + + #3 spi_miso = 1; + #4 spi_miso = 0; + #4 spi_miso = 1; + #4 spi_miso = 0; + #4 spi_miso = 1; + #4 spi_miso = 0; + #4 spi_miso = 1; + #4 spi_miso = 0; + #4 spi_miso = 1; + #4 spi_miso = 0; + #4 spi_miso = 1; + + #32 $finish; + end + + initial begin + #34 i_data = 8'h55; + go = 1; + #2 go = 0; + end +endmodule -- cgit v1.2.3-54-g00ecf