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
* 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/.
@ -9,17 +9,9 @@
* the input).
*/
module
`ifdef SPI_MASTER_NO_READ
spi_master_no_read
`else
`ifdef SPI_MASTER_NO_WRITE
spi_master_no_write
`else
spi_master
`endif
`endif
#(
module spi_master #(
parameter ENABLE_MISO = 1, // Enable MISO and from_slave port
parameter ENABLE_MOSI = 1, // Enable MOSI and to_slave port
parameter WID = 24, // Width of bits per transaction.
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.
@ -27,25 +19,22 @@ spi_master
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 PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read.
)
(
) (
input clk,
input rst_L,
`ifndef SPI_MASTER_NO_READ
output reg [WID-1:0] from_slave,
input miso,
`endif
`ifndef SPI_MASTER_NO_WRITE
input [WID-1:0] to_slave,
output reg mosi,
`endif
output reg sck_wire,
output reg finished,
output reg ready_to_arm,
input arm
);
`ifndef SPI_MASTER_NO_READ
/* MISO is almost always an external wire, so buffer it.
* 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.
@ -56,11 +45,10 @@ spi_master
reg miso_hot = 0;
reg read_miso = 0;
always @ (posedge clk) begin
always @ (posedge clk) if (ENABLE_MISO) begin
read_miso <= miso_hot;
miso_hot <= miso;
end
`endif
parameter WAIT_ON_ARM = 0;
parameter ON_CYCLE = 1;
@ -71,9 +59,7 @@ reg [1:0] state = WAIT_ON_ARM;
reg [WID_LEN-1:0] bit_counter = 0;
reg [TIMER_LEN-1:0] timer = 0;
`ifndef SPI_MASTER_NO_WRITE
reg [WID-1:0] send_buf = 0;
`endif
reg sck = 0;
assign sck_wire = sck;
@ -84,25 +70,23 @@ task idle_state();
end else begin
sck <= 1;
end
`ifndef SPI_MASTER_NO_WRITE
mosi <= 0;
`endif
if (ENABLE_MOSI) mosi <= 0;
timer <= 0;
bit_counter <= 0;
endtask
task read_data();
`ifndef SPI_MASTER_NO_READ
from_slave <= from_slave << 1;
from_slave[0] <= read_miso;
`endif
if (ENABLE_MISO) begin
from_slave <= from_slave << 1;
from_slave[0] <= read_miso;
end
endtask
task write_data();
`ifndef SPI_MASTER_NO_WRITE
mosi <= send_buf[WID-1];
send_buf <= send_buf << 1;
`endif
if (ENABLE_MOSI) begin
mosi <= send_buf[WID-1];
send_buf <= send_buf << 1;
end
endtask
task setup_bits();
@ -113,15 +97,15 @@ task setup_bits();
* For mode 01 and mode 10, the first action is a WRITE.
*/
if (POLARITY == PHASE) begin
`ifndef SPI_MASTER_NO_WRITE
mosi <= to_slave[WID-1];
send_buf <= to_slave << 1;
`endif
if (ENABLE_MOSI) begin
mosi <= to_slave[WID-1];
send_buf <= to_slave << 1;
end
state <= CYCLE_WAIT;
end else begin
`ifndef SPI_MASTER_NO_WRITE
send_buf <= to_slave;
`endif
if (ENABLE_MISO) begin
send_buf <= to_slave;
end
state <= ON_CYCLE;
end
endtask
@ -144,12 +128,8 @@ always @ (posedge clk) begin
finished <= 0;
state <= WAIT_ON_ARM;
ready_to_arm <= 1;
`ifndef SPI_MASTER_NO_READ
from_slave <= 0;
`endif
`ifndef SPI_MASTER_NO_WRITE
send_buf <= 0;
`endif
if (ENABLE_MISO) from_slave <= 0;
if (ENABLE_MOSI) send_buf <= 0;
end else case (state)
WAIT_ON_ARM: begin
`ifdef SIMULATION
@ -225,4 +205,3 @@ always @ (posedge clk) begin
end
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
* 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/.
*/
/* spi master with integrated ability to wait a certain amount of cycles
* 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_LEN = 5,
parameter CYCLE_HALF_WAIT = 1,
parameter TIMER_LEN = 3,
parameter SS_WAIT = 1,
parameter SS_WAIT_TIMER_LEN = 2,
parameter POLARITY = 0,
parameter PHASE = 0
)
(
) (
input clk,
input rst_L,
`ifndef SPI_MASTER_NO_READ
output [WID-1:0] from_slave,
input miso,
`endif
`ifndef SPI_MASTER_NO_WRITE
input [WID-1:0] to_slave,
output reg mosi,
`endif
output sck_wire,
output finished,
output ready_to_arm,
@ -42,7 +45,9 @@ reg ss = 0;
reg arm_master = 0;
assign ss_L = !ss;
`SPI_MASTER_NAME #(
spi_master #(
.ENABLE_MISO(ENABLE_MISO),
.ENABLE_MOSI(ENABLE_MOSI),
.WID(WID),
.WID_LEN(WID_LEN),
.CYCLE_HALF_WAIT(CYCLE_HALF_WAIT),
@ -52,14 +57,13 @@ assign ss_L = !ss;
) master (
.clk(clk),
.rst_L(rst_L),
`ifndef SPI_MASTER_NO_READ
.from_slave(from_slave),
.miso(miso),
`endif
`ifndef SPI_MASTER_NO_WRITE
.to_slave(to_slave),
.mosi(mosi),
`endif
.sck_wire(sck_wire),
.finished(finished),
.ready_to_arm(ready_to_arm),
@ -120,4 +124,3 @@ always @ (posedge clk) begin
end
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
* 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/.
*/
module
`ifdef SPI_SLAVE_NO_READ
spi_slave_no_read
`elsif SPI_SLAVE_NO_WRITE
spi_slave_no_write
`else
spi_slave
`endif
#(
module spi_slave #(
parameter ENABLE_MISO = 1, // Enable MISO and to_master port
parameter ENABLE_MOSI = 1, // Enable MOSI and from_master port
parameter WID = 24, // Width of bits per transaction.
parameter WID_LEN = 5, // Length in bits required to store WID
parameter POLARITY = 0,
parameter PHASE = 0 // 0 = rising-read falling-write, 1 = rising-write falling-read.
)
(
) (
input clk,
input rst_L,
input sck,
input ss_L,
`ifndef SPI_SLAVE_NO_READ
output reg [WID-1:0] from_master,
input mosi,
`endif
`ifndef SPI_SLAVE_NO_WRITE
input [WID-1:0] to_master,
output reg miso,
`endif
output reg finished,
input rdy,
output reg err
);
`ifndef SPI_SLAVE_NO_READ
/* MOSI is almost always an external wire, so buffer it. */
reg mosi_hot = 0;
reg read_mosi = 0;
always @ (posedge clk) begin
always @ (posedge clk) if (ENABLE_MOSI) begin
read_mosi <= mosi_hot;
mosi_hot <= mosi;
end
`endif
wire ss = !ss_L;
reg sck_delay = 0;
@ -58,34 +48,34 @@ reg [WID-1:0] send_buf = 0;
`endif
task read_data();
`ifndef SPI_SLAVE_NO_READ
from_master <= from_master << 1;
from_master[0] <= read_mosi;
`endif
if (ENABLE_MOSI) begin
from_master <= from_master << 1;
from_master[0] <= read_mosi;
end
endtask
task write_data();
`ifndef SPI_SLAVE_NO_WRITE
send_buf <= send_buf << 1;
miso <= send_buf[WID-1];
`endif
if (ENABLE_MISO) begin
send_buf <= send_buf << 1;
miso <= send_buf[WID-1];
end
endtask
task setup_bits();
`ifndef SPI_SLAVE_NO_WRITE
/* at Mode 00, the transmission starts with
* a rising edge, and at mode 11, it starts with a falling
* edge. For both modes, these are READs.
*
* For mode 01 and mode 10, the first action is a WRITE.
*/
if (POLARITY == PHASE) begin
miso <= to_master[WID-1];
send_buf <= to_master << 1;
end else begin
send_buf <= to_master;
if (ENABLE_MISO) begin
/* at Mode 00, the transmission starts with
* a rising edge, and at mode 11, it starts with a falling
* edge. For both modes, these are READs.
*
* For mode 01 and mode 10, the first action is a WRITE.
*/
if (POLARITY == PHASE) begin
miso <= to_master[WID-1];
send_buf <= to_master << 1;
end else begin
send_buf <= to_master;
end
end
`endif
endtask
task check_counter();
@ -102,13 +92,14 @@ always @ (posedge clk) begin
bit_counter <= 0;
ss_delay <= 0;
ready_at_start <= 0;
`ifndef SPI_SLAVE_NO_READ
from_master <= 0;
`endif
`ifndef SPI_SLAVE_NO_WRITE
miso <= 0;
send_buf <= 0;
`endif
if (ENABLE_MOSI) from_master <= 0;
if (ENABLE_MISO) begin
miso <= 0;
send_buf <= 0;
end
finished <= 0;
err <= 0;
end else begin
@ -163,4 +154,3 @@ always @ (posedge clk) begin
end
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"