diff options
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.pdfBinary files differ new 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 | 
