-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
eth: Add 10G PHY module and testbench
Signed-off-by: Alex Forencich <[email protected]>
- Loading branch information
1 parent
c6ea407
commit e35d2b2
Showing
16 changed files
with
1,553 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
taxi_eth_phy_10g.sv | ||
taxi_eth_phy_10g_rx.f | ||
taxi_eth_phy_10g_tx.f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// SPDX-License-Identifier: CERN-OHL-S-2.0 | ||
/* | ||
Copyright (c) 2018-2025 FPGA Ninja, LLC | ||
Authors: | ||
- Alex Forencich | ||
*/ | ||
|
||
`resetall | ||
`timescale 1ns / 1ps | ||
`default_nettype none | ||
|
||
/* | ||
* 10G Ethernet PHY | ||
*/ | ||
module taxi_eth_phy_10g # | ||
( | ||
parameter DATA_W = 64, | ||
parameter CTRL_W = (DATA_W/8), | ||
parameter HDR_W = 2, | ||
parameter logic BIT_REVERSE = 1'b0, | ||
parameter logic SCRAMBLER_DISABLE = 1'b0, | ||
parameter logic PRBS31_EN = 1'b0, | ||
parameter TX_SERDES_PIPELINE = 0, | ||
parameter RX_SERDES_PIPELINE = 0, | ||
parameter BITSLIP_HIGH_CYCLES = 1, | ||
parameter BITSLIP_LOW_CYCLES = 7, | ||
parameter COUNT_125US = 125000/6.4 | ||
) | ||
( | ||
input wire logic rx_clk, | ||
input wire logic rx_rst, | ||
input wire logic tx_clk, | ||
input wire logic tx_rst, | ||
|
||
/* | ||
* XGMII interface | ||
*/ | ||
input wire logic [DATA_W-1:0] xgmii_txd, | ||
input wire logic [CTRL_W-1:0] xgmii_txc, | ||
output wire logic [DATA_W-1:0] xgmii_rxd, | ||
output wire logic [CTRL_W-1:0] xgmii_rxc, | ||
|
||
/* | ||
* SERDES interface | ||
*/ | ||
output wire logic [DATA_W-1:0] serdes_tx_data, | ||
output wire logic [HDR_W-1:0] serdes_tx_hdr, | ||
input wire logic [DATA_W-1:0] serdes_rx_data, | ||
input wire logic [HDR_W-1:0] serdes_rx_hdr, | ||
output wire logic serdes_rx_bitslip, | ||
output wire logic serdes_rx_reset_req, | ||
|
||
/* | ||
* Status | ||
*/ | ||
output wire logic tx_bad_block, | ||
output wire logic [6:0] rx_error_count, | ||
output wire logic rx_bad_block, | ||
output wire logic rx_sequence_error, | ||
output wire logic rx_block_lock, | ||
output wire logic rx_high_ber, | ||
output wire logic rx_status, | ||
|
||
/* | ||
* Configuration | ||
*/ | ||
input wire logic cfg_tx_prbs31_enable = 1'b0, | ||
input wire logic cfg_rx_prbs31_enable = 1'b0 | ||
); | ||
|
||
taxi_eth_phy_10g_rx #( | ||
.DATA_W(DATA_W), | ||
.CTRL_W(CTRL_W), | ||
.HDR_W(HDR_W), | ||
.BIT_REVERSE(BIT_REVERSE), | ||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), | ||
.PRBS31_EN(PRBS31_EN), | ||
.SERDES_PIPELINE(RX_SERDES_PIPELINE), | ||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), | ||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), | ||
.COUNT_125US(COUNT_125US) | ||
) | ||
eth_phy_10g_rx_inst ( | ||
.clk(rx_clk), | ||
.rst(rx_rst), | ||
|
||
/* | ||
* XGMII interface | ||
*/ | ||
.xgmii_rxd(xgmii_rxd), | ||
.xgmii_rxc(xgmii_rxc), | ||
|
||
/* | ||
* SERDES interface | ||
*/ | ||
.serdes_rx_data(serdes_rx_data), | ||
.serdes_rx_hdr(serdes_rx_hdr), | ||
.serdes_rx_bitslip(serdes_rx_bitslip), | ||
.serdes_rx_reset_req(serdes_rx_reset_req), | ||
|
||
/* | ||
* Status | ||
*/ | ||
.rx_error_count(rx_error_count), | ||
.rx_bad_block(rx_bad_block), | ||
.rx_sequence_error(rx_sequence_error), | ||
.rx_block_lock(rx_block_lock), | ||
.rx_high_ber(rx_high_ber), | ||
.rx_status(rx_status), | ||
|
||
/* | ||
* Configuration | ||
*/ | ||
.cfg_rx_prbs31_enable(cfg_rx_prbs31_enable) | ||
); | ||
|
||
taxi_eth_phy_10g_tx #( | ||
.DATA_W(DATA_W), | ||
.CTRL_W(CTRL_W), | ||
.HDR_W(HDR_W), | ||
.BIT_REVERSE(BIT_REVERSE), | ||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), | ||
.PRBS31_EN(PRBS31_EN), | ||
.SERDES_PIPELINE(TX_SERDES_PIPELINE) | ||
) | ||
eth_phy_10g_tx_inst ( | ||
.clk(tx_clk), | ||
.rst(tx_rst), | ||
|
||
/* | ||
* XGMII interface | ||
*/ | ||
.xgmii_txd(xgmii_txd), | ||
.xgmii_txc(xgmii_txc), | ||
|
||
/* | ||
* SERDES interface | ||
*/ | ||
.serdes_tx_data(serdes_tx_data), | ||
.serdes_tx_hdr(serdes_tx_hdr), | ||
|
||
/* | ||
* Status | ||
*/ | ||
.tx_bad_block(tx_bad_block), | ||
|
||
/* | ||
* Configuration | ||
*/ | ||
.cfg_tx_prbs31_enable(cfg_tx_prbs31_enable) | ||
); | ||
|
||
endmodule | ||
|
||
`resetall |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
taxi_eth_phy_10g_rx.sv | ||
taxi_eth_phy_10g_rx_if.f | ||
taxi_xgmii_baser_dec_64.sv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// SPDX-License-Identifier: CERN-OHL-S-2.0 | ||
/* | ||
Copyright (c) 2018-2025 FPGA Ninja, LLC | ||
Authors: | ||
- Alex Forencich | ||
*/ | ||
|
||
`resetall | ||
`timescale 1ns / 1ps | ||
`default_nettype none | ||
|
||
/* | ||
* 10G Ethernet PHY RX | ||
*/ | ||
module taxi_eth_phy_10g_rx # | ||
( | ||
parameter DATA_W = 64, | ||
parameter CTRL_W = (DATA_W/8), | ||
parameter HDR_W = 2, | ||
parameter logic BIT_REVERSE = 1'b0, | ||
parameter logic SCRAMBLER_DISABLE = 1'b0, | ||
parameter logic PRBS31_EN = 1'b0, | ||
parameter SERDES_PIPELINE = 0, | ||
parameter BITSLIP_HIGH_CYCLES = 1, | ||
parameter BITSLIP_LOW_CYCLES = 7, | ||
parameter COUNT_125US = 125000/6.4 | ||
) | ||
( | ||
input wire logic clk, | ||
input wire logic rst, | ||
|
||
/* | ||
* XGMII interface | ||
*/ | ||
output wire logic [DATA_W-1:0] xgmii_rxd, | ||
output wire logic [CTRL_W-1:0] xgmii_rxc, | ||
|
||
/* | ||
* SERDES interface | ||
*/ | ||
input wire logic [DATA_W-1:0] serdes_rx_data, | ||
input wire logic [HDR_W-1:0] serdes_rx_hdr, | ||
output wire logic serdes_rx_bitslip, | ||
output wire logic serdes_rx_reset_req, | ||
|
||
/* | ||
* Status | ||
*/ | ||
output wire logic [6:0] rx_error_count, | ||
output wire logic rx_bad_block, | ||
output wire logic rx_sequence_error, | ||
output wire logic rx_block_lock, | ||
output wire logic rx_high_ber, | ||
output wire logic rx_status, | ||
|
||
/* | ||
* Configuration | ||
*/ | ||
input wire logic cfg_rx_prbs31_enable | ||
); | ||
|
||
// check configuration | ||
if (DATA_W != 64) | ||
$fatal(0, "Error: Interface width must be 64"); | ||
|
||
if (CTRL_W * 8 != DATA_W) | ||
$fatal(0, "Error: Interface requires byte (8-bit) granularity"); | ||
|
||
if (HDR_W != 2) | ||
$fatal(0, "Error: HDR_W must be 2"); | ||
|
||
wire [DATA_W-1:0] encoded_rx_data; | ||
wire [HDR_W-1:0] encoded_rx_hdr; | ||
|
||
taxi_eth_phy_10g_rx_if #( | ||
.DATA_W(DATA_W), | ||
.HDR_W(HDR_W), | ||
.BIT_REVERSE(BIT_REVERSE), | ||
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), | ||
.PRBS31_EN(PRBS31_EN), | ||
.SERDES_PIPELINE(SERDES_PIPELINE), | ||
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), | ||
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), | ||
.COUNT_125US(COUNT_125US) | ||
) | ||
eth_phy_10g_rx_if_inst ( | ||
.clk(clk), | ||
.rst(rst), | ||
|
||
/* | ||
* 10GBASE-R encoded interface | ||
*/ | ||
.encoded_rx_data(encoded_rx_data), | ||
.encoded_rx_hdr(encoded_rx_hdr), | ||
|
||
/* | ||
* SERDES interface | ||
*/ | ||
.serdes_rx_data(serdes_rx_data), | ||
.serdes_rx_hdr(serdes_rx_hdr), | ||
.serdes_rx_bitslip(serdes_rx_bitslip), | ||
.serdes_rx_reset_req(serdes_rx_reset_req), | ||
|
||
/* | ||
* Status | ||
*/ | ||
.rx_bad_block(rx_bad_block), | ||
.rx_sequence_error(rx_sequence_error), | ||
.rx_error_count(rx_error_count), | ||
.rx_block_lock(rx_block_lock), | ||
.rx_high_ber(rx_high_ber), | ||
.rx_status(rx_status), | ||
|
||
/* | ||
* Configuration | ||
*/ | ||
.cfg_rx_prbs31_enable(cfg_rx_prbs31_enable) | ||
); | ||
|
||
taxi_xgmii_baser_dec_64 #( | ||
.DATA_W(DATA_W), | ||
.CTRL_W(CTRL_W), | ||
.HDR_W(HDR_W) | ||
) | ||
xgmii_baser_dec_inst ( | ||
.clk(clk), | ||
.rst(rst), | ||
|
||
/* | ||
* 10GBASE-R encoded input | ||
*/ | ||
.encoded_rx_data(encoded_rx_data), | ||
.encoded_rx_hdr(encoded_rx_hdr), | ||
|
||
/* | ||
* XGMII interface | ||
*/ | ||
.xgmii_rxd(xgmii_rxd), | ||
.xgmii_rxc(xgmii_rxc), | ||
|
||
/* | ||
* Status | ||
*/ | ||
.rx_bad_block(rx_bad_block), | ||
.rx_sequence_error(rx_sequence_error) | ||
); | ||
|
||
endmodule | ||
|
||
`resetall |
Oops, something went wrong.