OpenCores
URL https://opencores.org/ocsvn/hdbn/hdbn/trunk

Subversion Repositories hdbn

[/] [hdbn/] [trunk/] [rtl/] [vhdl/] [hdbnd.vhd] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title        : hdbnd
-- Project      : hdbn
-------------------------------------------------------------------------------
-- File         : hdbnd.vhd
-- Author       : Allan Herriman <allanh@opencores.org>
-- Organization : Opencores
-- Created      : 9 Aug 1999
-- Platform     : ?
-- Simulators   : Any VHDL '87, '93 or '00 compliant simulator will work.
--                Tested with several versions of Modelsim and Simili.
-- Synthesizers : Any VHDL compliant synthesiser will work (tested with
--                Synplify Pro and Leonardo).
-- Targets      : Anything (contains no target dependent features except
--                combinatorial logic and D flip flops with async
--                reset or set).
-- Dependency   : None.  Complementary encoder is hdb3e.
-------------------------------------------------------------------------------
-- Description  : HDB3 or HDB2 (B3ZS) decoder.
--                Note: this module does not include clock recovery.
--                A separate CDR (Clock and Data Recovery) circuit must be
--                used.
--
--  HDB3 is typically used to encode data at 2.048, 8.448 and 34.368Mb/s
--  B3ZS is typically used to encode data at 44.736Mb/s
--  These encodings are polarity insensitive, so the P and N inputs may be
--  used interchangeably (swapped).
--
-- Reference    : ITU-T G.703
--
-------------------------------------------------------------------------------
-- Copyright (c) notice
-- http://www.opensource.org/licenses/bsd-license.html
--
-------------------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
--
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
 
entity hdbnd is
    generic (
        EncoderType             : integer range 2 to 3 := 3;   -- 3: HDB3 2: HDB2/B3ZS
        PulseActiveState        : std_logic := '1'          -- active state of P and N inputs
    );
    port (
        Reset_i                 : in    std_logic := '0';   -- active high async reset
        Clk_i                   : in    std_logic;          -- rising edge clock
        ClkEnable_i             : in    std_logic := '1';   -- active high clock enable
        P_i                     : in    std_logic;          -- +ve pulse input
        N_i                     : in    std_logic;          -- -ve pulse input
        Data_o                  : out   std_logic;          -- active high data output
        CodeError_o             : out   std_logic           -- active high error indicator
    );
end hdbnd; -- End entity hdbnd
 
 
architecture rtl of hdbnd is
 
    signal  PinRaw                  : std_logic;    -- registered P input
    signal  NinRaw                  : std_logic;    -- registered N input
    signal  Pin                     : std_logic;    -- registered P input (with polarity corrected)
    signal  Nin                     : std_logic;    -- registered N input (with polarity corrected)
    signal  Violation               : std_logic;    -- pulse violation detected
    signal  LastPulsePolarity       : std_logic;    -- last pulse sense 1=P, 0=N
    signal  LastViolationPolarity   : std_logic;    -- last violation sense "
 
    -- shift register bits (to align data with violations, so we can delete them)
    signal  Q1                      : std_logic;
    signal  Q2                      : std_logic;
    signal  Q3                      : std_logic;
 
    -- signals used for calculating CodeError
    signal  ViolationError          : std_logic;    -- indicates bad violation
    signal  ZeroCount               : integer range 0 to 3; -- counts 0s in input
    signal  TooManyZeros            : std_logic;    -- indicates 4 consecutive zeros detected
    signal  PulseError              : std_logic;    -- indicates simultaneous P and N pulse
 
begin
 
-------------------------------------------------------------------------------
-- PROCESS    : RegisterInput
-- DESCRIPTION: DFF to register P and N inputs (reduces fan-in, etc)
--              Most applications of this core will be taking inputs from
--              off-chip, so these FF will be in the I/O blocks.
-- Metastability issues: None.
--  Either (1) the external CDR provides adequate
--  timing margin (which ensures no metastability issues)
--  or (2) it doesn't provide adequate timing margin (which could happen
--  if the input cable is unplugged) and any metastable states are irrelevant,
--  as the downstream decoding logic is free of lockup states,
--  and will recover within a few clocks once the
--  CDR is providing normal input again.
-------------------------------------------------------------------------------
    RegisterInput: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            PinRaw <= '0';
            NinRaw <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                PinRaw <= to_X01(P_i);
                NinRaw <= to_X01(N_i);
            end if;
        end if;
    end process RegisterInput;
 
 
    --  Restore active low pulse inputs to active high for internal use.
    Pin <= PinRaw xor (not PulseActiveState);
    Nin <= NinRaw xor (not PulseActiveState);
 
 
-------------------------------------------------------------------------------
-- PROCESS    : DecodeViolation
-- DESCRIPTION: Work out whether there has been a pulse violation, and
--              remember the sense of the last input pulse.
-------------------------------------------------------------------------------
    DecodeViolation: process (Reset_i, Clk_i)
        variable tmp : std_logic_vector(1 downto 0);
    begin
        if Reset_i = '1' then
            LastPulsePolarity <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                tmp := Pin & Nin;
                case tmp is
                    when "00"   =>   LastPulsePolarity <= LastPulsePolarity; --hold
                    when "10"   =>   LastPulsePolarity <= '1';   -- set
                    when "01"   =>   LastPulsePolarity <= '0';   -- reset
                    when others =>   LastPulsePolarity <= '0';   -- don't care
                end case;
            end if;
        end if;
    end process DecodeViolation;
 
    Violation <= (Pin and LastPulsePolarity) or (Nin and (not LastPulsePolarity));
 
 
-------------------------------------------------------------------------------
-- PROCESS    : DelayData
-- DESCRIPTION: Delay the data input so that it lines up with the violation
-- signal, so we can remove the B bit (in process DecodeData).
-------------------------------------------------------------------------------
    DelayData: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            Q1 <= '0';
            Q2 <= '0';
            Q3 <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                Q1 <=  (Pin or Nin) and (not Violation); -- delete V bit
                Q2 <= Q1;
                if EncoderType = 3 then
                    -- HDB3, delay by 3 clocks
                    Q3 <= Q2;
                else
                    -- HDB2, delay by 2 clocks
                    Q3 <= Q1;   -- skip Q2
                end if;
            end if;
        end if;
    end process DelayData;
 
 
-------------------------------------------------------------------------------
-- PROCESS    : DecodeData
-- DESCRIPTION: remove B bits from data, and register output
-------------------------------------------------------------------------------
    DecodeData: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            Data_o <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                Data_o <= Q3 and (not Violation); -- delete B bit
            end if;
        end if;
    end process DecodeData;
 
 
-------------------------------------------------------------------------------
-- PROCESS    : CountZeros
-- DESCRIPTION: count number of contiguous zeros in input (mod 3 or 4)
-------------------------------------------------------------------------------
    CountZeros: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            ZeroCount <= 0;
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                if (Pin or Nin) = '1' then
                    ZeroCount <= 0;             -- have seen a 1, reset count
                elsif ZeroCount >= EncoderType then
                    ZeroCount <= EncoderType;   -- hold
                else
                    ZeroCount <= ZeroCount + 1; -- increment
                end if;
            end if;
        end if;
    end process CountZeros;
 
 
-------------------------------------------------------------------------------
-- PROCESS    : DecodeViolationError
-- DESCRIPTION: Remember the polarity of this violation, so that we can work
--              out whether the next violation is an error.
-------------------------------------------------------------------------------
    DecodeViolationError: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            LastViolationPolarity <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                if Violation = '1' then
                    LastViolationPolarity <= LastPulsePolarity;
                else
                    LastViolationPolarity <= LastViolationPolarity; -- latch
                end if;
            end if;
        end if;
    end process DecodeViolationError;
 
 
-------------------------------------------------------------------------------
-- The follow logic checks for various error conditions.
-------------------------------------------------------------------------------
 
    ViolationError <= Violation and (not (Pin xor LastViolationPolarity));
 
    PulseError <= Pin and Nin;
 
    TooManyZeros <= (not (Pin or Nin)) when (ZeroCount = EncoderType) else '0';
 
 
-------------------------------------------------------------------------------
-- PROCESS    : RegisterCodeError
-- DESCRIPTION: combine all error signals and register the output
-------------------------------------------------------------------------------
    RegisterCodeError: process (Reset_i, Clk_i)
    begin
        if Reset_i = '1' then
            CodeError_o <= '0';
        elsif rising_edge(Clk_i) then
            if ClkEnable_i = '1' then
                CodeError_o <= ViolationError or PulseError or TooManyZeros;
            end if;
        end if;
    end process RegisterCodeError;
 
 
end rtl; -- End architecture rtl;
-------------------------------------------------------------------------------
-- End of hdbnd.vhd
-------------------------------------------------------------------------------
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.