68 lines
1.6 KiB
Coq
68 lines
1.6 KiB
Coq
|
|
module spi_master_esp32(
|
|||
|
|
input wire clk,
|
|||
|
|
input wire rst_n,
|
|||
|
|
input wire start,
|
|||
|
|
input wire [15:0] din,
|
|||
|
|
output reg done,
|
|||
|
|
output wire sclk,
|
|||
|
|
output wire mosi,
|
|||
|
|
output reg cs
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
reg [3:0] bit_cnt;
|
|||
|
|
reg [15:0] shift_reg;
|
|||
|
|
reg sclk_reg;
|
|||
|
|
reg [1:0] state;
|
|||
|
|
|
|||
|
|
localparam IDLE = 2'b00, TRANSFER = 2'b01, DONE = 2'b10;
|
|||
|
|
|
|||
|
|
assign sclk = sclk_reg;
|
|||
|
|
assign mosi = shift_reg[15];
|
|||
|
|
|
|||
|
|
always @(posedge clk or negedge rst_n) begin
|
|||
|
|
if (!rst_n) begin
|
|||
|
|
state <= IDLE;
|
|||
|
|
cs <= 1;
|
|||
|
|
sclk_reg <= 0;
|
|||
|
|
bit_cnt <= 0;
|
|||
|
|
shift_reg <= 0;
|
|||
|
|
done <= 0;
|
|||
|
|
end
|
|||
|
|
else begin
|
|||
|
|
|
|||
|
|
if (start) begin
|
|||
|
|
case (state)
|
|||
|
|
IDLE: begin
|
|||
|
|
|
|||
|
|
|
|||
|
|
state <= TRANSFER;
|
|||
|
|
cs <= 0; // 选择从机
|
|||
|
|
shift_reg <= din;
|
|||
|
|
bit_cnt <= 0;
|
|||
|
|
done <= 0;
|
|||
|
|
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
TRANSFER: begin
|
|||
|
|
sclk_reg <= ~sclk_reg; //这样也是一个系统时钟周期新的sclk反转一次,所以sclk的频率也是115200.
|
|||
|
|
if (sclk_reg) begin //看上面的assign mosi = shift_reg[15]; 所以每个sclk高电平mosi输出要输出的值。
|
|||
|
|
shift_reg <= {shift_reg[14:0], 1'b0};
|
|||
|
|
bit_cnt <= bit_cnt + 1;
|
|||
|
|
if (bit_cnt == 15) begin
|
|||
|
|
state <= DONE;
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
DONE: begin
|
|||
|
|
state <= IDLE;
|
|||
|
|
cs <= 1; // 取消选择从机
|
|||
|
|
done <= 1;
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
endcase
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
endmodule
|