most of the way there

This commit is contained in:
2025-07-10 22:10:05 +01:00
parent 9f12c776ee
commit 55fb8e3be4
4 changed files with 726 additions and 543 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
module spi_master (
input wire clk,
output reg spi_clk = 0,
input wire start, // Pulse high to begin transfer
input reg [7:0] data_out = 8'd0,
output reg spi_mosi = 0,
output wire [7:0] data_in,
input wire spi_miso,
output reg busy = 0,
output reg spi_cs = 1 // Active low
);
// SPI Mode 0: CPOL = 0, CPHA = 0 (drive on falling, sample on rising)
reg [3:0] bit_cnt = 0;
reg [7:0] shift_reg_in = 0;
reg [7:0] shift_reg_out = 0;
typedef enum logic [1:0] {
IDLE,
CHIP_SEL,
BUSY,
DONE
} state_t;
state_t state = IDLE;
always @(posedge clk) begin
case (state)
IDLE: begin
spi_cs <= 1;
spi_clk <= 0;
busy <= 0;
if (start) begin
state <= CHIP_SEL;
shift_reg_out <= data_out;
bit_cnt <= 0;
end
end
// data is one cycle after CS is brought low
CHIP_SEL: begin
spi_cs <= 0;
busy <= 1;
state <= BUSY;
end
BUSY: begin
if (clk) begin
spi_clk <= ~spi_clk;
// Falling, drive data
if (!spi_clk) begin
spi_mosi <= shift_reg_out[7];
shift_reg_out <= {shift_reg_out[6:0], 1'b0};
end else begin
// Rising, sample data
shift_reg_in <= {shift_reg_in[6:0], spi_miso};
bit_cnt <= bit_cnt + 1;
if (bit_cnt == 7) begin
state <= DONE;
end
end
end
end
DONE: begin
spi_cs <= 1;
data_in <= {shift_reg_in[6:0], spi_miso};
state <= IDLE;
end
endcase
end
endmodule

View File

@@ -1,62 +1,36 @@
module top ( module top (
input wire clk_25mhz, input wire clk_25mhz,
output wire spi_clk, output wire spi_clk,
output wire spi_mosi, output wire spi_mosi,
input wire spi_miso, input wire spi_miso,
output wire spi_cs output wire spi_cs
); );
reg[7:0] miso; // we would prefer fifo
reg[7:0] mosi = 8'b01101011; wire[7:0] miso;
wire[7:0] mosi = 8'b01101011;
reg busy = 0;
reg start = 0;
always @(posedge clk_25mhz) begin
start <= 0;
if (!busy && !start) begin
start <= 1;
end
end
spi_master spimaster0( spi_master spimaster0(
.clk_25mhz(clk_25mhz), .clk(clk_25mhz),
.spi_clk(spi_clk), .spi_clk(spi_clk),
.data_in(mosi), .start(start),
.spi_miso(spi_miso),
.data_out(mosi), .data_out(mosi),
.spi_mosi(spi_mosi), .spi_mosi(spi_mosi),
.data_in(miso),
.spi_miso(spi_miso),
.busy(busy),
.spi_cs(spi_cs) .spi_cs(spi_cs)
); );
endmodule endmodule
module spi_master (
input wire clk_25mhz,
output reg spi_clk = 0,
output reg[7:0] data_in,
output reg spi_miso = 0,
input reg[7:0] data_out,
input reg spi_mosi = 0,
output wire spi_cs
);
assign spi_cs = 0; // Always selected (for test)
reg [7:0] mosi_shift = 8'b01101011; // Example byte
reg [3:0] bit_counter = 0;
reg spi_clk_en = 1;
localparam TRANSFERRING = 0, IDLE = 1;
wire spi_state = IDLE;
always_ff @(posedge clk_25mhz) begin
spi_clk <= ~spi_clk;
if (spi_clk == 0) begin
// Falling edge: shift data
spi_mosi <= mosi_shift[7];
mosi_shift <= {mosi_shift[6:0], 1'b0};
bit_counter <= bit_counter + 1;
end
end
endmodule

File diff suppressed because it is too large Load Diff