start cleanup of SPI

This commit is contained in:
Peter McGoron 2024-01-23 10:26:49 -05:00
parent df6fe45d65
commit 90b74593e9
10 changed files with 85 additions and 139 deletions

View File

@ -1,4 +1,4 @@
/* (c) Peter McGoron 2022 v0.3 /* (c) Peter McGoron 2022 v0.4
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this * License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -9,17 +9,9 @@
* the input). * the input).
*/ */
module module spi_master #(
`ifdef SPI_MASTER_NO_READ parameter ENABLE_MISO = 1, // Enable MISO and from_slave port
spi_master_no_read parameter ENABLE_MOSI = 1, // Enable MOSI and to_slave port
`else
`ifdef SPI_MASTER_NO_WRITE
spi_master_no_write
`else
spi_master
`endif
`endif
#(
parameter WID = 24, // Width of bits per transaction. parameter WID = 24, // Width of bits per transaction.
parameter WID_LEN = 5, // Length in bits required to store WID parameter WID_LEN = 5, // Length in bits required to store WID
parameter CYCLE_HALF_WAIT = 1, // Half of the wait time of a cycle minus 1. parameter CYCLE_HALF_WAIT = 1, // Half of the wait time of a cycle minus 1.
@ -27,25 +19,22 @@ spi_master
parameter TIMER_LEN = 3, // Length in bits required to store CYCLE_HALF_WAIT parameter TIMER_LEN = 3, // Length in bits required to store CYCLE_HALF_WAIT
parameter POLARITY = 0, // 0 = sck idle low, 1 = sck idle high parameter POLARITY = 0, // 0 = sck idle low, 1 = sck idle high
parameter PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read. parameter PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read.
) ) (
(
input clk, input clk,
input rst_L, input rst_L,
`ifndef SPI_MASTER_NO_READ
output reg [WID-1:0] from_slave, output reg [WID-1:0] from_slave,
input miso, input miso,
`endif
`ifndef SPI_MASTER_NO_WRITE
input [WID-1:0] to_slave, input [WID-1:0] to_slave,
output reg mosi, output reg mosi,
`endif
output reg sck_wire, output reg sck_wire,
output reg finished, output reg finished,
output reg ready_to_arm, output reg ready_to_arm,
input arm input arm
); );
`ifndef SPI_MASTER_NO_READ
/* MISO is almost always an external wire, so buffer it. /* MISO is almost always an external wire, so buffer it.
* This might not be necessary, since the master and slave do not respond * This might not be necessary, since the master and slave do not respond
* immediately to changes in the wires, but this is just to be safe. * immediately to changes in the wires, but this is just to be safe.
@ -56,11 +45,10 @@ spi_master
reg miso_hot = 0; reg miso_hot = 0;
reg read_miso = 0; reg read_miso = 0;
always @ (posedge clk) begin always @ (posedge clk) if (ENABLE_MISO) begin
read_miso <= miso_hot; read_miso <= miso_hot;
miso_hot <= miso; miso_hot <= miso;
end end
`endif
parameter WAIT_ON_ARM = 0; parameter WAIT_ON_ARM = 0;
parameter ON_CYCLE = 1; parameter ON_CYCLE = 1;
@ -71,9 +59,7 @@ reg [1:0] state = WAIT_ON_ARM;
reg [WID_LEN-1:0] bit_counter = 0; reg [WID_LEN-1:0] bit_counter = 0;
reg [TIMER_LEN-1:0] timer = 0; reg [TIMER_LEN-1:0] timer = 0;
`ifndef SPI_MASTER_NO_WRITE
reg [WID-1:0] send_buf = 0; reg [WID-1:0] send_buf = 0;
`endif
reg sck = 0; reg sck = 0;
assign sck_wire = sck; assign sck_wire = sck;
@ -84,25 +70,23 @@ task idle_state();
end else begin end else begin
sck <= 1; sck <= 1;
end end
`ifndef SPI_MASTER_NO_WRITE if (ENABLE_MOSI) mosi <= 0;
mosi <= 0;
`endif
timer <= 0; timer <= 0;
bit_counter <= 0; bit_counter <= 0;
endtask endtask
task read_data(); task read_data();
`ifndef SPI_MASTER_NO_READ if (ENABLE_MISO) begin
from_slave <= from_slave << 1; from_slave <= from_slave << 1;
from_slave[0] <= read_miso; from_slave[0] <= read_miso;
`endif end
endtask endtask
task write_data(); task write_data();
`ifndef SPI_MASTER_NO_WRITE if (ENABLE_MOSI) begin
mosi <= send_buf[WID-1]; mosi <= send_buf[WID-1];
send_buf <= send_buf << 1; send_buf <= send_buf << 1;
`endif end
endtask endtask
task setup_bits(); task setup_bits();
@ -113,15 +97,15 @@ task setup_bits();
* For mode 01 and mode 10, the first action is a WRITE. * For mode 01 and mode 10, the first action is a WRITE.
*/ */
if (POLARITY == PHASE) begin if (POLARITY == PHASE) begin
`ifndef SPI_MASTER_NO_WRITE if (ENABLE_MOSI) begin
mosi <= to_slave[WID-1]; mosi <= to_slave[WID-1];
send_buf <= to_slave << 1; send_buf <= to_slave << 1;
`endif end
state <= CYCLE_WAIT; state <= CYCLE_WAIT;
end else begin end else begin
`ifndef SPI_MASTER_NO_WRITE if (ENABLE_MISO) begin
send_buf <= to_slave; send_buf <= to_slave;
`endif end
state <= ON_CYCLE; state <= ON_CYCLE;
end end
endtask endtask
@ -144,12 +128,8 @@ always @ (posedge clk) begin
finished <= 0; finished <= 0;
state <= WAIT_ON_ARM; state <= WAIT_ON_ARM;
ready_to_arm <= 1; ready_to_arm <= 1;
`ifndef SPI_MASTER_NO_READ if (ENABLE_MISO) from_slave <= 0;
from_slave <= 0; if (ENABLE_MOSI) send_buf <= 0;
`endif
`ifndef SPI_MASTER_NO_WRITE
send_buf <= 0;
`endif
end else case (state) end else case (state)
WAIT_ON_ARM: begin WAIT_ON_ARM: begin
`ifdef SIMULATION `ifdef SIMULATION
@ -225,4 +205,3 @@ always @ (posedge clk) begin
end end
endmodule endmodule
`undefineall

View File

@ -1,3 +0,0 @@
`define SPI_MASTER_NO_READ
/* verilator lint_off DECLFILENAME */
`include "spi_master.v"

View File

@ -1,3 +0,0 @@
`define SPI_MASTER_NO_WRITE
/* verilator lint_off DECLFILENAME */
`include "spi_master.v"

View File

@ -1,4 +0,0 @@
`define SPI_MASTER_SS_NAME spi_master_ss
`define SPI_MASTER_NAME spi_master
/* verilator lint_off DECLFILENAME */
`include "spi_master_ss_template.v"

View File

@ -1,5 +0,0 @@
`define SPI_MASTER_SS_NAME spi_master_ss_no_read
`define SPI_MASTER_NAME spi_master_no_read
`define SPI_MASTER_NO_READ
/* verilator lint_off DECLFILENAME */
`include "spi_master_ss_template.v"

View File

@ -1,5 +0,0 @@
`define SPI_MASTER_SS_NAME spi_master_ss_no_write
`define SPI_MASTER_NAME spi_master_no_write
`define SPI_MASTER_NO_WRITE
/* verilator lint_off DECLFILENAME */
`include "spi_master_ss_template.v"

View File

@ -1,36 +1,39 @@
/* (c) Peter McGoron 2022 v0.3 /* (c) Peter McGoron 2022 v0.4
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this * License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
/* spi master with integrated ability to wait a certain amount of cycles /* spi master with integrated ability to wait a certain amount of cycles
* after activating SS. * after activating SS.
*/ */
module `SPI_MASTER_SS_NAME module spi_master_ss
#( #(
parameter SS_WAIT = 1, /* Amount of cycles to wait for SS
to enable */
parameter SS_WAIT_TIMER_LEN = 2, /* Amount of bits required to
store the SS wait time */
parameter ENABLE_MISO = 1,
parameter ENABLE_MOSI = 1,
parameter WID = 24, parameter WID = 24,
parameter WID_LEN = 5, parameter WID_LEN = 5,
parameter CYCLE_HALF_WAIT = 1, parameter CYCLE_HALF_WAIT = 1,
parameter TIMER_LEN = 3, parameter TIMER_LEN = 3,
parameter SS_WAIT = 1,
parameter SS_WAIT_TIMER_LEN = 2,
parameter POLARITY = 0, parameter POLARITY = 0,
parameter PHASE = 0 parameter PHASE = 0
) ) (
(
input clk, input clk,
input rst_L, input rst_L,
`ifndef SPI_MASTER_NO_READ
output [WID-1:0] from_slave, output [WID-1:0] from_slave,
input miso, input miso,
`endif
`ifndef SPI_MASTER_NO_WRITE
input [WID-1:0] to_slave, input [WID-1:0] to_slave,
output reg mosi, output reg mosi,
`endif
output sck_wire, output sck_wire,
output finished, output finished,
output ready_to_arm, output ready_to_arm,
@ -42,7 +45,9 @@ reg ss = 0;
reg arm_master = 0; reg arm_master = 0;
assign ss_L = !ss; assign ss_L = !ss;
`SPI_MASTER_NAME #( spi_master #(
.ENABLE_MISO(ENABLE_MISO),
.ENABLE_MOSI(ENABLE_MOSI),
.WID(WID), .WID(WID),
.WID_LEN(WID_LEN), .WID_LEN(WID_LEN),
.CYCLE_HALF_WAIT(CYCLE_HALF_WAIT), .CYCLE_HALF_WAIT(CYCLE_HALF_WAIT),
@ -52,14 +57,13 @@ assign ss_L = !ss;
) master ( ) master (
.clk(clk), .clk(clk),
.rst_L(rst_L), .rst_L(rst_L),
`ifndef SPI_MASTER_NO_READ
.from_slave(from_slave), .from_slave(from_slave),
.miso(miso), .miso(miso),
`endif
`ifndef SPI_MASTER_NO_WRITE
.to_slave(to_slave), .to_slave(to_slave),
.mosi(mosi), .mosi(mosi),
`endif
.sck_wire(sck_wire), .sck_wire(sck_wire),
.finished(finished), .finished(finished),
.ready_to_arm(ready_to_arm), .ready_to_arm(ready_to_arm),
@ -120,4 +124,3 @@ always @ (posedge clk) begin
end end
endmodule endmodule
`undefineall

View File

@ -1,51 +1,41 @@
/* (c) Peter McGoron 2022 v0.3 /* (c) Peter McGoron 2022 v0.4
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this * License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
module module spi_slave #(
`ifdef SPI_SLAVE_NO_READ parameter ENABLE_MISO = 1, // Enable MISO and to_master port
spi_slave_no_read parameter ENABLE_MOSI = 1, // Enable MOSI and from_master port
`elsif SPI_SLAVE_NO_WRITE
spi_slave_no_write
`else
spi_slave
`endif
#(
parameter WID = 24, // Width of bits per transaction. parameter WID = 24, // Width of bits per transaction.
parameter WID_LEN = 5, // Length in bits required to store WID parameter WID_LEN = 5, // Length in bits required to store WID
parameter POLARITY = 0, parameter POLARITY = 0,
parameter PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read. parameter PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read.
) ) (
(
input clk, input clk,
input rst_L, input rst_L,
input sck, input sck,
input ss_L, input ss_L,
`ifndef SPI_SLAVE_NO_READ
output reg [WID-1:0] from_master, output reg [WID-1:0] from_master,
input mosi, input mosi,
`endif
`ifndef SPI_SLAVE_NO_WRITE
input [WID-1:0] to_master, input [WID-1:0] to_master,
output reg miso, output reg miso,
`endif
output reg finished, output reg finished,
input rdy, input rdy,
output reg err output reg err
); );
`ifndef SPI_SLAVE_NO_READ
/* MOSI is almost always an external wire, so buffer it. */ /* MOSI is almost always an external wire, so buffer it. */
reg mosi_hot = 0; reg mosi_hot = 0;
reg read_mosi = 0; reg read_mosi = 0;
always @ (posedge clk) begin always @ (posedge clk) if (ENABLE_MOSI) begin
read_mosi <= mosi_hot; read_mosi <= mosi_hot;
mosi_hot <= mosi; mosi_hot <= mosi;
end end
`endif
wire ss = !ss_L; wire ss = !ss_L;
reg sck_delay = 0; reg sck_delay = 0;
@ -58,34 +48,34 @@ reg [WID-1:0] send_buf = 0;
`endif `endif
task read_data(); task read_data();
`ifndef SPI_SLAVE_NO_READ if (ENABLE_MOSI) begin
from_master <= from_master << 1; from_master <= from_master << 1;
from_master[0] <= read_mosi; from_master[0] <= read_mosi;
`endif end
endtask endtask
task write_data(); task write_data();
`ifndef SPI_SLAVE_NO_WRITE if (ENABLE_MISO) begin
send_buf <= send_buf << 1; send_buf <= send_buf << 1;
miso <= send_buf[WID-1]; miso <= send_buf[WID-1];
`endif end
endtask endtask
task setup_bits(); task setup_bits();
`ifndef SPI_SLAVE_NO_WRITE if (ENABLE_MISO) begin
/* at Mode 00, the transmission starts with /* at Mode 00, the transmission starts with
* a rising edge, and at mode 11, it starts with a falling * a rising edge, and at mode 11, it starts with a falling
* edge. For both modes, these are READs. * edge. For both modes, these are READs.
* *
* For mode 01 and mode 10, the first action is a WRITE. * For mode 01 and mode 10, the first action is a WRITE.
*/ */
if (POLARITY == PHASE) begin if (POLARITY == PHASE) begin
miso <= to_master[WID-1]; miso <= to_master[WID-1];
send_buf <= to_master << 1; send_buf <= to_master << 1;
end else begin end else begin
send_buf <= to_master; send_buf <= to_master;
end
end end
`endif
endtask endtask
task check_counter(); task check_counter();
@ -102,13 +92,14 @@ always @ (posedge clk) begin
bit_counter <= 0; bit_counter <= 0;
ss_delay <= 0; ss_delay <= 0;
ready_at_start <= 0; ready_at_start <= 0;
`ifndef SPI_SLAVE_NO_READ
from_master <= 0; if (ENABLE_MOSI) from_master <= 0;
`endif
`ifndef SPI_SLAVE_NO_WRITE if (ENABLE_MISO) begin
miso <= 0; miso <= 0;
send_buf <= 0; send_buf <= 0;
`endif end
finished <= 0; finished <= 0;
err <= 0; err <= 0;
end else begin end else begin
@ -163,4 +154,3 @@ always @ (posedge clk) begin
end end
endmodule endmodule
`undefineall

View File

@ -1,3 +0,0 @@
`define SPI_SLAVE_NO_READ
/* verilator lint_off DECLFILENAME */
`include "spi_slave.v"

View File

@ -1,3 +0,0 @@
`define SPI_SLAVE_NO_WRITE
/* verilator lint_off DECLFILENAME */
`include "spi_slave.v"