diff options
author | Martin Braun <martin.braun@ettus.com> | 2020-01-23 16:10:22 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2020-01-28 09:35:36 -0800 |
commit | bafa9d95453387814ef25e6b6256ba8db2df612f (patch) | |
tree | 39ba24b5b67072d354775272e687796bb511848d /fpga/usrp3/lib/wb_spi | |
parent | 3075b981503002df3115d5f1d0b97d2619ba30f2 (diff) | |
download | uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.gz uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.bz2 uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.zip |
Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.
This commit also updates the license files and paths therein.
We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.
== Original Codebase and Rebasing ==
The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/
It can be used for bisecting, reference, and a more detailed history.
The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.
If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:
- Create a directory to store patches (this should be an empty
directory):
mkdir ~/patches
- Now make sure that your FPGA codebase is based on the same state as
the code that was merged:
cd src/fpga # Or wherever your FPGA code is stored
git rebase v4.0.0.0-pre-uhd-merge
Note: The rebase command may look slightly different depending on what
exactly you're trying to rebase.
- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:
git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches
Note: Make sure that only patches are stored in your output directory.
It should otherwise be empty. Make sure that you picked the correct
range of commits, and only commits you wanted to rebase were exported
as patch files.
- Go to the UHD repository and apply the patches:
cd src/uhd # Or wherever your UHD repository is stored
git am --directory fpga ~/patches/*
rm -rf ~/patches # This is for cleanup
== Contributors ==
The following people have contributed mainly to these files (this list
is not complete):
Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>
Diffstat (limited to 'fpga/usrp3/lib/wb_spi')
-rw-r--r-- | fpga/usrp3/lib/wb_spi/Makefile.srcs | 14 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/bench/verilog/spi_slave_model.v | 73 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/bench/verilog/tb_spi_top.v | 339 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/bench/verilog/wb_master_model.v | 176 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/doc/spi.pdf | bin | 0 -> 78741 bytes | |||
-rwxr-xr-x | fpga/usrp3/lib/wb_spi/doc/src/spi.doc | bin | 0 -> 231936 bytes | |||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/rtl/verilog/spi_clgen.v | 105 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/rtl/verilog/spi_defines.v | 161 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/rtl/verilog/spi_shift.v | 235 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top.v | 289 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top16.v | 184 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/rtl.fl | 3 | ||||
-rwxr-xr-x | fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/run_sim | 108 | ||||
-rw-r--r-- | fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/sim.fl | 3 |
14 files changed, 1690 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/wb_spi/Makefile.srcs b/fpga/usrp3/lib/wb_spi/Makefile.srcs new file mode 100644 index 000000000..43048a126 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/Makefile.srcs @@ -0,0 +1,14 @@ +# +# Copyright 2013 Ettus Research LLC +# + +################################################## +# Control Lib Sources +################################################## +WB_SPI_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/wb_spi/, \ +rtl/verilog/spi_clgen.v \ +rtl/verilog/spi_defines.v \ +rtl/verilog/spi_shift.v \ +rtl/verilog/spi_top16.v \ +rtl/verilog/spi_top.v \ +)) diff --git a/fpga/usrp3/lib/wb_spi/bench/verilog/spi_slave_model.v b/fpga/usrp3/lib/wb_spi/bench/verilog/spi_slave_model.v new file mode 100644 index 000000000..dfdaed929 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/bench/verilog/spi_slave_model.v @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_slave_model.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "timescale.v" + +module spi_slave_model (rst, ss, sclk, mosi, miso); + + input rst; // reset + input ss; // slave select + input sclk; // serial clock + input mosi; // master out slave in + output miso; // master in slave out + + reg miso; + + reg rx_negedge; // slave receiving on negedge + reg tx_negedge; // slave transmiting on negedge + reg [31:0] data; // data register + + parameter Tp = 1; + + always @(posedge(sclk && !rx_negedge) or negedge(sclk && rx_negedge) or rst) + begin + if (rst) + data <= #Tp 32'b0; + else if (!ss) + data <= #Tp {data[30:0], mosi}; + end + + always @(posedge(sclk && !tx_negedge) or negedge(sclk && tx_negedge)) + begin + miso <= #Tp data[31]; + end + +endmodule + diff --git a/fpga/usrp3/lib/wb_spi/bench/verilog/tb_spi_top.v b/fpga/usrp3/lib/wb_spi/bench/verilog/tb_spi_top.v new file mode 100644 index 000000000..529c0aca1 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/bench/verilog/tb_spi_top.v @@ -0,0 +1,339 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// tb_spi_top.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// Based on: //// +//// - i2c/bench/verilog/tst_bench_top.v //// +//// Copyright (C) 2001 Richard Herveille //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "timescale.v" + +module tb_spi_top(); + + reg clk; + reg rst; + wire [31:0] adr; + wire [31:0] dat_i, dat_o; + wire we; + wire [3:0] sel; + wire stb; + wire cyc; + wire ack; + wire err; + wire int; + + wire [7:0] ss; + wire sclk; + wire mosi; + wire miso; + + reg [31:0] q; + reg [31:0] q1; + reg [31:0] q2; + reg [31:0] q3; + reg [31:0] result; + + parameter SPI_RX_0 = 5'h0; + parameter SPI_RX_1 = 5'h4; + parameter SPI_RX_2 = 5'h8; + parameter SPI_RX_3 = 5'hc; + parameter SPI_TX_0 = 5'h0; + parameter SPI_TX_1 = 5'h4; + parameter SPI_TX_2 = 5'h8; + parameter SPI_TX_3 = 5'hc; + parameter SPI_CTRL = 5'h10; + parameter SPI_DIVIDE = 5'h14; + parameter SPI_SS = 5'h18; + + // Generate clock + always #5 clk = ~clk; + + // Wishbone master model + wb_master_model #(32, 32) i_wb_master ( + .clk(clk), .rst(rst), + .adr(adr), .din(dat_i), .dout(dat_o), + .cyc(cyc), .stb(stb), .we(we), .sel(sel), .ack(ack), .err(err), .rty(1'b0) + ); + + // SPI master core + spi_top i_spi_top ( + .wb_clk_i(clk), .wb_rst_i(rst), + .wb_adr_i(adr[4:0]), .wb_dat_i(dat_o), .wb_dat_o(dat_i), + .wb_sel_i(sel), .wb_we_i(we), .wb_stb_i(stb), + .wb_cyc_i(cyc), .wb_ack_o(ack), .wb_err_o(err), .wb_int_o(int), + .ss_pad_o(ss), .sclk_pad_o(sclk), .mosi_pad_o(mosi), .miso_pad_i(miso) + ); + + // SPI slave model + spi_slave_model i_spi_slave ( + .rst(rst), .ss(ss[0]), .sclk(sclk), .mosi(mosi), .miso(miso) + ); + + initial + begin + $display("\nstatus: %t Testbench started\n\n", $time); + + $dumpfile("bench.vcd"); + $dumpvars(1, tb_spi_top); + $dumpvars(1, tb_spi_top.i_spi_slave); + + // Initial values + clk = 0; + + i_spi_slave.rx_negedge = 1'b0; + i_spi_slave.tx_negedge = 1'b0; + + result = 32'h0; + + // Reset system + rst = 1'b0; // negate reset + #2; + rst = 1'b1; // assert reset + repeat(20) @(posedge clk); + rst = 1'b0; // negate reset + + $display("status: %t done reset", $time); + + @(posedge clk); + + // Program core + i_wb_master.wb_write(0, SPI_DIVIDE, 32'h00); // set devider register + i_wb_master.wb_write(0, SPI_TX_0, 32'h5a); // set tx register to 0x5a + i_wb_master.wb_write(0, SPI_CTRL, 32'h208); // set 8 bit transfer + i_wb_master.wb_write(0, SPI_SS, 32'h01); // set ss 0 + + $display("status: %t programmed registers", $time); + + i_wb_master.wb_cmp(0, SPI_DIVIDE, 32'h00); // verify devider register + i_wb_master.wb_cmp(0, SPI_TX_0, 32'h5a); // verify tx register + i_wb_master.wb_cmp(0, SPI_CTRL, 32'h208); // verify tx register + i_wb_master.wb_cmp(0, SPI_SS, 32'h01); // verify ss register + + $display("status: %t verified registers", $time); + + i_spi_slave.rx_negedge = 1'b1; + i_spi_slave.tx_negedge = 1'b0; + i_spi_slave.data[31:0] = 32'ha5967e5a; + i_wb_master.wb_write(0, SPI_CTRL, 32'h308); // set 8 bit transfer, start transfer + + $display("status: %t generate transfer: 8 bit, msb first, tx posedge, rx negedge", $time); + + // Check bsy bit + i_wb_master.wb_read(0, SPI_CTRL, q); + while (q[8]) + i_wb_master.wb_read(1, SPI_CTRL, q); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + if (i_spi_slave.data[7:0] == 8'h5a && q == 32'h000000a5) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b0; + i_spi_slave.tx_negedge = 1'b1; + i_wb_master.wb_write(0, SPI_TX_0, 32'ha5); + i_wb_master.wb_write(0, SPI_CTRL, 32'h408); // set 8 bit transfer, tx negedge + i_wb_master.wb_write(0, SPI_CTRL, 32'h508); // set 8 bit transfer, tx negedge, start transfer + + $display("status: %t generate transfer: 8 bit, msb first, tx negedge, rx posedge", $time); + + // Check bsy bit + i_wb_master.wb_read(0, SPI_CTRL, q); + while (q[8]) + i_wb_master.wb_read(1, SPI_CTRL, q); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + if (i_spi_slave.data[7:0] == 8'ha5 && q == 32'h00000096) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b0; + i_spi_slave.tx_negedge = 1'b1; + i_wb_master.wb_write(0, SPI_TX_0, 32'h5aa5); + i_wb_master.wb_write(0, SPI_CTRL, 32'hc10); // set 16 bit transfer, tx negedge, lsb + i_wb_master.wb_write(0, SPI_CTRL, 32'hd10); // set 16 bit transfer, tx negedge, start transfer + + $display("status: %t generate transfer: 16 bit, lsb first, tx negedge, rx posedge", $time); + + // Check bsy bit + i_wb_master.wb_read(0, SPI_CTRL, q); + while (q[8]) + i_wb_master.wb_read(1, SPI_CTRL, q); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + if (i_spi_slave.data[15:0] == 16'ha55a && q == 32'h00005a7e) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b1; + i_spi_slave.tx_negedge = 1'b0; + i_wb_master.wb_write(0, SPI_TX_0, 32'h76543210); + i_wb_master.wb_write(0, SPI_TX_1, 32'hfedcba98); + i_wb_master.wb_write(0, SPI_CTRL, 32'h1a40); // set 64 bit transfer, rx negedge, lsb + i_wb_master.wb_write(0, SPI_CTRL, 32'h1b40); // set 64 bit transfer, rx negedge, start transfer + + $display("status: %t generate transfer: 64 bit, lsb first, tx posedge, rx negedge", $time); + + // Check bsy bit + i_wb_master.wb_read(0, SPI_CTRL, q); + while (q[8]) + i_wb_master.wb_read(1, SPI_CTRL, q); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + i_wb_master.wb_read(1, SPI_RX_1, q1); + result = result + q1; + + if (i_spi_slave.data == 32'h195d3b7f && q == 32'h5aa5a55a && q1 == 32'h76543210) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b0; + i_spi_slave.tx_negedge = 1'b1; + i_wb_master.wb_write(0, SPI_TX_0, 32'hccddeeff); + i_wb_master.wb_write(0, SPI_TX_1, 32'h8899aabb); + i_wb_master.wb_write(0, SPI_TX_2, 32'h44556677); + i_wb_master.wb_write(0, SPI_TX_3, 32'h00112233); + i_wb_master.wb_write(0, SPI_CTRL, 32'h400); + i_wb_master.wb_write(0, SPI_CTRL, 32'h500); + + $display("status: %t generate transfer: 128 bit, msb first, tx posedge, rx negedge", $time); + + // Check bsy bit + i_wb_master.wb_read(0, SPI_CTRL, q); + while (q[8]) + i_wb_master.wb_read(1, SPI_CTRL, q); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + i_wb_master.wb_read(1, SPI_RX_1, q1); + result = result + q1; + i_wb_master.wb_read(1, SPI_RX_2, q2); + result = result + q2; + i_wb_master.wb_read(1, SPI_RX_3, q3); + result = result + q3; + + if (i_spi_slave.data == 32'hccddeeff && q == 32'h8899aabb && q1 == 32'h44556677 && q2 == 32'h00112233 && q3 == 32'h195d3b7f) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b0; + i_spi_slave.tx_negedge = 1'b1; + i_wb_master.wb_write(0, SPI_TX_0, 32'haa55a5a5); + i_wb_master.wb_write(0, SPI_CTRL, 32'h1420); + i_wb_master.wb_write(0, SPI_CTRL, 32'h1520); + + $display("status: %t generate transfer: 32 bit, msb first, tx negedge, rx posedge, ie", $time); + + // Check interrupt signal + while (!int) + @(posedge clk); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + @(posedge clk); + if (!int && i_spi_slave.data == 32'haa55a5a5 && q == 32'hccddeeff) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b1; + i_spi_slave.tx_negedge = 1'b0; + i_wb_master.wb_write(0, SPI_TX_0, 32'h01248421); + i_wb_master.wb_write(0, SPI_CTRL, 32'h3220); + i_wb_master.wb_write(0, SPI_CTRL, 32'h3320); + + $display("status: %t generate transfer: 32 bit, msb first, tx posedge, rx negedge, ie, ass", $time); + + while (!int) + @(posedge clk); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + @(posedge clk); + if (!int && i_spi_slave.data == 32'h01248421 && q == 32'haa55a5a5) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + i_spi_slave.rx_negedge = 1'b1; + i_spi_slave.tx_negedge = 1'b0; + i_wb_master.wb_write(0, SPI_TX_0, 32'h1); + i_wb_master.wb_write(0, SPI_CTRL, 32'h3201); + i_wb_master.wb_write(0, SPI_CTRL, 32'h3301); + + $display("status: %t generate transfer: 1 bit, msb first, tx posedge, rx negedge, ie, ass", $time); + + while (!int) + @(posedge clk); + + i_wb_master.wb_read(1, SPI_RX_0, q); + result = result + q; + + @(posedge clk); + if (!int && i_spi_slave.data == 32'h02490843 && q == 32'h0) + $display("status: %t transfer completed: ok", $time); + else + $display("status: %t transfer completed: nok", $time); + + $display("\n\nstatus: %t Testbench done", $time); + + #25000; // wait 25us + + $display("report (%h)", (result ^ 32'h2e8b36ab) + 32'hdeaddead); + $display("exit (%h)", result ^ 32'h2e8b36ab); + + $stop; + end + +endmodule + + diff --git a/fpga/usrp3/lib/wb_spi/bench/verilog/wb_master_model.v b/fpga/usrp3/lib/wb_spi/bench/verilog/wb_master_model.v new file mode 100644 index 000000000..3f8b7ee6a --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/bench/verilog/wb_master_model.v @@ -0,0 +1,176 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// wb_master_model.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// Based on: //// +//// - i2c/bench/verilog/wb_master_model.v //// +//// Copyright (C) 2001 Richard Herveille //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "timescale.v" + +module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty); + + parameter dwidth = 32; + parameter awidth = 32; + + input clk, rst; + output [awidth -1:0] adr; + input [dwidth -1:0] din; + output [dwidth -1:0] dout; + output cyc, stb; + output we; + output [dwidth/8 -1:0] sel; + input ack, err, rty; + + // Internal signals + reg [awidth -1:0] adr; + reg [dwidth -1:0] dout; + reg cyc, stb; + reg we; + reg [dwidth/8 -1:0] sel; + + reg [dwidth -1:0] q; + + // Memory Logic + initial + begin + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + cyc = 1'b0; + stb = 1'bx; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + #1; + end + + // Wishbone write cycle + task wb_write; + input delay; + integer delay; + + input [awidth -1:0] a; + input [dwidth -1:0] d; + + begin + + // wait initial delay + repeat(delay) @(posedge clk); + + // assert wishbone signal + #1; + adr = a; + dout = d; + cyc = 1'b1; + stb = 1'b1; + we = 1'b1; + sel = {dwidth/8{1'b1}}; + @(posedge clk); + + // wait for acknowledge from slave + while(~ack) @(posedge clk); + + // negate wishbone signals + #1; + cyc = 1'b0; + stb = 1'bx; + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + + end + endtask + + // Wishbone read cycle + task wb_read; + input delay; + integer delay; + + input [awidth -1:0] a; + output [dwidth -1:0] d; + + begin + + // wait initial delay + repeat(delay) @(posedge clk); + + // assert wishbone signals + #1; + adr = a; + dout = {dwidth{1'bx}}; + cyc = 1'b1; + stb = 1'b1; + we = 1'b0; + sel = {dwidth/8{1'b1}}; + @(posedge clk); + + // wait for acknowledge from slave + while(~ack) @(posedge clk); + + // negate wishbone signals + #1; + cyc = 1'b0; + stb = 1'bx; + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + d = din; + + end + endtask + + // Wishbone compare cycle (read data from location and compare with expected data) + task wb_cmp; + input delay; + integer delay; + + input [awidth -1:0] a; + input [dwidth -1:0] d_exp; + + begin + wb_read (delay, a, q); + + if (d_exp !== q) + $display("Data compare error. Received %h, expected %h at time %t", q, d_exp, $time); + end + endtask + +endmodule + diff --git a/fpga/usrp3/lib/wb_spi/doc/spi.pdf b/fpga/usrp3/lib/wb_spi/doc/spi.pdf Binary files differnew file mode 100644 index 000000000..d88ee2807 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/doc/spi.pdf diff --git a/fpga/usrp3/lib/wb_spi/doc/src/spi.doc b/fpga/usrp3/lib/wb_spi/doc/src/spi.doc Binary files differnew file mode 100755 index 000000000..b04700177 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/doc/src/spi.doc diff --git a/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_clgen.v b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_clgen.v new file mode 100644 index 000000000..2d9c34f40 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_clgen.v @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_clgen.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "spi_defines.v" + +module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge); + + input clk_in; // input clock (system clock) + input rst; // reset + input enable; // clock enable + input go; // start transfer + input last_clk; // last clock + input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value) + output clk_out; // output clock + output pos_edge; // pulse marking positive edge of clk_out + output neg_edge; // pulse marking negative edge of clk_out + + reg clk_out; + reg pos_edge; + reg neg_edge; + + reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter + wire cnt_zero; // conter is equal to zero + wire cnt_one; // conter is equal to one + + + assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}}; + assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1}; + + // Counter counts half period + always @(posedge clk_in) + begin + if(rst) + cnt <= {`SPI_DIVIDER_LEN{1'b1}}; + else + begin + if(!enable || cnt_zero) + cnt <= divider; + else + cnt <= cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1}; + end + end + + // clk_out is asserted every other half period + always @(posedge clk_in) + begin + if(rst) + clk_out <= 1'b0; + else + clk_out <= (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out; + end + + // Pos and neg edge signals + always @(posedge clk_in) + begin + if(rst) + begin + pos_edge <= 1'b0; + neg_edge <= 1'b0; + end + else + begin + pos_edge <= (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable); + neg_edge <= (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable); + end + end +endmodule + diff --git a/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_defines.v b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_defines.v new file mode 100644 index 000000000..28b4f2fd3 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_defines.v @@ -0,0 +1,161 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_define.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +// +// Number of bits used for devider register. If used in system with +// low frequency of system clock this can be reduced. +// Use SPI_DIVIDER_LEN for fine tuning theexact number. +// +`define SPI_DIVIDER_LEN_8 +//`define SPI_DIVIDER_LEN_16 +//`define SPI_DIVIDER_LEN_24 +//`define SPI_DIVIDER_LEN_32 + +`ifdef SPI_DIVIDER_LEN_8 + `define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8 +`endif +`ifdef SPI_DIVIDER_LEN_16 + `define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16 +`endif +`ifdef SPI_DIVIDER_LEN_24 + `define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24 +`endif +`ifdef SPI_DIVIDER_LEN_32 + `define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32 +`endif + +// +// Maximum nuber of bits that can be send/received at once. +// Use SPI_MAX_CHAR for fine tuning the exact number, when using +// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8. +// +`ifndef SPI_MAX_CHAR_64 + `define SPI_MAX_CHAR_128 +`endif +//`define SPI_MAX_CHAR_64 +//`define SPI_MAX_CHAR_32 +//`define SPI_MAX_CHAR_24 +//`define SPI_MAX_CHAR_16 +//`define SPI_MAX_CHAR_8 + +`ifdef SPI_MAX_CHAR_128 + `define SPI_MAX_CHAR 128 // Can only be set to 128 + `define SPI_CHAR_LEN_BITS 7 +`endif +`ifdef SPI_MAX_CHAR_64 + `define SPI_MAX_CHAR 64 // Can only be set to 64 + `define SPI_CHAR_LEN_BITS 6 +`endif +`ifdef SPI_MAX_CHAR_32 + `define SPI_MAX_CHAR 32 // Can be set from 25 to 32 + `define SPI_CHAR_LEN_BITS 5 +`endif +`ifdef SPI_MAX_CHAR_24 + `define SPI_MAX_CHAR 24 // Can be set from 17 to 24 + `define SPI_CHAR_LEN_BITS 5 +`endif +`ifdef SPI_MAX_CHAR_16 + `define SPI_MAX_CHAR 16 // Can be set from 9 to 16 + `define SPI_CHAR_LEN_BITS 4 +`endif +`ifdef SPI_MAX_CHAR_8 + `define SPI_MAX_CHAR 8 // Can be set from 1 to 8 + `define SPI_CHAR_LEN_BITS 3 +`endif + +// +// Number of device select signals. Use SPI_SS_NB for fine tuning the +// exact number. +// +//`define SPI_SS_NB_8 +`define SPI_SS_NB_16 +//`define SPI_SS_NB_24 +//`define SPI_SS_NB_32 + +`ifdef SPI_SS_NB_8 + `define SPI_SS_NB 8 // Can be set from 1 to 8 +`endif +`ifdef SPI_SS_NB_16 + `define SPI_SS_NB 16 // Can be set from 9 to 16 +`endif +`ifdef SPI_SS_NB_24 + `define SPI_SS_NB 24 // Can be set from 17 to 24 +`endif +`ifdef SPI_SS_NB_32 + `define SPI_SS_NB 32 // Can be set from 25 to 32 +`endif + +// +// Bits of WISHBONE address used for partial decoding of SPI registers. +// +`define SPI_OFS_BITS 4:2 + +// +// Register offset +// +`define SPI_RX_0 0 +`define SPI_RX_1 1 +`define SPI_RX_2 2 +`define SPI_RX_3 3 +`define SPI_TX_0 0 +`define SPI_TX_1 1 +`define SPI_TX_2 2 +`define SPI_TX_3 3 +`define SPI_CTRL 4 +`define SPI_DIVIDE 5 +`define SPI_SS 6 + +// +// Number of bits in ctrl register +// +`define SPI_CTRL_BIT_NB 14 + +// +// Control register bit position +// +`define SPI_CTRL_ASS 13 +`define SPI_CTRL_IE 12 +`define SPI_CTRL_LSB 11 +`define SPI_CTRL_TX_NEGEDGE 10 +`define SPI_CTRL_RX_NEGEDGE 9 +`define SPI_CTRL_GO 8 +`define SPI_CTRL_RES_1 7 +`define SPI_CTRL_CHAR_LEN 6:0 + diff --git a/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_shift.v b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_shift.v new file mode 100644 index 000000000..ac3bb3f48 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_shift.v @@ -0,0 +1,235 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_shift.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "spi_defines.v" + +module spi_shift (clk, rst, latch, byte_sel, len, lsb, go, + pos_edge, neg_edge, rx_negedge, tx_negedge, + tip, last, + p_in, p_out, s_clk, s_in, s_out); + + input clk; // system clock + input rst; // reset + input [3:0] latch; // latch signal for storing the data in shift register + input [3:0] byte_sel; // byte select signals for storing the data in shift register + input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one) + input lsb; // lbs first on the line + input go; // start stansfer + input pos_edge; // recognize posedge of sclk + input neg_edge; // recognize negedge of sclk + input rx_negedge; // s_in is sampled on negative edge + input tx_negedge; // s_out is driven on negative edge + output tip; // transfer in progress + output last; // last bit + input [31:0] p_in; // parallel in + output [`SPI_MAX_CHAR-1:0] p_out; // parallel out + input s_clk; // serial clock + input s_in; // serial in + output s_out; // serial out + + reg s_out; + reg tip; + + reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count + reg [`SPI_MAX_CHAR-1:0] data; // shift register + wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position + wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position + wire rx_clk; // rx clock enable + wire tx_clk; // tx clock enable + + assign p_out = data; + + assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1}; + assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) : + (rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1}); + + assign last = !(|cnt); + + assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk); + assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last; + + // Character bit counter + always @(posedge clk) + begin + if(rst) + cnt <= {`SPI_CHAR_LEN_BITS+1{1'b0}}; + else + begin + if(tip) + cnt <= pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt; + else + cnt <= !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len}; + end + end + + // Transfer in progress + always @(posedge clk) + begin + if(rst) + tip <= 1'b0; + else if(go && ~tip) + tip <= 1'b1; + else if(tip && last && pos_edge) + tip <= 1'b0; + end + + // Sending bits to the line + always @(posedge clk) + begin + if (rst) + s_out <= 1'b0; + else + s_out <= (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out; + end + + // Receiving bits from the line + always @(posedge clk) + begin + if (rst) + data <= {`SPI_MAX_CHAR{1'b0}}; +`ifdef SPI_MAX_CHAR_128 + else if (latch[0] && !tip) + begin + if (byte_sel[3]) + data[31:24] <= p_in[31:24]; + if (byte_sel[2]) + data[23:16] <= p_in[23:16]; + if (byte_sel[1]) + data[15:8] <= p_in[15:8]; + if (byte_sel[0]) + data[7:0] <= p_in[7:0]; + end + else if (latch[1] && !tip) + begin + if (byte_sel[3]) + data[63:56] <= p_in[31:24]; + if (byte_sel[2]) + data[55:48] <= p_in[23:16]; + if (byte_sel[1]) + data[47:40] <= p_in[15:8]; + if (byte_sel[0]) + data[39:32] <= p_in[7:0]; + end + else if (latch[2] && !tip) + begin + if (byte_sel[3]) + data[95:88] <= p_in[31:24]; + if (byte_sel[2]) + data[87:80] <= p_in[23:16]; + if (byte_sel[1]) + data[79:72] <= p_in[15:8]; + if (byte_sel[0]) + data[71:64] <= p_in[7:0]; + end + else if (latch[3] && !tip) + begin + if (byte_sel[3]) + data[127:120] <= p_in[31:24]; + if (byte_sel[2]) + data[119:112] <= p_in[23:16]; + if (byte_sel[1]) + data[111:104] <= p_in[15:8]; + if (byte_sel[0]) + data[103:96] <= p_in[7:0]; + end +`else +`ifdef SPI_MAX_CHAR_64 + else if (latch[0] && !tip) + begin + if (byte_sel[3]) + data[31:24] <= p_in[31:24]; + if (byte_sel[2]) + data[23:16] <= p_in[23:16]; + if (byte_sel[1]) + data[15:8] <= p_in[15:8]; + if (byte_sel[0]) + data[7:0] <= p_in[7:0]; + end + else if (latch[1] && !tip) + begin + if (byte_sel[3]) + data[63:56] <= p_in[31:24]; + if (byte_sel[2]) + data[55:48] <= p_in[23:16]; + if (byte_sel[1]) + data[47:40] <= p_in[15:8]; + if (byte_sel[0]) + data[39:32] <= p_in[7:0]; + end +`else + else if (latch[0] && !tip) + begin + `ifdef SPI_MAX_CHAR_8 + if (byte_sel[0]) + data[`SPI_MAX_CHAR-1:0] <= p_in[`SPI_MAX_CHAR-1:0]; + `endif + `ifdef SPI_MAX_CHAR_16 + if (byte_sel[0]) + data[7:0] <= p_in[7:0]; + if (byte_sel[1]) + data[`SPI_MAX_CHAR-1:8] <= p_in[`SPI_MAX_CHAR-1:8]; + `endif + `ifdef SPI_MAX_CHAR_24 + if (byte_sel[0]) + data[7:0] <= p_in[7:0]; + if (byte_sel[1]) + data[15:8] <= p_in[15:8]; + if (byte_sel[2]) + data[`SPI_MAX_CHAR-1:16] <= p_in[`SPI_MAX_CHAR-1:16]; + `endif + `ifdef SPI_MAX_CHAR_32 + if (byte_sel[0]) + data[7:0] <= p_in[7:0]; + if (byte_sel[1]) + data[15:8] <= p_in[15:8]; + if (byte_sel[2]) + data[23:16] <= p_in[23:16]; + if (byte_sel[3]) + data[`SPI_MAX_CHAR-1:24] <= p_in[`SPI_MAX_CHAR-1:24]; + `endif + end +`endif +`endif + else + data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]]; + end + +endmodule + diff --git a/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top.v b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top.v new file mode 100644 index 000000000..acd1e4fbf --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top.v @@ -0,0 +1,289 @@ + +// Modified 2010 by Matt Ettus to remove old verilog style + +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_top.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// +//// SPDX-License-Identifier: LGPL-3.0-or-later +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + + +`include "spi_defines.v" + +module spi_top +( + // Wishbone signals + wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i, + wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_err_o, wb_int_o, + + // SPI signals + ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i +); + + // Wishbone signals + input wb_clk_i; // master clock input + input wb_rst_i; // synchronous active high reset + input [4:0] wb_adr_i; // lower address bits + input [32-1:0] wb_dat_i; // databus input + output [32-1:0] wb_dat_o; // databus output + input [3:0] wb_sel_i; // byte select inputs + input wb_we_i; // write enable input + input wb_stb_i; // stobe/core select signal + input wb_cyc_i; // valid bus cycle input + output wb_ack_o; // bus cycle acknowledge output + output wb_err_o; // termination w/ error + output wb_int_o; // interrupt request signal output + + // SPI signals + output [`SPI_SS_NB-1:0] ss_pad_o; // slave select + output sclk_pad_o; // serial clock + output mosi_pad_o; // master out slave in + input miso_pad_i; // master in slave out + + reg [32-1:0] wb_dat_o; + reg wb_ack_o; + reg wb_int_o; + + // Internal signals + reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register + reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register + reg [`SPI_SS_NB-1:0] ss; // Slave select register + reg [32-1:0] wb_dat; // wb data out + wire [`SPI_MAX_CHAR-1:0] rx; // Rx register + wire rx_negedge; // miso is sampled on negative edge + wire tx_negedge; // mosi is driven on negative edge + wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len + wire go; // go + wire lsb; // lsb first on line + wire ie; // interrupt enable + wire ass; // automatic slave select + wire spi_divider_sel; // divider register select + wire spi_ctrl_sel; // ctrl register select + wire [3:0] spi_tx_sel; // tx_l register select + wire spi_ss_sel; // ss register select + wire tip; // transfer in progress + wire pos_edge; // recognize posedge of sclk + wire neg_edge; // recognize negedge of sclk + wire last_bit; // marks last character bit + + // Address decoder + assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DIVIDE); + assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL); + assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0); + assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1); + assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_2); + assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_3); + assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_SS); + + // Read from registers + always @(wb_adr_i or rx or ctrl or divider or ss) + begin + case (wb_adr_i[`SPI_OFS_BITS]) +`ifdef SPI_MAX_CHAR_128 + `SPI_RX_0: wb_dat = rx[31:0]; + `SPI_RX_1: wb_dat = rx[63:32]; + `SPI_RX_2: wb_dat = rx[95:64]; + `SPI_RX_3: wb_dat = {{128-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:96]}; +`else +`ifdef SPI_MAX_CHAR_64 + `SPI_RX_0: wb_dat = rx[31:0]; + `SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:32]}; + `SPI_RX_2: wb_dat = 32'b0; + `SPI_RX_3: wb_dat = 32'b0; +`else + `SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:0]}; + `SPI_RX_1: wb_dat = 32'b0; + `SPI_RX_2: wb_dat = 32'b0; + `SPI_RX_3: wb_dat = 32'b0; +`endif +`endif + `SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl}; + `SPI_DIVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider}; + `SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss}; + default: wb_dat = 32'bx; + endcase + end + + // Wb data out + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + wb_dat_o <= 32'b0; + else + wb_dat_o <= wb_dat; + end + + // Wb acknowledge + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + wb_ack_o <= 1'b0; + else + wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o; + end + + // Wb error + assign wb_err_o = 1'b0; + + // Interrupt + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + wb_int_o <= 1'b0; + else if (ie && tip && last_bit && pos_edge) + wb_int_o <= 1'b1; + else if (wb_ack_o) + wb_int_o <= 1'b0; + end + + // Divider register + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + divider <= {`SPI_DIVIDER_LEN{1'b0}}; + else if (spi_divider_sel && wb_we_i && !tip) + begin + `ifdef SPI_DIVIDER_LEN_8 + if (wb_sel_i[0]) + divider <= wb_dat_i[`SPI_DIVIDER_LEN-1:0]; + `endif + `ifdef SPI_DIVIDER_LEN_16 + if (wb_sel_i[0]) + divider[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + divider[`SPI_DIVIDER_LEN-1:8] <= wb_dat_i[`SPI_DIVIDER_LEN-1:8]; + `endif + `ifdef SPI_DIVIDER_LEN_24 + if (wb_sel_i[0]) + divider[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + divider[15:8] <= wb_dat_i[15:8]; + if (wb_sel_i[2]) + divider[`SPI_DIVIDER_LEN-1:16] <= wb_dat_i[`SPI_DIVIDER_LEN-1:16]; + `endif + `ifdef SPI_DIVIDER_LEN_32 + if (wb_sel_i[0]) + divider[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + divider[15:8] <= wb_dat_i[15:8]; + if (wb_sel_i[2]) + divider[23:16] <= wb_dat_i[23:16]; + if (wb_sel_i[3]) + divider[`SPI_DIVIDER_LEN-1:24] <= wb_dat_i[`SPI_DIVIDER_LEN-1:24]; + `endif + end + end + + // Ctrl register + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + ctrl <= {`SPI_CTRL_BIT_NB{1'b0}}; + else if(spi_ctrl_sel && wb_we_i && !tip) + begin + if (wb_sel_i[0]) + ctrl[7:0] <= wb_dat_i[7:0] | {7'b0, ctrl[0]}; + if (wb_sel_i[1]) + ctrl[`SPI_CTRL_BIT_NB-1:8] <= wb_dat_i[`SPI_CTRL_BIT_NB-1:8]; + end + else if(tip && last_bit && pos_edge) + ctrl[`SPI_CTRL_GO] <= 1'b0; + end + + assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE]; + assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE]; + assign go = ctrl[`SPI_CTRL_GO]; + assign char_len = ctrl[`SPI_CTRL_CHAR_LEN]; + assign lsb = ctrl[`SPI_CTRL_LSB]; + assign ie = ctrl[`SPI_CTRL_IE]; + assign ass = ctrl[`SPI_CTRL_ASS]; + + // Slave select register + always @(posedge wb_clk_i) + begin + if (wb_rst_i) + ss <= {`SPI_SS_NB{1'b0}}; + else if(spi_ss_sel && wb_we_i && !tip) + begin + `ifdef SPI_SS_NB_8 + if (wb_sel_i[0]) + ss <= wb_dat_i[`SPI_SS_NB-1:0]; + `endif + `ifdef SPI_SS_NB_16 + if (wb_sel_i[0]) + ss[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + ss[`SPI_SS_NB-1:8] <= wb_dat_i[`SPI_SS_NB-1:8]; + `endif + `ifdef SPI_SS_NB_24 + if (wb_sel_i[0]) + ss[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + ss[15:8] <= wb_dat_i[15:8]; + if (wb_sel_i[2]) + ss[`SPI_SS_NB-1:16] <= wb_dat_i[`SPI_SS_NB-1:16]; + `endif + `ifdef SPI_SS_NB_32 + if (wb_sel_i[0]) + ss[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + ss[15:8] <= wb_dat_i[15:8]; + if (wb_sel_i[2]) + ss[23:16] <= wb_dat_i[23:16]; + if (wb_sel_i[3]) + ss[`SPI_SS_NB-1:24] <= wb_dat_i[`SPI_SS_NB-1:24]; + `endif + end + end + + assign ss_pad_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}})); + + spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit), + .divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge), + .neg_edge(neg_edge)); + + spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]), + .latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(wb_sel_i), .lsb(lsb), + .go(go), .pos_edge(pos_edge), .neg_edge(neg_edge), + .rx_negedge(rx_negedge), .tx_negedge(tx_negedge), + .tip(tip), .last(last_bit), + .p_in(wb_dat_i), .p_out(rx), + .s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o)); +endmodule + diff --git a/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top16.v b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top16.v new file mode 100644 index 000000000..1dc7d4c39 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/rtl/verilog/spi_top16.v @@ -0,0 +1,184 @@ + +// Modified 2010 by Matt Ettus to remove old verilog style and +// allow 16-bit operation + +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_top.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// +//// SPDX-License-Identifier: LGPL-3.0-or-later +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + + +`include "spi_defines.v" + +module spi_top16 + (input wb_clk_i, input wb_rst_i, + input [4:0] wb_adr_i, + input [15:0] wb_dat_i, + output reg [15:0] wb_dat_o, + input [1:0] wb_sel_i, + input wb_we_i, input wb_stb_i, input wb_cyc_i, + output reg wb_ack_o, output wb_err_o, output reg wb_int_o, + + // SPI signals + output [15:0] ss_pad_o, output sclk_pad_o, output mosi_pad_o, input miso_pad_i); + + // Internal signals + reg [15:0] divider; // Divider register + reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register + reg [15:0] ss; // Slave select register + reg [31:0] wb_dat; // wb data out + wire [31:0] rx; // Rx register + wire rx_negedge; // miso is sampled on negative edge + wire tx_negedge; // mosi is driven on negative edge + wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len + wire go; // go + wire lsb; // lsb first on line + wire ie; // interrupt enable + wire ass; // automatic slave select + wire spi_divider_sel; // divider register select + wire spi_ctrl_sel; // ctrl register select + wire [3:0] spi_tx_sel; // tx_l register select + wire spi_ss_sel; // ss register select + wire tip; // transfer in progress + wire pos_edge; // recognize posedge of sclk + wire neg_edge; // recognize negedge of sclk + wire last_bit; // marks last character bit + + // Address decoder + assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_DIVIDE); + assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_CTRL); + assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_0); + assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_1); + assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_2); + assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_3); + assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_SS); + + always @(wb_adr_i or rx or ctrl or divider or ss) + case (wb_adr_i[4:2]) + `SPI_RX_0: wb_dat = rx[31:0]; + `SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl}; + `SPI_DIVIDE: wb_dat = {16'b0, divider}; + `SPI_SS: wb_dat = {16'b0, ss}; + default : wb_dat = 32'd0; + endcase // case (wb_adr_i[4:2]) + + always @(posedge wb_clk_i) + if (wb_rst_i) + wb_dat_o <= 32'b0; + else + wb_dat_o <= wb_adr_i[1] ? wb_dat[31:16] : wb_dat[15:0]; + + always @(posedge wb_clk_i) + if (wb_rst_i) + wb_ack_o <= 1'b0; + else + wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o; + + assign wb_err_o = 1'b0; + + // Interrupt + always @(posedge wb_clk_i) + if (wb_rst_i) + wb_int_o <= 1'b0; + else if (ie && tip && last_bit && pos_edge) + wb_int_o <= 1'b1; + else if (wb_ack_o) + wb_int_o <= 1'b0; + + // Divider register + always @(posedge wb_clk_i) + if (wb_rst_i) + divider <= 16'b0; + else if (spi_divider_sel && wb_we_i && !tip && ~wb_adr_i[1]) + divider <= wb_dat_i; + + // Ctrl register + always @(posedge wb_clk_i) + if (wb_rst_i) + ctrl <= {`SPI_CTRL_BIT_NB{1'b0}}; + else if(spi_ctrl_sel && wb_we_i && !tip && ~wb_adr_i[1]) + begin + if (wb_sel_i[0]) + ctrl[7:0] <= wb_dat_i[7:0] | {7'b0, ctrl[0]}; + if (wb_sel_i[1]) + ctrl[`SPI_CTRL_BIT_NB-1:8] <= wb_dat_i[`SPI_CTRL_BIT_NB-1:8]; + end + else if(tip && last_bit && pos_edge) + ctrl[`SPI_CTRL_GO] <= 1'b0; + + assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE]; + assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE]; + assign go = ctrl[`SPI_CTRL_GO]; + assign char_len = ctrl[`SPI_CTRL_CHAR_LEN]; + assign lsb = ctrl[`SPI_CTRL_LSB]; + assign ie = ctrl[`SPI_CTRL_IE]; + assign ass = ctrl[`SPI_CTRL_ASS]; + + // Slave select register + always @(posedge wb_clk_i) + if (wb_rst_i) + ss <= 16'b0; + else if(spi_ss_sel && wb_we_i && !tip & ~wb_adr_i[1]) + begin + if (wb_sel_i[0]) + ss[7:0] <= wb_dat_i[7:0]; + if (wb_sel_i[1]) + ss[15:8] <= wb_dat_i[15:8]; + end + + assign ss_pad_o = ~((ss & {16{tip & ass}}) | (ss & {16{!ass}})); + + spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit), + .divider(divider[`SPI_DIVIDER_LEN-1:0]), .clk_out(sclk_pad_o), .pos_edge(pos_edge), + .neg_edge(neg_edge)); + + wire [3:0] new_sels = { (wb_adr_i[1] & wb_sel_i[1]), (wb_adr_i[1] & wb_sel_i[0]), + (~wb_adr_i[1] & wb_sel_i[1]), (~wb_adr_i[1] & wb_sel_i[0]) }; + + + spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]), + .latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(new_sels), .lsb(lsb), + .go(go), .pos_edge(pos_edge), .neg_edge(neg_edge), + .rx_negedge(rx_negedge), .tx_negedge(tx_negedge), + .tip(tip), .last(last_bit), + .p_in({wb_dat_i,wb_dat_i}), .p_out(rx), + .s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o)); + +endmodule // spi_top16 diff --git a/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/rtl.fl b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/rtl.fl new file mode 100644 index 000000000..d84a0840d --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/rtl.fl @@ -0,0 +1,3 @@ +spi_top.v +spi_clgen.v +spi_shift.v diff --git a/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/run_sim b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/run_sim new file mode 100755 index 000000000..1b13a35b9 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/run_sim @@ -0,0 +1,108 @@ +#!/bin/csh -f + +set current_par = 0 +set output_waveform = 0 +while ( $current_par < $# ) + @ current_par = $current_par + 1 + case wave: + @ output_waveform = 1 + breaksw + default: + echo 'Unknown option "'$argv[$current_par]'"!' + exit + breaksw + endsw +end + +echo "TEST: spi" + +#echo "-CDSLIB ./cds.lib" > ncvlog.args +#echo "-HDLVAR ./hdl.var" >> ncvlog.args +echo "-MESSAGES" > ncvlog.args +echo "-INCDIR ../../../bench/verilog" >> ncvlog.args +echo "-INCDIR ../../../rtl/verilog" >> ncvlog.args +echo "-NOCOPYRIGHT" >> ncvlog.args +echo "-UPDATE" >> ncvlog.args +echo "-LOGFILE ncvlog.log" >> ncvlog.args + +foreach filename ( `cat ./rtl.fl` ) + echo "../../../rtl/verilog/"$filename >> ncvlog.args +end + +foreach filename ( `cat ./sim.fl` ) + echo "../../../bench/verilog/"$filename >> ncvlog.args +end + +ncvlog -f ncvlog.args +if ($status != 0) then + echo "STATUS: failed" + exit +endif + + +echo "-MESSAGES" > ncelab.args +echo "-NOCOPYRIGHT" >> ncelab.args +#echo "-CDSLIB ./cds.lib" >> ncelab.args +#echo "-HDLVAR ./hdl.var" >> ncelab.args +echo "-LOGFILE ncelab.log" >> ncelab.args +echo "-SNAPSHOT worklib.tb_spi_top:v" >> ncelab.args +echo "-NOTIMINGCHECKS" >> ncelab.args +echo "-ACCESS +RWC" >> ncelab.args +echo "tb_spi_top" >> ncelab.args + +ncelab -f ncelab.args +if ($status != 0) then + echo "STATUS: failed" + exit +endif + + +echo "-MESSAGES" > ncsim.args +echo "-NOCOPYRIGHT" >> ncsim.args +#echo "-CDSLIB ./cds.lib" >> ncsim.args +#echo "-HDLVAR ./hdl.var" >> ncsim.args +echo "-INPUT ncsim.tcl" >> ncsim.args +echo "-LOGFILE ncsim.log" >> ncsim.args +echo "worklib.tb_spi_top:v" >> ncsim.args + +if ( $output_waveform ) then + echo "database -open waves -shm -into ../out/wav" > ./ncsim.tcl + echo "probe -create -database waves -shm tb_spi_top -all -depth all" >> ./ncsim.tcl + echo "stop -create -time 25000000 -relative" >> ./ncsim.tcl + echo "run" >> ./ncsim.tcl +else + echo "stop -create -time 25000000 -relative" >> ./ncsim.tcl + echo "run" > ./ncsim.tcl +endif + +echo "exit" >> ncsim.tcl + +ncsim -LICQUEUE -f ./ncsim.args + +set exit_line_nb = `sed -n '/exit/=' < ./ncsim.log` + +set dead_line_nb = 0 + +if ( $exit_line_nb ) then + + @ dead_line_nb = $exit_line_nb - 1 + set exit_line=`sed -n $exit_line_nb's/exit/&/gp' < ./ncsim.log` + set dead_line=`sed -n $dead_line_nb's/report/&/gp' < ./ncsim.log` + + if ( "$dead_line" == "report (deaddead)" ) then + if ( "$exit_line" == "exit (00000000)" ) then + echo "STATUS: passed" #|tee -a ./run_sim.log 2>&1 + else + echo "STATUS: failed" #|tee -a ./run_sim.log 2>&1 + endif + else + echo "STATUS: failed" + endif + +endif + +exit + + + + diff --git a/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/sim.fl b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/sim.fl new file mode 100644 index 000000000..283aad1f8 --- /dev/null +++ b/fpga/usrp3/lib/wb_spi/sim/rtl_sim/run/sim.fl @@ -0,0 +1,3 @@ +tb_spi_top.v +wb_master_model.v +spi_slave_model.v |