2023-03-17 19:35:37 -05:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-Only OR CERN-OHL-S-2.0
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2022 Sean Anderson <seanga2@gmail.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
`include "common.vh"
|
|
|
|
|
|
|
|
`timescale 1ns/1ps
|
|
|
|
|
|
|
|
module phy_core (
|
|
|
|
input clk,
|
|
|
|
|
|
|
|
/* "PMD" */
|
|
|
|
output tx_data,
|
|
|
|
input [1:0] rx_data,
|
|
|
|
input [1:0] rx_data_valid,
|
|
|
|
input signal_status,
|
|
|
|
|
|
|
|
/* "MII" */
|
|
|
|
input tx_ce,
|
|
|
|
input tx_en,
|
|
|
|
input [3:0] txd,
|
|
|
|
input tx_er,
|
|
|
|
|
|
|
|
output rx_ce,
|
|
|
|
output rx_dv,
|
|
|
|
output [3:0] rxd,
|
|
|
|
output rx_er,
|
|
|
|
|
|
|
|
output reg crs,
|
|
|
|
output reg col,
|
|
|
|
|
2023-02-20 17:37:06 -06:00
|
|
|
/* Control/status */
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
input loopback,
|
|
|
|
input coltest,
|
|
|
|
input link_monitor_test_mode,
|
|
|
|
input descrambler_test_mode,
|
|
|
|
output locked,
|
2023-02-20 17:37:06 -06:00
|
|
|
output reg link_status,
|
|
|
|
output receiving,
|
|
|
|
output reg false_carrier,
|
|
|
|
output reg symbol_error
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
wire tx_bits, transmitting;
|
|
|
|
|
|
|
|
pcs_tx pcs_tx (
|
|
|
|
.clk(clk),
|
|
|
|
.ce(tx_ce),
|
|
|
|
.enable(tx_en),
|
|
|
|
.data(txd),
|
|
|
|
.err(tx_er),
|
|
|
|
.bits(tx_bits),
|
|
|
|
.link_status(link_status),
|
|
|
|
.tx(transmitting)
|
|
|
|
);
|
|
|
|
|
|
|
|
scramble scrambler (
|
|
|
|
.clk(clk),
|
|
|
|
.unscrambled(tx_bits),
|
|
|
|
.scrambled(tx_data)
|
|
|
|
);
|
|
|
|
|
|
|
|
reg descrambler_enable, loopback_last;
|
|
|
|
initial loopback_last = 0;
|
|
|
|
wire [1:0] rx_bits, rx_bits_valid;
|
|
|
|
|
|
|
|
/* Force desynchronization when entering/exiting loopback */
|
|
|
|
always @(*) begin
|
|
|
|
if (loopback)
|
|
|
|
descrambler_enable = loopback_last;
|
|
|
|
else
|
|
|
|
descrambler_enable = signal_status && !loopback_last;
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge clk)
|
|
|
|
loopback_last <= loopback;
|
|
|
|
|
|
|
|
descramble descrambler (
|
|
|
|
.clk(clk),
|
|
|
|
.signal_status(descrambler_enable),
|
|
|
|
.scrambled(rx_data),
|
|
|
|
.scrambled_valid(rx_data_valid),
|
|
|
|
.descrambled(rx_bits),
|
|
|
|
.descrambled_valid(rx_bits_valid),
|
|
|
|
.test_mode(descrambler_test_mode),
|
|
|
|
.locked(locked)
|
|
|
|
);
|
|
|
|
|
|
|
|
/*
|
2023-03-15 12:44:20 -05:00
|
|
|
* $ scripts/lfsr.py 0x12000 41250 16
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
*
|
2023-03-15 12:44:20 -05:00
|
|
|
* 41250 cycles or 330 us at 125MHz
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
*/
|
2023-03-15 12:44:20 -05:00
|
|
|
localparam STABILIZE_VALUE = 17'h1590c;
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
/* 16 cycles; there's no instability while testing */
|
2023-03-15 12:44:20 -05:00
|
|
|
localparam TEST_STABILIZE_VALUE = 17'h038e3;
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
|
|
|
|
reg link_status_next;
|
|
|
|
initial link_status = 0;
|
|
|
|
reg [16:0] stabilize_timer, stabilize_timer_next;
|
|
|
|
initial stabilize_timer = STABILIZE_VALUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Link monitor process; this is the entirety of the (section 24.3) PMA
|
|
|
|
*
|
|
|
|
* Section 24.3.4.4 specifies that link_status is to be set to OK when
|
|
|
|
* stabilize_timer completes. However, I have also included whether
|
|
|
|
* the descrambler is locked. I think this matches the intent of the
|
|
|
|
* signal, which indicates whether "the receive channel is intact and
|
|
|
|
* enabled for reception."
|
|
|
|
*/
|
|
|
|
|
|
|
|
always @(*) begin
|
|
|
|
link_status_next = 0;
|
|
|
|
stabilize_timer_next = stabilize_timer;
|
|
|
|
|
|
|
|
if (signal_status) begin
|
|
|
|
if (&stabilize_timer) begin
|
|
|
|
link_status_next = locked;
|
|
|
|
end else begin
|
|
|
|
stabilize_timer_next[0] = stabilize_timer[16] ^ stabilize_timer[13];
|
|
|
|
stabilize_timer_next[16:1] = stabilize_timer[15:0];
|
|
|
|
end
|
|
|
|
end else if (link_monitor_test_mode) begin
|
|
|
|
stabilize_timer_next = TEST_STABILIZE_VALUE;
|
|
|
|
end else begin
|
|
|
|
stabilize_timer_next = STABILIZE_VALUE;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (loopback)
|
|
|
|
stabilize_timer_next = 17'h1ffff;
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge clk) begin
|
|
|
|
stabilize_timer <= stabilize_timer_next;
|
|
|
|
link_status <= link_status_next;
|
|
|
|
end
|
|
|
|
|
|
|
|
pcs_rx pcs_rx (
|
|
|
|
.clk(clk),
|
|
|
|
.ce(rx_ce),
|
|
|
|
.valid(rx_dv),
|
|
|
|
.data(rxd),
|
|
|
|
.err(rx_er),
|
|
|
|
.bits(rx_bits),
|
|
|
|
.bits_valid(rx_bits_valid),
|
|
|
|
.link_status(link_status),
|
|
|
|
.rx(receiving)
|
|
|
|
);
|
|
|
|
|
|
|
|
/*
|
2023-02-20 17:37:06 -06:00
|
|
|
* NB: CRS and COL are not required to be in any particular clock
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
* domain (not that it matters).
|
|
|
|
*/
|
|
|
|
always @(*) begin
|
|
|
|
crs = transmitting || receiving;
|
2022-11-30 17:12:13 -06:00
|
|
|
col = transmitting && receiving;
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
if (coltest)
|
|
|
|
col = transmitting;
|
|
|
|
else if (loopback)
|
|
|
|
col = 0;
|
2023-02-20 17:37:06 -06:00
|
|
|
|
|
|
|
false_carrier = 0;
|
|
|
|
symbol_error = 0;
|
|
|
|
if (rx_ce && rx_er) begin
|
|
|
|
if (rx_dv)
|
|
|
|
symbol_error = 1;
|
|
|
|
else
|
|
|
|
false_carrier = 1;
|
|
|
|
end
|
Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.
We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.
Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).
On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:14:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|