diff --git a/.gitignore b/.gitignore index 2022211..957c3ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -obj_dir -*mode[01][01].* +simtop_* diff --git a/COPYING_OHL b/COPYING_OHL new file mode 100644 index 0000000..7c98175 --- /dev/null +++ b/COPYING_OHL @@ -0,0 +1,311 @@ +CERN Open Hardware Licence Version 2 - Weakly Reciprocal + + +Preamble + +CERN has developed this licence to promote collaboration among +hardware designers and to provide a legal tool which supports the +freedom to use, study, modify, share and distribute hardware designs +and products based on those designs. Version 2 of the CERN Open +Hardware Licence comes in three variants: CERN-OHL-P (permissive); and +two reciprocal licences: this licence, CERN-OHL-W (weakly reciprocal) +and CERN-OHL-S (strongly reciprocal). + +The CERN-OHL-W is copyright CERN 2020. Anyone is welcome to use it, in +unmodified form only. + +Use of this Licence does not imply any endorsement by CERN of any +Licensor or their designs nor does it imply any involvement by CERN in +their development. + + +1 Definitions + + 1.1 'Licence' means this CERN-OHL-W. + + 1.2 'Compatible Licence' means + + a) any earlier version of the CERN Open Hardware licence, or + + b) any version of the CERN-OHL-S or the CERN-OHL-W, or + + c) any licence which permits You to treat the Source to which + it applies as licensed under CERN-OHL-S or CERN-OHL-W + provided that on Conveyance of any such Source, or any + associated Product You treat the Source in question as being + licensed under CERN-OHL-S or CERN-OHL-W as appropriate. + + 1.3 'Source' means information such as design materials or digital + code which can be applied to Make or test a Product or to + prepare a Product for use, Conveyance or sale, regardless of its + medium or how it is expressed. It may include Notices. + + 1.4 'Covered Source' means Source that is explicitly made available + under this Licence. + + 1.5 'Product' means any device, component, work or physical object, + whether in finished or intermediate form, arising from the use, + application or processing of Covered Source. + + 1.6 'Make' means to create or configure something, whether by + manufacture, assembly, compiling, loading or applying Covered + Source or another Product or otherwise. + + 1.7 'Available Component' means any part, sub-assembly, library or + code which: + + a) is licensed to You as Complete Source under a Compatible + Licence; or + + b) is available, at the time a Product or the Source containing + it is first Conveyed, to You and any other prospective + licensees + + i) with sufficient rights and information (including any + configuration and programming files and information + about its characteristics and interfaces) to enable it + either to be Made itself, or to be sourced and used to + Make the Product; or + ii) as part of the normal distribution of a tool used to + design or Make the Product. + + 1.8 'External Material' means anything (including Source) which: + + a) is only combined with Covered Source in such a way that it + interfaces with the Covered Source using a documented + interface which is described in the Covered Source; and + + b) is not a derivative of or contains Covered Source, or, if it + is, it is solely to the extent necessary to facilitate such + interfacing. + + 1.9 'Complete Source' means the set of all Source necessary to Make + a Product, in the preferred form for making modifications, + including necessary installation and interfacing information + both for the Product, and for any included Available Components. + If the format is proprietary, it must also be made available in + a format (if the proprietary tool can create it) which is + viewable with a tool available to potential licensees and + licensed under a licence approved by the Free Software + Foundation or the Open Source Initiative. Complete Source need + not include the Source of any Available Component, provided that + You include in the Complete Source sufficient information to + enable a recipient to Make or source and use the Available + Component to Make the Product. + + 1.10 'Source Location' means a location where a Licensor has placed + Covered Source, and which that Licensor reasonably believes will + remain easily accessible for at least three years for anyone to + obtain a digital copy. + + 1.11 'Notice' means copyright, acknowledgement and trademark notices, + Source Location references, modification notices (subsection + 3.3(b)) and all notices that refer to this Licence and to the + disclaimer of warranties that are included in the Covered + Source. + + 1.12 'Licensee' or 'You' means any person exercising rights under + this Licence. + + 1.13 'Licensor' means a natural or legal person who creates or + modifies Covered Source. A person may be a Licensee and a + Licensor at the same time. + + 1.14 'Convey' means to communicate to the public or distribute. + + +2 Applicability + + 2.1 This Licence governs the use, copying, modification, Conveying + of Covered Source and Products, and the Making of Products. By + exercising any right granted under this Licence, You irrevocably + accept these terms and conditions. + + 2.2 This Licence is granted by the Licensor directly to You, and + shall apply worldwide and without limitation in time. + + 2.3 You shall not attempt to restrict by contract or otherwise the + rights granted under this Licence to other Licensees. + + 2.4 This Licence is not intended to restrict fair use, fair dealing, + or any other similar right. + + +3 Copying, Modifying and Conveying Covered Source + + 3.1 You may copy and Convey verbatim copies of Covered Source, in + any medium, provided You retain all Notices. + + 3.2 You may modify Covered Source, other than Notices, provided that + You irrevocably undertake to make that modified Covered Source + available from a Source Location should You Convey a Product in + circumstances where the recipient does not otherwise receive a + copy of the modified Covered Source. In each case subsection 3.3 + shall apply. + + You may only delete Notices if they are no longer applicable to + the corresponding Covered Source as modified by You and You may + add additional Notices applicable to Your modifications. + + 3.3 You may Convey modified Covered Source (with the effect that You + shall also become a Licensor) provided that You: + + a) retain Notices as required in subsection 3.2; + + b) add a Notice to the modified Covered Source stating that You + have modified it, with the date and brief description of how + You have modified it; + + c) add a Source Location Notice for the modified Covered Source + if You Convey in circumstances where the recipient does not + otherwise receive a copy of the modified Covered Source; and + + d) license the modified Covered Source under the terms and + conditions of this Licence (or, as set out in subsection + 8.3, a later version, if permitted by the licence of the + original Covered Source). Such modified Covered Source must + be licensed as a whole, but excluding Available Components + contained in it or External Material to which it is + interfaced, which remain licensed under their own applicable + licences. + + +4 Making and Conveying Products + + 4.1 You may Make Products, and/or Convey them, provided that You + either provide each recipient with a copy of the Complete Source + or ensure that each recipient is notified of the Source Location + of the Complete Source. That Complete Source includes Covered + Source and You must accordingly satisfy Your obligations set out + in subsection 3.3. If specified in a Notice, the Product must + visibly and securely display the Source Location on it or its + packaging or documentation in the manner specified in that + Notice. + + 4.2 Where You Convey a Product which incorporates External Material, + the Complete Source for that Product which You are required to + provide under subsection 4.1 need not include any Source for the + External Material. + + 4.3 You may license Products under terms of Your choice, provided + that such terms do not restrict or attempt to restrict any + recipients' rights under this Licence to the Covered Source. + + +5 Research and Development + +You may Convey Covered Source, modified Covered Source or Products to +a legal entity carrying out development, testing or quality assurance +work on Your behalf provided that the work is performed on terms which +prevent the entity from both using the Source or Products for its own +internal purposes and Conveying the Source or Products or any +modifications to them to any person other than You. Any modifications +made by the entity shall be deemed to be made by You pursuant to +subsection 3.2. + + +6 DISCLAIMER AND LIABILITY + + 6.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products + are provided 'as is' and any express or implied warranties, + including, but not limited to, implied warranties of + merchantability, of satisfactory quality, non-infringement of + third party rights, and fitness for a particular purpose or use + are disclaimed in respect of any Source or Product to the + maximum extent permitted by law. The Licensor makes no + representation that any Source or Product does not or will not + infringe any patent, copyright, trade secret or other + proprietary right. The entire risk as to the use, quality, and + performance of any Source or Product shall be with You and not + the Licensor. This disclaimer of warranty is an essential part + of this Licence and a condition for the grant of any rights + granted under this Licence. + + 6.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to + the maximum extent permitted by law, have no liability for + direct, indirect, special, incidental, consequential, exemplary, + punitive or other damages of any character including, without + limitation, procurement of substitute goods or services, loss of + use, data or profits, or business interruption, however caused + and on any theory of contract, warranty, tort (including + negligence), product liability or otherwise, arising in any way + in relation to the Covered Source, modified Covered Source + and/or the Making or Conveyance of a Product, even if advised of + the possibility of such damages, and You shall hold the + Licensor(s) free and harmless from any liability, costs, + damages, fees and expenses, including claims by third parties, + in relation to such use. + + +7 Patents + + 7.1 Subject to the terms and conditions of this Licence, each + Licensor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as + stated in subsections 7.2 and 8.4) patent licence to Make, have + Made, use, offer to sell, sell, import, and otherwise transfer + the Covered Source and Products, where such licence applies only + to those patent claims licensable by such Licensor that are + necessarily infringed by exercising rights under the Covered + Source as Conveyed by that Licensor. + + 7.2 If You institute patent litigation against any entity (including + a cross-claim or counterclaim in a lawsuit) alleging that the + Covered Source or a Product constitutes direct or contributory + patent infringement, or You seek any declaration that a patent + licensed to You under this Licence is invalid or unenforceable + then any rights granted to You under this Licence shall + terminate as of the date such process is initiated. + + +8 General + + 8.1 If any provisions of this Licence are or subsequently become + invalid or unenforceable for any reason, the remaining + provisions shall remain effective. + + 8.2 You shall not use any of the name (including acronyms and + abbreviations), image, or logo by which the Licensor or CERN is + known, except where needed to comply with section 3, or where + the use is otherwise allowed by law. Any such permitted use + shall be factual and shall not be made so as to suggest any kind + of endorsement or implication of involvement by the Licensor or + its personnel. + + 8.3 CERN may publish updated versions and variants of this Licence + which it considers to be in the spirit of this version, but may + differ in detail to address new problems or concerns. New + versions will be published with a unique version number and a + variant identifier specifying the variant. If the Licensor has + specified that a given variant applies to the Covered Source + without specifying a version, You may treat that Covered Source + as being released under any version of the CERN-OHL with that + variant. If no variant is specified, the Covered Source shall be + treated as being released under CERN-OHL-S. The Licensor may + also specify that the Covered Source is subject to a specific + version of the CERN-OHL or any later version in which case You + may apply this or any later version of CERN-OHL with the same + variant identifier published by CERN. + + You may treat Covered Source licensed under CERN-OHL-W as + licensed under CERN-OHL-S if and only if all Available + Components referenced in the Covered Source comply with the + corresponding definition of Available Component for CERN-OHL-S. + + 8.4 This Licence shall terminate with immediate effect if You fail + to comply with any of its terms and conditions. + + 8.5 However, if You cease all breaches of this Licence, then Your + Licence from any Licensor is reinstated unless such Licensor has + terminated this Licence by giving You, while You remain in + breach, a notice specifying the breach and requiring You to cure + it within 30 days, and You have failed to come into compliance + in all material respects by the end of the 30 day period. Should + You repeat the breach after receipt of a cure notice and + subsequent reinstatement, this Licence will terminate + immediately and permanently. Section 6 shall continue to apply + after any termination. + + 8.6 This Licence shall not be enforceable except by a Licensor + acting as such, and third party beneficiary rights are + specifically excluded. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 1da0cc8..6fdee35 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,13 @@ via parameters. ## License -This Program is subject to the terms of the Mozilla Public License, -v.2.0. A copy of this license may be found in the file `COPYING`. You +All code in this project is licensed to the terms of the Mozilla Public +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). + ## Tests Go into `tests` and run `make`. To rerun tests, run `make clean` followed diff --git a/spi_master.v b/spi_master.v index cc5f01d..ae75394 100644 --- a/spi_master.v +++ b/spi_master.v @@ -31,10 +31,10 @@ spi_master `endif `ifndef SPI_MASTER_NO_WRITE input [WID-1:0] to_slave, - output mosi, + output reg mosi, `endif - output sck_wire, - output finished, + output reg sck_wire, + output reg finished, input arm ); @@ -141,7 +141,7 @@ always @ (posedge clk) begin timer <= 0; // Stop transfer when the clock returns // to its original polarity. - if (bit_counter == WID && sck == POLARITY) begin + if (bit_counter == WID[WID_LEN-1:0] && sck == POLARITY[0]) begin state <= WAIT_FINISHED; end else begin state <= ON_CYCLE; diff --git a/spi_master_no_read.v b/spi_master_no_read.v new file mode 100644 index 0000000..0999807 --- /dev/null +++ b/spi_master_no_read.v @@ -0,0 +1,3 @@ +`define SPI_MASTER_NO_READ +/* verilator lint_off DECLFILENAME */ +`include "spi_master.v" diff --git a/spi_slave.v b/spi_slave.v index 6efacdd..4c15e37 100644 --- a/spi_slave.v +++ b/spi_slave.v @@ -77,7 +77,7 @@ task setup_bits(); endtask task check_counter(); - if (bit_counter == WID) begin + if (bit_counter == WID[WID_LEN-1:0]) begin err <= ready_at_start; end else begin bit_counter <= bit_counter + 1; diff --git a/spi_slave_no_write.v b/spi_slave_no_write.v new file mode 100644 index 0000000..f60ea0b --- /dev/null +++ b/spi_slave_no_write.v @@ -0,0 +1,3 @@ +`define SPI_SLAVE_NO_WRITE +/* verilator lint_off DECLFILENAME */ +`include "spi_slave.v" diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 085cd92..0000000 --- a/tests/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -MODES=00 01 10 11 - -all: - for i in ${MODES}; do \ - make -f run_mode.makefile MODE="$$i"; \ - make -f run_mode.makefile MODE="$$i" PREFIX="read_only_" MASTER_TYPE="_no_write" SLAVE_TYPE="_no_read"; \ - done - -clean: - rm -rf obj_dir mode[01][01]* read_only_mode[01][01]* diff --git a/tests/mk.sh b/tests/mk.sh new file mode 100755 index 0000000..f907668 --- /dev/null +++ b/tests/mk.sh @@ -0,0 +1,54 @@ +#!/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 -) + + verilator --cc --exe -I.. -Wall -Wno-unused --trace \ + --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 \ + --Mdir $DIR \ + $EXTARG \ + simtop.v write_read.cpp $MODS + + 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" + ) + + ( \ + 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" + ) + + ( \ + 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" + ) + + done +done diff --git a/tests/mode_template.cpp b/tests/mode_template.cpp deleted file mode 100644 index 4b46fb4..0000000 --- a/tests/mode_template.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "Vmode@MODE@.h" -using TopModule = Vmode@MODE@; -#include "write_read.cpp" diff --git a/tests/mode_template.v b/tests/mode_template.v deleted file mode 100644 index 1df59b8..0000000 --- a/tests/mode_template.v +++ /dev/null @@ -1,34 +0,0 @@ -/* (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/. - */ - -module mode@MODE@ ( - input clk, - input [23:0] data_ctrl, - input activate, - input ss, - input rdy, - output master_finished -); - -spi_write_read -#( - .POLARITY(@POLARITY@), - .PHASE(@PHASE@) -) base ( - .clk(clk), - .data_ctrl(data_ctrl), - .activate(activate), - .master_finished(master_finished), - .ss(ss), - .rdy(rdy) -); - -initial begin - $dumpfile("mode@MODE@.vcd"); - $dumpvars(); -end - -endmodule diff --git a/tests/read_only_mode_template.cpp b/tests/read_only_mode_template.cpp deleted file mode 100644 index d09a0be..0000000 --- a/tests/read_only_mode_template.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "Vread_only_mode@MODE@.h" -using TopModule = Vread_only_mode@MODE@; -#define READ_ONLY -#include "write_read.cpp" diff --git a/tests/read_only_mode_template.v b/tests/read_only_mode_template.v deleted file mode 100644 index cd10c7d..0000000 --- a/tests/read_only_mode_template.v +++ /dev/null @@ -1,57 +0,0 @@ -/* (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/. - */ - -module read_only_mode@MODE@ ( - input clk, - input activate, - input ss, - input rdy, - output master_finished -); - -wire miso; -wire sck; -wire ss_L = !ss; -reg [23:0] from_slave_data; -reg finished; -reg err; - -spi_master_no_write -#( - .POLARITY(@POLARITY@), - .PHASE(@PHASE@) -) master ( - .clk(clk), - .from_slave(from_slave_data), - .miso(miso), - .sck_wire(sck), - .finished(master_finished), - .arm(activate) -); - -reg [23:0] to_master = 24'hF4325F; - -spi_slave_no_read -#( - .POLARITY(@POLARITY@), - .PHASE(@PHASE@) -) slave ( - .clk(clk), - .sck(sck), - .ss_L(ss_L), - .to_master(to_master), - .miso(miso), - .finished(finished), - .rdy(rdy), - .err(finished) -); - -initial begin - $dumpfile("read_only_mode@MODE@.vcd"); - $dumpvars(); -end - -endmodule diff --git a/tests/run_mode.makefile b/tests/run_mode.makefile deleted file mode 100644 index 2b48053..0000000 --- a/tests/run_mode.makefile +++ /dev/null @@ -1,24 +0,0 @@ -# (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/. - -TESTBENCH_BASE=${PREFIX}mode${MODE} -AUXFILES=../spi_master${MASTER_TYPE}.v ../spi_slave${SLAVE_TYPE}.v - -CPP_TESTBENCH=${TESTBENCH_BASE}.cpp -WAVEFILE=${TESTBENCH_BASE}.vcd - -FILES=${TESTBENCH_BASE}.v ${AUXFILES} ${CPP_TESTBENCH} - -${WAVEFILE}: obj_dir/V${TESTBENCH_BASE} - ./obj_dir/V${TESTBENCH_BASE} - -obj_dir/V${TESTBENCH_BASE}.mk: ${FILES} - verilator -I.. -Wall -Wno-unused -Wpedantic --trace --cc --exe ${FILES} --top ${TESTBENCH_BASE} -obj_dir/V${TESTBENCH_BASE}: obj_dir/V${TESTBENCH_BASE}.mk - make -C obj_dir -f V${TESTBENCH_BASE}.mk -${TESTBENCH_BASE}.v: mode_template.v - sed "s/@PHASE@/`echo ${MODE} | cut -c 2`/g; s/@POLARITY@/`echo ${MODE} | cut -c 1`/g; s/@MODE@/${MODE}/g" ${PREFIX}mode_template.v > ${TESTBENCH_BASE}.v -${TESTBENCH_BASE}.cpp: mode_template.cpp - sed "s/@PHASE@/`echo ${MODE} | cut -c 2`/g; s/@POLARITY@/`echo ${MODE} | cut -c 1`/g; s/@MODE@/${MODE}/g" ${PREFIX}mode_template.cpp > ${TESTBENCH_BASE}.cpp diff --git a/tests/simtop.v b/tests/simtop.v new file mode 100644 index 0000000..91533fd --- /dev/null +++ b/tests/simtop.v @@ -0,0 +1,87 @@ +/* (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/. + */ + +module simtop +#( + parameter POLARITY = 0, + parameter PHASE = 0, + parameter WID = 24, + parameter WID_LEN = 5 +) ( + input clk, +`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, + input ss, + input rdy, + output master_finished, + output err +); + +`ifndef SPI_MASTER_NO_READ +wire miso; +`endif + +`ifndef SPI_MASTER_NO_WRITE +wire mosi; +`endif + +wire sck; +wire ss_L = !ss; + +reg slave_finished; +reg slave_error; + +`SPI_MASTER_TYPE +#( + .POLARITY(POLARITY), + .PHASE(PHASE), + .WID(WID), + .WID_LEN(WID_LEN) +) master ( + .clk(clk), +`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 + .sck_wire(sck), + .finished(master_finished), + .arm(activate) +); + +`SPI_SLAVE_TYPE #( + .POLARITY(POLARITY), + .PHASE(PHASE), + .WID(WID), + .WID_LEN(WID_LEN) +) slave ( + .clk(clk), + .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) +); + +endmodule diff --git a/tests/spi_write_read.v b/tests/spi_write_read.v deleted file mode 100644 index efd9e88..0000000 --- a/tests/spi_write_read.v +++ /dev/null @@ -1,70 +0,0 @@ -/* (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/. - */ - -module spi_write_read -#( - parameter POLARITY = 0, - parameter PHASE = 0 -) -( - input clk, - input [23:0] data_ctrl, - input activate, - input ss, - input rdy, - output master_finished -); - -wire miso; -wire mosi; -wire sck; -wire ss_L = !ss; - -reg [23:0] from_slave_data; -reg slave_finished; -reg slave_error; - -spi_master -#( - .POLARITY(POLARITY), - .PHASE(PHASE) -) master ( - .clk(clk), - .to_slave(data_ctrl), - .from_slave(from_slave_data), - .miso(miso), - .mosi(mosi), - .sck_wire(sck), - .finished(master_finished), - .arm(activate) -); - -reg [23:0] data_from_master; -reg [23:0] data_to_master = 24'b111011011100010101010101; - -spi_slave #( - .POLARITY(POLARITY), - .PHASE(PHASE) -) slave ( - .clk(clk), - .sck(sck), - .ss_L(ss_L), - .from_master(data_from_master), - .to_master(data_to_master), - .mosi(mosi), - .miso(miso), - .finished(slave_finished), - .rdy(rdy), - .err(slave_error) -); - -always @ (posedge clk) begin - if (slave_finished) begin - data_to_master <= data_from_master; - end -end - -endmodule diff --git a/tests/write_read.cpp b/tests/write_read.cpp index 45bdc5a..2394b63 100644 --- a/tests/write_read.cpp +++ b/tests/write_read.cpp @@ -1,12 +1,21 @@ #include #include +#include "Vsimtop.h" -VerilatedContext *ctx; -TopModule *sim; +Vsimtop *sim; + +uint32_t main_time = 0; + +double sc_time_stamp() { + return main_time; +} static void progress() { sim->eval(); - ctx->timeInc(1); + main_time++; + sim->clk = !sim->clk; + sim->eval(); + main_time++; sim->clk = !sim->clk; } @@ -15,49 +24,67 @@ static void progress_n(int f) { progress(); } +static void test_cross_transfer(unsigned m2s, unsigned s2m) { +#ifndef SPI_MASTER_NO_WRITE + sim->master_to_slave = m2s; +#endif +#ifndef SPI_MASTER_NO_READ + sim->slave_to_master = s2m; +#endif + + progress(); + sim->ss = 1; + sim->rdy = 1; + sim->activate = 1; + progress(); + + while (!sim->master_finished) + progress(); + + progress_n(5); + sim->activate = 0; + sim->ss = 0; + sim->rdy = 0; + progress_n(5); + + if (sim->err) { + printf("slave error\n"); + } + +#ifndef SPI_MASTER_NO_WRITE + if (sim->master_to_slave != sim->from_master) { + printf("(m2s) %lx != %lx\n", sim->master_to_slave, sim->from_master); + } +#endif + +#ifndef SPI_MASTER_NO_READ + if (sim->slave_to_master != sim->from_slave) { + printf("(m2s) %lx != %lx\n", sim->slave_to_master, sim->from_slave); + } +#endif + +} + int main(int argc, char **argv) { - ctx = new VerilatedContext; - ctx->traceEverOn(true); - ctx->commandArgs(argc, argv); - sim = new TopModule(ctx); + int r = 0; + (void)r; + + Verilated::commandArgs(argc, argv); + Verilated::traceEverOn(true); + + sim = new Vsimtop; sim->ss = 0; sim->clk = 0; sim->activate = 0; sim->rdy = 0; - progress_n(8); - sim->ss = 1; - sim->rdy = 1; - progress(); - -#ifndef READ_ONLY - sim->data_ctrl = 0b110011011111001100011111; -#endif - sim->activate = 1; - - while (!sim->master_finished) - progress(); - progress_n(5); - sim->activate = 0; - sim->ss = 0; - sim->rdy = 0; - progress_n(5); - -#ifndef READ_ONLY - sim->data_ctrl = 0xFE3456; - sim->activate = 1; - sim->ss = 1; - sim->rdy = 1; - while (!sim->master_finished) - progress(); - progress_n(5); - sim->activate = 0; - sim->ss = 0; - sim->rdy = 0; - progress_n(5); -#endif + for (int i = 0; i < 10000; i++) { + unsigned m2s = rand() & ((1 << WID) - 1); + unsigned s2m = rand() & ((1 << WID) - 1); + test_cross_transfer(m2s, s2m); + } sim->final(); delete sim; - return 0; + return r; }