From 4ac5fabbabe570cfbfec249f4621e642cf3cb3b4 Mon Sep 17 00:00:00 2001 From: faramire Date: Wed, 17 Apr 2024 02:03:47 +0200 Subject: [PATCH] trying something new --- src/SPI_Master_With_Single_CS.v | 6 ++ src/SPI_driver.v | 125 +++++++++++++++++++------------- src/SPI_wrapper.v | 69 ++++++++++++++++++ src/clockdivider.v | 6 +- src/controller.v | 4 +- src/counter10.v | 11 ++- src/counter6.v | 11 ++- src/counter_chain.v | 12 +-- src/stopwatch_top.v | 30 ++++++-- 9 files changed, 193 insertions(+), 81 deletions(-) create mode 100644 src/SPI_wrapper.v diff --git a/src/SPI_Master_With_Single_CS.v b/src/SPI_Master_With_Single_CS.v index 49dbcf8..19ec4a0 100644 --- a/src/SPI_Master_With_Single_CS.v +++ b/src/SPI_Master_With_Single_CS.v @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2019 russell-merrick + * SPDX-License-Identifier: MIT + * https://github.com/nandland/spi-master + */ + /////////////////////////////////////////////////////////////////////////////// // Description: SPI (Serial Peripheral Interface) Master // With single chip-select (AKA Slave Select) capability diff --git a/src/SPI_driver.v b/src/SPI_driver.v index 5cf2611..b5693cd 100644 --- a/src/SPI_driver.v +++ b/src/SPI_driver.v @@ -5,78 +5,99 @@ `define default_netname none -module SPI_driver ( - input wire clk, - input wire clk_div, - input wire res, +module SPI_FSM ( // an FSM that stores and controls the transmission modes (reset, i) + 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 wire CS, - output wire clk_SPI + + output reg MOSI, + output reg CS, + output reg clk_SPI ); - reg [1:0] state; // FSM - localparam Reset = 2'b00; - localparam Init = 2'b01; - localparam Idle = 2'b10; - localparam Send = 2'b11; + reg send_init; // send a setup signal to the MAX display controller (enables BCD mode) + reg init_complete; // goes high once the setup signal has been fully send + reg init_reset; // sets init_complete back to 0 - wire send_order; // goes high to order a send - wire [15:0] data_send; // SPI data to be send, [11:8] is address, [7:0] is data - wire done_order; // goes high to signal end of send + reg send_time; // send the current time to the display, from the FSM + wire send_time_ena; // AND of the FSM order and the 100 Hz clock + assign send_time_ena = send_time & clk_div; + reg [2:0] current_digit; - reg [3:0] bit_send; // counts through bits - reg [2:0] digit; // counts through digits to be send + reg send_word; // send the word in out_word + reg send_is_busy; + reg [15:0] out_word; + reg [3:0] current_bit; + + // FSM + reg [1:0] state; + localparam Reset = 2'b00; + localparam Init = 2'b01; + localparam Time = 2'b10; - always @(posedge clk_div or negedge res) begin - if (!res) begin + always @(posedge clk_div or negedge res) begin // FSM + if (!res) begin // active low reset state <= Reset; - end else begin - Case(state) - Reset: begin - send_order <= 0; - done_order <= 0; - bit_send <= 0; - digit <= 0; - CS <= 1; - MOSI <= 0; - clk_SPI <= 0; - if (res) begin - state <= Init; - end + end + Case(state) + Reset: begin + send_time <= 1'b0; + send_init <= 1'b0; + init_reset <= 1'b1; + if (res) begin // once res goes high again: switch to Init + state <= Init; + init_reset <= 1'b0; end - - Init: begin - - state <= Idle; + end + + Init: begin + send_init <= 1'b1; + if (init_complete) begin + send_init <= 1'b0; + state <= Time; end + end - Idle: begin - if (ena) begin - state <= Send; - end - end + Time: begin + send_time <= 1'b1; + end + + default:; + endcase + end - Send: begin - if (!ena) begin - state <= Idle; - end else begin + always @(posedge send_init) begin // creates init to be send + if (send_init & !init_complete) begin + out_word <= 16'b0000100111111111; + send_word <= 1'b1; + end + end - end - end - default:; - endcase - end + always @(posedge send_time_ena) begin + current_digit <= 3'b0; end - always @(posedge send_order) begin - CS <= 0; + always @(posedge clk or posedge init_reset) begin // sends the word + if (init_reset) begin + init_complete <= 1'b0; + end + if (send_word) begin + send_is_busy <= 1'b1; + CS + end + else begin + CS <= 1'b1; + MOSI <= 1'b0; + clk_SPI_enable <= 1'b0; + end end endmodule diff --git a/src/SPI_wrapper.v b/src/SPI_wrapper.v new file mode 100644 index 0000000..fbec068 --- /dev/null +++ b/src/SPI_wrapper.v @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Fabio Ramirez Stern + * SPDX-License-Identifier: Apache-2.0 + */ + +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 reg MOSI, + output reg CS, + output reg clk_SPI +); + +// FSM + reg [1:0] state; + localparam Reset = 2'b00; + localparam Init = 2'b01; + localparam Time = 2'b10; + + always @(posedge clk_div or negedge res) begin // FSM + if (!res) begin // active low reset + state <= Reset; + end + Case(state) + Reset: begin + send_time <= 1'b0; + send_init <= 1'b0; + init_reset <= 1'b1; + if (res) begin // once res goes high again: switch to Init + state <= Init; + init_reset <= 1'b0; + end + end + + Init: begin + send_init <= 1'b1; + if (init_complete) begin + send_init <= 1'b0; + state <= Time; + end + end + + Time: begin + send_time <= 1'b1; + end + + default:; + endcase + end + + + + + SPI_Master_With_Single_CS SPI_Master1 ( + .i_Rst_L(res) + .i_Clk(clk) + ); + +endmodule \ No newline at end of file diff --git a/src/clockdivider.v b/src/clockdivider.v index b849d5e..a0a1922 100644 --- a/src/clockdivider.v +++ b/src/clockdivider.v @@ -19,12 +19,12 @@ module clockDivider ( always @(posedge clk_in or negedge res) begin if (!res) begin // async reset - counter <= 0; - clk_out <= 0; + counter <= 14'b0; + clk_out <= 1'b0; end else if (counter < (div-1)) begin // count up counter <= counter + 1; end else begin // reset counter and invert output - counter <= 0; + counter <= 1'b0; clk_out <= ~clk_out; end end diff --git a/src/controller.v b/src/controller.v index e88218e..b5726f1 100644 --- a/src/controller.v +++ b/src/controller.v @@ -15,14 +15,14 @@ module controller ( always @(posedge start_stop or negedge res) begin if (!res) - counter_enable <= 0; + counter_enable <= 1'b0; else counter_enable <= ~counter_enable; end always @(posedge lap_time or negedge res) begin if (!res) - display_enable <= 1; + display_enable <= 1'b1; else display_enable <= ~display_enable; end diff --git a/src/counter10.v b/src/counter10.v index 783364e..349e2ff 100644 --- a/src/counter10.v +++ b/src/counter10.v @@ -15,24 +15,23 @@ module counter10 ( output reg [3:0] cnt // 3 bit counter output ); - reg[3:0] counter = 0; parameter max_count = 10; always @(posedge clk or negedge res) begin if (!res) begin - cnt <= 0; - max <= 0; + cnt <= 4'b0; + max <= 1'b0; end else if (ena) begin if (cnt < (max_count-1)) begin cnt <= cnt + 1; end else begin - cnt <= 0; + cnt <= 4'b0; end if (cnt == max_count-2) begin - max <= 1; + max <= 1'b1; end else begin - max <= 0; + max <= 1'b0; end end end diff --git a/src/counter6.v b/src/counter6.v index 75d5eba..271474b 100644 --- a/src/counter6.v +++ b/src/counter6.v @@ -15,24 +15,23 @@ module counter6 ( output reg [2:0] cnt // 3 bit counter output ); - reg[2:0] counter = 0; parameter max_count = 6; always @(posedge clk or negedge res) begin if (!res) begin - cnt <= 0; - max <= 0; + cnt <= 3'b0; + max <= 1'b0; end else if (ena) begin if (cnt < (max_count-1)) begin cnt <= cnt + 1; end else begin - cnt <= 0; + cnt <= 3'b0; end if (cnt == max_count-2) begin - max <= 1; + max <= 1'b1; end else begin - max <= 0; + max <= 1'b0; end end end diff --git a/src/counter_chain.v b/src/counter_chain.v index 8634030..ebc7e09 100644 --- a/src/counter_chain.v +++ b/src/counter_chain.v @@ -10,12 +10,12 @@ module counter_chain ( input wire ena, input wire res, // the X denotes which digit the counter drives - output wire [3:0] ces_0X, // centiseconds (100th) - output wire [3:0] ces_X0, - output wire [3:0] sec_0X, // seconds - output wire [2:0] sec_X0, - output wire [3:0] min_0X, // minutes - output wire [2:0] min_X0 + output reg [3:0] ces_0X, // centiseconds (100th) + output reg [3:0] ces_X0, + output reg [3:0] sec_0X, // seconds + output reg [2:0] sec_X0, + output reg [3:0] min_0X, // minutes + output reg [2:0] min_X0 ); wire ces_X0_ena; diff --git a/src/stopwatch_top.v b/src/stopwatch_top.v index 162e96a..a735218 100644 --- a/src/stopwatch_top.v +++ b/src/stopwatch_top.v @@ -9,7 +9,9 @@ `include "counter6.v" `include "counter10.v" `include "counter_chain.v" -`include "SPI_driver.v" +`include "SPI_wrapper.v" +`include "SPI_Master_With_single_CS.v" +//`include "SPI_driver.v" // ui_in [0]: reset: resets the stopwatch to 00:00:00 // ui_in [1]: speed: @@ -74,7 +76,7 @@ module tt_um_faramire_stopwatch ( .ces_0X (ces_0X) ); - SPI_driver SPI_driver ( // drives the 7-segment displays connected via a MAX7219 chip over SPI + SPI_wrapper SPI_wrapper1 ( .clk (clk), .res (rst_n), .ena (display_enable), @@ -85,9 +87,25 @@ module tt_um_faramire_stopwatch ( .sec_0X (sec_0X), .ces_X0 (ces_X0), .ces_0X (ces_0X), - .MOSI (uo_out[0]), - .CS (uo_out[1]), - .clk_SPI (uo_out[2]) + .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 ); -endmodule + /* SPI_driver SPI_driver1 ( // drives the 7-segment displays connected via a MAX7219 chip over SPI + .clk (clk), + .res (rst_n), + .ena (display_enable), + .clk_div(dividedClock), + .min_X0 (min_X0), + .min_0X (min_0X), + .sec_X0 (sec_X0), + .sec_0X (sec_0X), + .ces_X0 (ces_X0), + .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 + ); */ + +endmodule \ No newline at end of file