Files
CGA-bench/data/myproject/clean/spi_controller_clean.v

136 lines
3.9 KiB
Coq
Raw Normal View History

2026-05-22 10:02:42 +08:00
`timescale 1ns/1ps
module spi_controller (
input clk,
input rst_n,
input [7:0] data_in,
input start,
input cpol,
input cpha,
output reg [7:0] data_out,
output reg busy,
output reg spi_clk,
output reg mosi,
input miso
);
localparam IDLE = 3'd0;
localparam LOAD = 3'd1;
localparam LEAD = 3'd2;
localparam SAMPLE = 3'd3;
localparam SHIFT = 3'd4;
localparam DONE = 3'd5;
localparam ERROR = 3'd6;
reg [2:0] state;
reg [2:0] bit_count;
reg [7:0] tx_shift;
reg [7:0] rx_shift;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
bit_count <= 3'd0;
tx_shift <= 8'd0;
rx_shift <= 8'd0;
data_out <= 8'd0;
busy <= 1'b0;
spi_clk <= 1'b0;
mosi <= 1'b0;
end else begin
case (state)
IDLE: begin
busy <= 1'b0;
spi_clk <= cpol;
mosi <= 1'b0;
if (start) begin
busy <= 1'b1;
bit_count <= 3'd7;
tx_shift <= data_in;
rx_shift <= 8'd0;
state <= LOAD;
end
end
LOAD: begin
busy <= 1'b1;
spi_clk <= cpol;
mosi <= tx_shift[7];
if (start) begin
state <= ERROR;
end else begin
state <= LEAD;
end
end
LEAD: begin
busy <= 1'b1;
spi_clk <= ~cpol;
if (start) begin
state <= ERROR;
end else if (!cpha) begin
rx_shift <= {rx_shift[6:0], miso};
if (bit_count == 3'd0) begin
data_out <= {rx_shift[6:0], miso};
state <= DONE;
end else begin
state <= SHIFT;
end
end else begin
state <= SAMPLE;
end
end
SAMPLE: begin
busy <= 1'b1;
spi_clk <= ~cpol;
if (start) begin
state <= ERROR;
end else begin
rx_shift <= {rx_shift[6:0], miso};
if (bit_count == 3'd0) begin
data_out <= {rx_shift[6:0], miso};
state <= DONE;
end else begin
state <= SHIFT;
end
end
end
SHIFT: begin
busy <= 1'b1;
spi_clk <= cpol;
tx_shift <= {tx_shift[6:0], 1'b0};
bit_count <= bit_count - 1'b1;
mosi <= tx_shift[6];
if (start) begin
state <= ERROR;
end else begin
state <= LEAD;
end
end
DONE: begin
busy <= 1'b0;
spi_clk <= cpol;
mosi <= 1'b0;
if (start) begin
state <= ERROR;
end else begin
state <= IDLE;
end
end
default: begin
busy <= 1'b0;
spi_clk <= cpol;
mosi <= 1'b0;
if (!start) begin
state <= IDLE;
end
end
endcase
end
end
endmodule