Skip to content

Commit

Permalink
rewrote entire SPI code
Browse files Browse the repository at this point in the history
  • Loading branch information
faramire committed Apr 18, 2024
1 parent c667465 commit 9e11362
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 2 deletions.
88 changes: 88 additions & 0 deletions src/SPI_master.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2024 Fabio Ramirez Stern
* SPDX-License-Identifier: Apache-2.0
*/

module SPI_Master (
input wire clk,
input wire res,
input wire cs_in, // CS input
input wire [15:0] word_in, // word to be sent

output reg sck, // serial clock
output reg mosi, // MOSI
output reg report_send, // data has been sent, CS can be pulled high
output reg report_ready // ready for next transmission
);

// FSM states
localparam IDLE = 2'b00;
localparam TRANSFER = 2'b01;
localparam DONE = 2'b10;

reg [1:0] state;
reg [1:0] count_bit; // count through the clock cylce: negedge, hold high (sample), negedge (set)
reg [3:0] count_word; // count through the bits of the word
reg [15:0] word_out;


always @(posedge clk or negedge res) begin
if (!res) begin // async reset, active low
sck <= 0;
mosi <= 0;
count_bit <= 0;
count_word <= 0;
word_out <= 16'b0;
report_send <= 0;
report_ready <= 0;
state <= IDLE;
end else begin
// FSM
case(state)

IDLE: begin
if (cs_in == 0) begin
sck <= 0;
mosi <= 0;
count_bit <= 0;
count_word <= 0;
word_out <= word_in;
report_send <= 1;
report_ready <= 1;
state <= TRANSFER;
end
end // IDLE

TRANSFER: begin
if (count_word == 0) begin // end of word?
state <= DONE;
end

// send out data on MOSI
if (count_bit == 0) begin
mosi <= word_out[count_word];
/* mosi <= word_out[15]; // or shift out?
word_out <= word_out << 1; */
count_word <= count_word - 2'b01;

end

// generate serial clock
if (count_bit == 1) begin
sck <= 1;
end

count_bit <= count_bit + 2'b01;
end // TRANSFER

DONE: begin
if (cs_in == 1) begin
state <= IDLE;
end
end // DONE

endcase
end
end

endmodule
141 changes: 141 additions & 0 deletions src/SPI_wrapper.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2024 Fabio Ramirez Stern
* SPDX-License-Identifier: Apache-2.0
*/
`include "SPI_master.v"
module SPI_wrapper (
input wire clk, // 1 MHz clock to run the FSM and other loops
input wire clk_div, // 100 Hz clock to trigger a time to be send out
input wire res, // reset, active low
input wire ena,

input wire [2:0] min_X0, // minutes
input wire [3:0] min_0X,
input wire [2:0] sec_X0, // seconds
input wire [3:0] sec_0X,
input wire [3:0] ces_X0, // centiseconds (100th)
input wire [3:0] ces_0X,

output wire Mosi,
output reg Cs,
output wire Clk_SPI
);

// FSM
reg [1:0] state;
localparam SETUP = 2'b00;
localparam IDLE = 2'b01;
localparam TRANSFER = 2'b10;
localparam DONE = 2'b11;

reg [15:0] word_out;
reg [2:0] digit_count;
reg [1:0] setup_count;
wire send_reported;
wire ready_reported;

always @(posedge clk or negedge res) begin // controlling FSM
if (!res) begin // active low reset
Cs <= 1;
word_out <= 16'b0;
digit_count <= 3'b0;
state <= SETUP;
end
case(state)

SETUP: begin // send a setup packet enabling BCD
if (res) begin
if (ready_reported == 1) begin
word_out <= 16'b0000_1001_1111_1111; // address = decode mode, data = BCD for all
Cs <= 0;
end
else if (send_reported == 1) begin // data send, Cs can be pulled high again
Cs <= 1;
state <= IDLE;
end
end
end // SETUP

IDLE: begin
if (clk_div & ena) begin // wait for the 100Hz clock to get high
digit_count <= 3'b000;
state <= TRANSFER;
end
end // IDLE
TRANSFER: begin

if (ready_reported == 1) begin // wait for TX ready
case(digit_count)

3'b000: begin // ces_0X
word_out <= {8'b0000_0001, 8'b0000_0000 | ces_0X}; // send the 16-bit word
Cs <= 0; // pull CS low to initiate send
digit_count <= 3'b001; // advance the position counter
end

3'b001: begin // ces_X0
word_out <= {8'b0000_0010, 8'b0000_0000 | ces_X0};
Cs <= 0;
digit_count <= 3'b010;
end

3'b010: begin // sec_0X
word_out <= {8'b0000_0011, 8'b0000_0000 | sec_0X};
Cs <= 0;
digit_count <= 3'b011;
end

3'b011: begin // sec_X0
word_out <= {8'b0000_0100, 8'b0000_0000 | sec_X0};
Cs <= 0;
digit_count <= 3'b100;
end

3'b100: begin // min_0X
word_out <= {8'b0000_0101, 8'b0000_0000 | min_0X};
Cs <= 0;
digit_count <= 3'b101;
end

3'b101: begin // min_X0
word_out <= {8'b0000_0110, 8'b0000_0000 | min_X0};
Cs <= 0;
digit_count <= 3'b110;
end

3'b110: begin // once send has been complete and CS is high again, switch state
state <= DONE;
end

default:digit_count <= 3'b000;
endcase

end else if (send_reported == 1) begin // once data has been send, pull CS high
Cs <= 1;
end
end // TRANSFER

DONE: begin // wait for the 100 Hz clock to go low again
if (!clk_div) begin
state <= IDLE;
end
end // DONE

default:state <= SETUP;
endcase
end

SPI_Master SPI_Master1 (
.clk(clk),
.res(res),
.cs_in(Cs),
.word_in(word_out),

.report_send(send_reported),
.report_ready(ready_reported),

.sck(clk_SPI),
.mosi(Mosi)
);

endmodule // SPI_wrapper
4 changes: 2 additions & 2 deletions src/stopwatch_top.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

// ui_in [0]: reset: resets the stopwatch to 00:00:00
// ui_in [1]: speed:

`include "SPI_wrapper.v"
module tt_um_faramire_stopwatch (
input wire [7:0] ui_in, // Dedicated inputs
output wire [7:0] uo_out, // Dedicated outputs
Expand Down Expand Up @@ -82,7 +82,7 @@ module tt_um_faramire_stopwatch (
.ces_0X (ces_0X),
.Mosi (uo_out[0]), // MOSI on out 0
.Cs (uo_out[1]), // CS on out 1
.clk_SPI (uo_out[2]) // CLK on out 3
.Clk_SPI (uo_out[2]) // CLK on out 3
);

endmodule // tt_um_faramire_stopwatch
Expand Down

0 comments on commit 9e11362

Please sign in to comment.