aboutsummaryrefslogtreecommitdiff
path: root/tests/spi_slave
diff options
context:
space:
mode:
Diffstat (limited to 'tests/spi_slave')
-rw-r--r--tests/spi_slave/Makefile9
-rw-r--r--tests/spi_slave/operations.memv62
-rw-r--r--tests/spi_slave/rom.mem258
-rw-r--r--tests/spi_slave/test.v141
4 files changed, 470 insertions, 0 deletions
diff --git a/tests/spi_slave/Makefile b/tests/spi_slave/Makefile
new file mode 100644
index 0000000..8a8d3e8
--- /dev/null
+++ b/tests/spi_slave/Makefile
@@ -0,0 +1,9 @@
+DEPENDS = operations.mem master.v spi_slave.v flash_memory.v messages.vh rom.mem
+
+IVFLAGS = \
+ -DMASTER_OPERATIONS_COUNT=$(call FILE_LINES,operations.mem) \
+ -DROM_WORDS_COUNT=$(call FILE_LINES,rom.mem)
+
+TOP = spi_test
+
+include ../../Makefile.test
diff --git a/tests/spi_slave/operations.memv b/tests/spi_slave/operations.memv
new file mode 100644
index 0000000..084353b
--- /dev/null
+++ b/tests/spi_slave/operations.memv
@@ -0,0 +1,62 @@
+`include "macroasm.vh" // look into macroasm.vh for more info
+
+// power up flash ship
+`WRITE (00100, 0001) // set bytes_to_output to 1
+`WRITE (00101, 0000) // set bytes_to_receive to 0
+
+`WRITE (00000, 00AB) // release power-down spi command
+
+`WRITE (00102, 1111) // start spi operation
+
+
+// reading this reg during operation should yield 1's
+`READ (00102, FFFF)
+
+
+// the completions of first write after spi operation has been started
+// will be delayed until the operations has finished. This is of no concern
+// here, since the master will just gently wait for ACK from slave.
+
+
+// read contents at addresses h3A through h4A
+`WRITE (00101, 0010) // set bytes_to_receive to 16 (h10)
+`READ (00102, 0000) // see, that operation indeed finished
+
+`WRITE (00000, 000B) // fast read spi command + 8 high address bits
+`WRITE (00001, 3A00) // 16 low address bits
+`WRITE (00002, 0000) // dummy byte
+
+`WRITE (00100, 0005) // set bytes_to_output to 5
+
+// Cause delay b4 starting operation - chip's power-up takes 3000ns
+`DESELECT
+`DESELECT
+`WAIT
+`DESELECT
+`WAIT
+`DESELECT
+
+`WRITE (00102, 1111) // start spi operation (bits written to h102 don't matter)
+
+`WRITE (00100, 0000) // force wait for operation completion
+
+// check the data we've just read
+`READ (00000, 00CB)
+`READ (00001, 00D2)
+`READ (00002, 00D9)
+`READ (00003, 00E0)
+`READ (00004, 00E7)
+`READ (00005, 00EE)
+`READ (00006, 00F5)
+`READ (00007, 00FC)
+
+// how about reading a single byte?
+`WRITE (00100, 0005) // set bytes_to_output to 5
+`WRITE (00101, 0001) // set bytes_to_receive to 1
+`WRITE (00000, 000B) // fast read spi command + 8 high address bits
+`WRITE (00001, E400) // 16 low address bits
+//`WRITE (00002, 0000) // dummy byte
+`WRITE (00102, BEEF) // start spi operation
+`WRITE (00100, 0000) // force wait for operation completion
+
+`READ (00000, xx1E) // check the byte we've just read
diff --git a/tests/spi_slave/rom.mem b/tests/spi_slave/rom.mem
new file mode 100644
index 0000000..06fff24
--- /dev/null
+++ b/tests/spi_slave/rom.mem
@@ -0,0 +1,258 @@
+// numbers 0, 7, 2*7, 3*7, ..., 256*7 in hex (2 LE bytes for each number)
+0 0
+7 0
+e 0
+15 0
+1c 0
+23 0
+2a 0
+31 0
+38 0
+3f 0
+46 0
+4d 0
+54 0
+5b 0
+62 0
+69 0
+70 0
+77 0
+7e 0
+85 0
+8c 0
+93 0
+9a 0
+a1 0
+a8 0
+af 0
+b6 0
+bd 0
+c4 0
+cb 0
+d2 0
+d9 0
+e0 0
+e7 0
+ee 0
+f5 0
+fc 0
+3 1
+a 1
+11 1
+18 1
+1f 1
+26 1
+2d 1
+34 1
+3b 1
+42 1
+49 1
+50 1
+57 1
+5e 1
+65 1
+6c 1
+73 1
+7a 1
+81 1
+88 1
+8f 1
+96 1
+9d 1
+a4 1
+ab 1
+b2 1
+b9 1
+c0 1
+c7 1
+ce 1
+d5 1
+dc 1
+e3 1
+ea 1
+f1 1
+f8 1
+ff 1
+6 2
+d 2
+14 2
+1b 2
+22 2
+29 2
+30 2
+37 2
+3e 2
+45 2
+4c 2
+53 2
+5a 2
+61 2
+68 2
+6f 2
+76 2
+7d 2
+84 2
+8b 2
+92 2
+99 2
+a0 2
+a7 2
+ae 2
+b5 2
+bc 2
+c3 2
+ca 2
+d1 2
+d8 2
+df 2
+e6 2
+ed 2
+f4 2
+fb 2
+2 3
+9 3
+10 3
+17 3
+1e 3
+25 3
+2c 3
+33 3
+3a 3
+41 3
+48 3
+4f 3
+56 3
+5d 3
+64 3
+6b 3
+72 3
+79 3
+80 3
+87 3
+8e 3
+95 3
+9c 3
+a3 3
+aa 3
+b1 3
+b8 3
+bf 3
+c6 3
+cd 3
+d4 3
+db 3
+e2 3
+e9 3
+f0 3
+f7 3
+fe 3
+5 4
+c 4
+13 4
+1a 4
+21 4
+28 4
+2f 4
+36 4
+3d 4
+44 4
+4b 4
+52 4
+59 4
+60 4
+67 4
+6e 4
+75 4
+7c 4
+83 4
+8a 4
+91 4
+98 4
+9f 4
+a6 4
+ad 4
+b4 4
+bb 4
+c2 4
+c9 4
+d0 4
+d7 4
+de 4
+e5 4
+ec 4
+f3 4
+fa 4
+1 5
+8 5
+f 5
+16 5
+1d 5
+24 5
+2b 5
+32 5
+39 5
+40 5
+47 5
+4e 5
+55 5
+5c 5
+63 5
+6a 5
+71 5
+78 5
+7f 5
+86 5
+8d 5
+94 5
+9b 5
+a2 5
+a9 5
+b0 5
+b7 5
+be 5
+c5 5
+cc 5
+d3 5
+da 5
+e1 5
+e8 5
+ef 5
+f6 5
+fd 5
+4 6
+b 6
+12 6
+19 6
+20 6
+27 6
+2e 6
+35 6
+3c 6
+43 6
+4a 6
+51 6
+58 6
+5f 6
+66 6
+6d 6
+74 6
+7b 6
+82 6
+89 6
+90 6
+97 6
+9e 6
+a5 6
+ac 6
+b3 6
+ba 6
+c1 6
+c8 6
+cf 6
+d6 6
+dd 6
+e4 6
+eb 6
+f2 6
+f9 6
+0 7
diff --git a/tests/spi_slave/test.v b/tests/spi_slave/test.v
new file mode 100644
index 0000000..f489fee
--- /dev/null
+++ b/tests/spi_slave/test.v
@@ -0,0 +1,141 @@
+`default_nettype none
+`timescale 1ns/1ns
+
+`include "messages.vh"
+
+`ifndef MASTER_OPERATIONS_COUNT
+ `error_MASTER_OPERATIONS_COUNT_must_be_defined
+; /* Cause syntax error */
+`endif
+
+`ifndef ROM_WORDS_COUNT
+ `error_ROM_WORDS_COUNT_must_be_defined
+; /* Cause syntax error */
+`endif
+
+`ifndef SIMULATION
+ `error_SIMULATION_not_defined
+; /* Cause syntax error */
+`endif
+
+module spi_test();
+ wire M_ACK_I;
+ wire M_CLK_I;
+ wire [19:0] M_ADR_O;
+ wire [15:0] M_DAT_I;
+ wire [15:0] M_DAT_O;
+ wire M_SEL_O; /* Ignored, assumed always high */
+ wire M_RST_I;
+ wire M_STB_O;
+ wire M_CYC_O;
+ wire M_WE_O;
+ wire M_STALL_I;
+
+ wire S_ACK_O;
+ wire S_CLK_I;
+ wire [8:0] S_ADR_I;
+ wire [15:0] S_DAT_I;
+ wire [15:0] S_DAT_O;
+ wire S_RST_I;
+ wire S_STB_I;
+ wire S_WE_I;
+ wire S_STALL_O;
+
+ /* Non-wishbone */
+ wire sdo;
+ wire sdi;
+ wire sck;
+ wire ss_n;
+
+ wire M_finished;
+
+ master_model
+ #(
+ .MASTER_NR(0),
+ .OPERATIONS_FILE("operations.mem"),
+ .OPERATIONS_COUNT(`MASTER_OPERATIONS_COUNT)
+ ) master
+ (
+ .ACK_I(M_ACK_I),
+ .CLK_I(M_CLK_I),
+ .ADR_O(M_ADR_O),
+ .DAT_I(M_DAT_I),
+ .DAT_O(M_DAT_O),
+ .SEL_O(M_SEL_O),
+ .RST_I(M_RST_I),
+ .STB_O(M_STB_O),
+ .CYC_O(M_CYC_O),
+ .WE_O(M_WE_O),
+ .STALL_I(M_STALL_I),
+
+ .finished(M_finished)
+ );
+
+ spi_slave slave
+ (
+ .ACK_O(S_ACK_O),
+ .CLK_I(S_CLK_I),
+ .ADR_I(S_ADR_I),
+ .DAT_I(S_DAT_I),
+ .DAT_O(S_DAT_O),
+ .RST_I(S_RST_I),
+ .STB_I(S_STB_I),
+ .WE_I(S_WE_I),
+ .STALL_O(S_STALL_O),
+
+ .sdo(sdo),
+ .sdi(sdi),
+ .sck(sck),
+ .ss_n(ss_n)
+ );
+
+ W25Q16BV_flash
+ #(
+ .BYTES_TO_INITIALIZE(`ROM_WORDS_COUNT * 2),
+ .INITIAL_CONTENTS_FILE("rom.mem")
+ ) flash
+ (
+ .sdo(sdo),
+ .sdi(sdi),
+ .sck(sck),
+ .ss_n(ss_n)
+ );
+
+ reg CLK;
+ reg RST;
+
+ assign M_ACK_I = S_ACK_O;
+ assign M_CLK_I = CLK;
+ assign M_DAT_I = S_DAT_O;
+ assign M_RST_I = RST;
+ assign M_STALL_I = S_STALL_O;
+
+ assign S_CLK_I = CLK;
+ assign S_ADR_I = M_ADR_O[8:0]; /* Ignore 11 topmost bits */
+ assign S_DAT_I = M_DAT_O;
+ assign S_RST_I = RST;
+ assign S_STB_I = M_STB_O && M_CYC_O;
+ assign S_WE_I = M_WE_O;
+
+ integer i;
+
+ initial begin
+ CLK <= 0;
+ RST <= 1;
+
+ for (i = 0; i < 600; i++) begin
+ #100; /* longer wait time so that power-up requires less idle ticks */
+
+ CLK <= ~CLK;
+
+ if (CLK)
+ RST <= 0;
+
+ if (M_finished)
+ $finish;
+ end
+
+ $display("error: master hasn't finished its operations in 300 ticks");
+ $finish;
+ end
+endmodule // spi_test