diff options
author | Ben Hilburn <ben.hilburn@ettus.com> | 2014-02-14 12:05:07 -0800 |
---|---|---|
committer | Ben Hilburn <ben.hilburn@ettus.com> | 2014-02-14 12:05:07 -0800 |
commit | ff1546f8137f7f92bb250f685561b0c34cc0e053 (patch) | |
tree | 7fa6fd05c8828df256a1b20e2935bd3ba9899e2c /fpga/usrp3/lib/xge | |
parent | 4f691d88123784c2b405816925f1a1aef69d18c1 (diff) | |
download | uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.gz uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.bz2 uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.zip |
Pushing the bulk of UHD-3.7.0 code.
Diffstat (limited to 'fpga/usrp3/lib/xge')
39 files changed, 7994 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..5af520788 --- /dev/null +++ b/fpga/usrp3/lib/xge/Makefile.srcs @@ -0,0 +1,29 @@ +################################################## +# 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 \ +)) + 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..72fe01de2 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/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 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 +`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..e1961eb78 --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v @@ -0,0 +1,1047 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// 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, + `ifdef MDIO + mdc, mdio_out, mdio_tri, xge_gpo, + `endif + + // 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 + `ifdef MDIO + ,mdio_in, xge_gpi + `endif + ); + + +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; + + `ifdef MDIO + 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; + + +`endif + + +/*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; + +`ifdef MDIO + 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; + +`endif + + +/*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 + +assign ctrl_tx_enable = cpureg_config0[0]; + + + +//--- +// 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; + +`ifdef MDIO + mdio_address <= 0; + mdio_operation <= 0; + mdio_write_data <= 0; + + mdio_running <= 0; + xge_gpi_reg <= 0; + xge_gpo <= 0; + xge_gpo_reg <= 0; + + +`endif + + + // 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; + +`ifdef MDIO + // 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; + + +`endif + //--- + // 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 + + `ifdef MDIO + `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 + + `endif + + 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 + +`ifdef MDIO + `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 + +`endif // `ifdef MDIO + + default: begin + end + + endcase + + end + + end + +end // always @ (posedge wb_clk_i or posedge wb_rst_i) + +`ifdef MDIO + // + // 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) + + + +`endif // ifdef MDIO + +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..2b750cd0e --- /dev/null +++ b/fpga/usrp3/lib/xge/rtl/verilog/xge_mac.v @@ -0,0 +1,423 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// 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 //// +//// //// +////////////////////////////////////////////////////////////////////// + + +`include "defines.v" + +module xge_mac(/*AUTOARG*/ + // Outputs + xgmii_txd, xgmii_txc, wb_int_o, wb_dat_o, wb_ack_o, pkt_tx_full, + pkt_rx_val, pkt_rx_sop, pkt_rx_mod, pkt_rx_err, pkt_rx_eop, + pkt_rx_data, pkt_rx_avail, + `ifdef MDIO + mdc, mdio_out, mdio_tri, xge_gpo, + `endif + // 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 + `ifdef MDIO + ,mdio_in, xge_gpi + `endif + ); + +/*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] 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 +`ifdef MDIO +input mdio_in; +input [7:0] xge_gpi; + +`endif + +// 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 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 +`ifdef MDIO +output mdc; +output mdio_out; +output mdio_tri; // Assert to tristate driver. +output [7:0] xge_gpo; + +`endif + +// End of automatics + +/*AUTOWIRE*/ +// Beginning of automatic wires (for undeclared instantiated-module outputs) +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 [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_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_local_fault_ctx; // From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.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_remote_fault_ctx;// From sync_clk_xgmii_tx0 of sync_clk_xgmii_tx.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 +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_tog), + .status_fragment_error_tog(status_fragment_error_tog), + .status_rxdfifo_ovflow_tog(status_rxdfifo_ovflow_tog), + .status_pause_frame_rx_tog(status_pause_frame_rx_tog), + // 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_tog), + // 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_tog), + // 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_tog), + // 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_crx), + .status_remote_fault_crx(status_remote_fault_crx), + // 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_wb sync_clk_wb0(/*AUTOINST*/ + // 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)); + +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_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(/*AUTOINST*/ + // 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) + // Customization + `ifdef MDIO + ,.mdc(mdc), + .mdio_in(mdio_in), + .mdio_out(mdio_out), + .mdio_tri(mdio_tri), + .xge_gpo(xge_gpo), + .xge_gpi(xge_gpi) + `endif +); + +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 |