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/xge | |
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/xge')
40 files changed, 8110 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/xge/Makefile.srcs b/fpga/usrp3/lib/xge/Makefile.srcs new file mode 100644 index 000000000..29e5e3e26 --- /dev/null +++ b/fpga/usrp3/lib/xge/Makefile.srcs @@ -0,0 +1,30 @@ +################################################## +# OpenCore XGE MAC Sources +################################################## +XGE_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/xge/, \ +rtl/verilog/fault_sm.v \ +rtl/verilog/generic_fifo.v \ +rtl/verilog/generic_fifo_ctrl.v \ +rtl/verilog/generic_mem_xilinx_block.v \ +rtl/verilog/generic_mem_medium.v \ +rtl/verilog/generic_mem_small.v \ +rtl/verilog/meta_sync.v \ +rtl/verilog/meta_sync_single.v \ +rtl/verilog/rx_checker.v \ +rtl/verilog/rx_data_fifo.v \ +rtl/verilog/rx_dequeue.v \ +rtl/verilog/rx_enqueue.v \ +rtl/verilog/rx_hold_fifo.v \ +rtl/verilog/sync_clk_core.v \ +rtl/verilog/sync_clk_wb.v \ +rtl/verilog/sync_clk_xgmii_tx.v \ +rtl/verilog/tx_checker.v \ +rtl/verilog/tx_data_fifo.v \ +rtl/verilog/tx_dequeue.v \ +rtl/verilog/tx_enqueue.v \ +rtl/verilog/tx_hold_fifo.v \ +rtl/verilog/wishbone_if.v \ +rtl/verilog/xge_mac.v \ +rtl/verilog/xge_mac_wb.v \ +)) + diff --git a/fpga/usrp3/lib/xge/README.txt b/fpga/usrp3/lib/xge/README.txt new file mode 100644 index 000000000..d4cb1a0d0 --- /dev/null +++ b/fpga/usrp3/lib/xge/README.txt @@ -0,0 +1,103 @@ + +======================== +10GE MAC Core +======================== + + +------------------------ +1. Directory Structure +------------------------ + +The directory structure for this project is shown below. + +. +|-- doc - Documentation files +| +|-- rtl +| |-- include - Verilog defines and utils +| `-- verilog - Verilog source files for xge_mac +| +|-- sim +| |-- systemc - SystemC simulation directory +| `-- verilog - Verilog simulation directory +| +`-- tbench + |-- systemc - SystemC test-bench source files + `-- verilog - Verilog test-bench source files + + + +------------------------ +2. Simulation +------------------------ + +There are two simulation environments that can be used to validate the code. +The verilog simulation is very basic and meant for those who want to look +at how the MAC operates without going through the effort of setting up SystemC. +The SystemC environment is more sophisticated and covers all features of the MAC. + + + +------------------------ +2.1 Verilog Simulation +------------------------ + +To run the verilog simulation, compile all project files under rtl/verilog along with +top level testbench file: + + - tbench/verilog/tb_xge_mac.v + +There is a Modelsim "do" file called "sim.do" under sim/verilog for those using Modelsim. +Once all the files are compiled, start simulation using entity "tb". + + +The verilog simulation reads packets from "packet_tx.txt" and writes them to the MAC +transmit fifo using the packet transmit interface (pkt_tx_data). As frames become +available in the transmit fifo, the MAC calulates the CRC and sends them out on xgmii_tx. +The xgmii_tx interface is looped-back to xgmii_rx in the testbench. The frames are thus +processed by the MAC receive engine and stored in the receive fifo. The testbench reads +frames from the receive interface (pkt_rx_data) and prints out the results. + + + +------------------------ +2.2 SystemC Simulation +------------------------ + +In order to use the SystemC environment it is required to first install SystemC from +www.systemc.org. Free membership may be required to download the core SystemC files. + +The testbench was developed and tested with Verilator, a free HDL simulator that +compiles verilog into C++ or SystemC code. You can download Verilator from +www.veripool.org. You also need to install SystemPerl and Verilog-Perl for waveform +traces. + + +Once all the required tools are installed: + + - Move to directory sim/systemc + + - Type "./compile.sh" + + - Type "./run.sh" + + +If the simulation is running correctly you should see messages from the scoreboard +as packets are transmited and received on the various interfaces. + +Simulation output: + + ----------------------- + Packet size + ----------------------- + SCOREBOARD XGMII INTERFACE TX (60) + SCOREBOARD XGMII INTERFACE TX (60) + SCOREBOARD PACKET INTERFACE TX (50) + SCOREBOARD XGMII INTERFACE TX (60) + SCOREBOARD PACKET INTERFACE TX (51) + SCOREBOARD XGMII INTERFACE TX (60) + SCOREBOARD PACKET INTERFACE RX (TX SIZE=60 RX SIZE=60) + ... + + + diff --git a/fpga/usrp3/lib/xge/doc/xge_mac_spec.pdf b/fpga/usrp3/lib/xge/doc/xge_mac_spec.pdf Binary files differnew file mode 100644 index 000000000..e17e997d7 --- /dev/null +++ b/fpga/usrp3/lib/xge/doc/xge_mac_spec.pdf diff --git a/fpga/usrp3/lib/xge/rtl/include/CRC32_D64.v b/fpga/usrp3/lib/xge/rtl/include/CRC32_D64.v new file mode 100644 index 000000000..f13f85e1f --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/include/CRC32_D64.v @@ -0,0 +1,266 @@ +/////////////////////////////////////////////////////////////////////// +// File: CRC32_D64.v +// Date: Fri Feb 8 19:30:02 2008 +// +// Copyright (C) 1999-2003 Easics NV. +// 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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Purpose: Verilog module containing a synthesizable CRC function +// * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) +// * data width: 64 +// +// Info: tools@easics.be +// http://www.easics.com +/////////////////////////////////////////////////////////////////////// + + +//module CRC32_D64; + + // polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) + // data width: 64 + // convention: the first serial data bit is D[63] + function [31:0] nextCRC32_D64; + + input [63:0] Data; + input [31:0] CRC; + + reg [63:0] D; + reg [31:0] C; + reg [31:0] NewCRC; + + begin + + D = Data; + C = CRC; + + NewCRC[0] = D[63] ^ D[61] ^ D[60] ^ D[58] ^ D[55] ^ D[54] ^ D[53] ^ + D[50] ^ D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[37] ^ D[34] ^ + D[32] ^ D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[26] ^ D[25] ^ + D[24] ^ D[16] ^ D[12] ^ D[10] ^ D[9] ^ D[6] ^ D[0] ^ + C[0] ^ C[2] ^ C[5] ^ C[12] ^ C[13] ^ C[15] ^ C[16] ^ + C[18] ^ C[21] ^ C[22] ^ C[23] ^ C[26] ^ C[28] ^ C[29] ^ + C[31]; + NewCRC[1] = D[63] ^ D[62] ^ D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[53] ^ + D[51] ^ D[50] ^ D[49] ^ D[47] ^ D[46] ^ D[44] ^ D[38] ^ + D[37] ^ D[35] ^ D[34] ^ D[33] ^ D[28] ^ D[27] ^ D[24] ^ + D[17] ^ D[16] ^ D[13] ^ D[12] ^ D[11] ^ D[9] ^ D[7] ^ + D[6] ^ D[1] ^ D[0] ^ C[1] ^ C[2] ^ C[3] ^ C[5] ^ C[6] ^ + C[12] ^ C[14] ^ C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[21] ^ + C[24] ^ C[26] ^ C[27] ^ C[28] ^ C[30] ^ C[31]; + NewCRC[2] = D[59] ^ D[58] ^ D[57] ^ D[55] ^ D[53] ^ D[52] ^ D[51] ^ + D[44] ^ D[39] ^ D[38] ^ D[37] ^ D[36] ^ D[35] ^ D[32] ^ + D[31] ^ D[30] ^ D[26] ^ D[24] ^ D[18] ^ D[17] ^ D[16] ^ + D[14] ^ D[13] ^ D[9] ^ D[8] ^ D[7] ^ D[6] ^ D[2] ^ + D[1] ^ D[0] ^ C[0] ^ C[3] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ + C[12] ^ C[19] ^ C[20] ^ C[21] ^ C[23] ^ C[25] ^ C[26] ^ + C[27]; + NewCRC[3] = D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[54] ^ D[53] ^ D[52] ^ + D[45] ^ D[40] ^ D[39] ^ D[38] ^ D[37] ^ D[36] ^ D[33] ^ + D[32] ^ D[31] ^ D[27] ^ D[25] ^ D[19] ^ D[18] ^ D[17] ^ + D[15] ^ D[14] ^ D[10] ^ D[9] ^ D[8] ^ D[7] ^ D[3] ^ + D[2] ^ D[1] ^ C[0] ^ C[1] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ + C[8] ^ C[13] ^ C[20] ^ C[21] ^ C[22] ^ C[24] ^ C[26] ^ + C[27] ^ C[28]; + NewCRC[4] = D[63] ^ D[59] ^ D[58] ^ D[57] ^ D[50] ^ D[48] ^ D[47] ^ + D[46] ^ D[45] ^ D[44] ^ D[41] ^ D[40] ^ D[39] ^ D[38] ^ + D[33] ^ D[31] ^ D[30] ^ D[29] ^ D[25] ^ D[24] ^ D[20] ^ + D[19] ^ D[18] ^ D[15] ^ D[12] ^ D[11] ^ D[8] ^ D[6] ^ + D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[1] ^ C[6] ^ C[7] ^ C[8] ^ + C[9] ^ C[12] ^ C[13] ^ C[14] ^ C[15] ^ C[16] ^ C[18] ^ + C[25] ^ C[26] ^ C[27] ^ C[31]; + NewCRC[5] = D[63] ^ D[61] ^ D[59] ^ D[55] ^ D[54] ^ D[53] ^ D[51] ^ + D[50] ^ D[49] ^ D[46] ^ D[44] ^ D[42] ^ D[41] ^ D[40] ^ + D[39] ^ D[37] ^ D[29] ^ D[28] ^ D[24] ^ D[21] ^ D[20] ^ + D[19] ^ D[13] ^ D[10] ^ D[7] ^ D[6] ^ D[5] ^ D[4] ^ + D[3] ^ D[1] ^ D[0] ^ C[5] ^ C[7] ^ C[8] ^ C[9] ^ C[10] ^ + C[12] ^ C[14] ^ C[17] ^ C[18] ^ C[19] ^ C[21] ^ C[22] ^ + C[23] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[6] = D[62] ^ D[60] ^ D[56] ^ D[55] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[47] ^ D[45] ^ D[43] ^ D[42] ^ D[41] ^ D[40] ^ + D[38] ^ D[30] ^ D[29] ^ D[25] ^ D[22] ^ D[21] ^ D[20] ^ + D[14] ^ D[11] ^ D[8] ^ D[7] ^ D[6] ^ D[5] ^ D[4] ^ + D[2] ^ D[1] ^ C[6] ^ C[8] ^ C[9] ^ C[10] ^ C[11] ^ + C[13] ^ C[15] ^ C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[23] ^ + C[24] ^ C[28] ^ C[30]; + NewCRC[7] = D[60] ^ D[58] ^ D[57] ^ D[56] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[47] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[41] ^ + D[39] ^ D[37] ^ D[34] ^ D[32] ^ D[29] ^ D[28] ^ D[25] ^ + D[24] ^ D[23] ^ D[22] ^ D[21] ^ D[16] ^ D[15] ^ D[10] ^ + D[8] ^ D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[0] ^ C[2] ^ + C[5] ^ C[7] ^ C[9] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ + C[15] ^ C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[24] ^ C[25] ^ + C[26] ^ C[28]; + NewCRC[8] = D[63] ^ D[60] ^ D[59] ^ D[57] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[40] ^ D[38] ^ + D[37] ^ D[35] ^ D[34] ^ D[33] ^ D[32] ^ D[31] ^ D[28] ^ + D[23] ^ D[22] ^ D[17] ^ D[12] ^ D[11] ^ D[10] ^ D[8] ^ + D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^ C[2] ^ C[3] ^ + C[5] ^ C[6] ^ C[8] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ + C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[25] ^ C[27] ^ C[28] ^ + C[31]; + NewCRC[9] = D[61] ^ D[60] ^ D[58] ^ D[55] ^ D[53] ^ D[52] ^ D[51] ^ + D[47] ^ D[46] ^ D[44] ^ D[43] ^ D[41] ^ D[39] ^ D[38] ^ + D[36] ^ D[35] ^ D[34] ^ D[33] ^ D[32] ^ D[29] ^ D[24] ^ + D[23] ^ D[18] ^ D[13] ^ D[12] ^ D[11] ^ D[9] ^ D[5] ^ + D[4] ^ D[2] ^ D[1] ^ C[0] ^ C[1] ^ C[2] ^ C[3] ^ C[4] ^ + C[6] ^ C[7] ^ C[9] ^ C[11] ^ C[12] ^ C[14] ^ C[15] ^ + C[19] ^ C[20] ^ C[21] ^ C[23] ^ C[26] ^ C[28] ^ C[29]; + NewCRC[10] = D[63] ^ D[62] ^ D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[55] ^ + D[52] ^ D[50] ^ D[42] ^ D[40] ^ D[39] ^ D[36] ^ D[35] ^ + D[33] ^ D[32] ^ D[31] ^ D[29] ^ D[28] ^ D[26] ^ D[19] ^ + D[16] ^ D[14] ^ D[13] ^ D[9] ^ D[5] ^ D[3] ^ D[2] ^ + D[0] ^ C[0] ^ C[1] ^ C[3] ^ C[4] ^ C[7] ^ C[8] ^ C[10] ^ + C[18] ^ C[20] ^ C[23] ^ C[24] ^ C[26] ^ C[27] ^ C[28] ^ + C[30] ^ C[31]; + NewCRC[11] = D[59] ^ D[58] ^ D[57] ^ D[56] ^ D[55] ^ D[54] ^ D[51] ^ + D[50] ^ D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[43] ^ D[41] ^ + D[40] ^ D[36] ^ D[33] ^ D[31] ^ D[28] ^ D[27] ^ D[26] ^ + D[25] ^ D[24] ^ D[20] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ + D[12] ^ D[9] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[1] ^ C[4] ^ + C[8] ^ C[9] ^ C[11] ^ C[12] ^ C[13] ^ C[15] ^ C[16] ^ + C[18] ^ C[19] ^ C[22] ^ C[23] ^ C[24] ^ C[25] ^ C[26] ^ + C[27]; + NewCRC[12] = D[63] ^ D[61] ^ D[59] ^ D[57] ^ D[56] ^ D[54] ^ D[53] ^ + D[52] ^ D[51] ^ D[50] ^ D[49] ^ D[47] ^ D[46] ^ D[42] ^ + D[41] ^ D[31] ^ D[30] ^ D[27] ^ D[24] ^ D[21] ^ D[18] ^ + D[17] ^ D[15] ^ D[13] ^ D[12] ^ D[9] ^ D[6] ^ D[5] ^ + D[4] ^ D[2] ^ D[1] ^ D[0] ^ C[9] ^ C[10] ^ C[14] ^ + C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ + C[24] ^ C[25] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[13] = D[62] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[54] ^ D[53] ^ + D[52] ^ D[51] ^ D[50] ^ D[48] ^ D[47] ^ D[43] ^ D[42] ^ + D[32] ^ D[31] ^ D[28] ^ D[25] ^ D[22] ^ D[19] ^ D[18] ^ + D[16] ^ D[14] ^ D[13] ^ D[10] ^ D[7] ^ D[6] ^ D[5] ^ + D[3] ^ D[2] ^ D[1] ^ C[0] ^ C[10] ^ C[11] ^ C[15] ^ + C[16] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ + C[25] ^ C[26] ^ C[28] ^ C[30]; + NewCRC[14] = D[63] ^ D[61] ^ D[59] ^ D[58] ^ D[56] ^ D[55] ^ D[54] ^ + D[53] ^ D[52] ^ D[51] ^ D[49] ^ D[48] ^ D[44] ^ D[43] ^ + D[33] ^ D[32] ^ D[29] ^ D[26] ^ D[23] ^ D[20] ^ D[19] ^ + D[17] ^ D[15] ^ D[14] ^ D[11] ^ D[8] ^ D[7] ^ D[6] ^ + D[4] ^ D[3] ^ D[2] ^ C[0] ^ C[1] ^ C[11] ^ C[12] ^ + C[16] ^ C[17] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ + C[24] ^ C[26] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[15] = D[62] ^ D[60] ^ D[59] ^ D[57] ^ D[56] ^ D[55] ^ D[54] ^ + D[53] ^ D[52] ^ D[50] ^ D[49] ^ D[45] ^ D[44] ^ D[34] ^ + D[33] ^ D[30] ^ D[27] ^ D[24] ^ D[21] ^ D[20] ^ D[18] ^ + D[16] ^ D[15] ^ D[12] ^ D[9] ^ D[8] ^ D[7] ^ D[5] ^ + D[4] ^ D[3] ^ C[1] ^ C[2] ^ C[12] ^ C[13] ^ C[17] ^ + C[18] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ C[24] ^ C[25] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[16] = D[57] ^ D[56] ^ D[51] ^ D[48] ^ D[47] ^ D[46] ^ D[44] ^ + D[37] ^ D[35] ^ D[32] ^ D[30] ^ D[29] ^ D[26] ^ D[24] ^ + D[22] ^ D[21] ^ D[19] ^ D[17] ^ D[13] ^ D[12] ^ D[8] ^ + D[5] ^ D[4] ^ D[0] ^ C[0] ^ C[3] ^ C[5] ^ C[12] ^ C[14] ^ + C[15] ^ C[16] ^ C[19] ^ C[24] ^ C[25]; + NewCRC[17] = D[58] ^ D[57] ^ D[52] ^ D[49] ^ D[48] ^ D[47] ^ D[45] ^ + D[38] ^ D[36] ^ D[33] ^ D[31] ^ D[30] ^ D[27] ^ D[25] ^ + D[23] ^ D[22] ^ D[20] ^ D[18] ^ D[14] ^ D[13] ^ D[9] ^ + D[6] ^ D[5] ^ D[1] ^ C[1] ^ C[4] ^ C[6] ^ C[13] ^ C[15] ^ + C[16] ^ C[17] ^ C[20] ^ C[25] ^ C[26]; + NewCRC[18] = D[59] ^ D[58] ^ D[53] ^ D[50] ^ D[49] ^ D[48] ^ D[46] ^ + D[39] ^ D[37] ^ D[34] ^ D[32] ^ D[31] ^ D[28] ^ D[26] ^ + D[24] ^ D[23] ^ D[21] ^ D[19] ^ D[15] ^ D[14] ^ D[10] ^ + D[7] ^ D[6] ^ D[2] ^ C[0] ^ C[2] ^ C[5] ^ C[7] ^ C[14] ^ + C[16] ^ C[17] ^ C[18] ^ C[21] ^ C[26] ^ C[27]; + NewCRC[19] = D[60] ^ D[59] ^ D[54] ^ D[51] ^ D[50] ^ D[49] ^ D[47] ^ + D[40] ^ D[38] ^ D[35] ^ D[33] ^ D[32] ^ D[29] ^ D[27] ^ + D[25] ^ D[24] ^ D[22] ^ D[20] ^ D[16] ^ D[15] ^ D[11] ^ + D[8] ^ D[7] ^ D[3] ^ C[0] ^ C[1] ^ C[3] ^ C[6] ^ C[8] ^ + C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[22] ^ C[27] ^ C[28]; + NewCRC[20] = D[61] ^ D[60] ^ D[55] ^ D[52] ^ D[51] ^ D[50] ^ D[48] ^ + D[41] ^ D[39] ^ D[36] ^ D[34] ^ D[33] ^ D[30] ^ D[28] ^ + D[26] ^ D[25] ^ D[23] ^ D[21] ^ D[17] ^ D[16] ^ D[12] ^ + D[9] ^ D[8] ^ D[4] ^ C[1] ^ C[2] ^ C[4] ^ C[7] ^ C[9] ^ + C[16] ^ C[18] ^ C[19] ^ C[20] ^ C[23] ^ C[28] ^ C[29]; + NewCRC[21] = D[62] ^ D[61] ^ D[56] ^ D[53] ^ D[52] ^ D[51] ^ D[49] ^ + D[42] ^ D[40] ^ D[37] ^ D[35] ^ D[34] ^ D[31] ^ D[29] ^ + D[27] ^ D[26] ^ D[24] ^ D[22] ^ D[18] ^ D[17] ^ D[13] ^ + D[10] ^ D[9] ^ D[5] ^ C[2] ^ C[3] ^ C[5] ^ C[8] ^ C[10] ^ + C[17] ^ C[19] ^ C[20] ^ C[21] ^ C[24] ^ C[29] ^ C[30]; + NewCRC[22] = D[62] ^ D[61] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[52] ^ + D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[43] ^ D[41] ^ D[38] ^ + D[37] ^ D[36] ^ D[35] ^ D[34] ^ D[31] ^ D[29] ^ D[27] ^ + D[26] ^ D[24] ^ D[23] ^ D[19] ^ D[18] ^ D[16] ^ D[14] ^ + D[12] ^ D[11] ^ D[9] ^ D[0] ^ C[2] ^ C[3] ^ C[4] ^ + C[5] ^ C[6] ^ C[9] ^ C[11] ^ C[12] ^ C[13] ^ C[15] ^ + C[16] ^ C[20] ^ C[23] ^ C[25] ^ C[26] ^ C[28] ^ C[29] ^ + C[30]; + NewCRC[23] = D[62] ^ D[60] ^ D[59] ^ D[56] ^ D[55] ^ D[54] ^ D[50] ^ + D[49] ^ D[47] ^ D[46] ^ D[42] ^ D[39] ^ D[38] ^ D[36] ^ + D[35] ^ D[34] ^ D[31] ^ D[29] ^ D[27] ^ D[26] ^ D[20] ^ + D[19] ^ D[17] ^ D[16] ^ D[15] ^ D[13] ^ D[9] ^ D[6] ^ + D[1] ^ D[0] ^ C[2] ^ C[3] ^ C[4] ^ C[6] ^ C[7] ^ C[10] ^ + C[14] ^ C[15] ^ C[17] ^ C[18] ^ C[22] ^ C[23] ^ C[24] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[24] = D[63] ^ D[61] ^ D[60] ^ D[57] ^ D[56] ^ D[55] ^ D[51] ^ + D[50] ^ D[48] ^ D[47] ^ D[43] ^ D[40] ^ D[39] ^ D[37] ^ + D[36] ^ D[35] ^ D[32] ^ D[30] ^ D[28] ^ D[27] ^ D[21] ^ + D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[14] ^ D[10] ^ D[7] ^ + D[2] ^ D[1] ^ C[0] ^ C[3] ^ C[4] ^ C[5] ^ C[7] ^ C[8] ^ + C[11] ^ C[15] ^ C[16] ^ C[18] ^ C[19] ^ C[23] ^ C[24] ^ + C[25] ^ C[28] ^ C[29] ^ C[31]; + NewCRC[25] = D[62] ^ D[61] ^ D[58] ^ D[57] ^ D[56] ^ D[52] ^ D[51] ^ + D[49] ^ D[48] ^ D[44] ^ D[41] ^ D[40] ^ D[38] ^ D[37] ^ + D[36] ^ D[33] ^ D[31] ^ D[29] ^ D[28] ^ D[22] ^ D[21] ^ + D[19] ^ D[18] ^ D[17] ^ D[15] ^ D[11] ^ D[8] ^ D[3] ^ + D[2] ^ C[1] ^ C[4] ^ C[5] ^ C[6] ^ C[8] ^ C[9] ^ C[12] ^ + C[16] ^ C[17] ^ C[19] ^ C[20] ^ C[24] ^ C[25] ^ C[26] ^ + C[29] ^ C[30]; + NewCRC[26] = D[62] ^ D[61] ^ D[60] ^ D[59] ^ D[57] ^ D[55] ^ D[54] ^ + D[52] ^ D[49] ^ D[48] ^ D[47] ^ D[44] ^ D[42] ^ D[41] ^ + D[39] ^ D[38] ^ D[31] ^ D[28] ^ D[26] ^ D[25] ^ D[24] ^ + D[23] ^ D[22] ^ D[20] ^ D[19] ^ D[18] ^ D[10] ^ D[6] ^ + D[4] ^ D[3] ^ D[0] ^ C[6] ^ C[7] ^ C[9] ^ C[10] ^ C[12] ^ + C[15] ^ C[16] ^ C[17] ^ C[20] ^ C[22] ^ C[23] ^ C[25] ^ + C[27] ^ C[28] ^ C[29] ^ C[30]; + NewCRC[27] = D[63] ^ D[62] ^ D[61] ^ D[60] ^ D[58] ^ D[56] ^ D[55] ^ + D[53] ^ D[50] ^ D[49] ^ D[48] ^ D[45] ^ D[43] ^ D[42] ^ + D[40] ^ D[39] ^ D[32] ^ D[29] ^ D[27] ^ D[26] ^ D[25] ^ + D[24] ^ D[23] ^ D[21] ^ D[20] ^ D[19] ^ D[11] ^ D[7] ^ + D[5] ^ D[4] ^ D[1] ^ C[0] ^ C[7] ^ C[8] ^ C[10] ^ C[11] ^ + C[13] ^ C[16] ^ C[17] ^ C[18] ^ C[21] ^ C[23] ^ C[24] ^ + C[26] ^ C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[28] = D[63] ^ D[62] ^ D[61] ^ D[59] ^ D[57] ^ D[56] ^ D[54] ^ + D[51] ^ D[50] ^ D[49] ^ D[46] ^ D[44] ^ D[43] ^ D[41] ^ + D[40] ^ D[33] ^ D[30] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^ + D[24] ^ D[22] ^ D[21] ^ D[20] ^ D[12] ^ D[8] ^ D[6] ^ + D[5] ^ D[2] ^ C[1] ^ C[8] ^ C[9] ^ C[11] ^ C[12] ^ + C[14] ^ C[17] ^ C[18] ^ C[19] ^ C[22] ^ C[24] ^ C[25] ^ + C[27] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[29] = D[63] ^ D[62] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[52] ^ + D[51] ^ D[50] ^ D[47] ^ D[45] ^ D[44] ^ D[42] ^ D[41] ^ + D[34] ^ D[31] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^ + D[23] ^ D[22] ^ D[21] ^ D[13] ^ D[9] ^ D[7] ^ D[6] ^ + D[3] ^ C[2] ^ C[9] ^ C[10] ^ C[12] ^ C[13] ^ C[15] ^ + C[18] ^ C[19] ^ C[20] ^ C[23] ^ C[25] ^ C[26] ^ C[28] ^ + C[30] ^ C[31]; + NewCRC[30] = D[63] ^ D[61] ^ D[59] ^ D[58] ^ D[56] ^ D[53] ^ D[52] ^ + D[51] ^ D[48] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[35] ^ + D[32] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[24] ^ + D[23] ^ D[22] ^ D[14] ^ D[10] ^ D[8] ^ D[7] ^ D[4] ^ + C[0] ^ C[3] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ C[16] ^ + C[19] ^ C[20] ^ C[21] ^ C[24] ^ C[26] ^ C[27] ^ C[29] ^ + C[31]; + NewCRC[31] = D[62] ^ D[60] ^ D[59] ^ D[57] ^ D[54] ^ D[53] ^ D[52] ^ + D[49] ^ D[47] ^ D[46] ^ D[44] ^ D[43] ^ D[36] ^ D[33] ^ + D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[25] ^ D[24] ^ + D[23] ^ D[15] ^ D[11] ^ D[9] ^ D[8] ^ D[5] ^ C[1] ^ + C[4] ^ C[11] ^ C[12] ^ C[14] ^ C[15] ^ C[17] ^ C[20] ^ + C[21] ^ C[22] ^ C[25] ^ C[27] ^ C[28] ^ C[30]; + + nextCRC32_D64 = NewCRC; + + end + + endfunction + +//endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/include/CRC32_D8.v b/fpga/usrp3/lib/xge/rtl/include/CRC32_D8.v new file mode 100644 index 000000000..814648684 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/include/CRC32_D8.v @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////// +// File: CRC32_D8.v +// Date: Fri Feb 8 19:26:59 2008 +// +// Copyright (C) 1999-2003 Easics NV. +// 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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Purpose: Verilog module containing a synthesizable CRC function +// * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) +// * data width: 8 +// +// Info: tools@easics.be +// http://www.easics.com +/////////////////////////////////////////////////////////////////////// + + +//module CRC32_D8; + + // polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) + // data width: 8 + // convention: the first serial data bit is D[7] + function [31:0] nextCRC32_D8; + + input [7:0] Data; + input [31:0] CRC; + + reg [7:0] D; + reg [31:0] C; + reg [31:0] NewCRC; + + begin + + D = Data; + C = CRC; + + NewCRC[0] = D[6] ^ D[0] ^ C[24] ^ C[30]; + NewCRC[1] = D[7] ^ D[6] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[30] ^ + C[31]; + NewCRC[2] = D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ + C[26] ^ C[30] ^ C[31]; + NewCRC[3] = D[7] ^ D[3] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[27] ^ + C[31]; + NewCRC[4] = D[6] ^ D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[5] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[24] ^ + C[25] ^ C[27] ^ C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[6] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ + C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[7] = D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ + C[27] ^ C[29] ^ C[31]; + NewCRC[8] = D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[24] ^ C[25] ^ + C[27] ^ C[28]; + NewCRC[9] = D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[1] ^ C[25] ^ C[26] ^ + C[28] ^ C[29]; + NewCRC[10] = D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[2] ^ C[24] ^ C[26] ^ + C[27] ^ C[29]; + NewCRC[11] = D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[3] ^ C[24] ^ C[25] ^ + C[27] ^ C[28]; + NewCRC[12] = D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ D[0] ^ C[4] ^ C[24] ^ + C[25] ^ C[26] ^ C[28] ^ C[29] ^ C[30]; + NewCRC[13] = D[7] ^ D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[1] ^ C[5] ^ C[25] ^ + C[26] ^ C[27] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[14] = D[7] ^ D[6] ^ D[4] ^ D[3] ^ D[2] ^ C[6] ^ C[26] ^ C[27] ^ + C[28] ^ C[30] ^ C[31]; + NewCRC[15] = D[7] ^ D[5] ^ D[4] ^ D[3] ^ C[7] ^ C[27] ^ C[28] ^ + C[29] ^ C[31]; + NewCRC[16] = D[5] ^ D[4] ^ D[0] ^ C[8] ^ C[24] ^ C[28] ^ C[29]; + NewCRC[17] = D[6] ^ D[5] ^ D[1] ^ C[9] ^ C[25] ^ C[29] ^ C[30]; + NewCRC[18] = D[7] ^ D[6] ^ D[2] ^ C[10] ^ C[26] ^ C[30] ^ C[31]; + NewCRC[19] = D[7] ^ D[3] ^ C[11] ^ C[27] ^ C[31]; + NewCRC[20] = D[4] ^ C[12] ^ C[28]; + NewCRC[21] = D[5] ^ C[13] ^ C[29]; + NewCRC[22] = D[0] ^ C[14] ^ C[24]; + NewCRC[23] = D[6] ^ D[1] ^ D[0] ^ C[15] ^ C[24] ^ C[25] ^ C[30]; + NewCRC[24] = D[7] ^ D[2] ^ D[1] ^ C[16] ^ C[25] ^ C[26] ^ C[31]; + NewCRC[25] = D[3] ^ D[2] ^ C[17] ^ C[26] ^ C[27]; + NewCRC[26] = D[6] ^ D[4] ^ D[3] ^ D[0] ^ C[18] ^ C[24] ^ C[27] ^ + C[28] ^ C[30]; + NewCRC[27] = D[7] ^ D[5] ^ D[4] ^ D[1] ^ C[19] ^ C[25] ^ C[28] ^ + C[29] ^ C[31]; + NewCRC[28] = D[6] ^ D[5] ^ D[2] ^ C[20] ^ C[26] ^ C[29] ^ C[30]; + NewCRC[29] = D[7] ^ D[6] ^ D[3] ^ C[21] ^ C[27] ^ C[30] ^ C[31]; + NewCRC[30] = D[7] ^ D[4] ^ C[22] ^ C[28] ^ C[31]; + NewCRC[31] = D[5] ^ C[23] ^ C[29]; + + nextCRC32_D8 = NewCRC; + + end + + endfunction + +//endmodule + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/include/defines.v b/fpga/usrp3/lib/xge/rtl/include/defines.v new file mode 100644 index 000000000..095f303bf --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/include/defines.v @@ -0,0 +1,125 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "defines.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + +// Define MDIO to add support for clause 22 and clause 45 MDIO interface +`define MDIO +// If WB clock is 62.5MHz and max MDC spec is 2.5MHz, then divide by 25 +//`define MDC_HALF_PERIOD 13 // Closest int to 12.5 +`define MDC_HALF_PERIOD 100 + +// CPU Registers + +`define CPUREG_CONFIG0 8'h00 +`define CPUREG_INT_PENDING 8'h04 +`define CPUREG_INT_STATUS 8'h08 +`define CPUREG_INT_MASK 8'h0c +//`ifdef MDIO +`define CPUREG_MDIO_DATA 8'h10 +`define CPUREG_MDIO_ADDR 8'h14 +`define CPUREG_MDIO_OP 8'h18 +`define CPUREG_MDIO_CONTROL 8'h1c +`define CPUREG_MDIO_STATUS 8'h1c +`define CPUREG_GPIO 8'h20 +//`endif + +// Ethernet codes + +`define IDLE 8'h07 +`define PREAMBLE 8'h55 +`define SEQUENCE 8'h9c +`define SFD 8'hd5 +`define START 8'hfb +`define TERMINATE 8'hfd +`define ERROR 8'hfe + + + +`define LINK_FAULT_OK 2'd0 +`define LINK_FAULT_LOCAL 2'd1 +`define LINK_FAULT_REMOTE 2'd2 + +`define FAULT_SEQ_LOCAL 1'b0 +`define FAULT_SEQ_REMOTE 1'b1 + +`define LOCAL_FAULT 8'd1 +`define REMOTE_FAULT 8'd2 + +`define PAUSE_FRAME 48'h010000c28001 + +`define LANE0 7:0 +`define LANE1 15:8 +`define LANE2 23:16 +`define LANE3 31:24 +`define LANE4 39:32 +`define LANE5 47:40 +`define LANE6 55:48 +`define LANE7 63:56 + + +`define TXSTATUS_NONE 8'h0 +`define TXSTATUS_EOP 3'd6 +`define TXSTATUS_SOP 3'd7 + +`define RXSTATUS_NONE 8'h0 +`define RXSTATUS_ERR 3'd5 +`define RXSTATUS_EOP 3'd6 +`define RXSTATUS_SOP 3'd7 + + +// +// FIFO Size: 8 * (2^AWIDTH) will be the size in bytes +// 7 --> 128 entries, 1024 bytes for data fifo +// +`define TX_DATA_FIFO_AWIDTH 9 +`define RX_DATA_FIFO_AWIDTH 9 + +// +// FIFO Size: Holding FIFOs are 16 deep +// +`define TX_HOLD_FIFO_AWIDTH 4 +`define RX_HOLD_FIFO_AWIDTH 4 + + +// Memory types +`define MEM_AUTO_SMALL 1 +`define MEM_AUTO_MEDIUM 2 +`define MEM_AUTO_XILINX 3 + + +// Changed system packet interface to big endian (12/12/2009) +// Comment out to use legacy mode +`define BIGENDIAN diff --git a/fpga/usrp3/lib/xge/rtl/include/timescale.v b/fpga/usrp3/lib/xge/rtl/include/timescale.v new file mode 100644 index 000000000..64502185f --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/include/timescale.v @@ -0,0 +1 @@ +`timescale 1ps / 1ps diff --git a/fpga/usrp3/lib/xge/rtl/include/utils.v b/fpga/usrp3/lib/xge/rtl/include/utils.v new file mode 100644 index 000000000..6137b3e31 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/include/utils.v @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "utils.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +function [63:0] reverse_64b; + input [63:0] data; + integer i; + begin + for (i = 0; i < 64; i = i + 1) begin + reverse_64b[i] = data[63 - i]; + end + end +endfunction + + +function [31:0] reverse_32b; + input [31:0] data; + integer i; + begin + for (i = 0; i < 32; i = i + 1) begin + reverse_32b[i] = data[31 - i]; + end + end +endfunction + + +function [7:0] reverse_8b; + input [7:0] data; + integer i; + begin + for (i = 0; i < 8; i = i + 1) begin + reverse_8b[i] = data[7 - i]; + end + end +endfunction + + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D64.v b/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D64.v new file mode 100644 index 000000000..f13f85e1f --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D64.v @@ -0,0 +1,266 @@ +/////////////////////////////////////////////////////////////////////// +// File: CRC32_D64.v +// Date: Fri Feb 8 19:30:02 2008 +// +// Copyright (C) 1999-2003 Easics NV. +// 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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Purpose: Verilog module containing a synthesizable CRC function +// * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) +// * data width: 64 +// +// Info: tools@easics.be +// http://www.easics.com +/////////////////////////////////////////////////////////////////////// + + +//module CRC32_D64; + + // polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) + // data width: 64 + // convention: the first serial data bit is D[63] + function [31:0] nextCRC32_D64; + + input [63:0] Data; + input [31:0] CRC; + + reg [63:0] D; + reg [31:0] C; + reg [31:0] NewCRC; + + begin + + D = Data; + C = CRC; + + NewCRC[0] = D[63] ^ D[61] ^ D[60] ^ D[58] ^ D[55] ^ D[54] ^ D[53] ^ + D[50] ^ D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[37] ^ D[34] ^ + D[32] ^ D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[26] ^ D[25] ^ + D[24] ^ D[16] ^ D[12] ^ D[10] ^ D[9] ^ D[6] ^ D[0] ^ + C[0] ^ C[2] ^ C[5] ^ C[12] ^ C[13] ^ C[15] ^ C[16] ^ + C[18] ^ C[21] ^ C[22] ^ C[23] ^ C[26] ^ C[28] ^ C[29] ^ + C[31]; + NewCRC[1] = D[63] ^ D[62] ^ D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[53] ^ + D[51] ^ D[50] ^ D[49] ^ D[47] ^ D[46] ^ D[44] ^ D[38] ^ + D[37] ^ D[35] ^ D[34] ^ D[33] ^ D[28] ^ D[27] ^ D[24] ^ + D[17] ^ D[16] ^ D[13] ^ D[12] ^ D[11] ^ D[9] ^ D[7] ^ + D[6] ^ D[1] ^ D[0] ^ C[1] ^ C[2] ^ C[3] ^ C[5] ^ C[6] ^ + C[12] ^ C[14] ^ C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[21] ^ + C[24] ^ C[26] ^ C[27] ^ C[28] ^ C[30] ^ C[31]; + NewCRC[2] = D[59] ^ D[58] ^ D[57] ^ D[55] ^ D[53] ^ D[52] ^ D[51] ^ + D[44] ^ D[39] ^ D[38] ^ D[37] ^ D[36] ^ D[35] ^ D[32] ^ + D[31] ^ D[30] ^ D[26] ^ D[24] ^ D[18] ^ D[17] ^ D[16] ^ + D[14] ^ D[13] ^ D[9] ^ D[8] ^ D[7] ^ D[6] ^ D[2] ^ + D[1] ^ D[0] ^ C[0] ^ C[3] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ + C[12] ^ C[19] ^ C[20] ^ C[21] ^ C[23] ^ C[25] ^ C[26] ^ + C[27]; + NewCRC[3] = D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[54] ^ D[53] ^ D[52] ^ + D[45] ^ D[40] ^ D[39] ^ D[38] ^ D[37] ^ D[36] ^ D[33] ^ + D[32] ^ D[31] ^ D[27] ^ D[25] ^ D[19] ^ D[18] ^ D[17] ^ + D[15] ^ D[14] ^ D[10] ^ D[9] ^ D[8] ^ D[7] ^ D[3] ^ + D[2] ^ D[1] ^ C[0] ^ C[1] ^ C[4] ^ C[5] ^ C[6] ^ C[7] ^ + C[8] ^ C[13] ^ C[20] ^ C[21] ^ C[22] ^ C[24] ^ C[26] ^ + C[27] ^ C[28]; + NewCRC[4] = D[63] ^ D[59] ^ D[58] ^ D[57] ^ D[50] ^ D[48] ^ D[47] ^ + D[46] ^ D[45] ^ D[44] ^ D[41] ^ D[40] ^ D[39] ^ D[38] ^ + D[33] ^ D[31] ^ D[30] ^ D[29] ^ D[25] ^ D[24] ^ D[20] ^ + D[19] ^ D[18] ^ D[15] ^ D[12] ^ D[11] ^ D[8] ^ D[6] ^ + D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[1] ^ C[6] ^ C[7] ^ C[8] ^ + C[9] ^ C[12] ^ C[13] ^ C[14] ^ C[15] ^ C[16] ^ C[18] ^ + C[25] ^ C[26] ^ C[27] ^ C[31]; + NewCRC[5] = D[63] ^ D[61] ^ D[59] ^ D[55] ^ D[54] ^ D[53] ^ D[51] ^ + D[50] ^ D[49] ^ D[46] ^ D[44] ^ D[42] ^ D[41] ^ D[40] ^ + D[39] ^ D[37] ^ D[29] ^ D[28] ^ D[24] ^ D[21] ^ D[20] ^ + D[19] ^ D[13] ^ D[10] ^ D[7] ^ D[6] ^ D[5] ^ D[4] ^ + D[3] ^ D[1] ^ D[0] ^ C[5] ^ C[7] ^ C[8] ^ C[9] ^ C[10] ^ + C[12] ^ C[14] ^ C[17] ^ C[18] ^ C[19] ^ C[21] ^ C[22] ^ + C[23] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[6] = D[62] ^ D[60] ^ D[56] ^ D[55] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[47] ^ D[45] ^ D[43] ^ D[42] ^ D[41] ^ D[40] ^ + D[38] ^ D[30] ^ D[29] ^ D[25] ^ D[22] ^ D[21] ^ D[20] ^ + D[14] ^ D[11] ^ D[8] ^ D[7] ^ D[6] ^ D[5] ^ D[4] ^ + D[2] ^ D[1] ^ C[6] ^ C[8] ^ C[9] ^ C[10] ^ C[11] ^ + C[13] ^ C[15] ^ C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[23] ^ + C[24] ^ C[28] ^ C[30]; + NewCRC[7] = D[60] ^ D[58] ^ D[57] ^ D[56] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[47] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[41] ^ + D[39] ^ D[37] ^ D[34] ^ D[32] ^ D[29] ^ D[28] ^ D[25] ^ + D[24] ^ D[23] ^ D[22] ^ D[21] ^ D[16] ^ D[15] ^ D[10] ^ + D[8] ^ D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[0] ^ C[2] ^ + C[5] ^ C[7] ^ C[9] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ + C[15] ^ C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[24] ^ C[25] ^ + C[26] ^ C[28]; + NewCRC[8] = D[63] ^ D[60] ^ D[59] ^ D[57] ^ D[54] ^ D[52] ^ D[51] ^ + D[50] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[40] ^ D[38] ^ + D[37] ^ D[35] ^ D[34] ^ D[33] ^ D[32] ^ D[31] ^ D[28] ^ + D[23] ^ D[22] ^ D[17] ^ D[12] ^ D[11] ^ D[10] ^ D[8] ^ + D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[1] ^ C[2] ^ C[3] ^ + C[5] ^ C[6] ^ C[8] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ + C[18] ^ C[19] ^ C[20] ^ C[22] ^ C[25] ^ C[27] ^ C[28] ^ + C[31]; + NewCRC[9] = D[61] ^ D[60] ^ D[58] ^ D[55] ^ D[53] ^ D[52] ^ D[51] ^ + D[47] ^ D[46] ^ D[44] ^ D[43] ^ D[41] ^ D[39] ^ D[38] ^ + D[36] ^ D[35] ^ D[34] ^ D[33] ^ D[32] ^ D[29] ^ D[24] ^ + D[23] ^ D[18] ^ D[13] ^ D[12] ^ D[11] ^ D[9] ^ D[5] ^ + D[4] ^ D[2] ^ D[1] ^ C[0] ^ C[1] ^ C[2] ^ C[3] ^ C[4] ^ + C[6] ^ C[7] ^ C[9] ^ C[11] ^ C[12] ^ C[14] ^ C[15] ^ + C[19] ^ C[20] ^ C[21] ^ C[23] ^ C[26] ^ C[28] ^ C[29]; + NewCRC[10] = D[63] ^ D[62] ^ D[60] ^ D[59] ^ D[58] ^ D[56] ^ D[55] ^ + D[52] ^ D[50] ^ D[42] ^ D[40] ^ D[39] ^ D[36] ^ D[35] ^ + D[33] ^ D[32] ^ D[31] ^ D[29] ^ D[28] ^ D[26] ^ D[19] ^ + D[16] ^ D[14] ^ D[13] ^ D[9] ^ D[5] ^ D[3] ^ D[2] ^ + D[0] ^ C[0] ^ C[1] ^ C[3] ^ C[4] ^ C[7] ^ C[8] ^ C[10] ^ + C[18] ^ C[20] ^ C[23] ^ C[24] ^ C[26] ^ C[27] ^ C[28] ^ + C[30] ^ C[31]; + NewCRC[11] = D[59] ^ D[58] ^ D[57] ^ D[56] ^ D[55] ^ D[54] ^ D[51] ^ + D[50] ^ D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[43] ^ D[41] ^ + D[40] ^ D[36] ^ D[33] ^ D[31] ^ D[28] ^ D[27] ^ D[26] ^ + D[25] ^ D[24] ^ D[20] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ + D[12] ^ D[9] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[1] ^ C[4] ^ + C[8] ^ C[9] ^ C[11] ^ C[12] ^ C[13] ^ C[15] ^ C[16] ^ + C[18] ^ C[19] ^ C[22] ^ C[23] ^ C[24] ^ C[25] ^ C[26] ^ + C[27]; + NewCRC[12] = D[63] ^ D[61] ^ D[59] ^ D[57] ^ D[56] ^ D[54] ^ D[53] ^ + D[52] ^ D[51] ^ D[50] ^ D[49] ^ D[47] ^ D[46] ^ D[42] ^ + D[41] ^ D[31] ^ D[30] ^ D[27] ^ D[24] ^ D[21] ^ D[18] ^ + D[17] ^ D[15] ^ D[13] ^ D[12] ^ D[9] ^ D[6] ^ D[5] ^ + D[4] ^ D[2] ^ D[1] ^ D[0] ^ C[9] ^ C[10] ^ C[14] ^ + C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ + C[24] ^ C[25] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[13] = D[62] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[54] ^ D[53] ^ + D[52] ^ D[51] ^ D[50] ^ D[48] ^ D[47] ^ D[43] ^ D[42] ^ + D[32] ^ D[31] ^ D[28] ^ D[25] ^ D[22] ^ D[19] ^ D[18] ^ + D[16] ^ D[14] ^ D[13] ^ D[10] ^ D[7] ^ D[6] ^ D[5] ^ + D[3] ^ D[2] ^ D[1] ^ C[0] ^ C[10] ^ C[11] ^ C[15] ^ + C[16] ^ C[18] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ + C[25] ^ C[26] ^ C[28] ^ C[30]; + NewCRC[14] = D[63] ^ D[61] ^ D[59] ^ D[58] ^ D[56] ^ D[55] ^ D[54] ^ + D[53] ^ D[52] ^ D[51] ^ D[49] ^ D[48] ^ D[44] ^ D[43] ^ + D[33] ^ D[32] ^ D[29] ^ D[26] ^ D[23] ^ D[20] ^ D[19] ^ + D[17] ^ D[15] ^ D[14] ^ D[11] ^ D[8] ^ D[7] ^ D[6] ^ + D[4] ^ D[3] ^ D[2] ^ C[0] ^ C[1] ^ C[11] ^ C[12] ^ + C[16] ^ C[17] ^ C[19] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ + C[24] ^ C[26] ^ C[27] ^ C[29] ^ C[31]; + NewCRC[15] = D[62] ^ D[60] ^ D[59] ^ D[57] ^ D[56] ^ D[55] ^ D[54] ^ + D[53] ^ D[52] ^ D[50] ^ D[49] ^ D[45] ^ D[44] ^ D[34] ^ + D[33] ^ D[30] ^ D[27] ^ D[24] ^ D[21] ^ D[20] ^ D[18] ^ + D[16] ^ D[15] ^ D[12] ^ D[9] ^ D[8] ^ D[7] ^ D[5] ^ + D[4] ^ D[3] ^ C[1] ^ C[2] ^ C[12] ^ C[13] ^ C[17] ^ + C[18] ^ C[20] ^ C[21] ^ C[22] ^ C[23] ^ C[24] ^ C[25] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[16] = D[57] ^ D[56] ^ D[51] ^ D[48] ^ D[47] ^ D[46] ^ D[44] ^ + D[37] ^ D[35] ^ D[32] ^ D[30] ^ D[29] ^ D[26] ^ D[24] ^ + D[22] ^ D[21] ^ D[19] ^ D[17] ^ D[13] ^ D[12] ^ D[8] ^ + D[5] ^ D[4] ^ D[0] ^ C[0] ^ C[3] ^ C[5] ^ C[12] ^ C[14] ^ + C[15] ^ C[16] ^ C[19] ^ C[24] ^ C[25]; + NewCRC[17] = D[58] ^ D[57] ^ D[52] ^ D[49] ^ D[48] ^ D[47] ^ D[45] ^ + D[38] ^ D[36] ^ D[33] ^ D[31] ^ D[30] ^ D[27] ^ D[25] ^ + D[23] ^ D[22] ^ D[20] ^ D[18] ^ D[14] ^ D[13] ^ D[9] ^ + D[6] ^ D[5] ^ D[1] ^ C[1] ^ C[4] ^ C[6] ^ C[13] ^ C[15] ^ + C[16] ^ C[17] ^ C[20] ^ C[25] ^ C[26]; + NewCRC[18] = D[59] ^ D[58] ^ D[53] ^ D[50] ^ D[49] ^ D[48] ^ D[46] ^ + D[39] ^ D[37] ^ D[34] ^ D[32] ^ D[31] ^ D[28] ^ D[26] ^ + D[24] ^ D[23] ^ D[21] ^ D[19] ^ D[15] ^ D[14] ^ D[10] ^ + D[7] ^ D[6] ^ D[2] ^ C[0] ^ C[2] ^ C[5] ^ C[7] ^ C[14] ^ + C[16] ^ C[17] ^ C[18] ^ C[21] ^ C[26] ^ C[27]; + NewCRC[19] = D[60] ^ D[59] ^ D[54] ^ D[51] ^ D[50] ^ D[49] ^ D[47] ^ + D[40] ^ D[38] ^ D[35] ^ D[33] ^ D[32] ^ D[29] ^ D[27] ^ + D[25] ^ D[24] ^ D[22] ^ D[20] ^ D[16] ^ D[15] ^ D[11] ^ + D[8] ^ D[7] ^ D[3] ^ C[0] ^ C[1] ^ C[3] ^ C[6] ^ C[8] ^ + C[15] ^ C[17] ^ C[18] ^ C[19] ^ C[22] ^ C[27] ^ C[28]; + NewCRC[20] = D[61] ^ D[60] ^ D[55] ^ D[52] ^ D[51] ^ D[50] ^ D[48] ^ + D[41] ^ D[39] ^ D[36] ^ D[34] ^ D[33] ^ D[30] ^ D[28] ^ + D[26] ^ D[25] ^ D[23] ^ D[21] ^ D[17] ^ D[16] ^ D[12] ^ + D[9] ^ D[8] ^ D[4] ^ C[1] ^ C[2] ^ C[4] ^ C[7] ^ C[9] ^ + C[16] ^ C[18] ^ C[19] ^ C[20] ^ C[23] ^ C[28] ^ C[29]; + NewCRC[21] = D[62] ^ D[61] ^ D[56] ^ D[53] ^ D[52] ^ D[51] ^ D[49] ^ + D[42] ^ D[40] ^ D[37] ^ D[35] ^ D[34] ^ D[31] ^ D[29] ^ + D[27] ^ D[26] ^ D[24] ^ D[22] ^ D[18] ^ D[17] ^ D[13] ^ + D[10] ^ D[9] ^ D[5] ^ C[2] ^ C[3] ^ C[5] ^ C[8] ^ C[10] ^ + C[17] ^ C[19] ^ C[20] ^ C[21] ^ C[24] ^ C[29] ^ C[30]; + NewCRC[22] = D[62] ^ D[61] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[52] ^ + D[48] ^ D[47] ^ D[45] ^ D[44] ^ D[43] ^ D[41] ^ D[38] ^ + D[37] ^ D[36] ^ D[35] ^ D[34] ^ D[31] ^ D[29] ^ D[27] ^ + D[26] ^ D[24] ^ D[23] ^ D[19] ^ D[18] ^ D[16] ^ D[14] ^ + D[12] ^ D[11] ^ D[9] ^ D[0] ^ C[2] ^ C[3] ^ C[4] ^ + C[5] ^ C[6] ^ C[9] ^ C[11] ^ C[12] ^ C[13] ^ C[15] ^ + C[16] ^ C[20] ^ C[23] ^ C[25] ^ C[26] ^ C[28] ^ C[29] ^ + C[30]; + NewCRC[23] = D[62] ^ D[60] ^ D[59] ^ D[56] ^ D[55] ^ D[54] ^ D[50] ^ + D[49] ^ D[47] ^ D[46] ^ D[42] ^ D[39] ^ D[38] ^ D[36] ^ + D[35] ^ D[34] ^ D[31] ^ D[29] ^ D[27] ^ D[26] ^ D[20] ^ + D[19] ^ D[17] ^ D[16] ^ D[15] ^ D[13] ^ D[9] ^ D[6] ^ + D[1] ^ D[0] ^ C[2] ^ C[3] ^ C[4] ^ C[6] ^ C[7] ^ C[10] ^ + C[14] ^ C[15] ^ C[17] ^ C[18] ^ C[22] ^ C[23] ^ C[24] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[24] = D[63] ^ D[61] ^ D[60] ^ D[57] ^ D[56] ^ D[55] ^ D[51] ^ + D[50] ^ D[48] ^ D[47] ^ D[43] ^ D[40] ^ D[39] ^ D[37] ^ + D[36] ^ D[35] ^ D[32] ^ D[30] ^ D[28] ^ D[27] ^ D[21] ^ + D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[14] ^ D[10] ^ D[7] ^ + D[2] ^ D[1] ^ C[0] ^ C[3] ^ C[4] ^ C[5] ^ C[7] ^ C[8] ^ + C[11] ^ C[15] ^ C[16] ^ C[18] ^ C[19] ^ C[23] ^ C[24] ^ + C[25] ^ C[28] ^ C[29] ^ C[31]; + NewCRC[25] = D[62] ^ D[61] ^ D[58] ^ D[57] ^ D[56] ^ D[52] ^ D[51] ^ + D[49] ^ D[48] ^ D[44] ^ D[41] ^ D[40] ^ D[38] ^ D[37] ^ + D[36] ^ D[33] ^ D[31] ^ D[29] ^ D[28] ^ D[22] ^ D[21] ^ + D[19] ^ D[18] ^ D[17] ^ D[15] ^ D[11] ^ D[8] ^ D[3] ^ + D[2] ^ C[1] ^ C[4] ^ C[5] ^ C[6] ^ C[8] ^ C[9] ^ C[12] ^ + C[16] ^ C[17] ^ C[19] ^ C[20] ^ C[24] ^ C[25] ^ C[26] ^ + C[29] ^ C[30]; + NewCRC[26] = D[62] ^ D[61] ^ D[60] ^ D[59] ^ D[57] ^ D[55] ^ D[54] ^ + D[52] ^ D[49] ^ D[48] ^ D[47] ^ D[44] ^ D[42] ^ D[41] ^ + D[39] ^ D[38] ^ D[31] ^ D[28] ^ D[26] ^ D[25] ^ D[24] ^ + D[23] ^ D[22] ^ D[20] ^ D[19] ^ D[18] ^ D[10] ^ D[6] ^ + D[4] ^ D[3] ^ D[0] ^ C[6] ^ C[7] ^ C[9] ^ C[10] ^ C[12] ^ + C[15] ^ C[16] ^ C[17] ^ C[20] ^ C[22] ^ C[23] ^ C[25] ^ + C[27] ^ C[28] ^ C[29] ^ C[30]; + NewCRC[27] = D[63] ^ D[62] ^ D[61] ^ D[60] ^ D[58] ^ D[56] ^ D[55] ^ + D[53] ^ D[50] ^ D[49] ^ D[48] ^ D[45] ^ D[43] ^ D[42] ^ + D[40] ^ D[39] ^ D[32] ^ D[29] ^ D[27] ^ D[26] ^ D[25] ^ + D[24] ^ D[23] ^ D[21] ^ D[20] ^ D[19] ^ D[11] ^ D[7] ^ + D[5] ^ D[4] ^ D[1] ^ C[0] ^ C[7] ^ C[8] ^ C[10] ^ C[11] ^ + C[13] ^ C[16] ^ C[17] ^ C[18] ^ C[21] ^ C[23] ^ C[24] ^ + C[26] ^ C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[28] = D[63] ^ D[62] ^ D[61] ^ D[59] ^ D[57] ^ D[56] ^ D[54] ^ + D[51] ^ D[50] ^ D[49] ^ D[46] ^ D[44] ^ D[43] ^ D[41] ^ + D[40] ^ D[33] ^ D[30] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^ + D[24] ^ D[22] ^ D[21] ^ D[20] ^ D[12] ^ D[8] ^ D[6] ^ + D[5] ^ D[2] ^ C[1] ^ C[8] ^ C[9] ^ C[11] ^ C[12] ^ + C[14] ^ C[17] ^ C[18] ^ C[19] ^ C[22] ^ C[24] ^ C[25] ^ + C[27] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[29] = D[63] ^ D[62] ^ D[60] ^ D[58] ^ D[57] ^ D[55] ^ D[52] ^ + D[51] ^ D[50] ^ D[47] ^ D[45] ^ D[44] ^ D[42] ^ D[41] ^ + D[34] ^ D[31] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[25] ^ + D[23] ^ D[22] ^ D[21] ^ D[13] ^ D[9] ^ D[7] ^ D[6] ^ + D[3] ^ C[2] ^ C[9] ^ C[10] ^ C[12] ^ C[13] ^ C[15] ^ + C[18] ^ C[19] ^ C[20] ^ C[23] ^ C[25] ^ C[26] ^ C[28] ^ + C[30] ^ C[31]; + NewCRC[30] = D[63] ^ D[61] ^ D[59] ^ D[58] ^ D[56] ^ D[53] ^ D[52] ^ + D[51] ^ D[48] ^ D[46] ^ D[45] ^ D[43] ^ D[42] ^ D[35] ^ + D[32] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[26] ^ D[24] ^ + D[23] ^ D[22] ^ D[14] ^ D[10] ^ D[8] ^ D[7] ^ D[4] ^ + C[0] ^ C[3] ^ C[10] ^ C[11] ^ C[13] ^ C[14] ^ C[16] ^ + C[19] ^ C[20] ^ C[21] ^ C[24] ^ C[26] ^ C[27] ^ C[29] ^ + C[31]; + NewCRC[31] = D[62] ^ D[60] ^ D[59] ^ D[57] ^ D[54] ^ D[53] ^ D[52] ^ + D[49] ^ D[47] ^ D[46] ^ D[44] ^ D[43] ^ D[36] ^ D[33] ^ + D[31] ^ D[30] ^ D[29] ^ D[28] ^ D[27] ^ D[25] ^ D[24] ^ + D[23] ^ D[15] ^ D[11] ^ D[9] ^ D[8] ^ D[5] ^ C[1] ^ + C[4] ^ C[11] ^ C[12] ^ C[14] ^ C[15] ^ C[17] ^ C[20] ^ + C[21] ^ C[22] ^ C[25] ^ C[27] ^ C[28] ^ C[30]; + + nextCRC32_D64 = NewCRC; + + end + + endfunction + +//endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D8.v b/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D8.v new file mode 100644 index 000000000..814648684 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/CRC32_D8.v @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////// +// File: CRC32_D8.v +// Date: Fri Feb 8 19:26:59 2008 +// +// Copyright (C) 1999-2003 Easics NV. +// 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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Purpose: Verilog module containing a synthesizable CRC function +// * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) +// * data width: 8 +// +// Info: tools@easics.be +// http://www.easics.com +/////////////////////////////////////////////////////////////////////// + + +//module CRC32_D8; + + // polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) + // data width: 8 + // convention: the first serial data bit is D[7] + function [31:0] nextCRC32_D8; + + input [7:0] Data; + input [31:0] CRC; + + reg [7:0] D; + reg [31:0] C; + reg [31:0] NewCRC; + + begin + + D = Data; + C = CRC; + + NewCRC[0] = D[6] ^ D[0] ^ C[24] ^ C[30]; + NewCRC[1] = D[7] ^ D[6] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[30] ^ + C[31]; + NewCRC[2] = D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ + C[26] ^ C[30] ^ C[31]; + NewCRC[3] = D[7] ^ D[3] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[27] ^ + C[31]; + NewCRC[4] = D[6] ^ D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ + C[27] ^ C[28] ^ C[30]; + NewCRC[5] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[24] ^ + C[25] ^ C[27] ^ C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[6] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ + C[28] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[7] = D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ + C[27] ^ C[29] ^ C[31]; + NewCRC[8] = D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[24] ^ C[25] ^ + C[27] ^ C[28]; + NewCRC[9] = D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[1] ^ C[25] ^ C[26] ^ + C[28] ^ C[29]; + NewCRC[10] = D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[2] ^ C[24] ^ C[26] ^ + C[27] ^ C[29]; + NewCRC[11] = D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[3] ^ C[24] ^ C[25] ^ + C[27] ^ C[28]; + NewCRC[12] = D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ D[0] ^ C[4] ^ C[24] ^ + C[25] ^ C[26] ^ C[28] ^ C[29] ^ C[30]; + NewCRC[13] = D[7] ^ D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[1] ^ C[5] ^ C[25] ^ + C[26] ^ C[27] ^ C[29] ^ C[30] ^ C[31]; + NewCRC[14] = D[7] ^ D[6] ^ D[4] ^ D[3] ^ D[2] ^ C[6] ^ C[26] ^ C[27] ^ + C[28] ^ C[30] ^ C[31]; + NewCRC[15] = D[7] ^ D[5] ^ D[4] ^ D[3] ^ C[7] ^ C[27] ^ C[28] ^ + C[29] ^ C[31]; + NewCRC[16] = D[5] ^ D[4] ^ D[0] ^ C[8] ^ C[24] ^ C[28] ^ C[29]; + NewCRC[17] = D[6] ^ D[5] ^ D[1] ^ C[9] ^ C[25] ^ C[29] ^ C[30]; + NewCRC[18] = D[7] ^ D[6] ^ D[2] ^ C[10] ^ C[26] ^ C[30] ^ C[31]; + NewCRC[19] = D[7] ^ D[3] ^ C[11] ^ C[27] ^ C[31]; + NewCRC[20] = D[4] ^ C[12] ^ C[28]; + NewCRC[21] = D[5] ^ C[13] ^ C[29]; + NewCRC[22] = D[0] ^ C[14] ^ C[24]; + NewCRC[23] = D[6] ^ D[1] ^ D[0] ^ C[15] ^ C[24] ^ C[25] ^ C[30]; + NewCRC[24] = D[7] ^ D[2] ^ D[1] ^ C[16] ^ C[25] ^ C[26] ^ C[31]; + NewCRC[25] = D[3] ^ D[2] ^ C[17] ^ C[26] ^ C[27]; + NewCRC[26] = D[6] ^ D[4] ^ D[3] ^ D[0] ^ C[18] ^ C[24] ^ C[27] ^ + C[28] ^ C[30]; + NewCRC[27] = D[7] ^ D[5] ^ D[4] ^ D[1] ^ C[19] ^ C[25] ^ C[28] ^ + C[29] ^ C[31]; + NewCRC[28] = D[6] ^ D[5] ^ D[2] ^ C[20] ^ C[26] ^ C[29] ^ C[30]; + NewCRC[29] = D[7] ^ D[6] ^ D[3] ^ C[21] ^ C[27] ^ C[30] ^ C[31]; + NewCRC[30] = D[7] ^ D[4] ^ C[22] ^ C[28] ^ C[31]; + NewCRC[31] = D[5] ^ C[23] ^ C[29]; + + nextCRC32_D8 = NewCRC; + + end + + endfunction + +//endmodule + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/defines.v b/fpga/usrp3/lib/xge/rtl/verilog/defines.v new file mode 100644 index 000000000..c78203353 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/defines.v @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "defines.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + +// If WB clock is 62.5MHz and max MDC spec is 2.5MHz, then divide by 25 +//`define MDC_HALF_PERIOD 13 // Closest int to 12.5 +`define MDC_HALF_PERIOD 100 + +// CPU Registers + +`define CPUREG_CONFIG0 8'h00 +`define CPUREG_INT_PENDING 8'h04 +`define CPUREG_INT_STATUS 8'h08 +`define CPUREG_INT_MASK 8'h0c +`define CPUREG_MDIO_DATA 8'h10 +`define CPUREG_MDIO_ADDR 8'h14 +`define CPUREG_MDIO_OP 8'h18 +`define CPUREG_MDIO_CONTROL 8'h1c +`define CPUREG_MDIO_STATUS 8'h1c +`define CPUREG_GPIO 8'h20 + +// Ethernet codes + +`define IDLE 8'h07 +`define PREAMBLE 8'h55 +`define SEQUENCE 8'h9c +`define SFD 8'hd5 +`define START 8'hfb +`define TERMINATE 8'hfd +`define ERROR 8'hfe + + + +`define LINK_FAULT_OK 2'd0 +`define LINK_FAULT_LOCAL 2'd1 +`define LINK_FAULT_REMOTE 2'd2 + +`define FAULT_SEQ_LOCAL 1'b0 +`define FAULT_SEQ_REMOTE 1'b1 + +`define LOCAL_FAULT 8'd1 +`define REMOTE_FAULT 8'd2 + +`define PAUSE_FRAME 48'h010000c28001 + +`define LANE0 7:0 +`define LANE1 15:8 +`define LANE2 23:16 +`define LANE3 31:24 +`define LANE4 39:32 +`define LANE5 47:40 +`define LANE6 55:48 +`define LANE7 63:56 + + +`define TXSTATUS_NONE 8'h0 +`define TXSTATUS_EOP 3'd6 +`define TXSTATUS_SOP 3'd7 + +`define RXSTATUS_NONE 8'h0 +`define RXSTATUS_ERR 3'd5 +`define RXSTATUS_EOP 3'd6 +`define RXSTATUS_SOP 3'd7 + + +// +// FIFO Size: 8 * (2^AWIDTH) will be the size in bytes +// 7 --> 128 entries, 1024 bytes for data fifo +// +`define TX_DATA_FIFO_AWIDTH 7 +`define RX_DATA_FIFO_AWIDTH 7 + +// +// FIFO Size: Holding FIFOs are 16 deep +// +`define TX_HOLD_FIFO_AWIDTH 4 +`define RX_HOLD_FIFO_AWIDTH 4 + + +// Memory types +`define MEM_AUTO_SMALL 1 +`define MEM_AUTO_MEDIUM 2 +`define MEM_AUTO_XILINX 3 + + +// Changed system packet interface to big endian (12/12/2009) +// Comment out to use legacy mode (i.e. the correct mode) +//`define BIGENDIAN diff --git a/fpga/usrp3/lib/xge/rtl/verilog/fault_sm.v b/fpga/usrp3/lib/xge/rtl/verilog/fault_sm.v new file mode 100644 index 000000000..525459ca3 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/fault_sm.v @@ -0,0 +1,287 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "fault_sm.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module fault_sm(/*AUTOARG*/ + // Outputs + status_local_fault_crx, status_remote_fault_crx, + // Inputs + clk_xgmii_rx, reset_xgmii_rx_n, local_fault_msg_det, + remote_fault_msg_det + ); + +input clk_xgmii_rx; +input reset_xgmii_rx_n; + +input [1:0] local_fault_msg_det; +input [1:0] remote_fault_msg_det; + +output status_local_fault_crx; +output status_remote_fault_crx; + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg status_local_fault_crx; +reg status_remote_fault_crx; +// End of automatics + +reg [1:0] curr_state; + +reg [7:0] col_cnt; +reg [1:0] fault_sequence; +reg [1:0] last_seq_type; +reg [1:0] link_fault; +reg [2:0] seq_cnt; +reg [1:0] seq_type; + +reg [1:0] seq_add; + +/*AUTOWIRE*/ + + +parameter [1:0] + SM_INIT = 2'd0, + SM_COUNT = 2'd1, + SM_FAULT = 2'd2, + SM_NEW_FAULT = 2'd3; + + +always @(/*AS*/local_fault_msg_det or remote_fault_msg_det) begin + + //--- + // Fault indication. Indicate remote or local fault + + fault_sequence = local_fault_msg_det | remote_fault_msg_det; + + + //--- + // Sequence type, local, remote, or ok + + if (|local_fault_msg_det) begin + seq_type = `LINK_FAULT_LOCAL; + end + else if (|remote_fault_msg_det) begin + seq_type = `LINK_FAULT_REMOTE; + end + else begin + seq_type = `LINK_FAULT_OK; + end + + + //--- + // Adder for number of faults, if detected in lower 4 lanes and + // upper 4 lanes, add 2. That's because we process 64-bit at a time + // instead of typically 32-bit xgmii. + + if (|remote_fault_msg_det) begin + seq_add = remote_fault_msg_det[1] + remote_fault_msg_det[0]; + end + else begin + seq_add = local_fault_msg_det[1] + local_fault_msg_det[0]; + end + +end + +always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin + + if (reset_xgmii_rx_n == 1'b0) begin + + + status_local_fault_crx <= 1'b0; + status_remote_fault_crx <= 1'b0; + + end + else begin + + //--- + // Status signal to generate local/remote fault interrupts + + status_local_fault_crx <= curr_state == SM_FAULT && + link_fault == `LINK_FAULT_LOCAL; + + status_remote_fault_crx <= curr_state == SM_FAULT && + link_fault == `LINK_FAULT_REMOTE; + + end + +end + +always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin + + if (reset_xgmii_rx_n == 1'b0) begin + + curr_state <= SM_INIT; + + col_cnt <= 8'b0; + last_seq_type <= `LINK_FAULT_OK; + link_fault <= `LINK_FAULT_OK; + seq_cnt <= 3'b0; + + end + else begin + + case (curr_state) + + SM_INIT: + begin + + last_seq_type <= seq_type; + + if (|fault_sequence) begin + + // If a fault is detected, capture the type of + // fault and start column counter. We need 4 fault + // messages in 128 columns to accept the fault. + + if (fault_sequence[0]) begin + col_cnt <= 8'd2; + end + else begin + col_cnt <= 8'd1; + end + seq_cnt <= {1'b0, seq_add}; + curr_state <= SM_COUNT; + + end + else begin + + // If no faults, stay in INIT and clear counters + + col_cnt <= 8'b0; + seq_cnt <= 3'b0; + + end + end + + SM_COUNT: + begin + + col_cnt <= col_cnt + 8'd2; + seq_cnt <= seq_cnt + {1'b0, seq_add}; + + if (!fault_sequence[0] && col_cnt >= 8'd127) begin + + // No new fault in lower lanes and almost + // reached the 128 columns count, abort fault. + + curr_state <= SM_INIT; + + end + else if (col_cnt > 8'd127) begin + + // Reached the 128 columns count, abort fault. + + curr_state <= SM_INIT; + + end + else if (|fault_sequence) begin + + // If fault type has changed, move to NEW_FAULT. + // If not, after detecting 4 fault messages move to + // FAULT state. + + if (seq_type != last_seq_type) begin + curr_state <= SM_NEW_FAULT; + end + else begin + if ((seq_cnt + {1'b0, seq_add}) > 3'd3) begin + col_cnt <= 8'b0; + link_fault <= seq_type; + curr_state <= SM_FAULT; + end + end + + end + end + + SM_FAULT: + begin + + col_cnt <= col_cnt + 8'd2; + + if (!fault_sequence[0] && col_cnt >= 8'd127) begin + + // No new fault in lower lanes and almost + // reached the 128 columns count, abort fault. + + curr_state <= SM_INIT; + + end + else if (col_cnt > 8'd127) begin + + // Reached the 128 columns count, abort fault. + + curr_state <= SM_INIT; + + end + else if (|fault_sequence) begin + + // Clear the column count each time we see a fault, + // if fault changes, go no next state. + + col_cnt <= 8'd0; + + if (seq_type != last_seq_type) begin + curr_state <= SM_NEW_FAULT; + end + end + + end + + SM_NEW_FAULT: + begin + + // Capture new fault type. Start counters. + + col_cnt <= 8'b0; + last_seq_type <= seq_type; + + seq_cnt <= {1'b0, seq_add}; + curr_state <= SM_COUNT; + + end + + endcase + + end + +end + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo.v b/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo.v new file mode 100644 index 000000000..aabe24171 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo.v @@ -0,0 +1,204 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "generic_fifo.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module generic_fifo( + + wclk, + wrst_n, + wen, + wdata, + wfull, + walmost_full, + + rclk, + rrst_n, + ren, + rdata, + rempty, + ralmost_empty +); + +//--- +// Parameters + +parameter DWIDTH = 32; +parameter AWIDTH = 3; +parameter RAM_DEPTH = (1 << AWIDTH); +parameter SYNC_WRITE = 1; +parameter SYNC_READ = 1; +parameter REGISTER_READ = 0; +parameter EARLY_READ = 0; +parameter CLOCK_CROSSING = 1; +parameter ALMOST_EMPTY_THRESH = 1; +parameter ALMOST_FULL_THRESH = RAM_DEPTH-2; +parameter MEM_TYPE = `MEM_AUTO_SMALL; + +//--- +// Ports + +input wclk; +input wrst_n; +input wen; +input [DWIDTH-1:0] wdata; +output wfull; +output walmost_full; + +input rclk; +input rrst_n; +input ren; +output [DWIDTH-1:0] rdata; +output rempty; +output ralmost_empty; + +// Wires + +wire mem_wen; +wire [AWIDTH:0] mem_waddr; + +wire mem_ren; +wire [AWIDTH:0] mem_raddr; + + +generic_fifo_ctrl #(.AWIDTH (AWIDTH), + .RAM_DEPTH (RAM_DEPTH), + .EARLY_READ (EARLY_READ), + .CLOCK_CROSSING (CLOCK_CROSSING), + .ALMOST_EMPTY_THRESH (ALMOST_EMPTY_THRESH), + .ALMOST_FULL_THRESH (ALMOST_FULL_THRESH) + ) + ctrl0(.wclk (wclk), + .wrst_n (wrst_n), + .wen (wen), + .wfull (wfull), + .walmost_full (walmost_full), + + .mem_wen (mem_wen), + .mem_waddr (mem_waddr), + + .rclk (rclk), + .rrst_n (rrst_n), + .ren (ren), + .rempty (rempty), + .ralmost_empty (ralmost_empty), + + .mem_ren (mem_ren), + .mem_raddr (mem_raddr) + ); + + + generate + if (MEM_TYPE == `MEM_AUTO_SMALL) begin + + generic_mem_small #(.DWIDTH (DWIDTH), + .AWIDTH (AWIDTH), + .RAM_DEPTH (RAM_DEPTH), + .SYNC_WRITE (SYNC_WRITE), + .SYNC_READ (SYNC_READ), + .REGISTER_READ (REGISTER_READ) + ) + mem0(.wclk (wclk), + .wrst_n (wrst_n), + .wen (mem_wen), + .waddr (mem_waddr), + .wdata (wdata), + + .rclk (rclk), + .rrst_n (rrst_n), + .ren (mem_ren), + .roen (ren), + .raddr (mem_raddr), + .rdata (rdata) + ); + + end + + if (MEM_TYPE == `MEM_AUTO_MEDIUM) begin + + generic_mem_medium #(.DWIDTH (DWIDTH), + .AWIDTH (AWIDTH), + .RAM_DEPTH (RAM_DEPTH), + .SYNC_WRITE (SYNC_WRITE), + .SYNC_READ (SYNC_READ), + .REGISTER_READ (REGISTER_READ) + ) + mem0(.wclk (wclk), + .wrst_n (wrst_n), + .wen (mem_wen), + .waddr (mem_waddr), + .wdata (wdata), + + .rclk (rclk), + .rrst_n (rrst_n), + .ren (mem_ren), + .roen (ren), + .raddr (mem_raddr), + .rdata (rdata) + ); + + end // if (MEM_TYPE == `MEM_AUTO_MEDIUM) + + if (MEM_TYPE == `MEM_AUTO_XILINX) begin + + + generic_mem_xilinx_block #(.DWIDTH (DWIDTH), + .AWIDTH (AWIDTH), + .RAM_DEPTH (RAM_DEPTH), + .SYNC_WRITE (SYNC_WRITE), + .SYNC_READ (SYNC_READ), + .REGISTER_READ (REGISTER_READ) + ) + mem0(.wclk (wclk), + .wrst_n (wrst_n), + .wen (mem_wen), + .waddr (mem_waddr), + .wdata (wdata), + + .rclk (rclk), + .rrst_n (rrst_n), + .ren (mem_ren), + .roen (ren), + .raddr (mem_raddr), + .rdata (rdata) + ); + end + + endgenerate + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo_ctrl.v b/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo_ctrl.v new file mode 100644 index 000000000..d64e662af --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/generic_fifo_ctrl.v @@ -0,0 +1,273 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "generic_fifo_ctrl.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module generic_fifo_ctrl( + + wclk, + wrst_n, + wen, + wfull, + walmost_full, + + mem_wen, + mem_waddr, + + rclk, + rrst_n, + ren, + rempty, + ralmost_empty, + + mem_ren, + mem_raddr +); + +//--- +// Parameters + +parameter AWIDTH = 3; +parameter RAM_DEPTH = (1 << AWIDTH); +parameter EARLY_READ = 0; +parameter CLOCK_CROSSING = 1; +parameter ALMOST_EMPTY_THRESH = 1; +parameter ALMOST_FULL_THRESH = RAM_DEPTH-2; + +//--- +// Ports + +input wclk; +input wrst_n; +input wen; +output wfull; +output walmost_full; + +output mem_wen; +output [AWIDTH:0] mem_waddr; + +input rclk; +input rrst_n; +input ren; +output rempty; +output ralmost_empty; + +output mem_ren; +output [AWIDTH:0] mem_raddr; + + + +//--- +// Local declarations + +// Registers + +reg [AWIDTH:0] wr_ptr; +reg [AWIDTH:0] rd_ptr; +reg [AWIDTH:0] next_rd_ptr; + +// Combinatorial + +wire [AWIDTH:0] wr_gray; +reg [AWIDTH:0] wr_gray_reg; +reg [AWIDTH:0] wr_gray_meta; +reg [AWIDTH:0] wr_gray_sync; +reg [AWIDTH:0] wck_rd_ptr; +wire [AWIDTH:0] wck_level; + +wire [AWIDTH:0] rd_gray; +reg [AWIDTH:0] rd_gray_reg; +reg [AWIDTH:0] rd_gray_meta; +reg [AWIDTH:0] rd_gray_sync; +reg [AWIDTH:0] rck_wr_ptr; +wire [AWIDTH:0] rck_level; + +wire [AWIDTH:0] depth; +wire [AWIDTH:0] empty_thresh; +wire [AWIDTH:0] full_thresh; + +// Variables + +integer i; + +//--- +// Assignments + +assign depth = RAM_DEPTH[AWIDTH:0]; +assign empty_thresh = ALMOST_EMPTY_THRESH[AWIDTH:0]; +assign full_thresh = ALMOST_FULL_THRESH[AWIDTH:0]; + +assign wfull = (wck_level == depth); +assign walmost_full = (wck_level >= (depth - full_thresh)); +assign rempty = (rck_level == 0); +assign ralmost_empty = (rck_level <= empty_thresh); + +//--- +// Write Pointer + +always @(posedge wclk or negedge wrst_n) +begin + if (!wrst_n) begin + wr_ptr <= {(AWIDTH+1){1'b0}}; + end + else if (wen && !wfull) begin + wr_ptr <= wr_ptr + {{(AWIDTH){1'b0}}, 1'b1}; + end +end + +//--- +// Read Pointer + +always @(ren, rd_ptr, rck_wr_ptr) +begin + next_rd_ptr = rd_ptr; + if (ren && rd_ptr != rck_wr_ptr) begin + next_rd_ptr = rd_ptr + {{(AWIDTH){1'b0}}, 1'b1}; + end +end + +always @(posedge rclk or negedge rrst_n) +begin + if (!rrst_n) begin + rd_ptr <= {(AWIDTH+1){1'b0}}; + end + else begin + rd_ptr <= next_rd_ptr; + end +end + +//--- +// Binary to Gray conversion + +assign wr_gray = wr_ptr ^ (wr_ptr >> 1); +assign rd_gray = rd_ptr ^ (rd_ptr >> 1); + +//--- +// Gray to Binary conversion + +always @(wr_gray_sync) +begin + rck_wr_ptr[AWIDTH] = wr_gray_sync[AWIDTH]; + for (i = 0; i < AWIDTH; i = i + 1) begin + rck_wr_ptr[AWIDTH-i-1] = rck_wr_ptr[AWIDTH-i] ^ wr_gray_sync[AWIDTH-i-1]; + end +end + +always @(rd_gray_sync) +begin + wck_rd_ptr[AWIDTH] = rd_gray_sync[AWIDTH]; + for (i = 0; i < AWIDTH; i = i + 1) begin + wck_rd_ptr[AWIDTH-i-1] = wck_rd_ptr[AWIDTH-i] ^ rd_gray_sync[AWIDTH-i-1]; + end +end + +//--- +// Clock-Domain Crossing + +generate + if (CLOCK_CROSSING) begin + + // Instantiate metastability flops + always @(posedge rclk or negedge rrst_n) + begin + if (!rrst_n) begin + rd_gray_reg <= {(AWIDTH+1){1'b0}}; + wr_gray_meta <= {(AWIDTH+1){1'b0}}; + wr_gray_sync <= {(AWIDTH+1){1'b0}}; + end + else begin + rd_gray_reg <= rd_gray; + wr_gray_meta <= wr_gray_reg; + wr_gray_sync <= wr_gray_meta; + end + end + + always @(posedge wclk or negedge wrst_n) + begin + if (!wrst_n) begin + wr_gray_reg <= {(AWIDTH+1){1'b0}}; + rd_gray_meta <= {(AWIDTH+1){1'b0}}; + rd_gray_sync <= {(AWIDTH+1){1'b0}}; + end + else begin + wr_gray_reg <= wr_gray; + rd_gray_meta <= rd_gray_reg; + rd_gray_sync <= rd_gray_meta; + end + end + end + else begin + + // No clock domain crossing + always @(wr_gray or rd_gray) + begin + wr_gray_sync = wr_gray; + rd_gray_sync = rd_gray; + end + end +endgenerate + +//--- +// FIFO Level + +assign wck_level = wr_ptr - wck_rd_ptr; +assign rck_level = rck_wr_ptr - rd_ptr; + +//--- +// Memory controls + +assign mem_waddr = wr_ptr; +assign mem_wen = wen && !wfull; + +generate + if (EARLY_READ) begin + + // With early read, data will be present at output + // before ren is asserted. Usufull if we want to add + // an output register and not add latency. + assign mem_raddr = next_rd_ptr; + assign mem_ren = 1'b1; + + end + else begin + + assign mem_raddr = rd_ptr; + assign mem_ren = ren; + + end +endgenerate + +endmodule diff --git a/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_medium.v b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_medium.v new file mode 100644 index 000000000..db857ff63 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_medium.v @@ -0,0 +1,180 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "generic_mem_medium.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module generic_mem_medium( + + wclk, + wrst_n, + wen, + waddr, + wdata, + + rclk, + rrst_n, + ren, + roen, + raddr, + rdata +); + +//--- +// Parameters + +parameter DWIDTH = 32; +parameter AWIDTH = 3; +parameter RAM_DEPTH = (1 << AWIDTH); +parameter SYNC_WRITE = 1; +parameter SYNC_READ = 1; +parameter REGISTER_READ = 0; + +//--- +// Ports + +input wclk; +input wrst_n; +input wen; +input [AWIDTH:0] waddr; +input [DWIDTH-1:0] wdata; + +input rclk; +input rrst_n; +input ren; +input roen; +input [AWIDTH:0] raddr; +output [DWIDTH-1:0] rdata; + +// Registered outputs +reg [DWIDTH-1:0] rdata; + + +//--- +// Local declarations + +// Registers + +reg [DWIDTH-1:0] mem_rdata; + + +// Memory - infer using Xilinx pragma for block ram. +//synthesis attribute ram_style of mem is block +reg [DWIDTH-1:0] mem [0:RAM_DEPTH-1]; + +// Variables + +integer i; + + +//--- +// Memory Write + +generate + if (SYNC_WRITE) begin + + // Generate synchronous write + always @(posedge wclk) + begin + if (wen) begin + mem[waddr[AWIDTH-1:0]] <= wdata; + end + end + end + else begin + + // Generate asynchronous write + always @(wen, waddr, wdata) + begin + if (wen) begin + mem[waddr[AWIDTH-1:0]] = wdata; + end + end + end +endgenerate + +//--- +// Memory Read + +generate + if (SYNC_READ) begin + + // Generate registered memory read + always @(posedge rclk /* IJB or negedge rrst_n*/) + begin + if (!rrst_n) begin + mem_rdata <= {(DWIDTH){1'b0}}; + end else if (ren) begin + mem_rdata <= mem[raddr[AWIDTH-1:0]]; + end + end + end + else begin + + // Generate unregisters memory read + always @(raddr, rclk) + begin + mem_rdata = mem[raddr[AWIDTH-1:0]]; + end + end +endgenerate + +generate + if (REGISTER_READ) begin + + // Generate registered output + always @(posedge rclk /* IJB or negedge rrst_n*/ ) + begin + if (!rrst_n) begin + rdata <= {(DWIDTH){1'b0}}; + end else if (roen) begin + rdata <= mem_rdata; + end + end + + end + else begin + + // Generate unregisters output + always @(mem_rdata) + begin + rdata = mem_rdata; + end + + end +endgenerate + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_small.v b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_small.v new file mode 100644 index 000000000..552e628e7 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_small.v @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "generic_mem_small.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + + +module generic_mem_small( + + wclk, + wrst_n, + wen, + waddr, + wdata, + + rclk, + rrst_n, + ren, + roen, + raddr, + rdata +); + +//--- +// Parameters + +parameter DWIDTH = 32; +parameter AWIDTH = 3; +parameter RAM_DEPTH = (1 << AWIDTH); +parameter SYNC_WRITE = 1; +parameter SYNC_READ = 1; +parameter REGISTER_READ = 0; + +//--- +// Ports + +input wclk; +input wrst_n; +input wen; +input [AWIDTH:0] waddr; +input [DWIDTH-1:0] wdata; + +input rclk; +input rrst_n; +input ren; +input roen; +input [AWIDTH:0] raddr; +output [DWIDTH-1:0] rdata; + +// Registered outputs +reg [DWIDTH-1:0] rdata; + + +//--- +// Local declarations + +// Registers + +reg [DWIDTH-1:0] mem_rdata; + + +// Memory + +(* ram_style = "block" *) reg [DWIDTH-1:0] mem [0:RAM_DEPTH-1]; + +// Variables + +integer i; + + +//--- +// Memory Write + +generate + if (SYNC_WRITE) begin + + // Generate synchronous write + always @(posedge wclk) + begin + if (wen) begin + mem[waddr[AWIDTH-1:0]] <= wdata; + end + end + end + else begin + + // Generate asynchronous write + always @(wen, waddr, wdata) + begin + if (wen) begin + mem[waddr[AWIDTH-1:0]] = wdata; + end + end + end +endgenerate + +//--- +// Memory Read + +generate + if (SYNC_READ) begin + + // Generate registered memory read + always @(posedge rclk /* IJB or negedge rrst_n */) + begin + if (!rrst_n) begin + mem_rdata <= {(DWIDTH){1'b0}}; + end else if (ren) begin + mem_rdata <= mem[raddr[AWIDTH-1:0]]; + end + end + end + else begin + + // Generate unregisters memory read + always @(raddr, rclk) + begin + mem_rdata = mem[raddr[AWIDTH-1:0]]; + end + end +endgenerate + +generate + if (REGISTER_READ) begin + + // Generate registered output + always @(posedge rclk /* IJB or negedge rrst_n*/) + begin + if (!rrst_n) begin + rdata <= {(DWIDTH){1'b0}}; + end else if (roen) begin + rdata <= mem_rdata; + end + end + + end + else begin + + // Generate unregisters output + always @(mem_rdata) + begin + rdata = mem_rdata; + end + + end +endgenerate + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_xilinx_block.v b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_xilinx_block.v new file mode 100644 index 000000000..4a7baf431 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/generic_mem_xilinx_block.v @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "generic_mem_medium.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module generic_mem_xilinx_block( + + wclk, + wrst_n, + wen, + waddr, + wdata, + + rclk, + rrst_n, + ren, + roen, + raddr, + rdata +); + +//--- +// Parameters + +parameter DWIDTH = 32; +parameter AWIDTH = 3; +parameter RAM_DEPTH = (1 << AWIDTH); +parameter SYNC_WRITE = 1; +parameter SYNC_READ = 1; +parameter REGISTER_READ = 0; + +//--- +// Ports + +input wclk; +input wrst_n; +input wen; +input [AWIDTH:0] waddr; +input [DWIDTH-1:0] wdata; + +input rclk; +input rrst_n; +input ren; +input roen; +input [AWIDTH:0] raddr; +output [DWIDTH-1:0] rdata; + +// Registered outputs +reg [DWIDTH-1:0] rdata; + + +//--- +// Local declarations + +// Registers + +reg [DWIDTH-1:0] mem_rdata; + + +// Memory - infer using Xilinx pragma for block ram. +//synthesis attribute ram_style of mem is block +reg [DWIDTH-1:0] mem [0:RAM_DEPTH-1]; + +// Variables + +integer i; + + + //--- + // Memory Write + + // Generate synchronous write + always @(posedge wclk) + begin + if (wen) begin + mem[waddr[AWIDTH-1:0]] <= wdata; + end + end + + + //--- + // Memory Read + + // Generate registered memory read + always @(posedge rclk) + begin + if (!rrst_n) begin + mem_rdata <= {(DWIDTH){1'b0}}; + end else if (ren) begin + mem_rdata <= mem[raddr[AWIDTH-1:0]]; + end + end + + +generate + if (REGISTER_READ) begin + + // Generate registered output + always @(posedge rclk) + begin + if (!rrst_n) begin + rdata <= {(DWIDTH){1'b0}}; + end else if (roen) begin + rdata <= mem_rdata; + end + end + + end + else begin + + // Generate unregisters output + always @(mem_rdata) + begin + rdata = mem_rdata; + end + + end +endgenerate + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/meta_sync.v b/fpga/usrp3/lib/xge/rtl/verilog/meta_sync.v new file mode 100644 index 000000000..db35d4b5c --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/meta_sync.v @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "meta_sync.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module meta_sync(/*AUTOARG*/ + // Outputs + out, + // Inputs + clk, reset_n, in + ); + +parameter DWIDTH = 1; +parameter EDGE_DETECT = 0; + +input clk; +input reset_n; + +input [DWIDTH-1:0] in; + +output [DWIDTH-1:0] out; + +generate +genvar i; + + for (i = 0; i < DWIDTH; i = i + 1) begin : meta + + meta_sync_single #(.EDGE_DETECT (EDGE_DETECT)) + meta_sync_single0 ( + // Outputs + .out (out[i]), + // Inputs + .clk (clk), + .reset_n (reset_n), + .in (in[i])); + + end + +endgenerate + +endmodule + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/meta_sync_single.v b/fpga/usrp3/lib/xge/rtl/verilog/meta_sync_single.v new file mode 100644 index 000000000..e2c7d8cbb --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/meta_sync_single.v @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "meta_sync_single.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module meta_sync_single(/*AUTOARG*/ + // Outputs + out, + // Inputs + clk, reset_n, in + ); + +parameter EDGE_DETECT = 0; + +input clk; +input reset_n; + +input in; + +output out; + +reg out; + + + +generate + + if (EDGE_DETECT) begin + + reg meta; + reg edg1; + reg edg2; + + always @(posedge clk or negedge reset_n) begin + + if (reset_n == 1'b0) begin + meta <= 1'b0; + edg1 <= 1'b0; + edg2 <= 1'b0; + out <= 1'b0; + end + else begin + meta <= in; + edg1 <= meta; + edg2 <= edg1; + out <= edg1 ^ edg2; + end + end + + end + else begin + + reg meta; + + always @(posedge clk or negedge reset_n) begin + + if (reset_n == 1'b0) begin + meta <= 1'b0; + out <= 1'b0; + end + else begin + meta <= in; + out <= meta; + end + end + + end + +endgenerate + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/rx_checker.v b/fpga/usrp3/lib/xge/rtl/verilog/rx_checker.v new file mode 100644 index 000000000..cb775a8d8 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/rx_checker.v @@ -0,0 +1,275 @@ +// +// Synthesizable Rx checker for 10G Ethernet MAC. +// Collects recevied packets and checks them against the deterministic expected result +// to verify correct loopback functionality if used with the tx_checker. +// + +`define IDLE 0 +`define SEARCH 1 +`define RECEIVE1 2 +`define RECEIVE2 3 +`define RECEIVE3 4 +`define DONE 5 +`define ERROR1 6 +`define ERROR2 7 +`define ERROR3 8 + + +module rx_checker + ( + input clk156, + input rst, + input enable, + output reg done, + output reg correct, + output reg [1:0] error, + // + input pkt_rx_avail, + input pkt_rx_val, + input pkt_rx_sop, + input pkt_rx_eop, + input [2:0] pkt_rx_mod, + input [63:0] pkt_rx_data, + input pkt_rx_err, + output reg pkt_rx_ren + ); + + + reg [10:0] payload; + reg [10:0] count; + reg [7:0] state; + + +always @(posedge clk156) + if (rst) + begin + // Reset + state <= `IDLE; + done <= 0; + correct <= 0; + error <= 0; + pkt_rx_ren <= 0; + count <= 0; + payload <= 45; // 1 less than ethernet minimum payload size.\ + end + else + begin + // Defaults + state <= state; + done <= 0; + correct <= 0; + error <= 0; + pkt_rx_ren <= 0; + count <= count; + payload <= payload; + + + case(state) + // Wait in IDLE state until enabled. + // incomming packets will not be detected in this state. + `IDLE: begin + if (enable) + state <= `SEARCH; + end // case: `IDLE + // + // Search for pkt_rx_avail going asserted to show that a packet is in the MAC's FIFO's. + // Then assert pkt_rx_ren back to MAC to start transfer. pkt_rx_ren now remains asserted until + // at least EOP, longer if pkt_rx_avail is still asserted at EOP as back-to-back Rx is possible. + // We can come into this state with pkt_rx_ren already enabled for back-to-back Rx cases. + // + `SEARCH: begin + if (pkt_rx_val) + state <= `ERROR1; // Illegal signalling + else if (payload == 1500) + state <= `DONE; + else if (pkt_rx_avail) + begin // rx_avail has been asserted, now assert rx_ren to start transfer. + payload <= payload + 1; + pkt_rx_ren <= 1; + state <= `RECEIVE1; + end + end + // + // Now wait for pkt_rx_val and pkt_rx_sop to assert in the same cycle with the first + // 8 octects of a new packet. When asserted check all data bits against expected data. + // Go to error states if something doesn't match or work correctly. + // + `RECEIVE1: begin + pkt_rx_ren <= 1; + + if (pkt_rx_err) + state <= `ERROR3; // CRC error from MAC + else if (pkt_rx_val && pkt_rx_sop && ~pkt_rx_eop) + begin + if ((pkt_rx_data[63:16] == 48'h0001020304) && (pkt_rx_data[15:0] == 16'h0000) && (pkt_rx_mod == 3'h0)) + state <= `RECEIVE2; + else + state <= `ERROR2; // Data missmatch error + end + else if (pkt_rx_val || pkt_rx_sop || pkt_rx_eop) // Error condition + begin + state <= `ERROR1; // Illegal signalling + end + end // case: `RECEIVE1 + // + // Check all data bits against expected data. + // Go to error states if something doesn't match or work correctly. + // + `RECEIVE2: begin + pkt_rx_ren <= 1; + + if (pkt_rx_err) + state <= `ERROR3; // CRC error from MAC + else if (pkt_rx_val && ~pkt_rx_sop && ~pkt_rx_eop) + begin + if ((pkt_rx_data[63:32] == 32'h05060708) && + (pkt_rx_data[31:16] == 16'h88b5) && + (pkt_rx_data[15:0] == 16'hBEEF) && + (pkt_rx_mod == 3'h0)) + begin + count <= payload - 2; // Preload counter for this packet + state <= `RECEIVE3; + end + else + state <= `ERROR2; // Data missmatch error + end + else if (~pkt_rx_val || pkt_rx_sop || pkt_rx_eop) // Error condition + begin + state <= `ERROR1; // Illegal signalling + end + end // case: `RECEIVE2 + // + // Should now have received both MAC addresses, the ETHERTYPE and first 2 octects of payload. + // Check remaining payload whilst looking for end of packet. + // Currently don;pt support chained RX of packets, pkt_rx_en will go to 0. + // (Remember packets are bigendian) + // + `RECEIVE3: begin + count <= count - 8; + + if (pkt_rx_err) + state <= `ERROR3; // CRC error from MAC + else if (pkt_rx_val && ~pkt_rx_sop) + begin + case({pkt_rx_eop,pkt_rx_mod}) + 4'b0000: begin + if (pkt_rx_data[63:0] == {8{count[10:3]}}) + begin + pkt_rx_ren <= 1; + state <= `RECEIVE3; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1000: begin + if (pkt_rx_data[63:0] == {8{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1001: begin + if (pkt_rx_data[63:56] == {1{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1010: begin + if (pkt_rx_data[63:48] == {2{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1011: begin + if (pkt_rx_data[63:40] == {3{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1100: begin + if (pkt_rx_data[63:32] == {4{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1101: begin + if (pkt_rx_data[63:24] == {5{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1110: begin + if (pkt_rx_data[63:16] == {6{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + 4'b1111: begin + if (pkt_rx_data[63:8] == {7{count[10:3]}}) + begin + pkt_rx_ren <= 0; + state <= `SEARCH; + end + else + state <= `ERROR2; // Data missmatch error + end + default: state <= `ERROR1; // Illegal signalling + endcase // case({pkt_rx_eop,pkt_rx_mod}) + end + end + // + // Finished. Received and verified full sequence. Now assert corret signal and done. + // Stay in this state until reset. + // + `DONE: begin + done <= 1; + correct <= 1; + end + // + // Signal protocol error. + // Stay in this state until reset. + // + `ERROR1: begin + done <= 1; + error <= 1; + end + // + // Data payload of packet did not match reference + // Stay in this state until reset. + // + `ERROR2: begin + done <= 1; + error <= 2; + end + // + // CRC error reported by MAC + // Stay in this state until reset. + // + `ERROR3: begin + done <= 1; + error <= 3; + end + endcase + end + +endmodule // rx_checker diff --git a/fpga/usrp3/lib/xge/rtl/verilog/rx_data_fifo.v b/fpga/usrp3/lib/xge/rtl/verilog/rx_data_fifo.v new file mode 100644 index 000000000..e38747f45 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/rx_data_fifo.v @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "rx_data_fifo.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module rx_data_fifo(/*AUTOARG*/ + // Outputs + rxdfifo_wfull, rxdfifo_rdata, rxdfifo_rstatus, rxdfifo_rempty, + rxdfifo_ralmost_empty, + // Inputs + clk_xgmii_rx, clk_156m25, reset_xgmii_rx_n, reset_156m25_n, + rxdfifo_wdata, rxdfifo_wstatus, rxdfifo_wen, rxdfifo_ren + ); + +input clk_xgmii_rx; +input clk_156m25; +input reset_xgmii_rx_n; +input reset_156m25_n; + +input [63:0] rxdfifo_wdata; +input [7:0] rxdfifo_wstatus; +input rxdfifo_wen; + +input rxdfifo_ren; + +output rxdfifo_wfull; + +output [63:0] rxdfifo_rdata; +output [7:0] rxdfifo_rstatus; +output rxdfifo_rempty; +output rxdfifo_ralmost_empty; + +generic_fifo #( + .DWIDTH (72), + .AWIDTH (`RX_DATA_FIFO_AWIDTH), + .REGISTER_READ (0), + .EARLY_READ (1), + .CLOCK_CROSSING (1), + .ALMOST_EMPTY_THRESH (4), + .MEM_TYPE (`MEM_AUTO_XILINX) +) +fifo0( + .wclk (clk_xgmii_rx), + .wrst_n (reset_xgmii_rx_n), + .wen (rxdfifo_wen), + .wdata ({rxdfifo_wstatus, rxdfifo_wdata}), + .wfull (rxdfifo_wfull), + .walmost_full (), + + .rclk (clk_156m25), + .rrst_n (reset_156m25_n), + .ren (rxdfifo_ren), + .rdata ({rxdfifo_rstatus, rxdfifo_rdata}), + .rempty (rxdfifo_rempty), + .ralmost_empty (rxdfifo_ralmost_empty) +); + + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/rx_dequeue.v b/fpga/usrp3/lib/xge/rtl/verilog/rx_dequeue.v new file mode 100644 index 000000000..3603f6d0c --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/rx_dequeue.v @@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "rx_dequeue.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module rx_dequeue(/*AUTOARG*/ + // Outputs + rxdfifo_ren, pkt_rx_data, pkt_rx_val, pkt_rx_sop, pkt_rx_eop, + pkt_rx_err, pkt_rx_mod, pkt_rx_avail, status_rxdfifo_udflow_tog, + // Inputs + clk_156m25, reset_156m25_n, rxdfifo_rdata, rxdfifo_rstatus, + rxdfifo_rempty, rxdfifo_ralmost_empty, pkt_rx_ren + ); + +input clk_156m25; +input reset_156m25_n; + +input [63:0] rxdfifo_rdata; +input [7:0] rxdfifo_rstatus; +input rxdfifo_rempty; +input rxdfifo_ralmost_empty; + +input pkt_rx_ren; + +output rxdfifo_ren; + +output [63:0] pkt_rx_data; +output pkt_rx_val; +output pkt_rx_sop; +output pkt_rx_eop; +output pkt_rx_err; +output [2:0] pkt_rx_mod; +output pkt_rx_avail; + +output status_rxdfifo_udflow_tog; + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg pkt_rx_avail; +reg [63:0] pkt_rx_data; +reg pkt_rx_eop; +reg pkt_rx_err; +reg [2:0] pkt_rx_mod; +reg pkt_rx_sop; +reg pkt_rx_val; +reg status_rxdfifo_udflow_tog; +// End of automatics + +reg end_eop; + +/*AUTOWIRE*/ + + +// End eop to force one cycle between packets + +assign rxdfifo_ren = !rxdfifo_rempty && pkt_rx_ren && !end_eop; + + + +always @(posedge clk_156m25 or negedge reset_156m25_n) begin + + if (reset_156m25_n == 1'b0) begin + + pkt_rx_avail <= 1'b0; + + pkt_rx_data <= 64'b0; + pkt_rx_sop <= 1'b0; + pkt_rx_eop <= 1'b0; + pkt_rx_err <= 1'b0; + pkt_rx_mod <= 3'b0; + + pkt_rx_val <= 1'b0; + + end_eop <= 1'b0; + + status_rxdfifo_udflow_tog <= 1'b0; + + end + else begin + + pkt_rx_avail <= !rxdfifo_ralmost_empty; + + + + // If eop shows up at the output of the fifo, we drive eop on + // the bus on the next read. This will be the last read for this + // packet. The fifo is designed to output data early. On last read, + // data from next packet will appear at the output of fifo. Modulus + // of packet length is in lower bits. + + pkt_rx_eop <= rxdfifo_ren && rxdfifo_rstatus[`RXSTATUS_EOP]; + pkt_rx_mod <= {3{rxdfifo_ren & rxdfifo_rstatus[`RXSTATUS_EOP]}} & rxdfifo_rstatus[2:0]; + + + pkt_rx_val <= rxdfifo_ren; + + if (rxdfifo_ren) begin + + `ifdef BIGENDIAN + pkt_rx_data <= {rxdfifo_rdata[7:0], + rxdfifo_rdata[15:8], + rxdfifo_rdata[23:16], + rxdfifo_rdata[31:24], + rxdfifo_rdata[39:32], + rxdfifo_rdata[47:40], + rxdfifo_rdata[55:48], + rxdfifo_rdata[63:56]}; + `else + pkt_rx_data <= rxdfifo_rdata; + `endif + + end + + + if (rxdfifo_ren && rxdfifo_rstatus[`RXSTATUS_SOP]) begin + + // SOP indication on first word + + pkt_rx_sop <= 1'b1; + pkt_rx_err <= 1'b0; + + end + else begin + + pkt_rx_sop <= 1'b0; + + + // Give an error if FIFO is to underflow + + if (rxdfifo_rempty && pkt_rx_ren && !end_eop) begin + pkt_rx_val <= 1'b1; + pkt_rx_eop <= 1'b1; + pkt_rx_err <= 1'b1; + end + + end + + + if (rxdfifo_ren && |(rxdfifo_rstatus[`RXSTATUS_ERR])) begin + + // Status stored in FIFO is propagated to error signal. + + pkt_rx_err <= 1'b1; + + end + + + //--- + // EOP indication at the end of the frame. Cleared otherwise. + + if (rxdfifo_ren && rxdfifo_rstatus[`RXSTATUS_EOP]) begin + end_eop <= 1'b1; + end + else if (pkt_rx_ren) begin + end_eop <= 1'b0; + end + + + + //--- + // FIFO errors, used to generate interrupts + + if (rxdfifo_rempty && pkt_rx_ren && !end_eop) begin + status_rxdfifo_udflow_tog <= ~status_rxdfifo_udflow_tog; + end + + end +end + +endmodule diff --git a/fpga/usrp3/lib/xge/rtl/verilog/rx_enqueue.v b/fpga/usrp3/lib/xge/rtl/verilog/rx_enqueue.v new file mode 100644 index 000000000..98a5ac660 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/rx_enqueue.v @@ -0,0 +1,763 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "rx_enqueue.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module rx_enqueue(/*AUTOARG*/ + // Outputs + rxdfifo_wdata, rxdfifo_wstatus, rxdfifo_wen, rxhfifo_ren, + rxhfifo_wdata, rxhfifo_wstatus, rxhfifo_wen, local_fault_msg_det, + remote_fault_msg_det, status_crc_error_tog, + status_fragment_error_tog, status_rxdfifo_ovflow_tog, + status_pause_frame_rx_tog, + // Inputs + clk_xgmii_rx, reset_xgmii_rx_n, xgmii_rxd, xgmii_rxc, rxdfifo_wfull, + rxhfifo_rdata, rxhfifo_rstatus, rxhfifo_rempty, + rxhfifo_ralmost_empty + ); + +`include "CRC32_D64.v" +`include "CRC32_D8.v" +`include "utils.v" + +input clk_xgmii_rx; +input reset_xgmii_rx_n; + +input [63:0] xgmii_rxd; +input [7:0] xgmii_rxc; + +input rxdfifo_wfull; + +input [63:0] rxhfifo_rdata; +input [7:0] rxhfifo_rstatus; +input rxhfifo_rempty; +input rxhfifo_ralmost_empty; + +output [63:0] rxdfifo_wdata; +output [7:0] rxdfifo_wstatus; +output rxdfifo_wen; + +output rxhfifo_ren; + +output [63:0] rxhfifo_wdata; +output [7:0] rxhfifo_wstatus; +output rxhfifo_wen; + +output [1:0] local_fault_msg_det; +output [1:0] remote_fault_msg_det; + +output status_crc_error_tog; +output status_fragment_error_tog; +output status_rxdfifo_ovflow_tog; + +output status_pause_frame_rx_tog; + + + + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg [1:0] local_fault_msg_det; +reg [1:0] remote_fault_msg_det; +reg [63:0] rxdfifo_wdata; +reg rxdfifo_wen; +reg [7:0] rxdfifo_wstatus; +reg rxhfifo_ren; +reg [63:0] rxhfifo_wdata; +reg rxhfifo_wen; +reg [7:0] rxhfifo_wstatus; +reg status_crc_error_tog; +reg status_fragment_error_tog; +reg status_pause_frame_rx_tog; +reg status_rxdfifo_ovflow_tog; +// End of automatics + +/*AUTOWIRE*/ + + +reg [63:32] xgmii_rxd_d1; +reg [7:4] xgmii_rxc_d1; + +reg [63:0] xgxs_rxd_barrel; +reg [7:0] xgxs_rxc_barrel; + +reg [63:0] xgxs_rxd_barrel_d1; +reg [7:0] xgxs_rxc_barrel_d1; + +reg barrel_shift; + +reg [31:0] crc32_d64; +reg [31:0] crc32_d8; + +reg [3:0] crc_bytes; +reg [3:0] next_crc_bytes; + +reg [63:0] crc_shift_data; +reg crc_start_8b; +reg crc_done; +reg crc_good; +reg crc_clear; + +reg [31:0] crc_rx; +reg [31:0] next_crc_rx; + +reg [2:0] curr_state; +reg [2:0] next_state; + +reg [13:0] curr_byte_cnt; +reg [13:0] next_byte_cnt; + +reg fragment_error; +reg rxd_ovflow_error; + +reg coding_error; +reg next_coding_error; + +reg [7:0] addmask; +reg [7:0] datamask; + +reg pause_frame; +reg next_pause_frame; +reg pause_frame_hold; + +reg good_pause_frame; + +reg drop_data; +reg next_drop_data; + +reg pkt_pending; + +reg rxhfifo_ren_d1; + +reg rxhfifo_ralmost_empty_d1; + + +parameter [2:0] + SM_IDLE = 3'd0, + SM_RX = 3'd1; + +always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin + + if (reset_xgmii_rx_n == 1'b0) begin + + xgmii_rxd_d1 <= 32'b0; + xgmii_rxc_d1 <= 4'b0; + + xgxs_rxd_barrel <= 64'b0; + xgxs_rxc_barrel <= 8'b0; + + xgxs_rxd_barrel_d1 <= 64'b0; + xgxs_rxc_barrel_d1 <= 8'b0; + + barrel_shift <= 1'b0; + + local_fault_msg_det <= 2'b0; + remote_fault_msg_det <= 2'b0; + + crc32_d64 <= 32'b0; + crc32_d8 <= 32'b0; + crc_bytes <= 4'b0; + + crc_shift_data <= 64'b0; + crc_done <= 1'b0; + crc_rx <= 32'b0; + + pause_frame_hold <= 1'b0; + + status_crc_error_tog <= 1'b0; + status_fragment_error_tog <= 1'b0; + status_rxdfifo_ovflow_tog <= 1'b0; + + status_pause_frame_rx_tog <= 1'b0; + + end + else begin + + //--- + // Link status RC layer + // Look for local/remote messages on lower 4 lanes and upper + // 4 lanes. This is a 64-bit interface but look at each 32-bit + // independantly. + + local_fault_msg_det[1] <= (xgmii_rxd[63:32] == + {`LOCAL_FAULT, 8'h0, 8'h0, `SEQUENCE} && + xgmii_rxc[7:4] == 4'b0001); + + local_fault_msg_det[0] <= (xgmii_rxd[31:0] == + {`LOCAL_FAULT, 8'h0, 8'h0, `SEQUENCE} && + xgmii_rxc[3:0] == 4'b0001); + + remote_fault_msg_det[1] <= (xgmii_rxd[63:32] == + {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE} && + xgmii_rxc[7:4] == 4'b0001); + + remote_fault_msg_det[0] <= (xgmii_rxd[31:0] == + {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE} && + xgmii_rxc[3:0] == 4'b0001); + + + //--- + // Rotating barrel. This function allow us to always align the start of + // a frame with LANE0. If frame starts in LANE4, it will be shifted 4 bytes + // to LANE0, thus reducing the amount of logic needed at the next stage. + + xgmii_rxd_d1[63:32] <= xgmii_rxd[63:32]; + xgmii_rxc_d1[7:4] <= xgmii_rxc[7:4]; + + if (xgmii_rxd[`LANE0] == `START && xgmii_rxc[0]) begin + + xgxs_rxd_barrel <= xgmii_rxd; + xgxs_rxc_barrel <= xgmii_rxc; + + barrel_shift <= 1'b0; + + end + else if (xgmii_rxd[`LANE4] == `START && xgmii_rxc[4]) begin + + xgxs_rxd_barrel <= {xgmii_rxd[31:0], xgmii_rxd_d1[63:32]}; + xgxs_rxc_barrel <= {xgmii_rxc[3:0], xgmii_rxc_d1[7:4]}; + + barrel_shift <= 1'b1; + + end + else if (barrel_shift) begin + + xgxs_rxd_barrel <= {xgmii_rxd[31:0], xgmii_rxd_d1[63:32]}; + xgxs_rxc_barrel <= {xgmii_rxc[3:0], xgmii_rxc_d1[7:4]}; + + end + else begin + + xgxs_rxd_barrel <= xgmii_rxd; + xgxs_rxc_barrel <= xgmii_rxc; + + end + + xgxs_rxd_barrel_d1 <= xgxs_rxd_barrel; + xgxs_rxc_barrel_d1 <= xgxs_rxc_barrel; + + + //--- + // When final CRC calculation begins we capture info relevant to + // current frame CRC claculation continues while next frame is + // being received. + + if (crc_start_8b) begin + + pause_frame_hold <= pause_frame; + + end + + //--- + // CRC Checking + + crc_rx <= next_crc_rx; + + if (crc_clear) begin + + // CRC is cleared at the beginning of the frame, calculate + // 64-bit at a time otherwise + + crc32_d64 <= 32'hffffffff; + + end + else begin + + crc32_d64 <= nextCRC32_D64(reverse_64b(xgxs_rxd_barrel_d1), crc32_d64); + + end + + if (crc_bytes != 4'b0) begin + + // When reaching the end of the frame we switch from 64-bit mode + // to 8-bit mode to accomodate odd number of bytes in the frame. + // crc_bytes indicated the number of remaining payload byte to + // compute CRC on. Calculate and decrement until it reaches 0. + + if (crc_bytes == 4'b1) begin + crc_done <= 1'b1; + end + + crc32_d8 <= nextCRC32_D8(reverse_8b(crc_shift_data[7:0]), crc32_d8); + crc_shift_data <= {8'h00, crc_shift_data[63:8]}; + crc_bytes <= crc_bytes - 4'b1; + + end + else if (crc_bytes == 4'b0) begin + + // Per Clause 46. Control code during data must be reported + // as a CRC error. Indicated here by coding_error. Corrupt CRC + // if coding error is detected. + + if (coding_error || next_coding_error) begin + crc32_d8 <= ~crc32_d64; + end + else begin + crc32_d8 <= crc32_d64; + end + + crc_done <= 1'b0; + + crc_shift_data <= xgxs_rxd_barrel_d1; + crc_bytes <= next_crc_bytes; + + end + + //--- + // Error detection + + if (crc_done && !crc_good) begin + status_crc_error_tog <= ~status_crc_error_tog; + end + + if (fragment_error) begin + status_fragment_error_tog <= ~status_fragment_error_tog; + end + + if (rxd_ovflow_error) begin + status_rxdfifo_ovflow_tog <= ~status_rxdfifo_ovflow_tog; + end + + //--- + // Frame receive indication + + if (good_pause_frame) begin + status_pause_frame_rx_tog <= ~status_pause_frame_rx_tog; + end + + end + +end + + +always @(/*AS*/crc32_d8 or crc_done or crc_rx or pause_frame_hold) begin + + + crc_good = 1'b0; + good_pause_frame = 1'b0; + + if (crc_done) begin + + // Check CRC. If this is a pause frame, report it to cpu. + + if (crc_rx == ~reverse_32b(crc32_d8)) begin + crc_good = 1'b1; + good_pause_frame = pause_frame_hold; + end + + end + +end + +always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin + + if (reset_xgmii_rx_n == 1'b0) begin + + curr_state <= SM_IDLE; + curr_byte_cnt <= 14'b0; + coding_error <= 1'b0; + pause_frame <= 1'b0; + + end + else begin + + curr_state <= next_state; + curr_byte_cnt <= next_byte_cnt; + coding_error <= next_coding_error; + pause_frame <= next_pause_frame; + + end + +end + + +always @(/*AS*/coding_error or crc_rx or curr_byte_cnt or curr_state + or pause_frame or xgxs_rxc_barrel or xgxs_rxc_barrel_d1 + or xgxs_rxd_barrel or xgxs_rxd_barrel_d1) begin + + next_state = curr_state; + + rxhfifo_wdata = xgxs_rxd_barrel_d1; + rxhfifo_wstatus = `RXSTATUS_NONE; + rxhfifo_wen = 1'b0; + + addmask[0] = !(xgxs_rxd_barrel_d1[`LANE0] == `TERMINATE && xgxs_rxc_barrel_d1[0]); + addmask[1] = !(xgxs_rxd_barrel_d1[`LANE1] == `TERMINATE && xgxs_rxc_barrel_d1[1]); + addmask[2] = !(xgxs_rxd_barrel_d1[`LANE2] == `TERMINATE && xgxs_rxc_barrel_d1[2]); + addmask[3] = !(xgxs_rxd_barrel_d1[`LANE3] == `TERMINATE && xgxs_rxc_barrel_d1[3]); + addmask[4] = !(xgxs_rxd_barrel_d1[`LANE4] == `TERMINATE && xgxs_rxc_barrel_d1[4]); + addmask[5] = !(xgxs_rxd_barrel_d1[`LANE5] == `TERMINATE && xgxs_rxc_barrel_d1[5]); + addmask[6] = !(xgxs_rxd_barrel_d1[`LANE6] == `TERMINATE && xgxs_rxc_barrel_d1[6]); + addmask[7] = !(xgxs_rxd_barrel_d1[`LANE7] == `TERMINATE && xgxs_rxc_barrel_d1[7]); + + datamask[0] = addmask[0]; + datamask[1] = &addmask[1:0]; + datamask[2] = &addmask[2:0]; + datamask[3] = &addmask[3:0]; + datamask[4] = &addmask[4:0]; + datamask[5] = &addmask[5:0]; + datamask[6] = &addmask[6:0]; + datamask[7] = &addmask[7:0]; + + next_crc_bytes = 4'b0; + next_crc_rx = crc_rx; + crc_start_8b = 1'b0; + crc_clear = 1'b0; + + next_byte_cnt = curr_byte_cnt; + + fragment_error = 1'b0; + + next_coding_error = coding_error; + next_pause_frame = pause_frame; + + case (curr_state) + + SM_IDLE: + begin + + next_byte_cnt = 14'b0; + crc_clear = 1'b1; + next_coding_error = 1'b0; + next_pause_frame = 1'b0; + + + // Detect the start of a frame + + if (xgxs_rxd_barrel_d1[`LANE0] == `START && xgxs_rxc_barrel_d1[0] && + xgxs_rxd_barrel_d1[`LANE1] == `PREAMBLE && !xgxs_rxc_barrel_d1[1] && + xgxs_rxd_barrel_d1[`LANE2] == `PREAMBLE && !xgxs_rxc_barrel_d1[2] && + xgxs_rxd_barrel_d1[`LANE3] == `PREAMBLE && !xgxs_rxc_barrel_d1[3] && + xgxs_rxd_barrel_d1[`LANE4] == `PREAMBLE && !xgxs_rxc_barrel_d1[4] && + xgxs_rxd_barrel_d1[`LANE5] == `PREAMBLE && !xgxs_rxc_barrel_d1[5] && + xgxs_rxd_barrel_d1[`LANE6] == `PREAMBLE && !xgxs_rxc_barrel_d1[6] && + xgxs_rxd_barrel_d1[`LANE7] == `SFD && !xgxs_rxc_barrel_d1[7]) begin + + next_state = SM_RX; + end + + end + + SM_RX: + begin + + // Pause frames are filtered + + rxhfifo_wen = !pause_frame; + + + if (xgxs_rxd_barrel_d1[`LANE0] == `START && xgxs_rxc_barrel_d1[0] && + xgxs_rxd_barrel_d1[`LANE7] == `SFD && !xgxs_rxc_barrel_d1[7]) begin + + // Fragment received, if we are still at SOP stage don't store + // the frame. If not, write a fake EOP and flag frame as bad. + + next_byte_cnt = 14'b0; + crc_clear = 1'b1; + next_coding_error = 1'b0; + + fragment_error = 1'b1; + rxhfifo_wstatus[`RXSTATUS_ERR] = 1'b1; + + if (curr_byte_cnt == 14'b0) begin + rxhfifo_wen = 1'b0; + end + else begin + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + end + + end + else if (curr_byte_cnt > 14'd9900) begin + + // Frame too long, TERMMINATE must have been corrupted. + // Abort transfer, write a fake EOP, report as fragment. + + fragment_error = 1'b1; + rxhfifo_wstatus[`RXSTATUS_ERR] = 1'b1; + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + next_state = SM_IDLE; + + end + else begin + + // Pause frame receive, these frame will be filtered + + if (curr_byte_cnt == 14'd0 && + xgxs_rxd_barrel_d1[47:0] == `PAUSE_FRAME) begin + + rxhfifo_wen = 1'b0; + next_pause_frame = 1'b1; + end + + + // Control character during data phase, force CRC error + + if (|(xgxs_rxc_barrel_d1 & datamask)) begin + + next_coding_error = 1'b1; + end + + + // Write SOP to status bits during first byte + + if (curr_byte_cnt == 14'b0) begin + rxhfifo_wstatus[`RXSTATUS_SOP] = 1'b1; + end + + /* verilator lint_off WIDTH */ + next_byte_cnt = curr_byte_cnt + + addmask[0] + addmask[1] + addmask[2] + addmask[3] + + addmask[4] + addmask[5] + addmask[6] + addmask[7]; + /* verilator lint_on WIDTH */ + + + + // We will not write to the fifo if all is left + // are four or less bytes of crc. We also strip off the + // crc, which requires looking one cycle ahead + // wstatus: + // [2:0] modulus of packet length + + // Look one cycle ahead for TERMINATE in lanes 0 to 4 + + if (xgxs_rxd_barrel[`LANE4] == `TERMINATE && xgxs_rxc_barrel[4]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd0; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd8; + next_crc_rx = xgxs_rxd_barrel[31:0]; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel[`LANE3] == `TERMINATE && xgxs_rxc_barrel[3]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd7; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd7; + next_crc_rx = {xgxs_rxd_barrel[23:0], xgxs_rxd_barrel_d1[63:56]}; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel[`LANE2] == `TERMINATE && xgxs_rxc_barrel[2]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd6; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd6; + next_crc_rx = {xgxs_rxd_barrel[15:0], xgxs_rxd_barrel_d1[63:48]}; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel[`LANE1] == `TERMINATE && xgxs_rxc_barrel[1]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd5; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd5; + next_crc_rx = {xgxs_rxd_barrel[7:0], xgxs_rxd_barrel_d1[63:40]}; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel[`LANE0] == `TERMINATE && xgxs_rxc_barrel[0]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd4; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd4; + next_crc_rx = xgxs_rxd_barrel_d1[63:32]; + + next_state = SM_IDLE; + + end + + // Look at current cycle for TERMINATE in lanes 5 to 7 + + if (xgxs_rxd_barrel_d1[`LANE7] == `TERMINATE && + xgxs_rxc_barrel_d1[7]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd3; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd3; + next_crc_rx = xgxs_rxd_barrel_d1[55:24]; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel_d1[`LANE6] == `TERMINATE && + xgxs_rxc_barrel_d1[6]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd2; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd2; + next_crc_rx = xgxs_rxd_barrel_d1[47:16]; + + next_state = SM_IDLE; + + end + + if (xgxs_rxd_barrel_d1[`LANE5] == `TERMINATE && + xgxs_rxc_barrel_d1[5]) begin + + rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1; + rxhfifo_wstatus[2:0] = 3'd1; + + crc_start_8b = 1'b1; + next_crc_bytes = 4'd1; + next_crc_rx = xgxs_rxd_barrel_d1[39:8]; + + next_state = SM_IDLE; + + end + end + end + + default: + begin + next_state = SM_IDLE; + end + + endcase + +end + + +always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin + + if (reset_xgmii_rx_n == 1'b0) begin + + rxhfifo_ralmost_empty_d1 <= 1'b1; + + drop_data <= 1'b0; + + pkt_pending <= 1'b0; + + rxhfifo_ren_d1 <= 1'b0; + + end + else begin + + rxhfifo_ralmost_empty_d1 <= rxhfifo_ralmost_empty; + + drop_data <= next_drop_data; + + pkt_pending <= rxhfifo_ren; + + rxhfifo_ren_d1 <= rxhfifo_ren; + + end + +end + +always @(/*AS*/crc_done or crc_good or drop_data or pkt_pending + or rxdfifo_wfull or rxhfifo_ralmost_empty_d1 or rxhfifo_rdata + or rxhfifo_ren_d1 or rxhfifo_rstatus) begin + + rxd_ovflow_error = 1'b0; + + rxdfifo_wdata = rxhfifo_rdata; + rxdfifo_wstatus = rxhfifo_rstatus; + + next_drop_data = drop_data; + + + // There must be at least 8 words in holding FIFO before we start reading. + // This provides enough time for CRC calculation. + + rxhfifo_ren = !rxhfifo_ralmost_empty_d1 || + (pkt_pending && !rxhfifo_rstatus[`RXSTATUS_EOP]); + + + if (rxhfifo_ren_d1 && rxhfifo_rstatus[`RXSTATUS_SOP]) begin + + // Reset drop flag on SOP + + next_drop_data = 1'b0; + + end + + if (rxhfifo_ren_d1 && rxdfifo_wfull && !next_drop_data) begin + + // FIFO overflow, abort transfer. The rest of the frame + // will be dropped. Since we can't put an EOP indication + // in a fifo already full, there will be no EOP and receive + // side will need to sync on next SOP. + + rxd_ovflow_error = 1'b1; + next_drop_data = 1'b1; + + end + + + rxdfifo_wen = rxhfifo_ren_d1 && !next_drop_data; + + + + if (crc_done && !crc_good) begin + + // Flag packet with error when CRC error is detected + + rxdfifo_wstatus[`RXSTATUS_ERR] = 1'b1; + + end + +end + +endmodule + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/rx_hold_fifo.v b/fpga/usrp3/lib/xge/rtl/verilog/rx_hold_fifo.v new file mode 100644 index 000000000..14c4abc65 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/rx_hold_fifo.v @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "rx_hold_fifo.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module rx_hold_fifo(/*AUTOARG*/ + // Outputs + rxhfifo_rdata, rxhfifo_rstatus, rxhfifo_rempty, + rxhfifo_ralmost_empty, + // Inputs + clk_xgmii_rx, reset_xgmii_rx_n, rxhfifo_wdata, rxhfifo_wstatus, + rxhfifo_wen, rxhfifo_ren + ); + +input clk_xgmii_rx; +input reset_xgmii_rx_n; + +input [63:0] rxhfifo_wdata; +input [7:0] rxhfifo_wstatus; +input rxhfifo_wen; + +input rxhfifo_ren; + +output [63:0] rxhfifo_rdata; +output [7:0] rxhfifo_rstatus; +output rxhfifo_rempty; +output rxhfifo_ralmost_empty; + +generic_fifo #( + .DWIDTH (72), + .AWIDTH (`RX_HOLD_FIFO_AWIDTH), + .REGISTER_READ (1), + .EARLY_READ (1), + .CLOCK_CROSSING (0), + .ALMOST_EMPTY_THRESH (7), + .MEM_TYPE (`MEM_AUTO_XILINX) +) +fifo0( + .wclk (clk_xgmii_rx), + .wrst_n (reset_xgmii_rx_n), + .wen (rxhfifo_wen), + .wdata ({rxhfifo_wstatus, rxhfifo_wdata}), + .wfull (), + .walmost_full (), + + .rclk (clk_xgmii_rx), + .rrst_n (reset_xgmii_rx_n), + .ren (rxhfifo_ren), + .rdata ({rxhfifo_rstatus, rxhfifo_rdata}), + .rempty (rxhfifo_rempty), + .ralmost_empty (rxhfifo_ralmost_empty) +); + + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_core.v b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_core.v new file mode 100644 index 000000000..30e9bd5c3 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_core.v @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "sync_clk_core.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module sync_clk_core(/*AUTOARG*/ + // Inputs + clk_xgmii_tx, reset_xgmii_tx_n + ); + +input clk_xgmii_tx; +input reset_xgmii_tx_n; + +//input ctrl_tx_disable_padding; + +//output ctrl_tx_disable_padding_ccr; + + +/*AUTOREG*/ + +/*AUTOWIRE*/ + +//wire [0:0] sig_out; + +//assign {ctrl_tx_disable_padding_ccr} = sig_out; + +//meta_sync #(.DWIDTH (1)) meta_sync0 ( +// // Outputs +// .out (sig_out), +// // Inputs +// .clk (clk_xgmii_tx), +// .reset_n (reset_xgmii_tx_n), +// .in ({ +// ctrl_tx_disable_padding +// })); + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_wb.v b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_wb.v new file mode 100644 index 000000000..a5c3f6230 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_wb.v @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "sync_clk_wb.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module sync_clk_wb(/*AUTOARG*/ + // Outputs + status_crc_error, status_fragment_error, status_txdfifo_ovflow, + status_txdfifo_udflow, status_rxdfifo_ovflow, status_rxdfifo_udflow, + status_pause_frame_rx, status_local_fault, status_remote_fault, + // Inputs + wb_clk_i, wb_rst_i, status_crc_error_tog, status_fragment_error_tog, + status_txdfifo_ovflow_tog, status_txdfifo_udflow_tog, + status_rxdfifo_ovflow_tog, status_rxdfifo_udflow_tog, + status_pause_frame_rx_tog, status_local_fault_crx, + status_remote_fault_crx + ); + +input wb_clk_i; +input wb_rst_i; + +input status_crc_error_tog; +input status_fragment_error_tog; + +input status_txdfifo_ovflow_tog; + +input status_txdfifo_udflow_tog; + +input status_rxdfifo_ovflow_tog; + +input status_rxdfifo_udflow_tog; + +input status_pause_frame_rx_tog; + +input status_local_fault_crx; +input status_remote_fault_crx; + +output status_crc_error; +output status_fragment_error; + +output status_txdfifo_ovflow; + +output status_txdfifo_udflow; + +output status_rxdfifo_ovflow; + +output status_rxdfifo_udflow; + +output status_pause_frame_rx; + +output status_local_fault; +output status_remote_fault; + +/*AUTOREG*/ + +/*AUTOWIRE*/ + +wire [6:0] sig_out1; +wire [1:0] sig_out2; + +assign status_crc_error = sig_out1[6]; +assign status_fragment_error = sig_out1[5]; +assign status_txdfifo_ovflow = sig_out1[4]; +assign status_txdfifo_udflow = sig_out1[3]; +assign status_rxdfifo_ovflow = sig_out1[2]; +assign status_rxdfifo_udflow = sig_out1[1]; +assign status_pause_frame_rx = sig_out1[0]; + +assign status_local_fault = sig_out2[1]; +assign status_remote_fault = sig_out2[0]; + +meta_sync #(.DWIDTH (7), .EDGE_DETECT (1)) meta_sync0 ( + // Outputs + .out (sig_out1), + // Inputs + .clk (wb_clk_i), + .reset_n (~wb_rst_i), + .in ({ + status_crc_error_tog, + status_fragment_error_tog, + status_txdfifo_ovflow_tog, + status_txdfifo_udflow_tog, + status_rxdfifo_ovflow_tog, + status_rxdfifo_udflow_tog, + status_pause_frame_rx_tog + })); + +meta_sync #(.DWIDTH (2), .EDGE_DETECT (0)) meta_sync1 ( + // Outputs + .out (sig_out2), + // Inputs + .clk (wb_clk_i), + .reset_n (~wb_rst_i), + .in ({ + status_local_fault_crx, + status_remote_fault_crx + })); + +endmodule +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_xgmii_tx.v b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_xgmii_tx.v new file mode 100644 index 000000000..34527b0bc --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/sync_clk_xgmii_tx.v @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "sync_clk_xgmii.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module sync_clk_xgmii_tx(/*AUTOARG*/ + // Outputs + ctrl_tx_enable_ctx, status_local_fault_ctx, status_remote_fault_ctx, + // Inputs + clk_xgmii_tx, reset_xgmii_tx_n, ctrl_tx_enable, + status_local_fault_crx, status_remote_fault_crx + ); + +input clk_xgmii_tx; +input reset_xgmii_tx_n; + +input ctrl_tx_enable; + +input status_local_fault_crx; +input status_remote_fault_crx; + +output ctrl_tx_enable_ctx; + +output status_local_fault_ctx; +output status_remote_fault_ctx; + +/*AUTOREG*/ + +/*AUTOWIRE*/ + +wire [2:0] sig_out; + +assign ctrl_tx_enable_ctx = sig_out[2]; +assign status_local_fault_ctx = sig_out[1]; +assign status_remote_fault_ctx = sig_out[0]; + +meta_sync #(.DWIDTH (3)) meta_sync0 ( + // Outputs + .out (sig_out), + // Inputs + .clk (clk_xgmii_tx), + .reset_n (reset_xgmii_tx_n), + .in ({ + ctrl_tx_enable, + status_local_fault_crx, + status_remote_fault_crx + })); + +endmodule +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/timescale.v b/fpga/usrp3/lib/xge/rtl/verilog/timescale.v new file mode 100644 index 000000000..64502185f --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/timescale.v @@ -0,0 +1 @@ +`timescale 1ps / 1ps diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_checker.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_checker.v new file mode 100644 index 000000000..002746186 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/tx_checker.v @@ -0,0 +1,143 @@ +// +// Synthesizable Tx checker for 10G Ethernet MAC. +// Generates deterministic packets that can be looped back and +// checked for correctness +// +`define IDLE 0 +`define MAC1 1 +`define MAC2 2 +`define PAYLOAD1 3 +`define WAIT 4 +`define DONE 5 + + +module tx_checker + ( + input clk156, + input rst, + input enable, + output reg done, + // + output reg pkt_tx_val, + output reg pkt_tx_sop, + output reg pkt_tx_eop, + output reg [2:0] pkt_tx_mod, + output reg [63:0] pkt_tx_data + ); + + reg [10:0] payload; + reg [10:0] count; + reg [7:0] state; + reg [9:0] delay; + + + + + +always @(posedge clk156) + if (rst) + begin + state <= `IDLE; + count <= 0; + payload <= 45; // 1 less than ethernet minimum payload size.\ + done <= 0; + delay <= 0; + pkt_tx_val <= 0; + pkt_tx_sop <= 0; + pkt_tx_eop <= 0; + pkt_tx_data <= 0; + pkt_tx_mod <= 0; + end + else + begin + state <= state; + pkt_tx_val <= 0; + pkt_tx_sop <= 0; + pkt_tx_eop <= 0; + pkt_tx_data <= 0; + pkt_tx_mod <= 0; + payload <= payload; + count <= count; + done <= 0; + delay <= delay; + + + + case(state) + // Wait in IDLE state until enabled. + // As we leave the idle state increment the payload count + // so that we have a test pattern that changes each iteration. + `IDLE: begin + if (enable) + begin + if (payload == 1500) + state <= `DONE; + else + begin + payload <= payload + 1; // Might need to tweak this later.. + state <= `MAC1; + end + end + end + // Assert SOP (Start of Packet) for 1 cycle. + // Assert VAL (Tx Valid) for duration of packet. + // Put first 8 octets out, including + // DST MAC addr and first 2 bytes of SRC MAC. + `MAC1: begin + pkt_tx_val <= 1; + pkt_tx_sop <= 1; + pkt_tx_data[63:16] <= 48'h0001020304; // DST MAC + pkt_tx_data[15:0] <= 16'h0000; // SRC MAC msb's + pkt_tx_mod <= 3'h0; // All octects valid + state <= `MAC2; + end + // SOP now deasserted for rest of packet. + // VAL remains asserted. + // Tx rest of SRC MAC and ether type then first two data octets. + `MAC2: begin + pkt_tx_val <= 1; + pkt_tx_data[63:32] <= 32'h05060708; // SRC MAC lsb's + pkt_tx_data[31:16] <= 16'h88b5; // Ethertype + pkt_tx_data[15:0] <= 16'hBEEF; // First 2 bytes of payload. + pkt_tx_mod <= 3'h0; // All octects valid + count <= payload - 2; // Preload counter for this packet + state <= `PAYLOAD1; + end + // Iterate in this state until end of packet. + // The first clock cycle in this state, SRC MAC and ETHERTYPE are being Tx'ed due to pipelining + `PAYLOAD1: begin + pkt_tx_val <= 1; + pkt_tx_data <= {8{count[10:3]}}; // Data pattern is 64bit word count value. + count <= count - 8; + if ((count[10:3] == 0) || (count[10:0] == 8)) // down to 8 or less octects to Tx. + begin + pkt_tx_mod <= count[2:0]; + pkt_tx_eop <= 1; + state <= `WAIT; + delay <= 20; // 20 cycle delay in END state before Tx next packet + end + end // case: `PAYLOAD1 + // Because of pipelining EOP is actually asserted in this state + // but we are already commited to the end of packet so no decisions need to be made. + // Make signals idle ready for next state after. + // Delay start of next packet to rate control test. + `WAIT:begin + delay <= delay - 1; + if (delay == 0) + state <= `IDLE; + end + // Have now transmitted one packet of every legal size (no jumbo frames) + // Stay in this state asserting done flag until reset. + `DONE:begin + state <= `DONE; + done <= 1; + end + + endcase // case(state) + + end + +endmodule // tx_checker + + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_data_fifo.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_data_fifo.v new file mode 100644 index 000000000..1aa9f952c --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/tx_data_fifo.v @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "tx_data_fifo.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module tx_data_fifo(/*AUTOARG*/ + // Outputs + txdfifo_wfull, txdfifo_walmost_full, txdfifo_rdata, txdfifo_rstatus, + txdfifo_rempty, txdfifo_ralmost_empty, + // Inputs + clk_xgmii_tx, clk_156m25, reset_xgmii_tx_n, reset_156m25_n, + txdfifo_wdata, txdfifo_wstatus, txdfifo_wen, txdfifo_ren + ); + +input clk_xgmii_tx; +input clk_156m25; +input reset_xgmii_tx_n; +input reset_156m25_n; + +input [63:0] txdfifo_wdata; +input [7:0] txdfifo_wstatus; +input txdfifo_wen; + +input txdfifo_ren; + +output txdfifo_wfull; +output txdfifo_walmost_full; + +output [63:0] txdfifo_rdata; +output [7:0] txdfifo_rstatus; +output txdfifo_rempty; +output txdfifo_ralmost_empty; + +generic_fifo #( + .DWIDTH (72), + .AWIDTH (`TX_DATA_FIFO_AWIDTH), + .REGISTER_READ (1), + .EARLY_READ (1), + .CLOCK_CROSSING (1), + .ALMOST_EMPTY_THRESH (7), + .ALMOST_FULL_THRESH (12), + .MEM_TYPE (`MEM_AUTO_XILINX) +) +fifo0( + .wclk (clk_156m25), + .wrst_n (reset_156m25_n), + .wen (txdfifo_wen), + .wdata ({txdfifo_wstatus, txdfifo_wdata}), + .wfull (txdfifo_wfull), + .walmost_full (txdfifo_walmost_full), + + .rclk (clk_xgmii_tx), + .rrst_n (reset_xgmii_tx_n), + .ren (txdfifo_ren), + .rdata ({txdfifo_rstatus, txdfifo_rdata}), + .rempty (txdfifo_rempty), + .ralmost_empty (txdfifo_ralmost_empty) +); + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v new file mode 100644 index 000000000..8444514ee --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v @@ -0,0 +1,938 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "tx_dequeue.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module tx_dequeue(/*AUTOARG*/ + // Outputs + txdfifo_ren, txhfifo_ren, txhfifo_wdata, txhfifo_wstatus, + txhfifo_wen, xgmii_txd, xgmii_txc, status_txdfifo_udflow_tog, + // Inputs + clk_xgmii_tx, reset_xgmii_tx_n, ctrl_tx_enable_ctx, + status_local_fault_ctx, status_remote_fault_ctx, txdfifo_rdata, + txdfifo_rstatus, txdfifo_rempty, txdfifo_ralmost_empty, + txhfifo_rdata, txhfifo_rstatus, txhfifo_rempty, + txhfifo_ralmost_empty, txhfifo_wfull, txhfifo_walmost_full + ); +`include "CRC32_D64.v" +`include "CRC32_D8.v" +`include "utils.v" + +input clk_xgmii_tx; +input reset_xgmii_tx_n; + +input ctrl_tx_enable_ctx; + +input status_local_fault_ctx; +input status_remote_fault_ctx; + +input [63:0] txdfifo_rdata; +input [7:0] txdfifo_rstatus; +input txdfifo_rempty; +input txdfifo_ralmost_empty; + +input [63:0] txhfifo_rdata; +input [7:0] txhfifo_rstatus; +input txhfifo_rempty; +input txhfifo_ralmost_empty; + +input txhfifo_wfull; +input txhfifo_walmost_full; + +output txdfifo_ren; + +output txhfifo_ren; + +output [63:0] txhfifo_wdata; +output [7:0] txhfifo_wstatus; +output txhfifo_wen; + +output [63:0] xgmii_txd; +output [7:0] xgmii_txc; + +output status_txdfifo_udflow_tog; + + + + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg status_txdfifo_udflow_tog; +reg txdfifo_ren; +reg txhfifo_ren; +reg [63:0] txhfifo_wdata; +reg txhfifo_wen; +reg [7:0] txhfifo_wstatus; +reg [7:0] xgmii_txc; +reg [63:0] xgmii_txd; +// End of automatics + +/*AUTOWIRE*/ + + +reg [63:0] xgxs_txd; +reg [7:0] xgxs_txc; + +reg [63:0] next_xgxs_txd; +reg [7:0] next_xgxs_txc; + +reg [2:0] curr_state_enc; +reg [2:0] next_state_enc; + +reg [0:0] curr_state_pad; +reg [0:0] next_state_pad; + +reg start_on_lane0; +reg next_start_on_lane0; + +reg [2:0] ifg_deficit; +reg [2:0] next_ifg_deficit; + +reg ifg_4b_add; +reg next_ifg_4b_add; + +reg ifg_8b_add; +reg next_ifg_8b_add; + +reg ifg_8b2_add; +reg next_ifg_8b2_add; + +reg [7:0] eop; +reg [7:0] next_eop; + +reg [63:32] xgxs_txd_barrel; +reg [7:4] xgxs_txc_barrel; + +reg [63:0] txhfifo_rdata_d1; + +reg [13:0] byte_cnt; + +reg [31:0] crc32_d64; +reg [31:0] crc32_d8; +reg [31:0] crc32_tx; + +reg [63:0] shift_crc_data; +reg [3:0] shift_crc_eop; +reg [3:0] shift_crc_cnt; + +reg [31:0] crc_data; + +reg frame_available; +reg next_frame_available; + +reg [63:0] next_txhfifo_wdata; +reg [7:0] next_txhfifo_wstatus; +reg next_txhfifo_wen; + +reg txdfifo_ren_d1; + +parameter [2:0] + SM_IDLE = 3'd0, + SM_PREAMBLE = 3'd1, + SM_TX = 3'd2, + SM_EOP = 3'd3, + SM_TERM = 3'd4, + SM_TERM_FAIL = 3'd5, + SM_IFG = 3'd6; + +parameter [0:0] + SM_PAD_EQ = 1'd0, + SM_PAD_PAD = 1'd1; + + +//--- +// RC layer + +always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin + + if (reset_xgmii_tx_n == 1'b0) begin + + xgmii_txd <= {8{`IDLE}}; + xgmii_txc <= 8'hff; + + end + else begin + + + //--- + // RC Layer, insert local or remote fault messages based on status + // of fault state-machine + + if (status_local_fault_ctx) begin + + // If local fault detected, send remote fault message to + // link partner + + xgmii_txd <= {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE, + `REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE}; + xgmii_txc <= {4'b0001, 4'b0001}; + end + else if (status_remote_fault_ctx) begin + + // If remote fault detected, inhibit transmission and send + // idle codes + + xgmii_txd <= {8{`IDLE}}; + xgmii_txc <= 8'hff; + end + else begin + xgmii_txd <= xgxs_txd; + xgmii_txc <= xgxs_txc; + end + end + +end + + +always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin + + if (reset_xgmii_tx_n == 1'b0) begin + + curr_state_enc <= SM_IDLE; + + start_on_lane0 <= 1'b1; + ifg_deficit <= 3'b0; + ifg_4b_add <= 1'b0; + ifg_8b_add <= 1'b0; + ifg_8b2_add <= 1'b0; + + eop <= 8'b0; + + txhfifo_rdata_d1 <= 64'b0; + + xgxs_txd_barrel <= {4{`IDLE}}; + xgxs_txc_barrel <= 4'hf; + + frame_available <= 1'b0; + + xgxs_txd <= {8{`IDLE}}; + xgxs_txc <= 8'hff; + + status_txdfifo_udflow_tog <= 1'b0; + + end + else begin + + curr_state_enc <= next_state_enc; + + start_on_lane0 <= next_start_on_lane0; + ifg_deficit <= next_ifg_deficit; + ifg_4b_add <= next_ifg_4b_add; + ifg_8b_add <= next_ifg_8b_add; + ifg_8b2_add <= next_ifg_8b2_add; + + eop <= next_eop; + + txhfifo_rdata_d1 <= txhfifo_rdata; + + xgxs_txd_barrel <= next_xgxs_txd[63:32]; + xgxs_txc_barrel <= next_xgxs_txc[7:4]; + + frame_available <= next_frame_available; + + //--- + // Barrel shifter. Previous stage always align packet with LANE0. + // This stage allow us to shift packet to align with LANE4 if needed + // for correct inter frame gap (IFG). + + if (next_start_on_lane0) begin + + xgxs_txd <= next_xgxs_txd; + xgxs_txc <= next_xgxs_txc; + + end + else begin + + xgxs_txd <= {next_xgxs_txd[31:0], xgxs_txd_barrel}; + xgxs_txc <= {next_xgxs_txc[3:0], xgxs_txc_barrel}; + + end + + //--- + // FIFO errors, used to generate interrupts. + + if (txdfifo_ren && txdfifo_rempty) begin + status_txdfifo_udflow_tog <= ~status_txdfifo_udflow_tog; + end + + end + +end + +always @(/*AS*/crc32_tx or ctrl_tx_enable_ctx or curr_state_enc or eop + or frame_available or ifg_4b_add or ifg_8b2_add or ifg_8b_add + or ifg_deficit or start_on_lane0 or status_local_fault_ctx + or txhfifo_ralmost_empty or txhfifo_rdata_d1 + or txhfifo_rempty or txhfifo_rstatus) begin + + next_state_enc = curr_state_enc; + + next_start_on_lane0 = start_on_lane0; + next_ifg_deficit = ifg_deficit; + next_ifg_4b_add = ifg_4b_add; + next_ifg_8b_add = ifg_8b_add; + next_ifg_8b2_add = ifg_8b2_add; + + next_eop = eop; + + next_xgxs_txd = {8{`IDLE}}; + next_xgxs_txc = 8'hff; + + txhfifo_ren = 1'b0; + + next_frame_available = frame_available; + + case (curr_state_enc) + + SM_IDLE: + begin + + // Wait for frame to be available. There should be a least N bytes in the + // data fifo or a crc in the control fifo. The N bytes in the data fifo + // give time to the enqueue engine to calculate crc and write it to the + // control fifo. If crc is already in control fifo we can start transmitting + // with no concern. Transmission is inhibited if local or remote faults + // are detected. + + if (ctrl_tx_enable_ctx && frame_available && + !status_local_fault_ctx && !status_local_fault_ctx) begin + + txhfifo_ren = 1'b1; + next_state_enc = SM_PREAMBLE; + + end + else begin + + next_frame_available = !txhfifo_ralmost_empty; + next_ifg_4b_add = 1'b0; + + end + + end + + SM_PREAMBLE: + begin + + // On reading SOP from fifo, send SFD and preamble characters + + if (txhfifo_rstatus[`TXSTATUS_SOP]) begin + + next_xgxs_txd = {`SFD, {6{`PREAMBLE}}, `START}; + next_xgxs_txc = 8'h01; + + txhfifo_ren = 1'b1; + + next_state_enc = SM_TX; + + end + else begin + + next_frame_available = 1'b0; + next_state_enc = SM_IDLE; + + end + + + // Depending on deficit idle count calculations, add 4 bytes + // or IFG or not. This will determine on which lane start the + // next frame. + + if (ifg_4b_add) begin + next_start_on_lane0 = 1'b0; + end + else begin + next_start_on_lane0 = 1'b1; + end + + end + + SM_TX: + begin + + next_xgxs_txd = txhfifo_rdata_d1; + next_xgxs_txc = 8'h00; + + txhfifo_ren = 1'b1; + + + // Wait for EOP indication to be read from the fifo, then + // transition to next state. + + if (txhfifo_rstatus[`TXSTATUS_EOP]) begin + + txhfifo_ren = 1'b0; + next_frame_available = !txhfifo_ralmost_empty; + next_state_enc = SM_EOP; + + end + else if (txhfifo_rempty || txhfifo_rstatus[`TXSTATUS_SOP]) begin + + // Failure condition, we did not see EOP and there + // is no more data in fifo or SOP, force end of packet transmit. + + next_state_enc = SM_TERM_FAIL; + + end + + next_eop[0] = txhfifo_rstatus[2:0] == 3'd1; + next_eop[1] = txhfifo_rstatus[2:0] == 3'd2; + next_eop[2] = txhfifo_rstatus[2:0] == 3'd3; + next_eop[3] = txhfifo_rstatus[2:0] == 3'd4; + next_eop[4] = txhfifo_rstatus[2:0] == 3'd5; + next_eop[5] = txhfifo_rstatus[2:0] == 3'd6; + next_eop[6] = txhfifo_rstatus[2:0] == 3'd7; + next_eop[7] = txhfifo_rstatus[2:0] == 3'd0; + + end + + SM_EOP: + begin + + // Insert TERMINATE character in correct lane depending on position + // of EOP read from fifo. Also insert CRC read from control fifo. + + if (eop[0]) begin + next_xgxs_txd = {{2{`IDLE}}, `TERMINATE, + crc32_tx[31:0], txhfifo_rdata_d1[7:0]}; + next_xgxs_txc = 8'b11100000; + end + + if (eop[1]) begin + next_xgxs_txd = {`IDLE, `TERMINATE, + crc32_tx[31:0], txhfifo_rdata_d1[15:0]}; + next_xgxs_txc = 8'b11000000; + end + + if (eop[2]) begin + next_xgxs_txd = {`TERMINATE, crc32_tx[31:0], txhfifo_rdata_d1[23:0]}; + next_xgxs_txc = 8'b10000000; + end + + if (eop[3]) begin + next_xgxs_txd = {crc32_tx[31:0], txhfifo_rdata_d1[31:0]}; + next_xgxs_txc = 8'b00000000; + end + + if (eop[4]) begin + next_xgxs_txd = {crc32_tx[23:0], txhfifo_rdata_d1[39:0]}; + next_xgxs_txc = 8'b00000000; + end + + if (eop[5]) begin + next_xgxs_txd = {crc32_tx[15:0], txhfifo_rdata_d1[47:0]}; + next_xgxs_txc = 8'b00000000; + end + + if (eop[6]) begin + next_xgxs_txd = {crc32_tx[7:0], txhfifo_rdata_d1[55:0]}; + next_xgxs_txc = 8'b00000000; + end + + if (eop[7]) begin + next_xgxs_txd = {txhfifo_rdata_d1[63:0]}; + next_xgxs_txc = 8'b00000000; + end + + if (!frame_available) begin + + // If there is not another frame ready to be transmitted, interface + // will go idle and idle deficit idle count calculation is irrelevant. + // Set deficit to 0. + + next_ifg_deficit = 3'b0; + + end + else begin + + // Idle deficit count calculated based on number of "wasted" bytes + // between TERMINATE and alignment of next frame in LANE0. + + next_ifg_deficit = ifg_deficit + + {2'b0, eop[0] | eop[4]} + + {1'b0, eop[1] | eop[5], 1'b0} + + {1'b0, eop[2] | eop[6], + eop[2] | eop[6]}; + end + + // IFG corrections based on deficit count and previous starting lane + // Calculated based on following table: + // + // DIC=0 DIC=1 DIC=2 DIC=3 + // ------------- ------------- ------------- ------------- + // PktLen IFG Next IFG Next IFG Next IFG Next + // Modulus Length DIC Length DIC Length DIC Length DIC + // ----------------------------------------------------------------------- + // 0 12 0 12 1 12 2 12 3 + // 1 11 1 11 2 11 3 15 0 + // 2 10 2 10 3 14 0 14 1 + // 3 9 3 13 0 13 1 13 2 + // + // + // In logic it translates into adding 4, 8, or 12 bytes of IFG relative + // to LANE0. + // IFG and Add columns assume no deficit applied + // IFG+DIC and Add+DIC assume deficit must be applied + // + // Start lane 0 Start lane 4 + // EOP Pads IFG IFG+DIC Add Add+DIC Add Add IFG + // 0 3 11 15 8 12 12 16 + // 1 2 10 14 8 12 12 16 + // 2 1 9 13 8 12 12 16 + // 3 8 12 12 4 4 8 8 + // 4 7 11 15 4 8 8 12 + // 5 6 10 14 4 8 8 12 + // 6 5 9 13 4 8 8 12 + // 7 4 12 12 8 8 12 12 + + if (!frame_available) begin + + // If there is not another frame ready to be transmitted, interface + // will go idle and idle deficit idle count calculation is irrelevant. + + next_ifg_4b_add = 1'b0; + next_ifg_8b_add = 1'b0; + next_ifg_8b2_add = 1'b0; + + end + else if (next_ifg_deficit[2] == ifg_deficit[2]) begin + + // Add 4 bytes IFG + + next_ifg_4b_add = (eop[0] & !start_on_lane0) | + (eop[1] & !start_on_lane0) | + (eop[2] & !start_on_lane0) | + (eop[3] & start_on_lane0) | + (eop[4] & start_on_lane0) | + (eop[5] & start_on_lane0) | + (eop[6] & start_on_lane0) | + (eop[7] & !start_on_lane0); + + // Add 8 bytes IFG + + next_ifg_8b_add = (eop[0]) | + (eop[1]) | + (eop[2]) | + (eop[3] & !start_on_lane0) | + (eop[4] & !start_on_lane0) | + (eop[5] & !start_on_lane0) | + (eop[6] & !start_on_lane0) | + (eop[7]); + + // Add another 8 bytes IFG + + next_ifg_8b2_add = 1'b0; + + end + else begin + + // Add 4 bytes IFG + + next_ifg_4b_add = (eop[0] & start_on_lane0) | + (eop[1] & start_on_lane0) | + (eop[2] & start_on_lane0) | + (eop[3] & start_on_lane0) | + (eop[4] & !start_on_lane0) | + (eop[5] & !start_on_lane0) | + (eop[6] & !start_on_lane0) | + (eop[7] & !start_on_lane0); + + // Add 8 bytes IFG + + next_ifg_8b_add = (eop[0]) | + (eop[1]) | + (eop[2]) | + (eop[3] & !start_on_lane0) | + (eop[4]) | + (eop[5]) | + (eop[6]) | + (eop[7]); + + // Add another 8 bytes IFG + + next_ifg_8b2_add = (eop[0] & !start_on_lane0) | + (eop[1] & !start_on_lane0) | + (eop[2] & !start_on_lane0); + + end + + if (|eop[2:0]) begin + + if (frame_available) begin + + // Next state depends on number of IFG bytes to be inserted. + // Skip idle state if needed. + + if (next_ifg_8b2_add) begin + next_state_enc = SM_IFG; + end + else if (next_ifg_8b_add) begin + next_state_enc = SM_IDLE; + end + else begin + txhfifo_ren = 1'b1; + next_state_enc = SM_PREAMBLE; + end + + end + else begin + next_state_enc = SM_IFG; + end + end + + if (|eop[7:3]) begin + next_state_enc = SM_TERM; + end + + end + + SM_TERM: + begin + + // Insert TERMINATE character in correct lane depending on position + // of EOP read from fifo. Also insert CRC read from control fifo. + + if (eop[3]) begin + next_xgxs_txd = {{7{`IDLE}}, `TERMINATE}; + next_xgxs_txc = 8'b11111111; + end + + if (eop[4]) begin + next_xgxs_txd = {{6{`IDLE}}, `TERMINATE, crc32_tx[31:24]}; + next_xgxs_txc = 8'b11111110; + end + + if (eop[5]) begin + next_xgxs_txd = {{5{`IDLE}}, `TERMINATE, crc32_tx[31:16]}; + next_xgxs_txc = 8'b11111100; + end + + if (eop[6]) begin + next_xgxs_txd = {{4{`IDLE}}, `TERMINATE, crc32_tx[31:8]}; + next_xgxs_txc = 8'b11111000; + end + + if (eop[7]) begin + next_xgxs_txd = {{3{`IDLE}}, `TERMINATE, crc32_tx[31:0]}; + next_xgxs_txc = 8'b11110000; + end + + // Next state depends on number of IFG bytes to be inserted. + // Skip idle state if needed. + + if (frame_available && !ifg_8b_add) begin + txhfifo_ren = 1'b1; + next_state_enc = SM_PREAMBLE; + end + else if (frame_available) begin + next_state_enc = SM_IDLE; + end + else begin + next_state_enc = SM_IFG; + end + + end + + SM_TERM_FAIL: + begin + + next_xgxs_txd = {{7{`IDLE}}, `TERMINATE}; + next_xgxs_txc = 8'b11111111; + next_state_enc = SM_IFG; + + end + + SM_IFG: + begin + + next_state_enc = SM_IDLE; + + end + + default: + begin + next_state_enc = SM_IDLE; + end + + endcase + +end + + +always @(/*AS*/crc32_d64 or txhfifo_wen or txhfifo_wstatus) begin + + if (txhfifo_wen && txhfifo_wstatus[`TXSTATUS_SOP]) begin + crc_data = 32'hffffffff; + end + else begin + crc_data = crc32_d64; + end + +end + +always @(/*AS*/byte_cnt or curr_state_pad or txdfifo_rdata + or txdfifo_rempty or txdfifo_ren_d1 or txdfifo_rstatus + or txhfifo_walmost_full) begin + + next_state_pad = curr_state_pad; + + next_txhfifo_wdata = txdfifo_rdata; + next_txhfifo_wstatus = txdfifo_rstatus; + + txdfifo_ren = 1'b0; + next_txhfifo_wen = 1'b0; + + case (curr_state_pad) + + SM_PAD_EQ: begin + + + //--- + // If room availabe in hoding fifo and data available in + // data fifo, transfer data words. If transmit state machine + // is reading from fifo we can assume room will be available. + + if (!txhfifo_walmost_full) begin + + txdfifo_ren = !txdfifo_rempty; + + end + + + //--- + // This logic dependent on read during previous cycle. + + if (txdfifo_ren_d1) begin + + next_txhfifo_wen = 1'b1; + + // On EOP, decide if padding is required for this packet. + + if (txdfifo_rstatus[`TXSTATUS_EOP]) begin + + if (byte_cnt < 14'd56) begin + + next_txhfifo_wstatus = `TXSTATUS_NONE; + txdfifo_ren = 1'b0; + next_state_pad = SM_PAD_PAD; + + end + else if (byte_cnt == 14'd56 && + (txdfifo_rstatus[2:0] == 3'd1 || + txdfifo_rstatus[2:0] == 3'd2 || + txdfifo_rstatus[2:0] == 3'd3)) begin + + // Pad up to LANE3, keep the other 4 bytes for crc that will + // be inserted by dequeue engine. + + next_txhfifo_wstatus[2:0] = 3'd4; + + // Pad end bytes with zeros. + + if (txdfifo_rstatus[2:0] == 3'd1) + next_txhfifo_wdata[31:8] = 24'b0; + if (txdfifo_rstatus[2:0] == 3'd2) + next_txhfifo_wdata[31:16] = 16'b0; + if (txdfifo_rstatus[2:0] == 3'd3) + next_txhfifo_wdata[31:24] = 8'b0; + + txdfifo_ren = 1'b0; + + end + else begin + + txdfifo_ren = 1'b0; + + end + + end + + end + + end + + SM_PAD_PAD: begin + + //--- + // Pad packet to 64 bytes by writting zeros to holding fifo. + + if (!txhfifo_walmost_full) begin + + next_txhfifo_wdata = 64'b0; + next_txhfifo_wstatus = `TXSTATUS_NONE; + next_txhfifo_wen = 1'b1; + + if (byte_cnt == 14'd56) begin + + + // Pad up to LANE3, keep the other 4 bytes for crc that will + // be inserted by dequeue engine. + + next_txhfifo_wstatus[`TXSTATUS_EOP] = 1'b1; + next_txhfifo_wstatus[2:0] = 3'd4; + + next_state_pad = SM_PAD_EQ; + + end + + end + + end + + default: + begin + next_state_pad = SM_PAD_EQ; + end + + endcase + +end + + +always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin + + if (reset_xgmii_tx_n == 1'b0) begin + + curr_state_pad <= SM_PAD_EQ; + + txdfifo_ren_d1 <= 1'b0; + + txhfifo_wdata <= 64'b0; + txhfifo_wstatus <= 8'b0; + txhfifo_wen <= 1'b0; + + byte_cnt <= 14'b0; + + shift_crc_data <= 64'b0; + shift_crc_eop <= 4'b0; + shift_crc_cnt <= 4'b0; + + end + else begin + + curr_state_pad <= next_state_pad; + + txdfifo_ren_d1 <= txdfifo_ren; + + txhfifo_wdata <= next_txhfifo_wdata; + txhfifo_wstatus <= next_txhfifo_wstatus; + txhfifo_wen <= next_txhfifo_wen; + + + //--- + // Reset byte count on SOP + + if (next_txhfifo_wen) begin + + if (next_txhfifo_wstatus[`TXSTATUS_SOP]) begin + + byte_cnt <= 14'd8; + + end + else begin + + byte_cnt <= byte_cnt + 14'd8; + + end + + end + + + //--- + // Calculate CRC as data is written to holding fifo. The holding fifo creates + // a delay that allow the CRC calculation to complete before the end of the frame + // is ready to be transmited. + + if (txhfifo_wen) begin + + crc32_d64 <= nextCRC32_D64(reverse_64b(txhfifo_wdata), crc_data); + + end + + if (txhfifo_wen && txhfifo_wstatus[`TXSTATUS_EOP]) begin + + // Last bytes calculated 8-bit at a time instead of 64-bit. Start + // this process at the end of the frame. + + crc32_d8 <= crc32_d64; + + shift_crc_data <= txhfifo_wdata; + shift_crc_cnt <= 4'd9; + + if (txhfifo_wstatus[2:0] == 3'b0) begin + shift_crc_eop <= 4'd8; + end + else begin + shift_crc_eop <= {1'b0, txhfifo_wstatus[2:0]}; + end + + end + else if (shift_crc_eop != 4'b0) begin + + // Complete crc calculation 8-bit at a time until finished. This can + // be 1 to 8 bytes long. + + crc32_d8 <= nextCRC32_D8(reverse_8b(shift_crc_data[7:0]), crc32_d8); + + shift_crc_data <= {8'b0, shift_crc_data[63:8]}; + shift_crc_eop <= shift_crc_eop - 4'd1; + + end + + + //--- + // Update CRC register at the end of calculation. Always update after 8 + // cycles for deterministic results, even if a single byte was present in + // last data word. + + if (shift_crc_cnt == 4'b1) begin + + crc32_tx <= ~reverse_32b(crc32_d8); + + end + else begin + + shift_crc_cnt <= shift_crc_cnt - 4'd1; + + end + + end + +end + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_enqueue.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_enqueue.v new file mode 100644 index 000000000..6a17d76f2 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/tx_enqueue.v @@ -0,0 +1,179 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "tx_enqueue.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module tx_enqueue(/*AUTOARG*/ + // Outputs + pkt_tx_full, txdfifo_wdata, txdfifo_wstatus, txdfifo_wen, + status_txdfifo_ovflow_tog, + // Inputs + clk_156m25, reset_156m25_n, pkt_tx_data, pkt_tx_val, pkt_tx_sop, + pkt_tx_eop, pkt_tx_mod, txdfifo_wfull, txdfifo_walmost_full + ); + +`include "CRC32_D64.v" +`include "CRC32_D8.v" +`include "utils.v" + +input clk_156m25; +input reset_156m25_n; + +input [63:0] pkt_tx_data; +input pkt_tx_val; +input pkt_tx_sop; +input pkt_tx_eop; +input [2:0] pkt_tx_mod; + +input txdfifo_wfull; +input txdfifo_walmost_full; + +output pkt_tx_full; + +output [63:0] txdfifo_wdata; +output [7:0] txdfifo_wstatus; +output txdfifo_wen; + +output status_txdfifo_ovflow_tog; + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg status_txdfifo_ovflow_tog; +reg [63:0] txdfifo_wdata; +reg txdfifo_wen; +reg [7:0] txdfifo_wstatus; +// End of automatics + +/*AUTOWIRE*/ + + +reg txd_ovflow; +reg next_txd_ovflow; + + + +// Full status if data fifo is almost full. +// Current packet can complete transfer since data input rate +// matches output rate. But next packet must wait for more headroom. + +assign pkt_tx_full = txdfifo_walmost_full; + + + +always @(posedge clk_156m25 or negedge reset_156m25_n) begin + + if (reset_156m25_n == 1'b0) begin + + txd_ovflow <= 1'b0; + + status_txdfifo_ovflow_tog <= 1'b0; + + end + else begin + + txd_ovflow <= next_txd_ovflow; + + //--- + // FIFO errors, used to generate interrupts + + if (next_txd_ovflow && !txd_ovflow) begin + status_txdfifo_ovflow_tog <= ~status_txdfifo_ovflow_tog; + end + + end + +end + +always @(/*AS*/pkt_tx_data or pkt_tx_eop or pkt_tx_mod or pkt_tx_sop + or pkt_tx_val or txd_ovflow or txdfifo_wfull) begin + + txdfifo_wstatus = `TXSTATUS_NONE; + txdfifo_wen = pkt_tx_val; + + next_txd_ovflow = txd_ovflow; + + `ifdef BIGENDIAN + txdfifo_wdata = {pkt_tx_data[7:0], pkt_tx_data[15:8], pkt_tx_data[23:16], pkt_tx_data[31:24], + pkt_tx_data[39:32], pkt_tx_data[47:40], pkt_tx_data[55:48], + pkt_tx_data[63:56]}; + `else + txdfifo_wdata = pkt_tx_data; + `endif + + // Write SOP marker to fifo. + + if (pkt_tx_val && pkt_tx_sop) begin + + txdfifo_wstatus[`TXSTATUS_SOP] = 1'b1; + + end + + + // Write EOP marker to fifo. + + if (pkt_tx_val) begin + + if (pkt_tx_eop) begin + txdfifo_wstatus[2:0] = pkt_tx_mod; + txdfifo_wstatus[`TXSTATUS_EOP] = 1'b1; + end + + end + + + // Overflow indication + + if (pkt_tx_val) begin + + if (txdfifo_wfull) begin + + next_txd_ovflow = 1'b1; + + end + else if (pkt_tx_sop) begin + + next_txd_ovflow = 1'b0; + + end + end + +end + + +endmodule +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_hold_fifo.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_hold_fifo.v new file mode 100644 index 000000000..a71c256c6 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/tx_hold_fifo.v @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "tx_hold_fifo.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module tx_hold_fifo(/*AUTOARG*/ + // Outputs + txhfifo_wfull, txhfifo_walmost_full, txhfifo_rdata, txhfifo_rstatus, + txhfifo_rempty, txhfifo_ralmost_empty, + // Inputs + clk_xgmii_tx, reset_xgmii_tx_n, txhfifo_wdata, txhfifo_wstatus, + txhfifo_wen, txhfifo_ren + ); + +input clk_xgmii_tx; +input reset_xgmii_tx_n; + +input [63:0] txhfifo_wdata; +input [7:0] txhfifo_wstatus; +input txhfifo_wen; + +input txhfifo_ren; + +output txhfifo_wfull; +output txhfifo_walmost_full; + +output [63:0] txhfifo_rdata; +output [7:0] txhfifo_rstatus; +output txhfifo_rempty; +output txhfifo_ralmost_empty; + +generic_fifo #( + .DWIDTH (72), + .AWIDTH (`TX_HOLD_FIFO_AWIDTH), + .REGISTER_READ (1), + .EARLY_READ (1), + .CLOCK_CROSSING (0), + .ALMOST_EMPTY_THRESH (7), + .ALMOST_FULL_THRESH (4), +// .MEM_TYPE (`MEM_AUTO_SMALL) + .MEM_TYPE (`MEM_AUTO_XILINX) +) +fifo0( + .wclk (clk_xgmii_tx), + .wrst_n (reset_xgmii_tx_n), + .wen (txhfifo_wen), + .wdata ({txhfifo_wstatus, txhfifo_wdata}), + .wfull (txhfifo_wfull), + .walmost_full (txhfifo_walmost_full), + + .rclk (clk_xgmii_tx), + .rrst_n (reset_xgmii_tx_n), + .ren (txhfifo_ren), + .rdata ({txhfifo_rstatus, txhfifo_rdata}), + .rempty (txhfifo_rempty), + .ralmost_empty (txhfifo_ralmost_empty) +); + +endmodule + +
\ No newline at end of file diff --git a/fpga/usrp3/lib/xge/rtl/verilog/utils.v b/fpga/usrp3/lib/xge/rtl/verilog/utils.v new file mode 100644 index 000000000..6137b3e31 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/utils.v @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "utils.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +function [63:0] reverse_64b; + input [63:0] data; + integer i; + begin + for (i = 0; i < 64; i = i + 1) begin + reverse_64b[i] = data[63 - i]; + end + end +endfunction + + +function [31:0] reverse_32b; + input [31:0] data; + integer i; + begin + for (i = 0; i < 32; i = i + 1) begin + reverse_32b[i] = data[31 - i]; + end + end +endfunction + + +function [7:0] reverse_8b; + input [7:0] data; + integer i; + begin + for (i = 0; i < 8; i = i + 1) begin + reverse_8b[i] = data[7 - i]; + end + end +endfunction + + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v b/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v new file mode 100644 index 000000000..b70bc7294 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v @@ -0,0 +1,1031 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "wishbone.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 "defines.v" + +module wishbone_if(/*AUTOARG*/ + // Outputs + wb_dat_o, wb_ack_o, wb_int_o, ctrl_tx_enable, + mdc, mdio_out, mdio_tri, xge_gpo, + + // Inputs + wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_we_i, wb_stb_i, wb_cyc_i, + status_crc_error, status_fragment_error, status_txdfifo_ovflow, + status_txdfifo_udflow, status_rxdfifo_ovflow, status_rxdfifo_udflow, + status_pause_frame_rx, status_local_fault, status_remote_fault, + mdio_in, xge_gpi + ); + + +input wb_clk_i; +input wb_rst_i; + +input [7:0] wb_adr_i; +input [31:0] wb_dat_i; +input wb_we_i; +input wb_stb_i; +input wb_cyc_i; + +output [31:0] wb_dat_o; +output wb_ack_o; +output wb_int_o; + +input status_crc_error; +input status_fragment_error; + +input status_txdfifo_ovflow; + +input status_txdfifo_udflow; + +input status_rxdfifo_ovflow; + +input status_rxdfifo_udflow; + +input status_pause_frame_rx; + +input status_local_fault; +input status_remote_fault; + +output ctrl_tx_enable; + +output reg mdc; +output reg mdio_out; +output reg mdio_tri; // Assert to tristate driver. +input mdio_in; +input [7:0] xge_gpi; +output reg [7:0] xge_gpo; + + // + // State Declarations + // + parameter IDLE = 0, + PREAMBLE1 = 1, + PREAMBLE2 = 2, + PREAMBLE3 = 3, + PREAMBLE4 = 4, + PREAMBLE5 = 5, + PREAMBLE6 = 6, + PREAMBLE7 = 7, + PREAMBLE8 = 8, + PREAMBLE9 = 9, + PREAMBLE10 = 10, + PREAMBLE11 = 11, + PREAMBLE12 = 12, + PREAMBLE13 = 13, + PREAMBLE14 = 14, + PREAMBLE15 = 15, + PREAMBLE16 = 16, + PREAMBLE17 = 17, + PREAMBLE18 = 18, + PREAMBLE19 = 19, + PREAMBLE20 = 20, + PREAMBLE21 = 21, + PREAMBLE22 = 22, + PREAMBLE23 = 23, + PREAMBLE24 = 24, + PREAMBLE25 = 25, + PREAMBLE26 = 26, + PREAMBLE27 = 27, + PREAMBLE28 = 28, + PREAMBLE29 = 29, + PREAMBLE30 = 30, + PREAMBLE31 = 31, + PREAMBLE32 = 32, + START1 = 33, + C22_START2 = 34, + C45_START2 = 35, + OP1 = 36, + OP2 = 37, + PRTAD1 = 38, + PRTAD2 = 39, + PRTAD3 = 40, + PRTAD4 = 41, + PRTAD5 = 42, + DEVAD1 = 43, + DEVAD2 = 44, + DEVAD3 = 45, + DEVAD4 = 46, + DEVAD5 = 47, + TA1 = 48, + TA2 = 49, + TA3 = 50, + READ1 = 51, + READ2 = 52, + READ3 = 53, + READ4 = 54, + READ5 = 55, + READ6 = 56, + READ7 = 57, + READ8 = 58, + READ9 = 59, + READ10 = 60, + READ11 = 61, + READ12 = 62, + READ13 = 63, + READ14 = 64, + READ15 = 65, + READ16 = 66, + WRITE1 = 67, + WRITE2 = 68, + WRITE3 = 69, + WRITE4 = 70, + WRITE5 = 71, + WRITE6 = 72, + WRITE7 = 73, + WRITE8 = 74, + WRITE9 = 75, + WRITE10 = 76, + WRITE11 = 77, + WRITE12 = 78, + WRITE13 = 79, + WRITE14 = 80, + WRITE15 = 81, + WRITE16 = 82, + C45_ADDR1 = 83, + C45_ADDR2 = 84, + C45_ADDR3 = 85, + C45_ADDR4 = 86, + C45_ADDR5 = 87, + C45_ADDR6 = 88, + C45_ADDR7 = 89, + C45_ADDR8 = 90, + C45_ADDR9 = 91, + C45_ADDR10 = 92, + C45_ADDR11 = 93, + C45_ADDR12 = 94, + C45_ADDR13 = 95, + C45_ADDR14 = 96, + C45_ADDR15 = 97, + C45_ADDR16 = 98, + PREIDLE = 99; + + + + +/*AUTOREG*/ +// Beginning of automatic regs (for this module's undeclared outputs) +reg [31:0] wb_dat_o; +reg wb_int_o; +// End of automatics + +reg [0:0] cpureg_config0; +reg [8:0] cpureg_int_pending; +reg [8:0] cpureg_int_mask; + +reg cpuack; + +reg status_remote_fault_d1; +reg status_local_fault_d1; + +reg [15:0] mdio_read_data; +reg [15:0] mdio_write_data; +reg [15:0] mdio_address; +reg [12:0] mdio_operation; +reg mdio_control; +reg [7:0] mdc_clk_count; +reg mdc_falling_edge; +reg mdio_running; +reg mdio_done; +reg [7:0] state; +reg [7:0] xge_gpi_reg; +reg [7:0] xge_gpo_reg; + + + +/*AUTOWIRE*/ + +wire [8:0] int_sources; + + +//--- +// Source of interrupts, some are edge sensitive, others +// expect a pulse signal. + +assign int_sources = { + status_fragment_error, + status_crc_error, + + status_pause_frame_rx, + + status_remote_fault ^ status_remote_fault_d1, + status_local_fault ^ status_local_fault_d1, + + status_rxdfifo_udflow, + status_rxdfifo_ovflow, + status_txdfifo_udflow, + status_txdfifo_ovflow + }; + +//--- +// Config Register 0 + +//TODO +//assign ctrl_tx_enable = cpureg_config0[0]; +assign ctrl_tx_enable = 1'b1; + + + +//--- +// Wishbone signals + +assign wb_ack_o = cpuack && wb_stb_i; + +always @(posedge wb_clk_i or posedge wb_rst_i) begin + + if (wb_rst_i == 1'b1) begin + + cpureg_config0 <= 1'h1; + cpureg_int_pending <= 9'b0; + cpureg_int_mask <= 9'b0; + + wb_dat_o <= 32'b0; + wb_int_o <= 1'b0; + + cpuack <= 1'b0; + + mdio_address <= 0; + mdio_operation <= 0; + mdio_write_data <= 0; + + mdio_running <= 0; + xge_gpi_reg <= 0; + xge_gpo <= 0; + xge_gpo_reg <= 0; + + + + + // status_remote_fault_d1 <= status_remote_fault; + // status_local_fault_d1 <= status_local_fault; + // IJB. Original code was unsynthesizable and a little bizzare + // implying reset would latch data. + status_remote_fault_d1 <= 0; + status_local_fault_d1 <= 0; + end + else begin + + wb_int_o <= |(cpureg_int_pending & cpureg_int_mask); + + cpureg_int_pending <= cpureg_int_pending | int_sources; + + cpuack <= wb_cyc_i && wb_stb_i; + + status_remote_fault_d1 <= status_remote_fault; + status_local_fault_d1 <= status_local_fault; + + // Handshake to MDIO state machine to reset running flag in status. + // Wait for falling MDC edge to prevent S/W race condition occuring + // where done flag still asserted but running flag now cleared (repeatedly). + if (mdio_done && mdc_falling_edge) + mdio_running <= 0; + + // Register GPIO to allow regs placed in the I/O cells and provide some metastability prot + xge_gpi_reg <= xge_gpi; + xge_gpo <= xge_gpo_reg; + + + //--- + // Read access + + if (wb_cyc_i && wb_stb_i && !wb_we_i) begin + + case ({wb_adr_i[7:2], 2'b0}) + + `CPUREG_CONFIG0: begin + wb_dat_o <= {31'b0, cpureg_config0}; + end + + `CPUREG_INT_PENDING: begin + wb_dat_o <= {23'b0, cpureg_int_pending}; + cpureg_int_pending <= int_sources; + wb_int_o <= 1'b0; + end + + `CPUREG_INT_STATUS: begin + wb_dat_o <= {23'b0, int_sources}; + end + + `CPUREG_INT_MASK: begin + wb_dat_o <= {23'b0, cpureg_int_mask}; + end + + `CPUREG_MDIO_DATA: begin + wb_dat_o <= {16'b0, mdio_read_data}; + end + + `CPUREG_MDIO_STATUS: begin + wb_dat_o <= {31'b0, mdio_running}; + end + + `CPUREG_GPIO: begin + wb_dat_o <= {24'b0, xge_gpi_reg}; + end + + + default: begin + end + + endcase + + end + + //--- + // Write access + + if (wb_cyc_i && wb_stb_i && wb_we_i) begin + $display("reg write @ addr %x",({wb_adr_i[7:2], 2'b0})); + + case ({wb_adr_i[7:2], 2'b0}) + + `CPUREG_CONFIG0: begin + cpureg_config0 <= wb_dat_i[0:0]; + end + + `CPUREG_INT_PENDING: begin + cpureg_int_pending <= wb_dat_i[8:0] | cpureg_int_pending | int_sources; + end + + `CPUREG_INT_MASK: begin + cpureg_int_mask <= wb_dat_i[8:0]; + end + + `CPUREG_MDIO_DATA: begin + mdio_write_data <= wb_dat_i[15:0]; + end + + `CPUREG_MDIO_ADDR: begin + mdio_address <= wb_dat_i[15:0]; + end + + `CPUREG_MDIO_OP: begin + mdio_operation <= wb_dat_i[12:0]; + end + + `CPUREG_MDIO_CONTROL: begin + // Trigger mdio operation here. Cleared by state machine at end of bus transaction. + if (wb_dat_i[0]) + mdio_running <= 1; + end + + `CPUREG_GPIO: begin + xge_gpo_reg <= wb_dat_i[7:0]; + end + + + default: begin + end + + endcase + + end + + end + +end // always @ (posedge wb_clk_i or posedge wb_rst_i) + + // + // Produce mdc clock as a signal synchronously from Wishbone clock. + // + always @(posedge wb_clk_i or posedge wb_rst_i) + if (wb_rst_i) + begin + mdc_clk_count <= 1; + mdc <= 0; + mdc_falling_edge <= 0; + end + else if (mdc_clk_count == `MDC_HALF_PERIOD) + begin + mdc_clk_count <= 1; + mdc <= ~mdc; + mdc_falling_edge <= mdc; + end + else + begin + mdc_clk_count <= mdc_clk_count + 1; + mdc_falling_edge <= 0; + end + + // + // MDIO state machine + // + always @(posedge wb_clk_i or posedge wb_rst_i) + if (wb_rst_i) + begin + mdio_tri <= 1; + mdio_out <= 0; + mdio_done <= 0; + mdio_read_data <= 0; + state <= IDLE; + end + else if (mdc_falling_edge) + // + // This is the MDIO bus controller. Use falling edge of MDC. + // + begin + // Defaults + mdio_tri <= 1; + mdio_out <= 0; + mdio_done <= 0; + + + case(state) + // IDLE. + // In Clause 22 & 45 the master of the MDIO bus is tristate during idle. + // + IDLE: begin + mdio_tri <= 1; + mdio_out <= 0; + if (mdio_running) + state <= PREAMBLE1; + end + // Preamble. All MDIO transactions begin witrh 32bits of 1 bits as a preamble. + PREAMBLE1: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE2; + end + PREAMBLE2: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE3; + end + PREAMBLE3: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE4; + end + PREAMBLE4: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE5; + end + PREAMBLE5: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE6; + end + PREAMBLE6: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE7; + end + PREAMBLE7: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE8; + end + PREAMBLE8: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE9; + end + PREAMBLE9: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE10; + end + PREAMBLE10: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE11; + end + PREAMBLE11: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE12; + end + PREAMBLE12: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE13; + end + PREAMBLE13: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE14; + end + PREAMBLE14: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE15; + end + PREAMBLE15: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE16; + end + PREAMBLE16: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE17; + end + PREAMBLE17: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE18; + end + PREAMBLE18: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE19; + end + PREAMBLE19: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE20; + end + PREAMBLE20: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE21; + end + PREAMBLE21: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE22; + end + PREAMBLE22: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE23; + end + PREAMBLE23: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE24; + end + PREAMBLE24: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE25; + end + PREAMBLE25: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE26; + end + PREAMBLE26: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE27; + end + PREAMBLE27: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE28; + end + PREAMBLE28: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE29; + end + PREAMBLE29: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE30; + end + PREAMBLE30: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE31; + end + PREAMBLE31: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= PREAMBLE32; + end + PREAMBLE32: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= START1; + end + // + // Start code for Clause 22 is 01 and Clause 45 is 00 + // + START1: begin + mdio_tri <= 0; + mdio_out <= 0; + if (mdio_operation[12]) + // Clause 45 bit set. + state <= C45_START2; + else + state <= C22_START2; + end + // + // 2nd Clause 22 start bit is a 1 + // + C22_START2: begin + mdio_tri <= 0; + mdio_out <= 1; + state <= OP1; + end + // + // 2nd Clause 45 start bit is a 0 + // + C45_START2: begin + mdio_tri <= 0; + mdio_out <= 0; + state <= OP1; + end + // + // Both Clause 22 & 45 use 2 bits for operation and are compatable. + // Note we don't screen here for illegal Clause 22 ops. + // + OP1: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[11]; + state <= OP2; + end + OP2: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[10]; + state <= PRTAD1; + end + // + // Both Clause 22 & 45 use 2 sucsessive 5 bit fields to form a hierarchical address + // though it's used slightly different between the 2 standards. + // + PRTAD1: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[9]; + state <= PRTAD2; + end + PRTAD2: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[8]; + state <= PRTAD3; + end + PRTAD3: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[7]; + state <= PRTAD4; + end + PRTAD4: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[6]; + state <= PRTAD5; + end + PRTAD5: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[5]; + state <= DEVAD1; + end + DEVAD1: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[4]; + state <= DEVAD2; + end + DEVAD2: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[3]; + state <= DEVAD3; + end + DEVAD3: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[2]; + state <= DEVAD4; + end + DEVAD4: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[1]; + state <= DEVAD5; + end + DEVAD5: begin + mdio_tri <= 0; + mdio_out <= mdio_operation[0]; + state <= TA1; + end + // + // Both Clause 22 & Clause 45 use the same turn around on the bus. + // Reads have Z as the first bit and 0 driven by the slave for the 2nd bit. + // Note that slaves drive the bus on the rising edge of MDC. + // Writes and Address cycles have 10 driven by the master. + // + TA1: begin + if (mdio_operation[11] == 0) // Write/Address + begin + mdio_tri <= 0; + mdio_out <= 1; + state <= TA2; + end + else // Read + begin + mdio_tri <= 1; + state <= TA3; + end + end + TA2: begin + mdio_tri <= 0; + mdio_out <= 0; + if (!mdio_operation[12]) // Clause 22 Write + state <= WRITE1; + else if (mdio_operation[10]) // Clause 45 Write + state <= WRITE1; + else // Clause 45 ADDRESS + state <= C45_ADDR1; + end + TA3: begin + mdio_tri <= 1; + state <= READ1; + end + // + // Clause 22 Reads and both forms of clause 45 Reads have the same bus transaction from here out. + // + READ1: begin + mdio_tri <= 1; + mdio_read_data[15] <= mdio_in; + state <= READ2; + end + READ2: begin + mdio_tri <= 1; + mdio_read_data[14] <= mdio_in; + state <= READ3; + end + READ3: begin + mdio_tri <= 1; + mdio_read_data[13] <= mdio_in; + state <= READ4; + end + READ4: begin + mdio_tri <= 1; + mdio_read_data[12] <= mdio_in; + state <= READ5; + end + READ5: begin + mdio_tri <= 1; + mdio_read_data[11] <= mdio_in; + state <= READ6; + end + READ6: begin + mdio_tri <= 1; + mdio_read_data[10] <= mdio_in; + state <= READ7; + end + READ7: begin + mdio_tri <= 1; + mdio_read_data[9] <= mdio_in; + state <= READ8; + end + READ8: begin + mdio_tri <= 1; + mdio_read_data[8] <= mdio_in; + state <= READ9; + end + READ9: begin + mdio_tri <= 1; + mdio_read_data[7] <= mdio_in; + state <= READ10; + end + READ10: begin + mdio_tri <= 1; + mdio_read_data[6] <= mdio_in; + state <= READ11; + end + READ11: begin + mdio_tri <= 1; + mdio_read_data[5] <= mdio_in; + state <= READ12; + end + READ12: begin + mdio_tri <= 1; + mdio_read_data[4] <= mdio_in; + state <= READ13; + end + READ13: begin + mdio_tri <= 1; + mdio_read_data[3] <= mdio_in; + state <= READ14; + end + READ14: begin + mdio_tri <= 1; + mdio_read_data[2] <= mdio_in; + state <= READ15; + end + READ15: begin + mdio_tri <= 1; + mdio_read_data[1] <= mdio_in; + state <= READ16; + end + READ16: begin + mdio_tri <= 1; + mdio_read_data[0] <= mdio_in; + state <= PREIDLE; + mdio_done <= 1; + end + // + // Write 16bits of data for all types of Write. + // + WRITE1:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[15]; + state <= WRITE2; + end + WRITE2:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[14]; + state <= WRITE3; + end + WRITE3:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[13]; + state <= WRITE4; + end + WRITE4:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[12]; + state <= WRITE5; + end + WRITE5:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[11]; + state <= WRITE6; + end + WRITE6:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[10]; + state <= WRITE7; + end + WRITE7:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[9]; + state <= WRITE8; + end + WRITE8:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[8]; + state <= WRITE9; + end + WRITE9:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[7]; + state <= WRITE10; + end + WRITE10:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[6]; + state <= WRITE11; + end + WRITE11:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[5]; + state <= WRITE12; + end + WRITE12:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[4]; + state <= WRITE13; + end + WRITE13:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[3]; + state <= WRITE14; + end + WRITE14:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[2]; + state <= WRITE15; + end + WRITE15:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[1]; + state <= WRITE16; + end + WRITE16:begin + mdio_tri <= 0; + mdio_out <= mdio_write_data[0]; + state <= PREIDLE; + mdio_done <= 1; + end + // + // Write 16bits of address for a Clause 45 Address transaction + // + C45_ADDR1:begin + mdio_tri <= 0; + mdio_out <= mdio_address[15]; + state <= C45_ADDR2; + end + C45_ADDR2:begin + mdio_tri <= 0; + mdio_out <= mdio_address[14]; + state <= C45_ADDR3; + end + C45_ADDR3:begin + mdio_tri <= 0; + mdio_out <= mdio_address[13]; + state <= C45_ADDR4; + end + C45_ADDR4:begin + mdio_tri <= 0; + mdio_out <= mdio_address[12]; + state <= C45_ADDR5; + end + C45_ADDR5:begin + mdio_tri <= 0; + mdio_out <= mdio_address[11]; + state <= C45_ADDR6; + end + C45_ADDR6:begin + mdio_tri <= 0; + mdio_out <= mdio_address[10]; + state <= C45_ADDR7; + end + C45_ADDR7:begin + mdio_tri <= 0; + mdio_out <= mdio_address[9]; + state <= C45_ADDR8; + end + C45_ADDR8:begin + mdio_tri <= 0; + mdio_out <= mdio_address[8]; + state <= C45_ADDR9; + end + C45_ADDR9:begin + mdio_tri <= 0; + mdio_out <= mdio_address[7]; + state <= C45_ADDR10; + end + C45_ADDR10:begin + mdio_tri <= 0; + mdio_out <= mdio_address[6]; + state <= C45_ADDR11; + end + C45_ADDR11:begin + mdio_tri <= 0; + mdio_out <= mdio_address[5]; + state <= C45_ADDR12; + end + C45_ADDR12:begin + mdio_tri <= 0; + mdio_out <= mdio_address[4]; + state <= C45_ADDR13; + end + C45_ADDR13:begin + mdio_tri <= 0; + mdio_out <= mdio_address[3]; + state <= C45_ADDR14; + end + C45_ADDR14:begin + mdio_tri <= 0; + mdio_out <= mdio_address[2]; + state <= C45_ADDR15; + end + C45_ADDR15:begin + mdio_tri <= 0; + mdio_out <= mdio_address[1]; + state <= C45_ADDR16; + end + C45_ADDR16:begin + mdio_tri <= 0; + mdio_out <= mdio_address[0]; + state <= PREIDLE; + mdio_done <= 1; + end + // + // PREIDLE allows the mdio_running bit to reset. + // + PREIDLE: begin + state <= IDLE; + end + endcase // case(state) + + end // if (mdc_falling_edge) + + + + +endmodule + diff --git a/fpga/usrp3/lib/xge/rtl/verilog/xge_mac.v b/fpga/usrp3/lib/xge/rtl/verilog/xge_mac.v new file mode 100644 index 000000000..2b08e3b61 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/xge_mac.v @@ -0,0 +1,329 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "xge_mac.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module xge_mac (/*AUTOARG*/ + // Outputs + xgmii_txd, xgmii_txc, pkt_tx_full, + pkt_rx_val, pkt_rx_sop, pkt_rx_mod, pkt_rx_err, pkt_rx_eop, + pkt_rx_data, pkt_rx_avail, + status_crc_error, status_fragment_error, status_txdfifo_ovflow, + status_txdfifo_udflow, status_rxdfifo_ovflow, status_rxdfifo_udflow, + status_pause_frame_rx, status_local_fault, status_remote_fault, + // Inputs + xgmii_rxd, xgmii_rxc, reset_xgmii_tx_n, reset_xgmii_rx_n, + reset_156m25_n, pkt_tx_val, pkt_tx_sop, pkt_tx_mod, pkt_tx_eop, + pkt_tx_data, pkt_rx_ren, ctrl_tx_enable, + clk_xgmii_tx, clk_xgmii_rx, clk_156m25 +); + +/*AUTOINPUT*/ +// Beginning of automatic inputs (from unused autoinst inputs) +input clk_156m25; // To rx_dq0 of rx_dequeue.v, ... +input clk_xgmii_rx; // To rx_eq0 of rx_enqueue.v, ... +input clk_xgmii_tx; // To tx_dq0 of tx_dequeue.v, ... +input pkt_rx_ren; // To rx_dq0 of rx_dequeue.v +input [63:0] pkt_tx_data; // To tx_eq0 of tx_enqueue.v +input pkt_tx_eop; // To tx_eq0 of tx_enqueue.v +input [2:0] pkt_tx_mod; // To tx_eq0 of tx_enqueue.v +input pkt_tx_sop; // To tx_eq0 of tx_enqueue.v +input pkt_tx_val; // To tx_eq0 of tx_enqueue.v +input reset_156m25_n; // To rx_dq0 of rx_dequeue.v, ... +input reset_xgmii_rx_n; // To rx_eq0 of rx_enqueue.v, ... +input reset_xgmii_tx_n; // To tx_dq0 of tx_dequeue.v, ... +input [7:0] xgmii_rxc; // To rx_eq0 of rx_enqueue.v +input [63:0] xgmii_rxd; // To rx_eq0 of rx_enqueue.v +input ctrl_tx_enable; // From wishbone_if0 of wishbone_if.v +// End of automatics + +/*AUTOOUTPUT*/ +// Beginning of automatic outputs (from unused autoinst outputs) +output pkt_rx_avail; // From rx_dq0 of rx_dequeue.v +output [63:0] pkt_rx_data; // From rx_dq0 of rx_dequeue.v +output pkt_rx_eop; // From rx_dq0 of rx_dequeue.v +output pkt_rx_err; // From rx_dq0 of rx_dequeue.v +output [2:0] pkt_rx_mod; // From rx_dq0 of rx_dequeue.v +output pkt_rx_sop; // From rx_dq0 of rx_dequeue.v +output pkt_rx_val; // From rx_dq0 of rx_dequeue.v +output pkt_tx_full; // From tx_eq0 of tx_enqueue.v +output [7:0] xgmii_txc; // From tx_dq0 of tx_dequeue.v +output [63:0] xgmii_txd; // From tx_dq0 of tx_dequeue.v + +output status_crc_error; +output status_fragment_error; +output status_txdfifo_ovflow; +output status_txdfifo_udflow; +output status_rxdfifo_ovflow; +output status_rxdfifo_udflow; +output status_pause_frame_rx; +output status_local_fault; +output status_remote_fault; + +// End of automatics + +/*AUTOWIRE*/ +// Beginning of automatic wires (for undeclared instantiated-module outputs) +wire ctrl_tx_enable_ctx; // From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v +wire [1:0] local_fault_msg_det; // From rx_eq0 of rx_enqueue.v +wire [1:0] remote_fault_msg_det; // From rx_eq0 of rx_enqueue.v +wire rxdfifo_ralmost_empty; // From rx_data_fifo0 of rx_data_fifo.v +wire [63:0] rxdfifo_rdata; // From rx_data_fifo0 of rx_data_fifo.v +wire rxdfifo_rempty; // From rx_data_fifo0 of rx_data_fifo.v +wire rxdfifo_ren; // From rx_dq0 of rx_dequeue.v +wire [7:0] rxdfifo_rstatus; // From rx_data_fifo0 of rx_data_fifo.v +wire [63:0] rxdfifo_wdata; // From rx_eq0 of rx_enqueue.v +wire rxdfifo_wen; // From rx_eq0 of rx_enqueue.v +wire rxdfifo_wfull; // From rx_data_fifo0 of rx_data_fifo.v +wire [7:0] rxdfifo_wstatus; // From rx_eq0 of rx_enqueue.v +wire rxhfifo_ralmost_empty; // From rx_hold_fifo0 of rx_hold_fifo.v +wire [63:0] rxhfifo_rdata; // From rx_hold_fifo0 of rx_hold_fifo.v +wire rxhfifo_rempty; // From rx_hold_fifo0 of rx_hold_fifo.v +wire rxhfifo_ren; // From rx_eq0 of rx_enqueue.v +wire [7:0] rxhfifo_rstatus; // From rx_hold_fifo0 of rx_hold_fifo.v +wire [63:0] rxhfifo_wdata; // From rx_eq0 of rx_enqueue.v +wire rxhfifo_wen; // From rx_eq0 of rx_enqueue.v +wire [7:0] rxhfifo_wstatus; // From rx_eq0 of rx_enqueue.v +wire status_local_fault_ctx; // From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v +wire status_remote_fault_ctx;// From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v +wire txdfifo_ralmost_empty; // From tx_data_fifo0 of tx_data_fifo.v +wire [63:0] txdfifo_rdata; // From tx_data_fifo0 of tx_data_fifo.v +wire txdfifo_rempty; // From tx_data_fifo0 of tx_data_fifo.v +wire txdfifo_ren; // From tx_dq0 of tx_dequeue.v +wire [7:0] txdfifo_rstatus; // From tx_data_fifo0 of tx_data_fifo.v +wire txdfifo_walmost_full; // From tx_data_fifo0 of tx_data_fifo.v +wire [63:0] txdfifo_wdata; // From tx_eq0 of tx_enqueue.v +wire txdfifo_wen; // From tx_eq0 of tx_enqueue.v +wire txdfifo_wfull; // From tx_data_fifo0 of tx_data_fifo.v +wire [7:0] txdfifo_wstatus; // From tx_eq0 of tx_enqueue.v +wire txhfifo_ralmost_empty; // From tx_hold_fifo0 of tx_hold_fifo.v +wire [63:0] txhfifo_rdata; // From tx_hold_fifo0 of tx_hold_fifo.v +wire txhfifo_rempty; // From tx_hold_fifo0 of tx_hold_fifo.v +wire txhfifo_ren; // From tx_dq0 of tx_dequeue.v +wire [7:0] txhfifo_rstatus; // From tx_hold_fifo0 of tx_hold_fifo.v +wire txhfifo_walmost_full; // From tx_hold_fifo0 of tx_hold_fifo.v +wire [63:0] txhfifo_wdata; // From tx_dq0 of tx_dequeue.v +wire txhfifo_wen; // From tx_dq0 of tx_dequeue.v +wire txhfifo_wfull; // From tx_hold_fifo0 of tx_hold_fifo.v +wire [7:0] txhfifo_wstatus; // From tx_dq0 of tx_dequeue.v +// End of automatics + +rx_enqueue rx_eq0(/*AUTOINST*/ + // Outputs + .rxdfifo_wdata (rxdfifo_wdata[63:0]), + .rxdfifo_wstatus (rxdfifo_wstatus[7:0]), + .rxdfifo_wen (rxdfifo_wen), + .rxhfifo_ren (rxhfifo_ren), + .rxhfifo_wdata (rxhfifo_wdata[63:0]), + .rxhfifo_wstatus (rxhfifo_wstatus[7:0]), + .rxhfifo_wen (rxhfifo_wen), + .local_fault_msg_det (local_fault_msg_det[1:0]), + .remote_fault_msg_det (remote_fault_msg_det[1:0]), + .status_crc_error_tog (status_crc_error), + .status_fragment_error_tog(status_fragment_error), + .status_rxdfifo_ovflow_tog(status_rxdfifo_ovflow), + .status_pause_frame_rx_tog(status_pause_frame_rx), + // Inputs + .clk_xgmii_rx (clk_xgmii_rx), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .xgmii_rxd (xgmii_rxd[63:0]), + .xgmii_rxc (xgmii_rxc[7:0]), + .rxdfifo_wfull (rxdfifo_wfull), + .rxhfifo_rdata (rxhfifo_rdata[63:0]), + .rxhfifo_rstatus (rxhfifo_rstatus[7:0]), + .rxhfifo_rempty (rxhfifo_rempty), + .rxhfifo_ralmost_empty(rxhfifo_ralmost_empty)); + +rx_dequeue rx_dq0(/*AUTOINST*/ + // Outputs + .rxdfifo_ren (rxdfifo_ren), + .pkt_rx_data (pkt_rx_data[63:0]), + .pkt_rx_val (pkt_rx_val), + .pkt_rx_sop (pkt_rx_sop), + .pkt_rx_eop (pkt_rx_eop), + .pkt_rx_err (pkt_rx_err), + .pkt_rx_mod (pkt_rx_mod[2:0]), + .pkt_rx_avail (pkt_rx_avail), + .status_rxdfifo_udflow_tog(status_rxdfifo_udflow), + // Inputs + .clk_156m25 (clk_156m25), + .reset_156m25_n (reset_156m25_n), + .rxdfifo_rdata (rxdfifo_rdata[63:0]), + .rxdfifo_rstatus (rxdfifo_rstatus[7:0]), + .rxdfifo_rempty (rxdfifo_rempty), + .rxdfifo_ralmost_empty(rxdfifo_ralmost_empty), + .pkt_rx_ren (pkt_rx_ren)); + +rx_data_fifo rx_data_fifo0(/*AUTOINST*/ + // Outputs + .rxdfifo_wfull (rxdfifo_wfull), + .rxdfifo_rdata (rxdfifo_rdata[63:0]), + .rxdfifo_rstatus (rxdfifo_rstatus[7:0]), + .rxdfifo_rempty (rxdfifo_rempty), + .rxdfifo_ralmost_empty(rxdfifo_ralmost_empty), + // Inputs + .clk_xgmii_rx (clk_xgmii_rx), + .clk_156m25 (clk_156m25), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .reset_156m25_n (reset_156m25_n), + .rxdfifo_wdata (rxdfifo_wdata[63:0]), + .rxdfifo_wstatus (rxdfifo_wstatus[7:0]), + .rxdfifo_wen (rxdfifo_wen), + .rxdfifo_ren (rxdfifo_ren)); + +rx_hold_fifo rx_hold_fifo0(/*AUTOINST*/ + // Outputs + .rxhfifo_rdata (rxhfifo_rdata[63:0]), + .rxhfifo_rstatus (rxhfifo_rstatus[7:0]), + .rxhfifo_rempty (rxhfifo_rempty), + .rxhfifo_ralmost_empty(rxhfifo_ralmost_empty), + // Inputs + .clk_xgmii_rx (clk_xgmii_rx), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .rxhfifo_wdata (rxhfifo_wdata[63:0]), + .rxhfifo_wstatus (rxhfifo_wstatus[7:0]), + .rxhfifo_wen (rxhfifo_wen), + .rxhfifo_ren (rxhfifo_ren)); + +tx_enqueue tx_eq0 (/*AUTOINST*/ + // Outputs + .pkt_tx_full (pkt_tx_full), + .txdfifo_wdata (txdfifo_wdata[63:0]), + .txdfifo_wstatus (txdfifo_wstatus[7:0]), + .txdfifo_wen (txdfifo_wen), + .status_txdfifo_ovflow_tog(status_txdfifo_ovflow), + // Inputs + .clk_156m25 (clk_156m25), + .reset_156m25_n (reset_156m25_n), + .pkt_tx_data (pkt_tx_data[63:0]), + .pkt_tx_val (pkt_tx_val), + .pkt_tx_sop (pkt_tx_sop), + .pkt_tx_eop (pkt_tx_eop), + .pkt_tx_mod (pkt_tx_mod[2:0]), + .txdfifo_wfull (txdfifo_wfull), + .txdfifo_walmost_full(txdfifo_walmost_full)); + +tx_dequeue tx_dq0(/*AUTOINST*/ + // Outputs + .txdfifo_ren (txdfifo_ren), + .txhfifo_ren (txhfifo_ren), + .txhfifo_wdata (txhfifo_wdata[63:0]), + .txhfifo_wstatus (txhfifo_wstatus[7:0]), + .txhfifo_wen (txhfifo_wen), + .xgmii_txd (xgmii_txd[63:0]), + .xgmii_txc (xgmii_txc[7:0]), + .status_txdfifo_udflow_tog(status_txdfifo_udflow), + // Inputs + .clk_xgmii_tx (clk_xgmii_tx), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + .ctrl_tx_enable_ctx (ctrl_tx_enable_ctx), + .status_local_fault_ctx(status_local_fault_ctx), + .status_remote_fault_ctx(status_remote_fault_ctx), + .txdfifo_rdata (txdfifo_rdata[63:0]), + .txdfifo_rstatus (txdfifo_rstatus[7:0]), + .txdfifo_rempty (txdfifo_rempty), + .txdfifo_ralmost_empty(txdfifo_ralmost_empty), + .txhfifo_rdata (txhfifo_rdata[63:0]), + .txhfifo_rstatus (txhfifo_rstatus[7:0]), + .txhfifo_rempty (txhfifo_rempty), + .txhfifo_ralmost_empty(txhfifo_ralmost_empty), + .txhfifo_wfull (txhfifo_wfull), + .txhfifo_walmost_full (txhfifo_walmost_full)); + +tx_data_fifo tx_data_fifo0(/*AUTOINST*/ + // Outputs + .txdfifo_wfull (txdfifo_wfull), + .txdfifo_walmost_full(txdfifo_walmost_full), + .txdfifo_rdata (txdfifo_rdata[63:0]), + .txdfifo_rstatus (txdfifo_rstatus[7:0]), + .txdfifo_rempty (txdfifo_rempty), + .txdfifo_ralmost_empty(txdfifo_ralmost_empty), + // Inputs + .clk_xgmii_tx (clk_xgmii_tx), + .clk_156m25 (clk_156m25), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + .reset_156m25_n (reset_156m25_n), + .txdfifo_wdata (txdfifo_wdata[63:0]), + .txdfifo_wstatus (txdfifo_wstatus[7:0]), + .txdfifo_wen (txdfifo_wen), + .txdfifo_ren (txdfifo_ren)); + +tx_hold_fifo tx_hold_fifo0(/*AUTOINST*/ + // Outputs + .txhfifo_wfull (txhfifo_wfull), + .txhfifo_walmost_full(txhfifo_walmost_full), + .txhfifo_rdata (txhfifo_rdata[63:0]), + .txhfifo_rstatus (txhfifo_rstatus[7:0]), + .txhfifo_rempty (txhfifo_rempty), + .txhfifo_ralmost_empty(txhfifo_ralmost_empty), + // Inputs + .clk_xgmii_tx (clk_xgmii_tx), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + .txhfifo_wdata (txhfifo_wdata[63:0]), + .txhfifo_wstatus (txhfifo_wstatus[7:0]), + .txhfifo_wen (txhfifo_wen), + .txhfifo_ren (txhfifo_ren)); + +fault_sm fault_sm0(/*AUTOINST*/ + // Outputs + .status_local_fault_crx(status_local_fault), + .status_remote_fault_crx(status_remote_fault), + // Inputs + .clk_xgmii_rx (clk_xgmii_rx), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .local_fault_msg_det (local_fault_msg_det[1:0]), + .remote_fault_msg_det(remote_fault_msg_det[1:0])); + +sync_clk_xgmii_tx sync_clk_xgmii_tx0(/*AUTOINST*/ + // Outputs + .ctrl_tx_enable_ctx(ctrl_tx_enable_ctx), + .status_local_fault_ctx(status_local_fault_ctx), + .status_remote_fault_ctx(status_remote_fault_ctx), + // Inputs + .clk_xgmii_tx (clk_xgmii_tx), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + .ctrl_tx_enable (ctrl_tx_enable), + .status_local_fault_crx(status_local_fault), + .status_remote_fault_crx(status_remote_fault)); + +// IJB. This module has only inputs and is treated as a black box by XST which causes a fatal error. +// Commented out. Original pupose/intent unknown. +//sync_clk_core sync_clk_core0(/*AUTOINST*/ +// // Inputs +// .clk_xgmii_tx (clk_xgmii_tx), +// .reset_xgmii_tx_n (reset_xgmii_tx_n)); + +endmodule diff --git a/fpga/usrp3/lib/xge/rtl/verilog/xge_mac_wb.v b/fpga/usrp3/lib/xge/rtl/verilog/xge_mac_wb.v new file mode 100644 index 000000000..615602db9 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/xge_mac_wb.v @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "xge_mac_wb.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module xge_mac_wb ( + // Outputs + xgmii_txd, xgmii_txc, pkt_tx_full, + pkt_rx_val, pkt_rx_sop, pkt_rx_mod, pkt_rx_err, pkt_rx_eop, + pkt_rx_data, pkt_rx_avail, + wb_int_o, wb_dat_o, wb_ack_o, + mdc, mdio_out, mdio_tri, xge_gpo, + + // Inputs + xgmii_rxd, xgmii_rxc, + wb_we_i, wb_stb_i, wb_rst_i, wb_dat_i, + wb_cyc_i, wb_clk_i, wb_adr_i, + reset_xgmii_tx_n, reset_xgmii_rx_n, reset_156m25_n, + pkt_tx_val, pkt_tx_sop, pkt_tx_mod, pkt_tx_eop, + pkt_tx_data, pkt_rx_ren, + clk_xgmii_tx, clk_xgmii_rx, clk_156m25, + mdio_in, xge_gpi +); + + input clk_156m25; // To rx_dq0 of rx_dequeue.v, ... + input clk_xgmii_rx; // To rx_eq0 of rx_enqueue.v, ... + input clk_xgmii_tx; // To tx_dq0 of tx_dequeue.v, ... + input pkt_rx_ren; // To rx_dq0 of rx_dequeue.v + input [63:0] pkt_tx_data; // To tx_eq0 of tx_enqueue.v + input pkt_tx_eop; // To tx_eq0 of tx_enqueue.v + input [2:0] pkt_tx_mod; // To tx_eq0 of tx_enqueue.v + input pkt_tx_sop; // To tx_eq0 of tx_enqueue.v + input pkt_tx_val; // To tx_eq0 of tx_enqueue.v + input reset_156m25_n; // To rx_dq0 of rx_dequeue.v, ... + input reset_xgmii_rx_n; // To rx_eq0 of rx_enqueue.v, ... + input reset_xgmii_tx_n; // To tx_dq0 of tx_dequeue.v, ... + input [7:0] wb_adr_i; // To wishbone_if0 of wishbone_if.v + input wb_clk_i; // To sync_clk_wb0 of sync_clk_wb.v, ... + input wb_cyc_i; // To wishbone_if0 of wishbone_if.v + input [31:0] wb_dat_i; // To wishbone_if0 of wishbone_if.v + input wb_rst_i; // To sync_clk_wb0 of sync_clk_wb.v, ... + input wb_stb_i; // To wishbone_if0 of wishbone_if.v + input wb_we_i; // To wishbone_if0 of wishbone_if.v + input [7:0] xgmii_rxc; // To rx_eq0 of rx_enqueue.v + input [63:0] xgmii_rxd; // To rx_eq0 of rx_enqueue.v + input mdio_in; + input [7:0] xge_gpi; + + output pkt_rx_avail; // From rx_dq0 of rx_dequeue.v + output [63:0] pkt_rx_data; // From rx_dq0 of rx_dequeue.v + output pkt_rx_eop; // From rx_dq0 of rx_dequeue.v + output pkt_rx_err; // From rx_dq0 of rx_dequeue.v + output [2:0] pkt_rx_mod; // From rx_dq0 of rx_dequeue.v + output pkt_rx_sop; // From rx_dq0 of rx_dequeue.v + output pkt_rx_val; // From rx_dq0 of rx_dequeue.v + output pkt_tx_full; // From tx_eq0 of tx_enqueue.v + output wb_ack_o; // From wishbone_if0 of wishbone_if.v + output [31:0] wb_dat_o; // From wishbone_if0 of wishbone_if.v + output wb_int_o; // From wishbone_if0 of wishbone_if.v + output [7:0] xgmii_txc; // From tx_dq0 of tx_dequeue.v + output [63:0] xgmii_txd; // From tx_dq0 of tx_dequeue.v + output mdc; + output mdio_out; + output mdio_tri; // Assert to tristate driver. + output [7:0] xge_gpo; + + wire ctrl_tx_enable; // From wishbone_if0 of wishbone_if.v + wire ctrl_tx_enable_ctx; // From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v + wire status_local_fault_ctx; // From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v + wire status_remote_fault_ctx;// From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.v + wire status_crc_error; // From sync_clk_wb0 of sync_clk_wb.v + wire status_crc_error_tog; // From rx_eq0 of rx_enqueue.v + wire status_fragment_error; // From sync_clk_wb0 of sync_clk_wb.v + wire status_fragment_error_tog;// From rx_eq0 of rx_enqueue.v + wire status_local_fault; // From sync_clk_wb0 of sync_clk_wb.v + wire status_local_fault_crx; // From fault_sm0 of fault_sm.v + wire status_pause_frame_rx; // From sync_clk_wb0 of sync_clk_wb.v + wire status_pause_frame_rx_tog;// From rx_eq0 of rx_enqueue.v + wire status_remote_fault; // From sync_clk_wb0 of sync_clk_wb.v + wire status_remote_fault_crx;// From fault_sm0 of fault_sm.v + wire status_rxdfifo_ovflow; // From sync_clk_wb0 of sync_clk_wb.v + wire status_rxdfifo_ovflow_tog;// From rx_eq0 of rx_enqueue.v + wire status_rxdfifo_udflow; // From sync_clk_wb0 of sync_clk_wb.v + wire status_rxdfifo_udflow_tog;// From rx_dq0 of rx_dequeue.v + wire status_txdfifo_ovflow; // From sync_clk_wb0 of sync_clk_wb.v + wire status_txdfifo_ovflow_tog;// From tx_eq0 of tx_enqueue.v + wire status_txdfifo_udflow; // From sync_clk_wb0 of sync_clk_wb.v + wire status_txdfifo_udflow_tog;// From tx_dq0 of tx_dequeue.v + + xge_mac xge_mac ( + // Clocks and Resets + .clk_156m25 (clk_156m25), + .clk_xgmii_rx (clk_xgmii_rx), + .clk_xgmii_tx (clk_xgmii_tx), + .reset_156m25_n (reset_156m25_n), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + // XGMII + .xgmii_txc (xgmii_txc[7:0]), + .xgmii_txd (xgmii_txd[63:0]), + .xgmii_rxc (xgmii_rxc[7:0]), + .xgmii_rxd (xgmii_rxd[63:0]), + // Packet interface + .pkt_rx_avail (pkt_rx_avail), + .pkt_rx_data (pkt_rx_data), + .pkt_rx_eop (pkt_rx_eop), + .pkt_rx_err (pkt_rx_err), + .pkt_rx_mod (pkt_rx_mod), + .pkt_rx_sop (pkt_rx_sop), + .pkt_rx_val (pkt_rx_val), + .pkt_tx_full (pkt_tx_full), + // Inputs + .pkt_rx_ren (pkt_rx_ren), + .pkt_tx_data (pkt_tx_data), + .pkt_tx_eop (pkt_tx_eop), + .pkt_tx_mod (pkt_tx_mod), + .pkt_tx_sop (pkt_tx_sop), + .pkt_tx_val (pkt_tx_val), + // Control and Status + .ctrl_tx_enable (ctrl_tx_enable), + .status_crc_error (status_crc_error_tog), + .status_fragment_error (status_fragment_error_tog), + .status_txdfifo_ovflow (status_txdfifo_ovflow_tog), + .status_txdfifo_udflow (status_txdfifo_udflow_tog), + .status_rxdfifo_ovflow (status_rxdfifo_ovflow_tog), + .status_rxdfifo_udflow (status_rxdfifo_udflow_tog), + .status_pause_frame_rx (status_pause_frame_rx_tog), + .status_local_fault (status_local_fault_crx), + .status_remote_fault (status_remote_fault_crx) + ); + + sync_clk_wb sync_clk_wb0 ( + // Outputs + .status_crc_error (status_crc_error), + .status_fragment_error (status_fragment_error), + .status_txdfifo_ovflow (status_txdfifo_ovflow), + .status_txdfifo_udflow (status_txdfifo_udflow), + .status_rxdfifo_ovflow (status_rxdfifo_ovflow), + .status_rxdfifo_udflow (status_rxdfifo_udflow), + .status_pause_frame_rx (status_pause_frame_rx), + .status_local_fault (status_local_fault), + .status_remote_fault (status_remote_fault), + // Inputs + .wb_clk_i (wb_clk_i), + .wb_rst_i (wb_rst_i), + .status_crc_error_tog (status_crc_error_tog), + .status_fragment_error_tog(status_fragment_error_tog), + .status_txdfifo_ovflow_tog(status_txdfifo_ovflow_tog), + .status_txdfifo_udflow_tog(status_txdfifo_udflow_tog), + .status_rxdfifo_ovflow_tog(status_rxdfifo_ovflow_tog), + .status_rxdfifo_udflow_tog(status_rxdfifo_udflow_tog), + .status_pause_frame_rx_tog(status_pause_frame_rx_tog), + .status_local_fault_crx(status_local_fault_crx), + .status_remote_fault_crx(status_remote_fault_crx) + ); + + +// IJB. This module has only inputs and is treated as a black box by XST which causes a fatal error. +// Commented out. Original pupose/intent unknown. +//sync_clk_core sync_clk_core0(/*AUTOINST*/ +// // Inputs +// .clk_xgmii_tx (clk_xgmii_tx), +// .reset_xgmii_tx_n (reset_xgmii_tx_n)); + wishbone_if wishbone_if0 ( + // Outputs + .wb_dat_o (wb_dat_o[31:0]), + .wb_ack_o (wb_ack_o), + .wb_int_o (wb_int_o), + .ctrl_tx_enable (ctrl_tx_enable), + // Inputs + .wb_clk_i (wb_clk_i), + .wb_rst_i (wb_rst_i), + .wb_adr_i (wb_adr_i[7:0]), + .wb_dat_i (wb_dat_i[31:0]), + .wb_we_i (wb_we_i), + .wb_stb_i (wb_stb_i), + .wb_cyc_i (wb_cyc_i), + .status_crc_error (status_crc_error), + .status_fragment_error (status_fragment_error), + .status_txdfifo_ovflow (status_txdfifo_ovflow), + .status_txdfifo_udflow (status_txdfifo_udflow), + .status_rxdfifo_ovflow (status_rxdfifo_ovflow), + .status_rxdfifo_udflow (status_rxdfifo_udflow), + .status_pause_frame_rx (status_pause_frame_rx), + .status_local_fault (status_local_fault), + .status_remote_fault (status_remote_fault), + // MDIO + .mdc(mdc), + .mdio_in(mdio_in), + .mdio_out(mdio_out), + .mdio_tri(mdio_tri), + .xge_gpo(xge_gpo), + .xge_gpi(xge_gpi) + ); + +endmodule diff --git a/fpga/usrp3/lib/xge/sim/verilog/xge_mac.prj b/fpga/usrp3/lib/xge/sim/verilog/xge_mac.prj new file mode 100644 index 000000000..b99046a72 --- /dev/null +++ b/fpga/usrp3/lib/xge/sim/verilog/xge_mac.prj @@ -0,0 +1,43 @@ +verilog work ../../rtl/verilog/fault_sm.v -i ../../rtl/include + +verilog work ../../rtl/verilog/generic_mem_small.v -i ../../rtl/include + +verilog work ../../rtl/verilog/generic_mem_medium.v -i ../../rtl/include + +verilog work ../../rtl/verilog/generic_fifo_ctrl.v -i ../../rtl/include + +verilog work ../../rtl/verilog/generic_fifo.v -i ../../rtl/include + +verilog work ../../rtl/verilog/meta_sync.v -i ../../rtl/include + +verilog work ../../rtl/verilog/meta_sync_single.v -i ../../rtl/include + +verilog work ../../rtl/verilog/rx_hold_fifo.v -i ../../rtl/include + +verilog work ../../rtl/verilog/rx_data_fifo.v -i ../../rtl/include + +verilog work ../../rtl/verilog/rx_dequeue.v -i ../../rtl/include + +verilog work ../../rtl/verilog/rx_enqueue.v -i ../../rtl/include + +verilog work ../../rtl/verilog/sync_clk_core.v -i ../../rtl/include + +verilog work ../../rtl/verilog/sync_clk_wb.v -i ../../rtl/include + +verilog work ../../rtl/verilog/sync_clk_xgmii_tx.v -i ../../rtl/include + +verilog work ../../rtl/verilog/tx_hold_fifo.v -i ../../rtl/include + +verilog work ../../rtl/verilog/tx_data_fifo.v -i ../../rtl/include + +verilog work ../../rtl/verilog/tx_dequeue.v -i ../../rtl/include + +verilog work ../../rtl/verilog/tx_enqueue.v -i ../../rtl/include + +verilog work ../../rtl/verilog/wishbone_if.v -i ../../rtl/include + +verilog work ../../rtl/verilog/xge_mac.v -i ../../rtl/include + +verilog work ../../tbench/verilog/tb_xge_mac.v -i ../../rtl/include + + diff --git a/fpga/usrp3/lib/xge/tbench/verilog/packets_tx.txt b/fpga/usrp3/lib/xge/tbench/verilog/packets_tx.txt new file mode 100644 index 000000000..8e8411c97 --- /dev/null +++ b/fpga/usrp3/lib/xge/tbench/verilog/packets_tx.txt @@ -0,0 +1,73 @@ +SEND_PKT +59 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c + +SEND_PKT +60 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d + +SEND_PKT +61 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e + +SEND_PKT +62 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f + +SEND_PKT +63 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 + +SEND_PKT +64 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 + +SEND_PKT +65 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 +32 + +SEND_PKT +66 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 +32 33 + +SEND_PKT +67 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 +32 33 34 + +SEND_PKT +68 +00 00 01 00 00 01 00 10 94 00 00 02 88 b5 00 01 +02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 +22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 +32 33 34 35 diff --git a/fpga/usrp3/lib/xge/tbench/verilog/tb_xge_mac.v b/fpga/usrp3/lib/xge/tbench/verilog/tb_xge_mac.v new file mode 100644 index 000000000..bb3de297c --- /dev/null +++ b/fpga/usrp3/lib/xge/tbench/verilog/tb_xge_mac.v @@ -0,0 +1,514 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "tb_xge_mac.v" //// +//// //// +//// This file is part of the "10GE MAC" project //// +//// http://www.opencores.org/cores/xge_mac/ //// +//// //// +//// Author(s): //// +//// - A. Tanguay (antanguay@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 AUTHORS. All rights reserved. //// +//// //// +//// 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" +`include "defines.v" + +//`define GXB +//`define XIL + +module tb; + + +/*AUTOREG*/ + +reg [7:0] tx_buffer[0:10000]; +integer tx_length; + +reg clk_156m25; +reg clk_312m50; +reg clk_xgmii_rx; +reg clk_xgmii_tx; + +reg reset_156m25_n; +reg reset_xgmii_rx_n; +reg reset_xgmii_tx_n; + +reg pkt_rx_ren; + +reg [63:0] pkt_tx_data; +reg pkt_tx_val; +reg pkt_tx_sop; +reg pkt_tx_eop; +reg [2:0] pkt_tx_mod; + +/*AUTOWIRE*/ +// Beginning of automatic wires (for undeclared instantiated-module outputs) +wire pkt_rx_avail; // From dut of xge_mac.v +wire [63:0] pkt_rx_data; // From dut of xge_mac.v +wire pkt_rx_eop; // From dut of xge_mac.v +wire pkt_rx_err; // From dut of xge_mac.v +wire [2:0] pkt_rx_mod; // From dut of xge_mac.v +wire pkt_rx_sop; // From dut of xge_mac.v +wire pkt_rx_val; // From dut of xge_mac.v +wire pkt_tx_full; // From dut of xge_mac.v +wire wb_ack_o; // From dut of xge_mac.v +wire [31:0] wb_dat_o; // From dut of xge_mac.v +wire wb_int_o; // From dut of xge_mac.v +wire [7:0] xgmii_txc; // From dut of xge_mac.v +wire [63:0] xgmii_txd; // From dut of xge_mac.v +// End of automatics + +wire [7:0] wb_adr_i; +wire [31:0] wb_dat_i; + +wire [7:0] xgmii_rxc; +wire [63:0] xgmii_rxd; + +wire [3:0] tx_dataout; + +wire xaui_tx_l0_n; +wire xaui_tx_l0_p; +wire xaui_tx_l1_n; +wire xaui_tx_l1_p; +wire xaui_tx_l2_n; +wire xaui_tx_l2_p; +wire xaui_tx_l3_n; +wire xaui_tx_l3_p; + +xge_mac dut(/*AUTOINST*/ + // Outputs + .pkt_rx_avail (pkt_rx_avail), + .pkt_rx_data (pkt_rx_data[63:0]), + .pkt_rx_eop (pkt_rx_eop), + .pkt_rx_err (pkt_rx_err), + .pkt_rx_mod (pkt_rx_mod[2:0]), + .pkt_rx_sop (pkt_rx_sop), + .pkt_rx_val (pkt_rx_val), + .pkt_tx_full (pkt_tx_full), + .wb_ack_o (wb_ack_o), + .wb_dat_o (wb_dat_o[31:0]), + .wb_int_o (wb_int_o), + .xgmii_txc (xgmii_txc[7:0]), + .xgmii_txd (xgmii_txd[63:0]), + // Inputs + .clk_156m25 (clk_156m25), + .clk_xgmii_rx (clk_xgmii_rx), + .clk_xgmii_tx (clk_xgmii_tx), + .pkt_rx_ren (pkt_rx_ren), + .pkt_tx_data (pkt_tx_data[63:0]), + .pkt_tx_eop (pkt_tx_eop), + .pkt_tx_mod (pkt_tx_mod[2:0]), + .pkt_tx_sop (pkt_tx_sop), + .pkt_tx_val (pkt_tx_val), + .reset_156m25_n (reset_156m25_n), + .reset_xgmii_rx_n (reset_xgmii_rx_n), + .reset_xgmii_tx_n (reset_xgmii_tx_n), + .wb_adr_i (wb_adr_i[7:0]), + .wb_clk_i (wb_clk_i), + .wb_cyc_i (wb_cyc_i), + .wb_dat_i (wb_dat_i[31:0]), + .wb_rst_i (wb_rst_i), + .wb_stb_i (wb_stb_i), + .wb_we_i (wb_we_i), + .xgmii_rxc (xgmii_rxc[7:0]), + .xgmii_rxd (xgmii_rxd[63:0])); + +`ifdef GXB +// Example of transceiver instance +gxb gxb(// Outputs + .rx_ctrldetect ({xgmii_rxc[7], + xgmii_rxc[5], + xgmii_rxc[3], + xgmii_rxc[1], + xgmii_rxc[6], + xgmii_rxc[4], + xgmii_rxc[2], + xgmii_rxc[0]}), + .rx_dataout ({xgmii_rxd[63:56], + xgmii_rxd[47:40], + xgmii_rxd[31:24], + xgmii_rxd[15:8], + xgmii_rxd[55:48], + xgmii_rxd[39:32], + xgmii_rxd[23:16], + xgmii_rxd[7:0]}), + .tx_dataout (tx_dataout[3:0]), + // Inputs + .pll_inclk (clk_156m25), + .rx_analogreset (~reset_156m25_n), + .rx_cruclk ({clk_156m25, clk_156m25, clk_156m25, clk_156m25}), + .rx_datain (tx_dataout[3:0]), + .rx_digitalreset (~reset_156m25_n), + .tx_ctrlenable ({xgmii_txc[7], + xgmii_txc[5], + xgmii_txc[3], + xgmii_txc[1], + xgmii_txc[6], + xgmii_txc[4], + xgmii_txc[2], + xgmii_txc[0]}), + .tx_datain ({xgmii_txd[63:56], + xgmii_txd[47:40], + xgmii_txd[31:24], + xgmii_txd[15:8], + xgmii_txd[55:48], + xgmii_txd[39:32], + xgmii_txd[23:16], + xgmii_txd[7:0]}), + .tx_digitalreset (~reset_156m25_n)); +`endif + +`ifdef XIL +// Example of transceiver instance +xaui_block xaui(// Outputs + .txoutclk (), + .xgmii_rxd (xgmii_rxd[63:0]), + .xgmii_rxc (xgmii_rxc[7:0]), + .xaui_tx_l0_p (xaui_tx_l0_p), + .xaui_tx_l0_n (xaui_tx_l0_n), + .xaui_tx_l1_p (xaui_tx_l1_p), + .xaui_tx_l1_n (xaui_tx_l1_n), + .xaui_tx_l2_p (xaui_tx_l2_p), + .xaui_tx_l2_n (xaui_tx_l2_n), + .xaui_tx_l3_p (xaui_tx_l3_p), + .xaui_tx_l3_n (xaui_tx_l3_n), + .txlock (), + .align_status (), + .sync_status (), + .mgt_tx_ready (), + .drp_o (), + .drp_rdy (), + .status_vector (), + // Inputs + .dclk (clk_156m25), + .clk156 (clk_156m25), + .clk312 (clk_312m50), + .refclk (clk_156m25), + .reset (~reset_156m25_n), + .reset156 (~reset_156m25_n), + .xgmii_txd (xgmii_txd[63:0]), + .xgmii_txc (xgmii_txc[7:0]), + .xaui_rx_l0_p (xaui_tx_l0_p), + .xaui_rx_l0_n (xaui_tx_l0_n), + .xaui_rx_l1_p (xaui_tx_l1_p), + .xaui_rx_l1_n (xaui_tx_l1_n), + .xaui_rx_l2_p (xaui_tx_l2_p), + .xaui_rx_l2_n (xaui_tx_l2_n), + .xaui_rx_l3_p (xaui_tx_l3_p), + .xaui_rx_l3_n (xaui_tx_l3_n), + .signal_detect (4'b1111), + .drp_addr (7'b0), + .drp_en (2'b0), + .drp_i (16'b0), + .drp_we (2'b0), + .configuration_vector (7'b0)); + +glbl glbl(); +`endif + +//--- +// Unused for this testbench + +assign wb_adr_i = 8'b0; +assign wb_clk_i = 1'b0; +assign wb_cyc_i = 1'b0; +assign wb_dat_i = 32'b0; +assign wb_rst_i = 1'b1; +assign wb_stb_i = 1'b0; +assign wb_we_i = 1'b0; + + +//--- +// XGMII Loopback +// This test is done with loopback on XGMII or using one of the tranceiver examples + +`ifndef GXB + `ifndef XIL + assign xgmii_rxc = xgmii_txc; + assign xgmii_rxd = xgmii_txd; + `endif +`endif + +//--- +// Clock generation + +initial begin + clk_156m25 = 1'b0; + clk_xgmii_rx = 1'b0; + clk_xgmii_tx = 1'b0; + forever begin + WaitPS(3200); + clk_156m25 = ~clk_156m25; + clk_xgmii_rx = ~clk_xgmii_rx; + clk_xgmii_tx = ~clk_xgmii_tx; + end +end + +initial begin + clk_312m50 = 1'b0; + forever begin + WaitPS(1600); + clk_312m50 = ~clk_312m50; + end +end + +//--- +// Reset Generation + +initial begin + reset_156m25_n = 1'b0; + reset_xgmii_rx_n = 1'b0; + reset_xgmii_tx_n = 1'b0; + WaitNS(20); + reset_156m25_n = 1'b1; + reset_xgmii_rx_n = 1'b1; + reset_xgmii_tx_n = 1'b1; +end + + +//--- +// Init signals + +initial begin + + for (tx_length = 0; tx_length <= 1000; tx_length = tx_length + 1) begin + tx_buffer[tx_length] = 0; + end + + pkt_rx_ren = 1'b0; + + pkt_tx_data = 64'b0; + pkt_tx_val = 1'b0; + pkt_tx_sop = 1'b0; + pkt_tx_eop = 1'b0; + pkt_tx_mod = 3'b0; + +end + +task WaitNS; + input [31:0] delay; + begin + #(1000*delay); + end +endtask + +task WaitPS; + input [31:0] delay; + begin + #(delay); + end +endtask + + +//--- +// Task to send a single packet + +task TxPacket; + integer i; + begin + + $display("Transmit packet with length: %d", tx_length); + + @(posedge clk_156m25); + WaitNS(1); + pkt_tx_val = 1'b1; + + for (i = 0; i < tx_length; i = i + 8) begin + + pkt_tx_sop = 1'b0; + pkt_tx_eop = 1'b0; + pkt_tx_mod = 2'b0; + + if (i == 0) pkt_tx_sop = 1'b1; + + if (i + 8 >= tx_length) begin + pkt_tx_eop = 1'b1; + pkt_tx_mod = tx_length % 8; + end + + pkt_tx_data[`LANE7] = tx_buffer[i]; + pkt_tx_data[`LANE6] = tx_buffer[i+1]; + pkt_tx_data[`LANE5] = tx_buffer[i+2]; + pkt_tx_data[`LANE4] = tx_buffer[i+3]; + pkt_tx_data[`LANE3] = tx_buffer[i+4]; + pkt_tx_data[`LANE2] = tx_buffer[i+5]; + pkt_tx_data[`LANE1] = tx_buffer[i+6]; + pkt_tx_data[`LANE0] = tx_buffer[i+7]; + + @(posedge clk_156m25); + WaitNS(1); + + end + + pkt_tx_val = 1'b0; + pkt_tx_eop = 1'b0; + pkt_tx_mod = 3'b0; + + end + +endtask + + +//--- +// Task to read a single packet from command file and transmit + +task CmdTxPacket; + input [31:0] file; + integer count; + integer data; + integer i; + begin + + count = $fscanf(file, "%2d", tx_length); + + if (count == 1) begin + + for (i = 0; i < tx_length; i = i + 1) begin + + count = $fscanf(file, "%2X", data); + if (count) begin + tx_buffer[i] = data; + end + + end + + TxPacket(); + + end + end + +endtask + + +//--- +// Task to read commands from file and stop when complete + +task ProcessCmdFile; + integer file_cmd; + integer count; + reg [8*8-1:0] str; + begin + + file_cmd = $fopen("../../tbench/verilog/packets_tx.txt", "r"); + if (!file_cmd) $stop; + + while (!$feof(file_cmd)) begin + + count = $fscanf(file_cmd, "%s", str); + // IJB. WTF! if (count != 1) $continue; + if (count === 1) // IJB. I think this is what's intended. + begin + + $display("CMD %s", str); + + case (str) + + "SEND_PKT": + begin + CmdTxPacket(file_cmd); + end + + endcase // case(str) + end + + end + + $fclose(file_cmd); + + WaitNS(50000); + $stop; + + end +endtask + +initial begin + WaitNS(5000); +`ifdef XIL + WaitNS(200000); +`endif + ProcessCmdFile(); +end + + +//--- +// Task to read a single packet from receive interface and display + +task RxPacket; + reg done; + begin + + done = 0; + + pkt_rx_ren <= 1'b1; + @(posedge clk_156m25); + + while (!done) begin + + if (pkt_rx_val) begin + + if (pkt_rx_sop) begin + $display("\n\n------------------------"); + end + + $display("%x", pkt_rx_data); + + if (pkt_rx_eop) begin + done <= 1; + pkt_rx_ren <= 1'b0; + end + + if (pkt_rx_eop) begin + $display("------------------------\n\n"); + end + + end + + @(posedge clk_156m25); + + end + + end +endtask + +initial begin + + forever begin + + if (pkt_rx_avail) begin + RxPacket(); + end + + @(posedge clk_156m25); + + end + +end + +endmodule +
\ No newline at end of file |