---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2004
--
-- Filename: DataRectifier.vhd
-- Language: VHDL '93
-- Project:  Digitiser Card DSP FPGA
--
-- Design Description:
-- Module to rectify ADC datastream.
--
-- Type of rectification used depends on pMode control input
--
--
-- pMode | Rectification
--  000  | Bipolar mode, no rectification
--  001  | Fullwae rectification
--  010  | +Ve 1/2 wave rectification
--  011  | -Ve 1/2 wave rectification
--  100  | Test mode - write test data to SRAM
---------------------------------------------------------------------------

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

entity DataRectifier is
  port(pnReset       : in  std_ulogic;
       pADC_2xClk    : in  std_ulogic;
       pDropSamples  : in  std_logic_vector(3 downto 0);
       pMode         : in  std_logic_vector(1 downto 0);
       p8BitValues   : in  std_ulogic;
       pDataIn       : in  std_logic_vector(11 downto 0);
       pSampleEn     : out std_ulogic;
       pDataOut      : out std_logic_vector(11 downto 0);
       pRectifiedOut : out std_logic_vector(10 downto 0));
end entity DataRectifier;


architecture Rtl of DataRectifier is

  attribute uselowskewlines: string;

  signal DataIn:       std_logic_vector(11 downto 0);  -- 12/8 bit unrectified data
  signal PipelineData: std_logic_vector(11 downto 0);  -- Pipeline stage for data
  signal RectifiedData: std_logic_vector(10 downto 0);  -- Pipeline stage for rectified data

  signal DropCount: integer range 0 to 15;
  signal SampleEn:  std_ulogic;
  attribute uselowskewlines of SampleEn : signal is "yes";


begin

  -- Generate the enable for the sample data stream
  GenSampleEn: process(pnReset, pADC_2xClk)
  begin
    if pnReset = '0' then
      DropCount <= 0;
      SampleEn  <= '1';
    elsif rising_edge(pADC_2xClk) then

      if DropCount = 0 then
        SampleEn <= '1';
      else
        SampleEn <= '0';
      end if;

      if DropCount = 0 then
        DropCount <= conv_integer(unsigned(pDropSamples));
      else
        DropCount <= DropCount - 1;
      end if;
    end if;
  end process GenSampleEn;

  pSampleEn <= SampleEn;


  -- Truncate to 8 bits of data if required
  GenDataIn: process(pnReset, pADC_2xClk)
  begin
    if pnReset = '0' then
      DataIn <= X"000";
    elsif rising_edge(pADC_2xClk) then
      if p8BitValues = '0' then
        DataIn <= pDataIn;
      else
        DataIn(11 downto 7) <= (others => pDataIn(11));
        DataIn(6 downto 0)  <= pDataIn(10 downto 4);
      end if;
    end if;
  end process GenDataIn;


  -- Generate the rectified sample datastream
  Gen_pDataOut: process(pnReset, pADC_2xClk)
    variable vTemp: std_logic_vector(10 downto 0);
  begin
--    if pnReset = '0' then
--      PipelineData <= X"000";
--      RectifiedData <= (others => '0');
--      pDataOut     <= X"000";
--      pRectifiedOut <= (others => '0');

--    elsif rising_edge(pADC_2xClk) then
    if rising_edge(pADC_2xClk) then
      if SampleEn = '1' then
        PipelineData <= DataIn;
        
        -- fullwave rectified data
        vTemp := not DataIn(10 downto 0);
        if DataIn = X"800" then
          -- Catch condition when Data in = -2048 (0x800)
          -- This must be converted to +2047 (0x7FF)
          RectifiedData <= "11111111111";
        elsif DataIn(11) = '1' then
          RectifiedData <= (unsigned(vTemp) + 1);
        else
          RectifiedData <= DataIn(10 downto 0);
        end if;

        case pMode is
          when "00" =>
            -- Bipolar mode, no rectification
            pDataOut      <= PipelineData;
            pRectifiedOut <= RectifiedData;

          when "01" =>
            -- Fullwave rectification
            pDataOut      <= '0' & RectifiedData;
            pRectifiedOut <= RectifiedData;

          when "10" =>
            -- +Ve 1/2 wave rectification
            if PipelineData(11) = '1' then  -- -Ve value
              pDataOut      <= X"000";
              pRectifiedOut <= (others => '0');
            else  -- +Ve value
              pDataOut      <= '0' & RectifiedData;
              pRectifiedOut <= RectifiedData;
            end if;

          when others => --"11" =>
            -- -Ve 1/2 wave rectification
            if PipelineData(11) = '1' then  -- -Ve value
              pDataOut      <= '0' & RectifiedData;
              pRectifiedOut <= RectifiedData;
            else  -- +Ve value
              pDataOut      <= X"000";
              pRectifiedOut <= (others => '0');
            end if;

        end case;
      end if;
    end if;
  end process Gen_pDataOut;


end architecture Rtl;