URL
https://opencores.org/ocsvn/hdbn/hdbn/trunk
Subversion Repositories hdbn
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/tags/arelease/bench/vhdl/hdbn_tb.vhd
0,0 → 1,341
------------------------------------------------------------------------------- |
-- Title : hdbn_tb |
-- Project : hdbn |
------------------------------------------------------------------------------- |
-- File : hdbn_tb.vhd |
-- Author : Allan Herriman <allanh@opencores.org> |
-- Organization : Opencores |
-- Created : 9 Aug 1999 |
-- Platform : ? |
-- Simulators : Should work in any VHDL '93 or '00 compliant simulator. |
-- (Strict '87 compliant simulators will not work, as some |
-- '93 features have been used.) |
-- Tested with several versions of Modelsim and Simili. |
-- Most recently tested with Modelsim PE 5.6d and Simili 2.1b10 |
-- on Windows 2000 |
-- Synthesizers : N/A (this is a testbench) |
-- Targets : N/A (this is a testbench) |
-- Dependency : entities hdbne and hdbnd |
------------------------------------------------------------------------------- |
-- Description : testbench for entities hdbne and hdbnd. |
-- This is an "assertion based" test. If it runs to |
-- completion (about 16ms) without errors, it has passed. |
-- |
-- 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; |
|
use std.textio.all; |
|
|
entity hdbn_tb is |
generic ( |
HalfWidthOutputs : boolean := FALSE; -- set TRUE to use 2x clock on encoder |
InjectError : boolean := FALSE; -- set TRUE to test decoder error detection |
SwapPandN : boolean := FALSE; -- set TRUE to swap P,N signals between enc and dec |
EncoderType : integer range 2 to 3 := 3; -- 3: HDB3 2: HDB2/B3ZS |
PulseActiveState : std_logic := '1'; -- active state of P and N signals |
LogSpiceFile : boolean := FALSE; -- set TRUE to log encoder output in Spice PWL format |
LogFileName : string := "hdbn.txt"; |
StartupTransient : time := 15 us -- disables assertions for this long |
); |
end hdbn_tb; -- End entity hdbn_tb |
|
|
architecture tb of hdbn_tb is |
|
signal Reset : std_logic := '1'; |
signal Clk : std_logic := '0'; |
signal TxClk : std_logic := '0'; |
signal TxClkEnable : std_logic; |
signal Data : std_logic; -- encoder input (stimulus) |
signal DataOut : std_logic; -- decoder output |
signal CodeError : std_logic; |
signal P : std_logic; |
signal N : std_logic; |
|
signal PwithErrors : std_logic; |
signal NwithErrors : std_logic; |
|
signal InjectedError : std_logic := '0'; |
|
signal DataDelayed : std_logic; -- Matches delay of encoder |
signal DataDelayedSomeMore : std_logic; -- Matches delay of encoder and decoder |
signal Violation : std_logic; |
|
signal SimulationFinished : boolean := FALSE; |
|
begin |
|
|
------------------------------------------------------------------------------- |
-- Instantiation of entity 'hdbne' - hdbn encoder under test |
------------------------------------------------------------------------------- |
eUT : entity work.hdbne |
generic map ( |
EncoderType => EncoderType, |
PulseActiveState => PulseActiveState |
) |
port map ( |
Reset_i => Reset, |
Clk_i => TxClk, |
ClkEnable_i => TxClkEnable, |
Data_i => Data, |
OutputGate_i => TxClkEnable, |
P_o => P, |
N_o => N |
); |
|
|
------------------------------------------------------------------------------- |
-- Instantiation of entity 'hdbnd' - hdbn decoder under test |
------------------------------------------------------------------------------- |
dUT : entity work.hdbnd |
generic map ( |
EncoderType => EncoderType, |
PulseActiveState => PulseActiveState |
) |
port map ( |
Reset_i => Reset, |
Clk_i => Clk, |
ClkEnable_i => '1', |
P_i => PwithErrors, |
N_i => NwithErrors, |
Data_o => DataOut, |
CodeError_o => CodeError |
); |
|
|
------------------------------------------------------------------------------- |
-- make two clocks, 4.096MHz and 2.048MHz. |
-- Use HalfWidthOutputs to select which one is used for encoder |
-- Note: care must be taken to balance delta delays, otherwise races between |
-- the clocks may cause unpredictable results. |
------------------------------------------------------------------------------- |
MakeClk: process |
variable Clkv : std_logic := '0'; |
variable Clk2xv : std_logic := '0'; |
begin |
wait for 122 ns; |
if SimulationFinished then |
wait until not SimulationFinished; |
end if; |
Clk2xv := not Clk2xv; |
if Clk2xv = '1' then |
Clkv := not Clkv; |
end if; |
|
-- assign to signals, all in the same delta cycle |
Clk <= Clkv; |
if HalfWidthOutputs then |
-- run Encoder twice as fast, with every 2nd clock enabled |
TxClk <= Clk2xv; |
TxClkEnable <= not Clkv; |
else |
-- run Encoder at normal speed, with all clocks enabled |
TxClk <= Clkv; |
TxClkEnable <= '1'; |
end if; |
|
end process MakeClk; |
|
------------------------------------------------------------------------------- |
-- Make async, active high Reset signal |
------------------------------------------------------------------------------- |
Reset <= '1', '0' after 50 ns; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : StimulusGen, makes pseudo random bit sequence for testing. |
-- DESCRIPTION: 15 bit LFSR |
-- See ITU-T O.151 for details of this LFSR (this is the "official" PRBS to |
-- use for 2.048Mbps testing). |
------------------------------------------------------------------------------- |
StimulusGen: process (Reset, Clk) |
variable shiftreg : Std_logic_vector(14 downto 0) := (others => '0'); |
begin |
if Reset = '1' then |
shiftreg := (others => '0'); |
Data <= '0'; |
elsif rising_edge(Clk) then |
shiftreg := shiftreg(13 downto 0) & (not (shiftreg(14) xor shiftreg(13))); |
|
if HalfWidthOutputs then |
Data <= shiftreg(1); -- compensate for earlier sampling in hdbne when run from Clk2x |
else |
Data <= shiftreg(0); |
end if; |
DataDelayed <= shiftreg(3 + EncoderType); -- for violation visualisation |
DataDelayedSomeMore <= shiftreg(5 + 2 * EncoderType); -- for decoder testing |
|
if shiftreg = (shiftreg'range => '0') then |
report "hdbn simulation finished"; |
SimulationFinished <= TRUE after 10 us; |
end if; |
|
end if; |
end process StimulusGen; |
|
|
-------------------------------------------------------------------------------- |
-- optionally inject errors, to test decoder error detection |
-- and optionally crossover P&N on the line |
-------------------------------------------------------------------------------- |
InjectErrors : if InjectError generate |
InjectedError <= '0', |
'1' after StartupTransient + 1 us, |
'0' after StartupTransient + 1.500 us; |
end generate InjectErrors; |
|
-- normal connection, P->P, N->N |
NoSwapLines : if not SwapPandN generate |
PwithErrors <= P xor InjectedError; |
NwithErrors <= N; |
end generate NoSwapLines; |
|
-- check that it still works with P and N crossed over |
SwapLines : if SwapPandN generate |
PwithErrors <= N xor InjectedError; |
NwithErrors <= P; |
end generate SwapLines; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : Checker |
-- DESCRIPTION: Checks aspects of the hdb2/hdb3 encoder against the spec, |
-- and checks the decoder against the encoder |
------------------------------------------------------------------------------- |
Checker: process (Clk) |
variable RunningSum : integer := 0; |
variable ZeroCount : integer := 0; |
begin |
if rising_edge(Clk) then |
|
-- Encoder P and N outputs should never be active at the same time |
assert (not ((P = PulseActiveState) and (N = PulseActiveState))) |
report "Simultaneous P and N Pulse Error on HDBNE output" |
severity error; |
|
-- There should be no DC component on the line |
if P = PulseActiveState then |
RunningSum := RunningSum + 1; |
elsif N = PulseActiveState then |
RunningSum := RunningSum - 1; |
end if; |
|
assert RunningSum < 2 and RunningSum > -2 |
report "Running Sum Error on HDBNE output" |
severity error; |
|
-- There shouldn't be too many zeros in a row at encoder output |
if P = PulseActiveState or N = PulseActiveState then |
ZeroCount := 0; |
else |
ZeroCount := ZeroCount + 1; |
end if; |
|
assert (ZeroCount <= EncoderType) or (now < StartupTransient) |
report "Long String Of Zeros on HDBNE output" |
severity error; |
|
-- The decoder output should match the encoder input |
assert ((DataDelayedSomeMore xor DataOut) = '0') or (now < StartupTransient) |
report "Decoder Bit Error on HDBND output" |
severity error; |
|
-- The decoder shouldn't detect any errors |
assert (CodeError = '0') or (now < StartupTransient) |
report "Decoder Code Error on HDBND output" |
severity error; |
|
end if; |
end process Checker; |
|
|
Violation <= DataDelayed xor (P or N); -- for visualisation only |
-- (only useful if HalfWidthOutputs is FALSE) |
|
|
------------------------------------------------------------------------------- |
-- Log values to a file in PSpice "PWL" format, for testing of E1 LIU, etc. |
-- |
-- Note: this process isn't an essential part of the test bench. |
-- |
-- Example spice usage: |
-- |
-- .PARAM PH = 2.37V ; G.703 2.048Mbps pulse height |
-- .PARAM PW = 244ns ; G.703 2.048Mbps pulse width |
-- |
-- Vdrive 1 0 PWL |
-- + TIME_SCALE_FACTOR={PW} |
-- + VALUE_SCALE_FACTOR={PH} |
-- + FILE hdbn.txt |
-- |
------------------------------------------------------------------------------- |
GenLogger : if LogSpiceFile generate |
|
Logger : process (Clk) |
FILE log_file : text open write_mode IS LogFileName; |
VARIABLE l : line; |
variable LineNumber : integer := 0; |
variable value : integer; |
variable FirstTime : boolean := TRUE; |
begin |
if rising_edge(Clk) then |
|
if FirstTime then |
-- output (0, 0) as the first line in the file |
write(l, '(' & integer'image(LineNumber) & ", 0)"); |
writeline(log_file, l); |
FirstTime := FALSE; |
end if; |
|
if P = PulseActiveState then |
value := 1; |
elsif N = PulseActiveState then |
value := -1; |
else |
value := 0; |
end if; |
|
if value = 0 then |
-- don't bother to print it (as the voltage is already 0), but do update the time! |
LineNumber := LineNumber + 2; |
else |
-- ramp the voltage from 0 to the peak value |
write(l, '(' & integer'image(LineNumber) & ".49, 0)"); |
writeline(log_file, l); |
write(l, '(' & integer'image(LineNumber) & ".5, " & integer'image(value) & ')'); |
writeline(log_file, l); |
LineNumber := LineNumber + 1; |
|
-- ramp the voltage from the peak value back to 0 |
write(l, '(' & integer'image(LineNumber) & ".49, " & integer'image(value) & ')'); |
writeline(log_file, l); |
write(l, '(' & integer'image(LineNumber) & ".5, 0)"); |
writeline(log_file, l); |
LineNumber := LineNumber + 1; |
end if; |
end if; |
end process Logger; |
|
end generate GenLogger; |
|
|
end architecture tb; |
------------------------------------------------------------------------------- |
-- End of hdbn_tb.vhd |
------------------------------------------------------------------------------- |
/tags/arelease/rtl/vhdl/hdbnd.vhd
0,0 → 1,262
------------------------------------------------------------------------------- |
-- 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 |
------------------------------------------------------------------------------- |
/tags/arelease/rtl/vhdl/hdbne.vhd
0,0 → 1,273
------------------------------------------------------------------------------- |
-- Title : hdbne |
-- Project : hdbn |
------------------------------------------------------------------------------- |
-- File : hdbne.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 decoder is hdb3d. |
------------------------------------------------------------------------------- |
-- Description : HDB3 or HDB2 (B3ZS) encoder. |
-- P and N outputs are full width by default. |
-- Half width pulses can be created by using a double rate clock and |
-- strobing ClkEnable and OutputEnable appropriately (high every second clock). |
-- |
-- 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 |
-- The outputs will require pulse shaping if used to drive the line. |
-- These encodings are polarity insensitive, so the P and N outputs 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 hdbne is |
generic ( |
EncoderType : integer range 2 to 3 := 3; -- 3: HDB3 2: HDB2/B3ZS |
PulseActiveState : std_logic := '1' -- active state of P and N outputs |
); |
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 |
Data_i : in std_logic; -- active high data input |
OutputGate_i : in std_logic := '1'; -- '0' forces P and N to not PulseActiveState (synchronously, but ignoring ClkEnable) |
P_o : out std_logic; -- encoded +ve pulse output |
N_o : out std_logic -- encoded -ve pulse output |
); |
end hdbne; -- End entity hdbne |
|
|
architecture rtl of hdbne is |
|
signal Q1 : std_logic; -- Q1 through Q5 form a shift |
signal Q2 : std_logic; -- register for aligning |
signal Q3 : std_logic; -- the data so we can insert |
signal Q4 : std_logic; -- the violations |
signal Q5 : std_logic; |
|
signal AMI : std_logic; -- sense of pulse (P or N) |
signal ViolationType : std_logic; -- sense of violation |
signal ZeroCount : integer range 0 to 3; -- counts 0s in input |
signal ZeroString : std_logic; -- goes to '1' when 3 or 4 0s seen |
signal ZeroStringDelayed : std_logic; -- above delayed by 1 clock |
|
begin |
|
------------------------------------------------------------------------------- |
-- PROCESS : RegisterInput |
-- DESCRIPTION: DFF (Q1) to register input data (reduces fan-in, etc) |
------------------------------------------------------------------------------- |
RegisterInput: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
Q1 <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
Q1 <= to_X01(Data_i); |
end if; |
end if; |
end process RegisterInput; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : CountZeros |
-- DESCRIPTION: count number of contiguous zeros in input (mod 4 or mod 3) |
------------------------------------------------------------------------------- |
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 Q1 = '1' then |
ZeroCount <= 0; -- have seen a 1, reset count |
elsif ZeroCount >= EncoderType then |
ZeroCount <= 0; -- increment modulo 3 or 4 |
else |
ZeroCount <= ZeroCount + 1; -- increment |
end if; |
end if; |
end if; |
end process CountZeros; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : DecodeCount (combinatorial) |
-- DESCRIPTION: decode ZeroCount to indicate when string of 3 or 4 zeros is present |
-- Note: this process is not clocked |
------------------------------------------------------------------------------- |
DecodeCount: process (Q1, ZeroCount) |
begin |
if ZeroCount = EncoderType and Q1 = '0' then |
ZeroString <= '1'; |
else |
ZeroString <= '0'; |
end if; |
end process DecodeCount; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : RegisterZeroString |
-- DESCRIPTION: DFF to register the ZeroString signal |
------------------------------------------------------------------------------- |
RegisterZeroString: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
ZeroStringDelayed <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
ZeroStringDelayed <= ZeroString; |
end if; |
end if; |
end process RegisterZeroString; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : DelayData |
-- DESCRIPTION: insert 1 if needed for violation, and delay data by 2 or 3 clocks |
-- to line up with ZeroString detection. |
------------------------------------------------------------------------------- |
DelayData: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
Q2 <= '0'; |
Q3 <= '0'; |
Q4 <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
Q2 <= Q1 or ZeroString; -- insert Violation bit |
Q3 <= Q2; |
if EncoderType = 3 then |
-- HDB3, delay by 3 clocks |
Q4 <= Q3; |
else |
-- HDB2, delay by 2 clocks |
Q4 <= Q2; -- skip Q3 |
end if; |
end if; |
end if; |
end process DelayData; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : InsertBBit |
-- DESCRIPTION: Delay Q4 by one clock, and insert B bit if needed. |
------------------------------------------------------------------------------- |
InsertBBit: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
Q5 <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
Q5 <= Q4 or (ZeroString and (not ViolationType)); |
end if; |
end if; |
end process InsertBBit; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : ToggleViolationType |
-- DESCRIPTION: Toggle ViolationType whenever Q5 is 1 |
------------------------------------------------------------------------------- |
ToggleViolationType: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
ViolationType <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
ViolationType <= ViolationType xor Q5; |
end if; |
end if; |
end process ToggleViolationType; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : AMIFlipFlop |
-- DESCRIPTION: toggle AMI to alternate P and N pulses. Force a violation (no |
-- toggle) occasionally. |
------------------------------------------------------------------------------- |
AMIFlipFlop: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
AMI <= '0'; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' then |
AMI <= AMI xor (Q5 and (ViolationType nand (ZeroString or ZeroStringDelayed))); |
end if; |
end if; |
end process AMIFlipFlop; |
|
|
------------------------------------------------------------------------------- |
-- PROCESS : MakePandNPulses |
-- DESCRIPTION: Gate Q5 with AMI to produce the P and N outputs |
-- Note that OutputEnable overrides ClkEnable, to allow creation of |
-- half width pulses. |
-- The flip flops P and N will drive the outputs to the LIU, and these |
-- flip flops should be in the IOBs in an FPGA. Clk to output delay |
-- should be matched for P and N to avoid pulse shape distortion at the LIU |
-- output. |
------------------------------------------------------------------------------- |
MakePandNPulses: process (Reset_i, Clk_i) |
begin |
if Reset_i = '1' then |
P_o <= not PulseActiveState; |
N_o <= not PulseActiveState; |
elsif rising_edge(Clk_i) then |
if ClkEnable_i = '1' or OutputGate_i /= '1' then |
if OutputGate_i /= '1' then |
-- force output to '0' |
P_o <= not PulseActiveState; |
N_o <= not PulseActiveState; |
else |
-- normal operation |
if Q5 = '1' then |
if AMI = '1' then |
-- output '1' on P |
P_o <= PulseActiveState; |
N_o <= not PulseActiveState; |
else |
-- output '1' on N |
P_o <= not PulseActiveState; |
N_o <= PulseActiveState; |
end if; |
else |
-- output '0' |
P_o <= not PulseActiveState; |
N_o <= not PulseActiveState; |
end if; |
end if; |
end if; |
end if; |
end process MakePandNPulses; |
|
|
end rtl; -- End architecture rtl; |
------------------------------------------------------------------------------- |
-- End of hdbne.vhd |
------------------------------------------------------------------------------- |
/tags/arelease/doc/hdbn.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
tags/arelease/doc/hdbn.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: tags/arelease/doc/src/hdbn.doc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: tags/arelease/doc/src/hdbn.doc
===================================================================
--- tags/arelease/doc/src/hdbn.doc (nonexistent)
+++ tags/arelease/doc/src/hdbn.doc (revision 3)
tags/arelease/doc/src/hdbn.doc
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property