--
-- VHDL Architecture THERMAL_CNTRL_lib.PWM_CNTRL.rtl
--
-- Created:
--          by - JUSTIN DEARY
--          at - 06/14/2006
--
-- Mentor Graphics HDL Designer(TM) 2004.1a (Build 15)
-------------------------------------------------------------

-- This PWM control component generates a pwm frequency to a heater/fan at a 70Hz frequency.
-- The PWM duty cycle is set by the 16 bit value of MOD_CV_CNTRL "modified Control variable register" 
--
-- new PWM_DCYCLE_CNT and PWM_FREQ_CNT values are loaded on falling edge of DATARDY so proper arbitration
-- must be managed to ensure valid count value.


-- Component Requirements
-- CNT_CLOCK must be 4.5MHz to produce 70Hz pwm frequency
-- DATARDY must be a synchronized signal


LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;

--EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
ENTITY PWM_CNTRL IS
  PORT(           
  --INPUTS FROM BOARD
  SYSCLOCK        : IN  STD_LOGIC;   -- system clock
  CNT_CLOCK       : IN  STD_LOGIC;   -- pos_edge clock that sets pwm freq range. clock must be doc in perf spec        
  RESET           : IN  STD_LOGIC;   -- high active - PLD Reset
  TRI_REG         : IN  STD_LOGIC;   -- tristates PWM output pin

  DATARDY         : IN    STD_LOGIC;   -- high active -  SINAL MUST BE SYNCHED!!
  PWMOUT          : OUT   STD_LOGIC;       
  PWM_FREQ_CNT    : IN    STD_LOGIC_VECTOR(15 downto 0);   
  PWM_DCYCLE_CNT  : IN    STD_LOGIC_VECTOR(15 downto 0));  -- PWM_DCYCLE_CNT must be less then PWM_FREQ_CNT

END PWM_CNTRL;
--EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE




--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--THE ARCHITECTURE BODY DESCRIBES THE FUNCTIONAL COMPOSITION OF THIS DESIGN
architecture rtl of pwm_cntrl is    

SIGNAL  PWMCOUNT              :unsigned (15 downto 0); 
SIGNAL  B_PWM_FREQ_CNT        :unsigned (15 downto 0);  
SIGNAL  B_PWM_DCYCLE_CNT      :unsigned (15 downto 0);
BEGIN
  

  DCYCLE_REG: PROCESS(DATARDY ,RESET,SYSCLOCK)   
  begin        
    if (RESET = '1') then    
      B_PWM_DCYCLE_CNT    <= X"4000";   --keeps fan at 50% during reset
      B_PWM_FREQ_CNT      <= X"8000";           
    elsif rising_edge(SYSCLOCK) then
	  if (DATARDY  = '0') then 
        B_PWM_FREQ_CNT <= unsigned(PWM_FREQ_CNT);         --buffered register written on falling edge of DATARDY       
        if   (B_PWM_FREQ_CNT < unsigned(PWM_DCYCLE_CNT)) then 
           B_PWM_DCYCLE_CNT <= B_PWM_FREQ_CNT;     --ensures software never drives less then 25%duty cycle         
        else
           B_PWM_DCYCLE_CNT <= unsigned(PWM_DCYCLE_CNT);     --buffered register written on falling edge of DATARDY   
        end if;
	  end if;	       
    end if;                              
  END PROCESS DCYCLE_REG;            
  

  PWMPROCESS: PROCESS(CNT_CLOCK)     
  begin        
    if (rising_edge(CNT_CLOCK)) then 
        if (PWMCOUNT < B_PWM_FREQ_CNT) then   --B_PWM_FREQ_CNT sets pwm frequency
          PWMCOUNT <= PWMCOUNT + X"0001";
        else 
          PWMCOUNT <= X"0000";
        end if;     
    end if;                                      
  END PROCESS PWMPROCESS;                           
  
  
  -- THIS PROCESS HOLDS THE LOGIC FOR THE PWM OUTPUT. 
  PWM_LOGIC: PROCESS(CNT_CLOCK)     
  begin
  if (TRI_REG = '0') then 
      if (B_PWM_DCYCLE_CNT > PWMCOUNT) then
        PWMOUT <= '1';
      else
        PWMOUT <= '0';
      end if;
  elsif (TRI_REG = '1') then
      PWMOUT <= 'Z';
  end if;  
   
  END PROCESS PWM_LOGIC;
  
END ARCHITECTURE rtl;

