---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2004-5
--
-- Filename: PeripheralFpgaTop.vhd
-- Language: VHDL '93
-- Project:  Digitiser Card DSP FPGA
--
-- Design Description:
-- Top Level for Digitiser Card Peripheral FPGA - Sequence table version
---------------------------------------------------------------------------

library IEEE;
Use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_Arith.all;

library UNISIM;
use UNISIM.vcomponents.all;

library work;
use work.PeripheralFpgaPkg.all;

entity PeripheralFpgaTop is
  port(-- Local bus
       pnLReset     : in    std_ulogic;
       pnFpgaCs     : in    std_ulogic;
       pLWnR        : in    std_ulogic;
       pLA          : in    std_logic_vector(31 downto 2);
       pLD          : inout std_logic_vector(31 downto 0);
       pLCLK        : in    std_ulogic;
       -- Sample Clock
       pSampleClk   : in    std_ulogic;
       -- Shaft Encoder Inputs
       pEncoder0In  : in    std_logic_vector(1 downto 0);
       pEncoder1In  : in    std_logic_vector(1 downto 0);
       pEncoder2In  : in    std_logic_vector(1 downto 0);
       pEncoder3In  : in    std_logic_vector(1 downto 0);
       pEncoder4In  : in    std_logic_vector(1 downto 0);
       pEncoder5In  : in    std_logic_vector(1 downto 0);
       -- Control Signals
       pSEL_1M_50R  : out   std_ulogic;
       pSEL_AC_DC   : out   std_ulogic;
       pATOD_RANGE  : out   std_ulogic;
       pDATA_FORMAT : out   std_ulogic;
       pPORT_FORMAT : out   std_ulogic;
       pSENSE       : out   std_ulogic;
       pDdsKey      : out   std_ulogic;
       pDdsFsk      : out   std_ulogic;
       pAIN         : out   std_logic_vector(3 downto 0);
       pAUX         : out   std_logic_vector(1 downto 0);
       pGAIN        : out   std_logic_vector(5 downto 0);
       pCAL         : out   std_logic_vector(2 downto 0);
       -- Generic IO
       pPIO         : inout std_logic_vector(62 downto 2);
       -- Sensor Array Connections
       pProbeSense  : in    std_ulogic;
       pProbeAper   : out   std_logic_vector(1 downto 0);
       pProbeDSel   : out   std_ulogic;
       pProbeDClk   : out   std_ulogic;
       pProbeTx     : out   std_ulogic;
       pProbeData   : out   std_logic_vector(7 downto 0);
       -- Connections to DSP FPGA
       pZ0          : in    std_ulogic;  -- ClkDll reset control
       pZ1          : out   std_ulogic;  -- Serial shaft encoder results enable
       pZ2          : out   std_ulogic;  -- Serial shaft encoder results
       pZ3          : out   std_ulogic;  -- Serial gate data out
       pZ4          : out   std_ulogic;  -- Serial gate data enable out
       pZ5          : out   std_ulogic;  -- Serial gate sel (bit 0)
       pZ6          : out   std_ulogic;  -- Serial gate sel (bit 1)
       pZ7          : out   std_ulogic;  -- Serial gate sel (bit 2)
       pZ8          : in    std_ulogic;  -- B-Scan is active
       pZ9          : in    std_ulogic;  -- PRx Acknowledge signal
       pZ10         : out   std_ulogic;  -- Trigger signal for DSP FPGA
       pZ11         : out   std_ulogic;  -- Sequence Step control
       pZ12         : in    std_ulogic;  -- BEA switch (FPGABusy signal on PCB)
       -- Calibration DAC Signals
       pCalDac_SDI  : out   std_ulogic;
       pCalDac_CLK  : out   std_ulogic;
       pCalDac_nLD  : out   std_ulogic;
       pCalDac_nCS  : out   std_ulogic;
       -- LEDs
       pLED_D8      : out   std_ulogic;
       pLED_D9      : out   std_ulogic);
end entity PeripheralFpgaTop;



architecture Rtl of PeripheralFpgaTop is

  component IBUFG
    port (I   : in    std_ulogic;
          O   : out   std_ulogic);
  end component;

  component BUFG
    port (I   : in    std_ulogic;
          O   : out   std_ulogic);
  end component;

  component CLKDLL  -- Xilinx CLKDLL component
    port (CLKIN  : in  std_ulogic;
          CLKFB  : in  std_ulogic;
          RST    : in  std_ulogic;
          CLK0   : out std_ulogic;
          CLK90  : out std_ulogic;
          CLK180 : out std_ulogic;
          CLK270 : out std_ulogic;
          CLK2X  : out std_ulogic;
          CLKDV  : out std_ulogic;
          LOCKED : out std_ulogic);
  end component;

  component IFD
    port (D : in  std_ulogic;
          C : in  std_ulogic;
          Q : out std_ulogic);
  end component;

  component OFD
    port (D : in  std_ulogic;
          C : in  std_ulogic;
          Q : out std_ulogic);
  end component;


  component StrobeExtender is
    generic(gLfsrBits: integer range 3 to 32 := 3);
    port(pnReset    : in  std_ulogic;
         pClk       : in  std_ulogic;
         pStrobeIn  : in  std_ulogic;
         pStrobeOut : out std_ulogic);
  end component StrobeExtender;


  component TriggerDelay is
    port(pnReset            : in  std_ulogic;
         pSampleClk         : in  std_ulogic;
         pTriggerDelay      : in  std_logic_vector(20 downto 0);
         pTriggerIn         : in  std_ulogic;
         pTriggerOut        : out std_ulogic);
  end component TriggerDelay;


  component PerLBusInterface
    port (-- Local bus signals
          pnReset            : in  std_ulogic;
          pLClk              : in  std_ulogic;
          pnFPGACS           : in  std_ulogic;
          pLAin              : in  std_logic_vector(31 downto 2);
          pLDin              : in  std_logic_vector(31 downto 0);
          pLDout             : out std_logic_vector(31 downto 0);
          pLDoutput_enable   : out std_ulogic;
          pLWnR              : in  std_ulogic;
          -- Generic IO signals
          pPioIn             : in  std_logic_vector(62 downto 2);
          pPioOut            : out std_logic_vector(62 downto 2);
          pPioDdr            : out std_logic_vector(62 downto 2);
          -- Inputs for readable register bits
          pEncoder0Pos       : in  std_logic_vector(31 downto 0);
          pEncoder1Pos       : in  std_logic_vector(31 downto 0);
          pEncoder2Pos       : in  std_logic_vector(31 downto 0);
          pEncoder3Pos       : in  std_logic_vector(31 downto 0);
          pEncoder4Pos       : in  std_logic_vector(31 downto 0);
          pEncoder5Pos       : in  std_logic_vector(31 downto 0);
          -- Peripheral FPGA Gate data outputs
          pGateDataOut       : out std_ulogic;
          pGateDataEn        : out std_ulogic;
          pGateDataSel       : out std_logic_vector(2 downto 0);
          -- Calibration DAC outputs
          pCalDac_SDI        : out std_ulogic;
          pCalDac_CLK        : out std_ulogic;
          pCalDac_nLD        : out std_ulogic;
          pCalDac_nCS        : out std_ulogic;
          -- Control signals from registers
          pEncoderReset      : out std_logic_vector(5 downto 0);
          pForceSequence     : out std_ulogic;
          pSequenceActive    : in  std_ulogic;
          -- Sequence table control signals
          pSequenceStep      : in  std_logic_vector(4 downto 0);
          pGateStep          : out std_ulogic;
          pGateStepEn        : out std_ulogic;
          -- Register Outputs
          pRegData           : out tRegSet);
  end component;


  component DualPortRam is
    generic(gAddressWidth: integer range 1 to 32 := 6;
            gDataWidth:    integer range 1 to 32 := 32);
    port(pClk       : in  std_ulogic;
         pWriteEn   : in  std_ulogic;
         pAddr      : in  std_logic_vector(gAddressWidth-1 downto 0);
         pDataIn    : in  std_logic_vector(gDataWidth-1 downto 0);
         pDataOut   : out std_logic_vector(gDataWidth-1 downto 0);
         pDpClk     : in  std_ulogic;
         pDpAddr    : in  std_logic_vector(gAddressWidth-1 downto 0);
         pDpDataOut : out std_logic_vector(gDataWidth-1 downto 0));
  end component DualPortRam;


  component EncoderMonitor is
    port (-- Local bus signals
          pnReset          : in  std_ulogic;
          pLCLK            : in  std_ulogic;
          pEncoderReset    : in  std_logic_vector(5 downto 0);
          pEncoderSelect   : in  std_logic_vector(2 downto 0);
          pClicksPerBScan  : in  std_logic_vector(15 downto 0);
          pFractClicks     : in  std_logic_vector(7 downto 0);
          pBScanActive     : in  std_ulogic;
          pEncoder0In      : in  std_logic_vector(1 downto 0);
          pEncoder1In      : in  std_logic_vector(1 downto 0);
          pEncoder2In      : in  std_logic_vector(1 downto 0);
          pEncoder3In      : in  std_logic_vector(1 downto 0);
          pEncoder4In      : in  std_logic_vector(1 downto 0);
          pEncoder5In      : in  std_logic_vector(1 downto 0);
          pEncoder0Pos     : out std_logic_vector(31 downto 0);
          pEncoder1Pos     : out std_logic_vector(31 downto 0);
          pEncoder2Pos     : out std_logic_vector(31 downto 0);
          pEncoder3Pos     : out std_logic_vector(31 downto 0);
          pEncoder4Pos     : out std_logic_vector(31 downto 0);
          pEncoder5Pos     : out std_logic_vector(31 downto 0);
          pSerialOut       : out std_ulogic;
          pSerialOutEn     : out std_ulogic;
          pBScanTriggerOut : out std_ulogic;
          pBScanTriggerIn  : in  std_ulogic);
  end component EncoderMonitor;


  component SequenceCtrl
    Port (-- Local bus signals
          pnReset          : in  std_ulogic;
          pSampleClk       : in  std_ulogic;
          pLClk            : in  std_ulogic;
          -- Sequence operation controls
          pStartSequence   : in  std_ulogic;
          pSequenceTrigger : in  std_ulogic;
          pSeqTriggerEn    : in  std_ulogic;
          pStepAck         : in  std_ulogic;
          pSequenceActive  : out std_ulogic;
          -- Register data in
          pSteps           : in  std_logic_vector(4 downto 0);
          pAScanRepRate    : in  std_logic_vector(16 downto 0);
          pOverSample      : in  std_logic_vector(7 downto 0);
          pStepNo          : out std_logic_vector(4 downto 0);
          -- Step control
          pGateStep        : in  std_ulogic;
          pGateStepEn      : in  std_ulogic;
          pDspStep         : out std_ulogic;
          -- Trigger data out
          pTriggerOut      : out std_ulogic;
          pStartNewSequence: out std_ulogic);
  end component;


  component TriggerPulseGen is
    port (-- Local bus signals
          pnReset            : in  std_ulogic;
          pSample2xClk       : in  std_ulogic;
          pTriggerLen        : in  std_logic_vector(11 downto 0);
          pTriggerIn         : in  std_ulogic;
          pTxDone            : out std_ulogic;
          pTriggerOut        : out std_ulogic);
  end component TriggerPulseGen;


  signal DelayedTrigger: std_ulogic;
  signal TriggerOut:     std_ulogic;

  signal ElementNumOut: std_logic_vector(7 downto 0);

  signal RegData:        tRegSet;

  signal LD_Out: std_logic_vector(31 downto 0);
  signal LD_En:  std_ulogic;

  -- Encoder inputs after clocking through flip-flops
  signal iEncoder0In:        std_logic_vector(1 downto 0);
  signal iEncoder1In:        std_logic_vector(1 downto 0);
  signal iEncoder2In:        std_logic_vector(1 downto 0);
  signal iEncoder3In:        std_logic_vector(1 downto 0);
  signal iEncoder4In:        std_logic_vector(1 downto 0);
  signal iEncoder5In:        std_logic_vector(1 downto 0);
  signal Encoder0In:         std_logic_vector(1 downto 0);
  signal Encoder1In:         std_logic_vector(1 downto 0);
  signal Encoder2In:         std_logic_vector(1 downto 0);
  signal Encoder3In:         std_logic_vector(1 downto 0);
  signal Encoder4In:         std_logic_vector(1 downto 0);
  signal Encoder5In:         std_logic_vector(1 downto 0);

  signal SampleClkIn:        std_ulogic;
  signal SampleClk_NoBuff:   std_ulogic;
  signal SampleClk:          std_ulogic;
  signal Sample2xClk:        std_ulogic;
  signal Sample2xClk_NoBuff: std_ulogic;
  signal Sample2xClkValid:   std_ulogic;

  signal LCLK_NoBuff:  std_ulogic;
  signal LCLK:         std_ulogic;

  signal CalDac_SDI:  std_ulogic;
  signal CalDac_CLK:  std_ulogic;
  signal CalDac_nLD:  std_ulogic;
  signal CalDac_nCS:  std_ulogic;

  signal BlkRamDataIn: std_logic_vector(7 downto 0);
  signal BlkRamAddr1:  std_logic_vector(6 downto 0);
  signal BlkRamAddr2:  std_logic_vector(6 downto 0);
  signal BlkRamWrEn:   std_ulogic;

  signal TxCount:      std_logic_vector(6 downto 0);
  signal RxCount:      std_logic_vector(6 downto 0);
  signal TxCountMux:   std_logic_vector(6 downto 0);
  signal RxCountMux:   std_logic_vector(6 downto 0);

  signal AScanTrigger:       std_ulogic;
  signal EncoderScanTrigger: std_ulogic;
  signal ForceSequence:      std_ulogic;
  signal DoSequence:         std_ulogic;
  signal BeaSwitch:          std_ulogic;
  signal NewSequence:        std_ulogic;
  signal NewSequenceExt:     std_ulogic;
  signal NewSequencePulse:   std_ulogic;
  signal SequenceActive:     std_ulogic;
                                         
  signal EncoderReset: std_logic_vector(5 downto 0);
  signal Encoder0Pos:  std_logic_vector(31 downto 0);
  signal Encoder1Pos:  std_logic_vector(31 downto 0);
  signal Encoder2Pos:  std_logic_vector(31 downto 0);
  signal Encoder3Pos:  std_logic_vector(31 downto 0);
  signal Encoder4Pos:  std_logic_vector(31 downto 0);
  signal Encoder5Pos:  std_logic_vector(31 downto 0);

  signal TrigDelay:    std_logic_vector(20 downto 0);

  -- Serial version of Shaft encoder results for DSP FPGA
  signal SerialOut:   std_ulogic;
  signal SerialOutEn: std_ulogic;
  signal LastBScan:   std_ulogic;

  -- Serial version of gate data for DSP FPGA
  signal GateDataOut: std_ulogic;
  signal GateDataEn:  std_ulogic;
  signal GateDataSel: std_logic_vector(2 downto 0);

  -- Generic IO signals
  signal PioIn:       std_logic_vector(62 downto 2);
  signal PioOut:      std_logic_vector(62 downto 2);
  signal PioDdr:      std_logic_vector(62 downto 2);

  -- Sequence Table Contol
  signal SequenceStep: std_logic_vector(4 downto 0);
  signal GateStep:     std_ulogic;
  signal GateStepEn:   std_ulogic;

  constant cVcc: std_ulogic := '1';
  constant cGnd: std_ulogic := '0';

  attribute KEEP: string;
  attribute KEEP of LCLK : signal is "true";

begin


  -- Create the generic IO ports
  GenPio: for Count in 2 to 62 generate
    pPIO(Count) <= PioOut(Count) when PioDdr(Count) = '0' else 'Z';
  end generate;

  -- Bea switch to alternative input control
  BeaSwitch <= '0' when (RegData(cHardwareCtrl)(30 downto 25) = "000000") else pZ12;
  -- Connect up the peripheral hardware control outputs
  pAUX         <= RegData(cHardwareCtrl)(30 downto 29) when BeaSwitch = '1' else RegData(cHardwareCtrl)(24 downto 23);
  pCAL         <= RegData(cHardwareCtrl)(22 downto 20);
  pDdsFsk      <= RegData(cHardwareCtrl)(19);
  pDdsKey      <= RegData(cHardwareCtrl)(18);
  -- 16:15
  pSENSE       <= '1' when (RegData(cHardwareCtrl)(15) = '1') else 'Z';
  pATOD_RANGE  <= RegData(cHardwareCtrl)(14);
  pDATA_FORMAT <= RegData(cHardwareCtrl)(13);
  pPORT_FORMAT <= RegData(cHardwareCtrl)(12);
  pGAIN        <= RegData(cHardwareCtrl)(11 downto 6);
  pAIN         <= RegData(cHardwareCtrl)(28 downto 25) when BeaSwitch = '1' else RegData(cHardwareCtrl)(5 downto 2);
  pSEL_1M_50R  <= RegData(cHardwareCtrl)(1);
  pSEL_AC_DC   <= RegData(cHardwareCtrl)(0);


  --
  -- Instantiate components to produce frequency doubled pSampleClk
  -- Start
  --
  IBUFG0: IBUFG
    port map(I   => pSampleClk,
             O   => SampleClkIn);


  CLKDLL0: CLKDLL
    port map(CLKIN  => SampleClkIn,
             CLKFB  => SampleClk,
             RST    => pZ0,  -- Need to bring a reset in from DSP FPGA
             CLK0   => SampleClk_NoBuff,
             CLK90  => open,
             CLK180 => open,
             CLK270 => open,
             CLK2X  => open,
             CLKDV  => open,
             LOCKED => open);

  BUFG0: BUFG
    port map(I   => SampleClk_NoBuff,
             O   => SampleClk);

  CLKDLL1: CLKDLL
    port map(CLKIN  => SampleClk,
             CLKFB  => Sample2xClk,
             RST    => pZ0,  -- Need to bring a reset in from DSP FPGA
             CLK0   => open,
             CLK90  => open,
             CLK180 => open,
             CLK270 => open,
             CLK2X  => Sample2xClk_NoBuff,
             CLKDV  => open,
             LOCKED => Sample2xClkValid);

  BUFG1: BUFG
    port map(I   => Sample2xClk_NoBuff,
             O   => Sample2xClk);

  --
  -- Instantiate components to produce frequency doubled pSampleClock
  -- Done
  --

  -- Ensure LCLK is allocated a clock buffer
  IBUFG1: IBUFG
    port map(I   => pLCLK,
             O   => LCLK_NoBuff);

  BUFG2: BUFG
   port map(I   => LCLK_NoBuff,
            O   => LCLK);

  -- Connect generic IO input to PIO pins
  PioIn <= pPio;

  PerLBusInterface0: PerLBusInterface
    Port map(-- Local bus signals
             pnReset            => pnLReset,
             pLClk              => LCLK,
             pnFPGACS           => pnFpgaCs,
             pLAin              => pLA,
             pLDin              => pLD,
             pLDout             => LD_Out,
             pLDoutput_enable   => LD_En,
             pLWnR              => pLWnR,
             -- Generic IO signals
             pPioIn             => PioIn,
             pPioOut            => PioOut,
             pPioDdr            => PioDdr,
             -- Inputs for readable register bits
             pEncoder0Pos       => Encoder0Pos,
             pEncoder1Pos       => Encoder1Pos,
             pEncoder2Pos       => Encoder2Pos,
             pEncoder3Pos       => Encoder3Pos,
             pEncoder4Pos       => Encoder4Pos,
             pEncoder5Pos       => Encoder5Pos,
             -- Peripheral FPGA Gate data outputs
             pGateDataOut       => GateDataOut,
             pGateDataEn        => GateDataEn,
             pGateDataSel       => GateDataSel,
             -- Calibration DAC outputs
             pCalDac_SDI        => CalDac_SDI,
             pCalDac_CLK        => CalDac_CLK,
             pCalDac_nLD        => CalDac_nLD,
             pCalDac_nCS        => CalDac_nCS,
             -- Control signals from registers
             pEncoderReset      => EncoderReset,
             pForceSequence     => ForceSequence,
             pSequenceActive    => SequenceActive,
             -- Sequence table control signals
             pSequenceStep      => SequenceStep,
             pGateStep          => GateStep,
             pGateStepEn        => GateStepEn,
             -- Register Outputs
             pRegData           => RegData);

  TrigDelay <= RegData(cTriggerCtrl)(24 downto 20) & RegData(cTriggerCtrl)(15 downto 0);

  TriggerDelay0: TriggerDelay
    port map(pnReset          => pnLReset,
             pSampleClk       => SampleClk,
             pTriggerDelay    => TrigDelay,
             pTriggerIn       => AScanTrigger,
             pTriggerOut      => DelayedTrigger);


  pLD <= LD_Out when LD_En = '1' else (others => 'Z');

  OFD0: OFD
    port map(D => CalDac_SDI,
             C => LCLK,
             Q => pCalDac_SDI);

  OFD1: OFD
    port map(D => CalDac_CLK,
             C => LCLK,
             Q => pCalDac_CLK);

  OFD2: OFD
    port map(D => CalDac_nLD,
             C => LCLK,
             Q => pCalDac_nLD);

  OFD3: OFD
    port map(D => CalDac_nCS,
             C => LCLK,
             Q => pCalDac_nCS);

  -- Clock the encoder inputs thru IOB input flip-flops
  IFD0: IFD
    port map(D => pEncoder0In(0),
             C => LCLK,
             Q => iEncoder0In(0));
  IFD1: IFD
    port map(D => pEncoder0In(1),
             C => LCLK,
             Q => iEncoder0In(1));
  IFD2: IFD
    port map(D => pEncoder1In(0),
             C => LCLK,
             Q => iEncoder1In(0));
  IFD3: IFD
    port map(D => pEncoder1In(1),
             C => LCLK,
             Q => iEncoder1In(1));
  IFD4: IFD
    port map(D => pEncoder2In(0),
             C => LCLK,
             Q => iEncoder2In(0));
  IFD5: IFD
    port map(D => pEncoder2In(1),
             C => LCLK,
             Q => iEncoder2In(1));
  IFD6: IFD
    port map(D => pEncoder3In(0),
             C => LCLK,
             Q => iEncoder3In(0));
  IFD7: IFD
    port map(D => pEncoder3In(1),
             C => LCLK,
             Q => iEncoder3In(1));
  IFD8: IFD
    port map(D => pEncoder4In(0),
             C => LCLK,
             Q => iEncoder4In(0));
  IFD9: IFD
    port map(D => pEncoder4In(1),
             C => LCLK,
             Q => iEncoder4In(1));
  IFD10: IFD
    port map(D => pEncoder5In(0),
             C => LCLK,
             Q => iEncoder5In(0));
  IFD11: IFD
    port map(D => pEncoder5In(1),
             C => LCLK,
             Q => iEncoder5In(1));

  -- Clock encoder data a 2nd time to remove metastability
  ClkEncoderData: process(pnLReset, LCLK)
  begin
    if pnLReset = '0' then
      Encoder0In  <= "00";
      Encoder1In  <= "00";
      Encoder2In  <= "00";
      Encoder3In  <= "00";
      Encoder4In  <= "00";
      Encoder5In  <= "00";
    elsif rising_edge(LCLK) then
      Encoder0In  <= iEncoder0In;
      Encoder1In  <= iEncoder1In;
      Encoder2In  <= iEncoder2In;
      Encoder3In  <= iEncoder3In;
      Encoder4In  <= iEncoder4In;
      Encoder5In  <= iEncoder5In;
    end if;
  end process ClkEncoderData;


  EncoderMonitor0: EncoderMonitor
    Port map(pnReset          => pnLReset,
             pLCLK            => LCLK,
             pEncoderReset    => EncoderReset,
             pEncoderSelect   => RegData(cBScanTriggerCtrl)(18 downto 16),
             pClicksPerBScan  => RegData(cBScanTriggerCtrl)(15 downto 0),
             pFractClicks     => RegData(cBScanTriggerCtrl)(27 downto 20),
             pBScanActive     => pZ8,
             pEncoder0In      => Encoder0In,
             pEncoder1In      => Encoder1In,
             pEncoder2In      => Encoder2In,
             pEncoder3In      => Encoder3In,
             pEncoder4In      => Encoder4In,
             pEncoder5In      => Encoder5In,
             pEncoder0Pos     => Encoder0Pos,
             pEncoder1Pos     => Encoder1Pos,
             pEncoder2Pos     => Encoder2Pos,
             pEncoder3Pos     => Encoder3Pos,
             pEncoder4Pos     => Encoder4Pos,
             pEncoder5Pos     => Encoder5Pos,
             pSerialOut       => SerialOut,
             pSerialOutEn     => SerialOutEn,
             pBScanTriggerOut => EncoderScanTrigger,
             pBScanTriggerIn  => NewSequencePulse);

  -- Extend BScan trigger to 2 cycles
  GenNewSequenceExt: process(pnLReset, SampleClk)
    variable vTemp: std_logic_vector(1 downto 0);
  begin
    if pnLReset = '0' then
      NewSequenceExt <= '0';
    elsif rising_edge(SampleClk) then
      if vTemp(1 downto 0) = "01" or (vTemp(0) = '0' and NewSequence = '1') then
        NewSequenceExt <= '1';
      else
        NewSequenceExt <= '0';
      end if;

      vTemp := vTemp(0) & NewSequence;
    end if;
  end process GenNewSequenceExt;

  -- clock into LClk domain
  GenNewSequencePulse: process(pnLReset, LClk)
    variable vTemp: std_logic_vector(2 downto 0);
  begin
    if pnLReset = '0' then
     NewSequencePulse <= '0';
    elsif rising_edge(LClk) then
     if vTemp(2 downto 1) = "01" then
       NewSequencePulse <= '1';
     else
       NewSequencePulse <= '0';
     end if;

     vTemp := vTemp(1 downto 0) & NewSequenceExt;
    end if;
  end process GenNewSequencePulse;

  -- Connect up the encoder data outputs for the DSP FPGA
  OFD4: OFD
    port map(D => SerialOutEn,
             C => LCLK,
             Q => pZ1);

  OFD5: OFD
    port map(D => SerialOut,
             C => LCLK,
             Q => pZ2);

  -- Connect up Serial gate data outputs for DSP FPGA
  OFD6: OFD
    port map(D => GateDataOut,
             C => LCLK,
             Q => pZ3);

  OFD7: OFD
    port map(D => GateDataEn,
             C => LCLK,
             Q => pZ4);

  OFD8: OFD
    port map(D => GateDataSel(0),
             C => LCLK,
             Q => pZ5);

  OFD9: OFD
    port map(D => GateDataSel(1),
             C => LCLK,
             Q => pZ6);

  OFD10: OFD
    port map(D => GateDataSel(2),
             C => LCLK,
             Q => pZ7);


  DoSequence <= EncoderScanTrigger or ForceSequence;

  SeqCtrl0: SequenceCtrl
    port map(-- Local bus signals
             pnReset          => pnLReset,
             pSampleClk       => SampleClk,
             pLClk            => LCLK,
             -- Sequence operation controls
             pStartSequence   => RegData(cSeqControl)(31),
             pSequenceTrigger => DoSequence,
             pSeqTriggerEn    => RegData(cBScanTriggerCtrl)(30),
             pStepAck         => pZ9,
             pSequenceActive  => SequenceActive,
             -- Register data in
             pSteps           => RegData(cSeqControl)(4 downto 0),
             pAScanRepRate    => RegData(cAScanCtrl)(16 downto 0),
             pOverSample      => RegData(cAScanCtrl)(27 downto 20),
             pStepNo          => SequenceStep,
             -- Step control
             pGateStep        => GateStep,
             pGateStepEn      => GateStepEn,
             pDspStep         => pZ11,
             -- Trigger data out
             pTriggerOut      => AScanTrigger,
             pStartNewSequence=> NewSequence);

  TriggerPulseGen0: TriggerPulseGen
    port map(-- Local bus signals
             pnReset            => pnLReset,
             pSample2xClk       => Sample2xClk,
             pTriggerLen        => RegData(cPulseGenerator)(11 downto 0),
             pTriggerIn         => AScanTrigger,
             pTxDone            => open,
             pTriggerOut        => TriggerOut);

  -- Connect internal trigger signals to outputs
  pProbeAper <= (others => cGnd);
  pProbeData <= (others => cGnd);
  pProbeDSel <= cGnd;
  pProbeDClk <= cGnd;
  pProbeTx   <= TriggerOut;

  -- Connect up DSP interconnection outputs
  pZ10 <= DelayedTrigger;

  -- Drive LED outputs
  pLED_D8      <= not Sample2xClkValid;
  pLED_D9      <= not AScanTrigger; -- cGnd;  -- LED not used


end architecture Rtl;