---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2008
--
-- Filename: SDRAMRefresh.vhd
-- Language: VHDL '93
-- Project:  NDTS2100 DSP FPGA
--
-- Design Description:
-- SDRAM refresh controller
-- Counts number of clock pulses for each refresh cycle.
-- If refresh is held-off, a count of cycles to be carried out when re-enabled is made.
---------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;


entity SDRAMRefresh is
  generic(ClocksPerCycle: integer := 100;
          RefreshCount  : integer := 1024);
	port(Reset          : in  std_ulogic;
	     SyncRst        : in  std_ulogic;
       InitWait       : in  std_ulogic;
	     RefreshHoldOff : in  std_ulogic;
	     SDClk          : in  std_ulogic;
		   RfshDone       : in  std_ulogic;
		   RfshReq        : out std_ulogic);
end SDRAMRefresh;


architecture Rtl of SDRAMRefresh is

	signal ClockCount: integer range 1 to ClocksPerCycle;
	signal CycleCount: integer range 0 to RefreshCount;

begin

	RfshCount: process (Reset, SDClk)
	begin
		if Reset = '1' then
		  ClockCount <= 1;
		elsif SDClk'event and SDClk = '1' then
		  if SyncRst = '1' or InitWait = '1' then
		    ClockCount <= 1;
		  else
		    if (ClockCount = ClocksPerCycle) then
		      ClockCount <= 1;
		    else
		      ClockCount <= ClockCount + 1;
        end if;
		  end if;
		end if;
	end process RfshCount;

	RfshCycleCount: process (Reset, SDClk)
	begin
		if Reset = '1' then
		  CycleCount <= 0;
		elsif SDClk'event and SDClk = '1' then
		  if SyncRst = '1' or InitWait = '1' then
		    CycleCount <= 0;
		  else
		    if ClockCount = ClocksPerCycle and RfshDone = '0' then
		      if CycleCount = RefreshCount then
            report "Refresh Held off for greater than refresh period" severity error;
		      else
		        CycleCount <= CycleCount + 1;
          end if;
	      end if;
        if RfshDone = '1' and ClockCount /= ClocksPerCycle then
          CycleCount <= Cyclecount - 1;
        end if;
		  end if;
		end if;
	end process RfshCycleCount;

	RfshReqLat : process (Reset, SDClk)
	begin
		if Reset = '1' then
			RfshReq <= '0';
		elsif SDClk'event and SDClk = '1' then
      if SyncRst = '1' or InitWait = '1' or RfshDone = '1' then
        RfshReq <= '0';
      elsif CycleCount > 0 and RefreshHoldOff = '0' then
        RfshReq <= '1';
      end if;
    end if;
	end process RfshReqLat;

end Rtl;
