aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2024-01-23 14:05:26 -0500
committerGravatar Peter McGoron 2024-01-23 14:05:26 -0500
commitbf78682e7358b12c335b216297a246aad3e4f411 (patch)
treeaf74bbd5fcb3a7051cc96736e5192cd271510d0e
parentstart cleanup of SPI (diff)
clean up tests
-rw-r--r--.gitignore2
-rw-r--r--Makefile0
-rw-r--r--README.md7
-rw-r--r--spi_master.v24
-rw-r--r--spi_master_ss.v (renamed from spi_master_ss_template.v)6
-rw-r--r--spi_slave.v18
-rwxr-xr-xtests/clean.sh2
-rwxr-xr-xtests/mk.sh85
-rwxr-xr-xtests/runtests.py72
-rw-r--r--tests/simtop.v39
10 files changed, 115 insertions, 140 deletions
diff --git a/.gitignore b/.gitignore
index 957c3ef..9d496ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-simtop_*
+tests/test_*
diff --git a/Makefile b/Makefile
deleted file mode 100644
index e69de29..0000000
--- a/Makefile
+++ /dev/null
diff --git a/README.md b/README.md
index 6570060..c31801a 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ License, v.2.0. A copy of this license may be found in the file `COPYING`. You
can obtain one at https://mozilla.org/MPL/2.0/.
All Verilog source in this project is dual-licensed under the MPL v2.0
-and the CERN-OHL-W v2.0 (or any later version).
+and the CERN-OHL-W v2.0.
## Tests
@@ -18,11 +18,6 @@ Run `./mk.sh` in `tests/` to generate and run tests.
## Modules
-"master_no_read" and "slave_no_write" have no Master In, Slave Out ("miso")
-wires (and no corresponding shift registers), while "master_no_write"
-and "slave_no_read" have no Master Out, Slave In ("mosi") wires. This
-is for compatability for "SPI compatible" devices that are read only.
-
"master_ss" and others include a timer that will assert the Slave Select
pin and wait a set number of clock cycles before starting the SPI transfer.
diff --git a/spi_master.v b/spi_master.v
index 715ad98..5f478d7 100644
--- a/spi_master.v
+++ b/spi_master.v
@@ -1,7 +1,7 @@
-/* (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/.
+/* (c) Peter McGoron 2022-2024 v0.4
+ *
+ * This code is disjunctively dual-licensed under the MPL v2.0, or the
+ * CERN-OHL-W v2.
*/
/* CYCLE_HALF_WAIT should take into account the setup time of the slave
@@ -45,7 +45,7 @@ module spi_master #(
reg miso_hot = 0;
reg read_miso = 0;
-always @ (posedge clk) if (ENABLE_MISO) begin
+always @ (posedge clk) if (ENABLE_MISO == 1) begin
read_miso <= miso_hot;
miso_hot <= miso;
end
@@ -70,20 +70,20 @@ task idle_state();
end else begin
sck <= 1;
end
- if (ENABLE_MOSI) mosi <= 0;
+ if (ENABLE_MOSI == 1) mosi <= 0;
timer <= 0;
bit_counter <= 0;
endtask
task read_data();
- if (ENABLE_MISO) begin
+ if (ENABLE_MISO == 1) begin
from_slave <= from_slave << 1;
from_slave[0] <= read_miso;
end
endtask
task write_data();
- if (ENABLE_MOSI) begin
+ if (ENABLE_MOSI == 1) begin
mosi <= send_buf[WID-1];
send_buf <= send_buf << 1;
end
@@ -97,13 +97,13 @@ task setup_bits();
* For mode 01 and mode 10, the first action is a WRITE.
*/
if (POLARITY == PHASE) begin
- if (ENABLE_MOSI) begin
+ if (ENABLE_MOSI == 1) begin
mosi <= to_slave[WID-1];
send_buf <= to_slave << 1;
end
state <= CYCLE_WAIT;
end else begin
- if (ENABLE_MISO) begin
+ if (ENABLE_MISO == 1) begin
send_buf <= to_slave;
end
state <= ON_CYCLE;
@@ -128,8 +128,8 @@ always @ (posedge clk) begin
finished <= 0;
state <= WAIT_ON_ARM;
ready_to_arm <= 1;
- if (ENABLE_MISO) from_slave <= 0;
- if (ENABLE_MOSI) send_buf <= 0;
+ if (ENABLE_MISO == 1) from_slave <= 0;
+ if (ENABLE_MOSI == 1) send_buf <= 0;
end else case (state)
WAIT_ON_ARM: begin
`ifdef SIMULATION
diff --git a/spi_master_ss_template.v b/spi_master_ss.v
index e5624ce..f71a874 100644
--- a/spi_master_ss_template.v
+++ b/spi_master_ss.v
@@ -1,7 +1,7 @@
/* (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/.
+ *
+ * This code is disjunctively dual-licensed under the MPL v2.0, or the
+ * CERN-OHL-W v2.
*/
/* spi master with integrated ability to wait a certain amount of cycles
diff --git a/spi_slave.v b/spi_slave.v
index 3530b5e..be1371f 100644
--- a/spi_slave.v
+++ b/spi_slave.v
@@ -1,7 +1,7 @@
/* (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/.
+ *
+ * This code is disjunctively dual-licensed under the MPL v2.0, or the
+ * CERN-OHL-W v2.
*/
module spi_slave #(
@@ -32,7 +32,7 @@ module spi_slave #(
reg mosi_hot = 0;
reg read_mosi = 0;
-always @ (posedge clk) if (ENABLE_MOSI) begin
+always @ (posedge clk) if (ENABLE_MOSI == 1) begin
read_mosi <= mosi_hot;
mosi_hot <= mosi;
end
@@ -48,21 +48,21 @@ reg [WID-1:0] send_buf = 0;
`endif
task read_data();
- if (ENABLE_MOSI) begin
+ if (ENABLE_MOSI == 1) begin
from_master <= from_master << 1;
from_master[0] <= read_mosi;
end
endtask
task write_data();
- if (ENABLE_MISO) begin
+ if (ENABLE_MISO == 1) begin
send_buf <= send_buf << 1;
miso <= send_buf[WID-1];
end
endtask
task setup_bits();
- if (ENABLE_MISO) begin
+ if (ENABLE_MISO == 1) 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.
@@ -93,9 +93,9 @@ always @ (posedge clk) begin
ss_delay <= 0;
ready_at_start <= 0;
- if (ENABLE_MOSI) from_master <= 0;
+ if (ENABLE_MOSI == 1) from_master <= 0;
- if (ENABLE_MISO) begin
+ if (ENABLE_MISO == 1) begin
miso <= 0;
send_buf <= 0;
end
diff --git a/tests/clean.sh b/tests/clean.sh
index 9d50089..238fbaf 100755
--- a/tests/clean.sh
+++ b/tests/clean.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-rm -rf simtop_*
+rm -rf test_master* test_ss*
diff --git a/tests/mk.sh b/tests/mk.sh
deleted file mode 100755
index 707b753..0000000
--- a/tests/mk.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-run_test() {
- POL=$1
- PHASE=$2
- MASTER_TYPE=$3
- SLAVE_TYPE=$4
- DIR=$5
- WID=$6
- MODS=$7
- EXTARG=$8
- WIDLEN=$(printf "import math\nprint(math.floor(math.log2($WID) + 1))" | python3 -)
-
- echo "running $POL$PHASE $MASTER_TYPE"
-
- verilator --cc --exe -I.. -Wall -Wno-unused --trace --trace-fst \
- --top-module simtop \
- -GPOLARITY=$POL -GPHASE=$PHASE -GWID=$WID -CFLAGS -DWID=$WID \
- -GWID_LEN=$WIDLEN \
- -DSPI_MASTER_TYPE=$MASTER_TYPE -DSPI_SLAVE_TYPE=$SLAVE_TYPE \
- -DVCDFILE="\"$DIR.fst\"" \
- -DSIMULATION \
- --Mdir $DIR \
- $EXTARG \
- simtop.v write_read.cpp $MODS \
- || exit 1
-
- cd "$DIR"
- make -f Vsimtop.mk
- ./Vsimtop
-}
-
-for POL in 0 1; do
- for PHASE in 0 1; do
- ( \
- run_test $POL $PHASE \
- spi_master spi_slave \
- simtop_$POL$PHASE 24 \
- "../spi_master.v ../spi_slave.v"
- ) || exit 1
-
- ( \
- run_test $POL $PHASE \
- spi_master_ss spi_slave \
- simtop_ss$POL$PHASE 24 \
- "../spi_master_ss.v ../spi_slave.v" \
- "-DSPI_MASTER_SS -CFLAGS -DSPI_MASTER_SS"
- ) || exit 1
-
- ( \
- run_test $POL $PHASE \
- spi_master_no_write spi_slave_no_read \
- simtop_no_write_$POL$PHASE 24 \
- "../spi_master_no_write.v ../spi_slave_no_read.v" \
- "-DSPI_MASTER_NO_WRITE -CFLAGS -DSPI_MASTER_NO_WRITE"
- ) || exit 1
-
- ( \
- run_test $POL $PHASE \
- spi_master_ss_no_write spi_slave_no_read \
- simtop_ss_no_write_$POL$PHASE 24 \
- "../spi_master_ss_no_write.v ../spi_slave_no_read.v" \
- "-DSPI_MASTER_NO_WRITE -CFLAGS -DSPI_MASTER_NO_WRITE
- -DSPI_MASTER_SS -CFLAGS -DSPI_MASTER_SS"
- ) || exit 1
-
- ( \
- run_test $POL $PHASE \
- spi_master_no_read spi_slave_no_write \
- simtop_no_read_$POL$PHASE 24 \
- "../spi_master_no_read.v ../spi_slave_no_write.v" \
- "-DSPI_MASTER_NO_READ -CFLAGS -DSPI_MASTER_NO_READ"
- ) || exit 1
-
- ( \
- run_test $POL $PHASE \
- spi_master_ss_no_read spi_slave_no_write \
- simtop_ss_no_read_$POL$PHASE 24 \
- "../spi_master_ss_no_read.v ../spi_slave_no_write.v" \
- "-DSPI_MASTER_NO_READ -CFLAGS -DSPI_MASTER_NO_READ
- -DSPI_MASTER_SS -CFLAGS -DSPI_MASTER_SS"
- ) || exit 1
-
- done
-done
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100755
index 0000000..5b883bb
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python3
+
+import math
+import subprocess
+import sys
+import os
+from collections import namedtuple
+
+class Case:
+ def __init__(self, master_name, defflags, params):
+ self.master_name = master_name
+ self.defflags = defflags
+ self.params = params
+
+ def run(self, dirname, pol, phase, wid):
+ dirname = f'{dirname}{pol}{phase}'
+ widlen = math.floor(math.log2(wid) + 1)
+ args = ["verilator", "--cc", "--exe", "-I..", "-Wall", "--trace",
+ "--trace-fst", "-Wno-unused",
+ "--top-module", "simtop",
+ f"-GPOLARITY={pol}", f"-GPHASE={phase}",
+ f"-GWID={wid}", f"-CFLAGS", f"-DWID={wid}",
+ f"-GWID_LEN={widlen}",
+ f"-DSPI_MASTER_TYPE={self.master_name}",
+ f'-DVCDFILE="{dirname}/trace.fst"',
+ f"-DSIMULATION",
+ f"--Mdir", dirname
+ ]
+
+ for flag in self.defflags:
+ args.extend([f'-D{flag}', '-CFLAGS', f'-D{flag}'])
+ for param in self.params:
+ args.append(f'-G{param}={self.params[param]}')
+
+ args.extend(['simtop.v', 'write_read.cpp', '../spi_slave.v', f'../{self.master_name}.v'])
+
+ print(args)
+ proc = subprocess.run(args, stdout=sys.stdout, stderr=sys.stderr)
+ if proc.returncode != 0:
+ print("Verilator failed")
+ return False
+
+ os.chdir(dirname)
+ proc = subprocess.run(["make", "-f", "Vsimtop.mk"], stdout=sys.stdout, stderr=sys.stderr)
+ if proc.returncode != 0:
+ print("Make failed")
+ os.chdir("..")
+ return False
+
+ proc = subprocess.run("./Vsimtop", stdout=sys.stdout, stderr=sys.stderr)
+ os.chdir("..")
+ if proc.returncode != 0:
+ print("Vsimtop failed")
+ return False
+ return True
+
+cases = {}
+# Add basic cases
+cases[f'test_master'] = Case("spi_master", [], {})
+cases[f'test_ss'] = Case("spi_master_ss", ["SPI_MASTER_SS"], {})
+cases[f'test_master_no_write'] = Case("spi_master", ['SPI_MASTER_NO_WRITE'], {'ENABLE_MOSI': 0})
+cases[f'test_ss_no_write'] = Case("spi_master_ss", ["SPI_MASTER_SS", 'SPI_MASTER_NO_WRITE'], {'ENABLE_MOSI': 0})
+cases[f'test_master_no_read'] = Case("spi_master", ['SPI_MASTER_NO_READ'], {'ENABLE_MISO': 1})
+cases[f'test_ss_no_read'] = Case("spi_master_ss", ["SPI_MASTER_SS", 'SPI_MASTER_NO_READ'], {'ENABLE_MISO': 1})
+
+failures=0
+for polarity in [0, 1]:
+ for phase in [0, 1]:
+ for casename in cases:
+ if not cases[casename].run(casename, polarity, phase, 24):
+ failures += 1
+print(f'Failures: {failures}')
diff --git a/tests/simtop.v b/tests/simtop.v
index 1e6662a..c280633 100644
--- a/tests/simtop.v
+++ b/tests/simtop.v
@@ -1,11 +1,13 @@
-/* (c) Peter McGoron 2022
- * 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/.
+/* (c) Peter McGoron 2022-2024 v0.4
+ *
+ * This code is disjunctively dual-licensed under the MPL v2.0, or the
+ * CERN-OHL-W v2.
*/
module simtop
#(
+ parameter ENABLE_MOSI = 1,
+ parameter ENABLE_MISO = 1,
parameter POLARITY = 0,
parameter PHASE = 0,
parameter WID = 24,
@@ -13,14 +15,13 @@ module simtop
) (
input clk,
input rst_L,
-`ifndef SPI_MASTER_NO_WRITE
+
input [WID-1:0] master_to_slave,
output [WID-1:0] from_master,
-`endif
-`ifndef SPI_MASTER_NO_READ
+
input [WID-1:0] slave_to_master,
output [WID-1:0] from_slave,
-`endif
+
input activate,
`ifndef SPI_MASTER_SS
input ss,
@@ -31,13 +32,9 @@ module simtop
output err
);
-`ifndef SPI_MASTER_NO_READ
wire miso;
-`endif
-`ifndef SPI_MASTER_NO_WRITE
wire mosi;
-`endif
wire sck;
wire ss_L;
@@ -46,8 +43,8 @@ wire ss_L;
assign ss_L = !ss;
`endif
-reg slave_finished;
-reg slave_error;
+wire slave_finished;
+wire slave_error;
`SPI_MASTER_TYPE
#(
@@ -55,6 +52,8 @@ reg slave_error;
.SS_WAIT(5),
.SS_WAIT_TIMER_LEN(3),
`endif
+ .ENABLE_MOSI(ENABLE_MOSI),
+ .ENABLE_MISO(ENABLE_MISO),
.CYCLE_HALF_WAIT(5),
.TIMER_LEN(3),
.POLARITY(POLARITY),
@@ -64,14 +63,10 @@ reg slave_error;
) master (
.clk(clk),
.rst_L(rst_L),
-`ifndef SPI_MASTER_NO_WRITE
.to_slave(master_to_slave),
.mosi(mosi),
-`endif
-`ifndef SPI_MASTER_NO_READ
.from_slave(from_slave),
.miso(miso),
-`endif
`ifdef SPI_MASTER_SS
.ss_L(ss_L),
`endif
@@ -81,7 +76,9 @@ reg slave_error;
.arm(activate)
);
-`SPI_SLAVE_TYPE #(
+spi_slave #(
+ .ENABLE_MOSI(ENABLE_MOSI),
+ .ENABLE_MISO(ENABLE_MISO),
.POLARITY(POLARITY),
.PHASE(PHASE),
.WID(WID),
@@ -91,14 +88,10 @@ reg slave_error;
.rst_L(rst_L),
.sck(sck),
.ss_L(ss_L),
-`ifndef SPI_MASTER_NO_WRITE
.from_master(from_master),
.mosi(mosi),
-`endif
-`ifndef SPI_MASTER_NO_READ
.to_master(slave_to_master),
.miso(miso),
-`endif
.finished(slave_finished),
.rdy(rdy),
.err(err)