UberDDR3/delete_later/rtl/hdmi/synccount.v

120 lines
3.3 KiB
Verilog

////////////////////////////////////////////////////////////////////////////////
//
// Filename: synccount.v
// {{{
// Project: 10Gb Ethernet switch
//
// Purpose:
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
// }}}
// Copyright (C) 2023, Gisselquist Technology, LLC
// {{{
// This file is part of the ETH10G project.
//
// The ETH10G project contains free software and gateware, licensed under the
// Apache License, Version 2.0 (the "License"). You may not use this project,
// or this file, except in compliance with the License. You may obtain a copy
// of the License at
// }}}
// http://www.apache.org/licenses/LICENSE-2.0
// {{{
// Unless required by applicable law or agreed to in writing, files
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//
////////////////////////////////////////////////////////////////////////////////
//
//
`default_nettype none
// }}}
module synccount #(
// {{{
// (i_clk, i_reset, i_v, i_val, o_val);
// NBITS -- num bits required to desecribe the sync location
parameter NBITS=16,
// QUALITY_BITS --require 2^QUALITY_BITS successful observations
parameter QUALITY_BITS=3,
// INITIAL_GOOD -- do we expect a particular sync? Y/N
parameter [0:0] INITIAL_GOOD = 1'b0,
// INITIAL_VALUE-- what initial sync location is expected
parameter [(NBITS-1):0] INITIAL_VALUE = 0,
// INITIAL_COUNT-- how much credibility for initial location
parameter [QUALITY_BITS-1:0] INITIAL_COUNT = 0,
// Shall we just bypass the quality test completely?
parameter [0:0] OPT_BYPASS_TEST = 1'b0
// }}}
) (
// {{{
input wire i_clk, i_reset,
//
// i_v - valid sync indicator. If (whatever) synchronization
// is found at position i_val in the stream, then i_v will be
// set. We'll see how often it gets set to know if this is
// (or isn't) a repeatable measurement.
input wire i_v,
input wire [NBITS-1:0] i_val,
output reg [NBITS-1:0] o_val
// }}}
);
generate if (OPT_BYPASS_TEST)
begin : BYPASS_CHECK
always @(posedge i_clk)
if (i_v)
o_val <= i_val;
end else begin : REQUIRE_QUALITY
reg inc, dec;
reg [QUALITY_BITS-1:0] ngood;
reg [(NBITS-1):0] r_val;
reg r_eq, no_val, r_v;
initial r_v = 1'b0;
always @(posedge i_clk)
r_v <= i_v;
initial r_eq = 1'b0;
always @(posedge i_clk)
r_eq <= (i_val == r_val);
initial no_val = (!INITIAL_GOOD);
always @(posedge i_clk)
no_val <= (ngood == 0);
initial r_val = INITIAL_VALUE;
always @(posedge i_clk)
if ((r_v)&&(no_val))
r_val <= i_val;
initial inc = 1'b0;
initial dec = 1'b0;
always @(posedge i_clk)
begin
inc <= (!i_reset)&&(r_v)&&((r_eq)||(no_val));
dec <= (!i_reset)&&(r_v)&&(!r_eq);
end
initial ngood = INITIAL_COUNT;
always @(posedge i_clk)
if (i_reset)
ngood <= 0;
else if ((inc)&&(!(&ngood)))
ngood <= ngood + 1'b1;
else if ((dec)&&(ngood != 0))
ngood <= ngood - 1'b1;
initial o_val = INITIAL_VALUE;
always @(posedge i_clk)
if (&ngood)
o_val <= r_val;
else if (ngood == 0)
o_val <= 0;
end endgenerate
endmodule