pmd: Delay signal_status/detect until data is valid

The data yielded by the PMD is not really valid until it has made its
way through the pipeline. Delay it until the data is valid. As a side
effect, this should also eliminate any metastability. This is not
necessary for real hardware, but it allows us to to post-synthesis
simulation (where we can't reach in and probe the internal valid
signal).

Additionally, ensure that the state is known by resetting it when we
don't have a signal.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2022-08-06 15:36:27 -04:00
parent fafce4df00
commit d8ce1652ae
1 changed files with 18 additions and 4 deletions

View File

@ -23,13 +23,14 @@ module pmd (
input rx,
/* PMD */
output reg signal_status,
output signal_status,
input pmd_data_tx,
output reg [1:0] pmd_data_rx,
output reg [1:0] pmd_data_rx_valid
);
reg [1:0] rx_p, rx_n;
reg [3:0] sd_delay;
`ifdef SYNTHESIS
SB_IO #(
@ -38,7 +39,7 @@ module pmd (
) signal_detect_pin (
.PACKAGE_PIN(signal_detect),
.INPUT_CLK(rx_clk_125),
.D_IN_0(signal_status)
.D_IN_0(sd_delay[0])
);
SB_IO #(
@ -52,7 +53,7 @@ module pmd (
);
`else
always @(posedge rx_clk_125)
signal_status <= signal_detect;
sd_delay[0] <= signal_detect;
always @(posedge rx_clk_250)
rx_p[0] <= rx;
@ -61,6 +62,17 @@ module pmd (
rx_n[0] <= rx;
`endif
/*
* Delay signal status until the known good data has had a chance to
* make it through the pipeline. This isn't necessary for real hardware
* (since signal status is asserted long after we have good data), but
* it helps out during simulation. It also helps avoid metastability.
*/
always @(posedge rx_clk_125)
sd_delay[3:1] <= sd_delay[2:0];
assign signal_status = sd_delay[3];
/*
* Get things into the rx_clk_250 domain so that we sample posedge before
* negedge. Without this we can have a negedge which happens before the
@ -135,8 +147,10 @@ module pmd (
else
valid_next = valid;
if (!signal_status)
if (!signal_status) begin
state_next = A;
valid_next = 0;
end
pmd_data_rx_next[0] = rx_d[2];
pmd_data_rx_valid_next = 1;