start cleanup of SPI
This commit is contained in:
parent
df6fe45d65
commit
90b74593e9
75
spi_master.v
75
spi_master.v
|
@ -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
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
`define SPI_MASTER_NO_READ
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
`include "spi_master.v"
|
|
@ -1,3 +0,0 @@
|
|||
`define SPI_MASTER_NO_WRITE
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
`include "spi_master.v"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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
|
||||
|
|
86
spi_slave.v
86
spi_slave.v
|
@ -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
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
`define SPI_SLAVE_NO_READ
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
`include "spi_slave.v"
|
|
@ -1,3 +0,0 @@
|
|||
`define SPI_SLAVE_NO_WRITE
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
`include "spi_slave.v"
|
Loading…
Reference in New Issue