LIBRARY ieee;
USE ieee.numeric_std.all;
USE ieee.std_logic_1164.all;

ENTITY ePWM IS
	PORT
	(
		SYSCLK 		: 	IN		std_logic;								--! System clock
		EPWMxSYNCI	: 	IN 		std_logic;								--! Time-base synchronization input.
		TZ			:	IN 		std_logic_vector(5 DOWNTO 0); 			--! Trip zone inputs
		EPWMxSYNCO 	:  	OUT 	std_logic;								--! Time-base synchronization output. 
		
		EPWMxSOCA	:	OUT 	std_logic;								--! SOC pulse output A
		EPWMxSOCB	:	OUT 	std_logic;								--! SOC pulse output B
		EPWMxINTn	:	OUT 	std_logic;								--! Event Trigger interrupt output
		
		EPWMXTZINT 	: 	OUT 	std_logic;								--! Trip Zone interrupt output
		
		EPWMXA		: 	OUT 	std_logic; 								--! PWM output A
		EPWMXB		: 	OUT 	std_logic;								--! PWM output	B	
		
		TBCTL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Time-Base Control Register
		TBSTS		:	OUT		std_logic_vector(15 DOWNTO 0);			--! Time-Base Status Register
		--TBPHSHR		:	IN		std_logic_vector(15 DOWNTO 0);			--! Extension for HRPWM Phase Register (NOT IMPLEMENTED YET)	
		TBPHS		:	IN		std_logic_vector(15 DOWNTO 0);			--! Time-Base Phase Register
		TBCTR		:	OUT		std_logic_vector(15 DOWNTO 0);			--! Time-Base Counter Register
		TBPRD		:	IN		std_logic_vector(15 DOWNTO 0);			--! Time-Base Period Register
		
		CMPCTL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Counter-Compare Control Register
		--CMPAHR		:	IN		std_logic_vector(15 DOWNTO 0);			--! Extension for HRPWM Counter-Compare A Register (NOT IMPLEMENTED YET)
		CMPA		:	IN		std_logic_vector(15 DOWNTO 0);			--! Counter-Compare A Register
		CMPB		:	IN		std_logic_vector(15 DOWNTO 0);			--! Counter-Compare B Register
		
		AQCTLA		:	IN		std_logic_vector(15 DOWNTO 0);			--! Action-Qualifier Control Register for Output A (EPWMxA)
		AQCTLB		:	IN		std_logic_vector(15 DOWNTO 0);			--! Action-Qualifier Control Register for Output B (EPWMxB)
		--AQSFRC		:	IN		std_logic_vector(15 DOWNTO 0);			--! Action-Qualifier Software Force Register
		--AQCSFRC		:	IN		std_logic_vector(15 DOWNTO 0);			--! Action-Qualifier Continuous S/W Force Register Set
		
		DBCTL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Dead-Band Generator Control Register
		DBRED		:	IN		std_logic_vector(15 DOWNTO 0);			--! Dead-Band Generator Rising Edge Delay Count Register
		DBFED		:	IN		std_logic_vector(15 DOWNTO 0);			--! Dead-Band Generator Falling Edge Delay Count Register
		
		TZSEL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Select Register
		TZCTL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Control Register
		TZEINT		:	IN		std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Enable Interrupt Register
		TZFLG		:	OUT 	std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Flag Register
		TZCLR		:	IN		std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Clear Register
		TZFRC		:	IN		std_logic_vector(15 DOWNTO 0);			--! Trip-Zone Force Register
		
		ETSEL		:	IN		std_logic_vector(15 DOWNTO 0);			--! Event-Trigger Selection Register
		ETPS		:	INOUT	std_logic_vector(15 DOWNTO 0);			--! Event-Trigger Pre-Scale Register
		ETFLG		:	OUT		std_logic_vector(15 DOWNTO 0);			--! Event-Trigger Flag Register
		ETCLR		:	IN		std_logic_vector(15 DOWNTO 0);			--! Event-Trigger Clear Register
		ETFRC		:	IN		std_logic_vector(15 DOWNTO 0);			--! Event-Trigger Force Register
		
		PCCTL		:	IN		std_logic_vector(15 DOWNTO 0)			--! PWM-Chopper Control Register
	);
END ePWM;

ARCHITECTURE Structural OF ePWM IS

	SIGNAL TBCLK			:	std_logic := '0';										--! Time-base clock

	SIGNAL SIG_CTR			: 	std_logic_vector(15 DOWNTO 0) := (OTHERS => '0');		--! counter value
	SIGNAL SIG_CTR_PRD		: 	std_logic := '0';										--! Time-base counter equal to the specified period.
	SIGNAL SIG_CTR_ZERO		: 	std_logic := '0'; 										--! Time-base counter equal to zero
	SIGNAL SIG_CTR_CMPA		: 	std_logic := '0'; 										--! Time-base counter equal to active counter-compare A register
	SIGNAL SIG_CTR_CMPB		: 	std_logic := '0'; 										--! Time-base counter equal to active counter-compare B register 
	SIGNAL SIG_CTR_DIR		: 	std_logic := '0'; 										--! Time-base counter direction
	
	SIGNAL SIG_EPWMXA		: 	std_logic := '0'; 										--! EPWMXA signal from AQ to DB
	SIGNAL SIG_EPWMXB		: 	std_logic := '0'; 										--! EPWMXB signal from AQ to DB
	SIGNAL SIG_EPWMXA_DT	: 	std_logic := '0'; 										--! EPWMXA signal from DB to CHP
	SIGNAL SIG_EPWMXB_DT	: 	std_logic := '0'; 										--! EPWMXB signal from DB to CHP
	SIGNAL SIG_EPWMXA_CHP	: 	std_logic := '0'; 										--! EPWMXA signal from CHP to TZ
	SIGNAL SIG_EPWMXB_CHP	: 	std_logic := '0'; 										--! EPWMXB signal from CHP to TZ
		
	-- ePWM aliases map to register

	-- Time Base (TB)
	ALIAS CLKDIV 		IS TBCTL(13 DOWNTO 11);
	ALIAS HSPCLKDIV 	IS TBCTL(10 DOWNTO 8);
	ALIAS SYNCOSEL 		IS TBCTL(5 DOWNTO 4);
	ALIAS PRDLD 		IS TBCTL(3);
	ALIAS PHSEN			IS TBCTL(2);
	ALIAS CTRMODE		IS TBCTL(1 DOWNTO 0);	
	ALIAS CTRMAX		IS TBSTS(2);
	ALIAS SYNCI			IS TBSTS(1);
	ALIAS CTRDIR		IS TBSTS(0);

	-- Counter Compare (CC)
	-- ALIAS SHDWBFULL	IS CMPCTL(9);
	-- ALIAS SHDWAFULL	IS CMPCTL(8);
	ALIAS SHDWBMODE		IS CMPCTL(5);
	ALIAS SHDWAMODE		IS CMPCTL(4);
	ALIAS LOADBMODE		IS CMPCTL(3 DOWNTO 2);
	ALIAS LOADAMODE		IS CMPCTL(1 DOWNTO 0);
	
	-- Action Qualifier (AQ)
	ALIAS A_CBD			IS AQCTLA(11 DOWNTO 10);
	ALIAS A_CBU			IS AQCTLA(9 DOWNTO 8);
	ALIAS A_CAD			IS AQCTLA(7 DOWNTO 6);
	ALIAS A_CAU			IS AQCTLA(5 DOWNTO 4);
	ALIAS A_PRD			IS AQCTLA(3 DOWNTO 2);
	ALIAS A_ZRO			IS AQCTLA(1 DOWNTO 0);
	
	ALIAS B_CBD			IS AQCTLB(11 DOWNTO 10);
	ALIAS B_CBU			IS AQCTLB(9 DOWNTO 8);
	ALIAS B_CAD			IS AQCTLB(7 DOWNTO 6);
	ALIAS B_CAU			IS AQCTLB(5 DOWNTO 4);
	ALIAS B_PRD			IS AQCTLB(3 DOWNTO 2);
	ALIAS B_ZRO			IS AQCTLB(1 DOWNTO 0);
	
	-- Dead Band (DB)
	ALIAS IN_MODE		IS DBCTL(5 DOWNTO 4);
	ALIAS POLSEL		IS DBCTL(3 DOWNTO 2);
	ALIAS OUT_MODE		IS DBCTL(1 DOWNTO 0);
	ALIAS RIS_DEL		IS DBRED(9 DOWNTO 0);
	ALIAS FAL_DEL		IS DBFED(9 DOWNTO 0);
	
	-- Trip Zone (TZ)
	ALIAS	TZSEL_CBC	IS TZSEL(5 DOWNTO 0);
	ALIAS TZSEL_OSHT	IS TZSEL(13 DOWNTO 8);
	ALIAS TZA			IS TZCTL(1 DOWNTO 0);
	ALIAS TZB			IS TZCTL(3 DOWNTO 2);
	ALIAS TZEINT_OST	IS TZEINT(2);
	ALIAS TZEINT_CBC	IS TZEINT(1);	
	ALIAS TZFLG_OST		IS TZFLG(2);
	ALIAS TZFLG_CBC		IS TZFLG(1);
	ALIAS TZFLG_INT		IS TZFLG(0);
	ALIAS TZCLR_OST		IS TZCLR(2);
	ALIAS TZCLR_CBC		IS TZCLR(1);
	ALIAS TZCLR_INT		IS TZCLR(0);
	ALIAS TZFRC_OSHT	IS TZFRC(2);
	ALIAS TZFRC_CBC		IS TZFRC(1);
	
	-- Event Trigger (ET)
	ALIAS SOCB_EN		IS ETSEL(15);
	ALIAS SOCB_SEL		IS ETSEL(14 DOWNTO 12);
	ALIAS SOCA_EN		IS ETSEL(11);
	ALIAS SOCA_SEL		IS ETSEL(10 DOWNTO 8);
	ALIAS INT_EN		IS ETSEL(3);
	ALIAS INT_SEL		IS ETSEL(2 DOWNTO 0);
	ALIAS SOCB_PRD		IS ETPS(13 DOWNTO 12);
	ALIAS INT_PRD		IS ETPS(11 DOWNTO 10);
	ALIAS SOCA_PRD		IS ETPS(9 DOWNTO 8);
	ALIAS SOCB_CNT		IS ETPS(5 DOWNTO 4);
	ALIAS INT_CNT		IS ETPS(3 DOWNTO 2);
	ALIAS SOCA_CNT		IS ETPS(1 DOWNTO 0);
	ALIAS SOCB_ETFLG	IS ETFLG(3);
	ALIAS SOCA_ETFLG	IS ETFLG(2);
	ALIAS INT_ETFLG		IS ETFLG(0);
	ALIAS SOCB_ETCLR	IS ETCLR(3);
	ALIAS SOCA_ETCLR	IS ETCLR(2);
	ALIAS INT_ETCLR		IS ETCLR(0);
	ALIAS SOCB_ETFRC	IS ETFRC(3);
	ALIAS SOCA_ETFRC	IS ETFRC(2);
	ALIAS INT_ETFRC		IS ETFRC(0);
	
	-- Chopper (CHP)
	ALIAS CHPDUTY		IS PCCTL(10 DOWNTO 8);
	ALIAS CHPFREQ		IS PCCTL(7 DOWNTO 5);
	ALIAS OSHTWTH		IS PCCTL(4 DOWNTO 1);
	ALIAS CHPEN			IS PCCTL(0);
	
	
BEGIN

	time_base: ENTITY work.time_base
		PORT MAP 
		(
			SYSCLK 		=> SYSCLK,
			EPWMxSYNCI 	=> EPWMxSYNCI,
			EPWMxSYNCO 	=> EPWMxSYNCO,
			SYNCOSEL 	=> SYNCOSEL,
			CMPBE 		=> SIG_CTR_CMPB,
			CTRMODE 	=> CTRMODE, 
			TBPRD 		=> TBPRD,
			TBPHS 		=> TBPHS,
			PHSEN 		=> PHSEN,
			PRDLD 		=> PRDLD,
			CLKDIV 		=> CLKDIV,
			HSPCLKDIV 	=> HSPCLKDIV,
			CTR_dir 	=> SIG_CTR_DIR,
			CTR_zero 	=> SIG_CTR_ZERO,
			CTR_prd 	=> SIG_CTR_PRD,
			TBCLK 		=> TBCLK,
			CTR 		=> SIG_CTR
		);
																
	counter_compare: ENTITY work.counter_compare
		PORT MAP 
		(
			TBCLK 		=> TBCLK,
			CTR 		=> SIG_CTR,
			CTR_PRD 	=> SIG_CTR_PRD,
			CTR_ZERO 	=> SIG_CTR_ZERO,
			CMPA 		=> CMPA,
			SHDWAMODE 	=> SHDWAMODE,
			LOADAMODE 	=> LOADAMODE,
			--SHDWAFULL => SHDWAFULL,
			CMPAE 		=> SIG_CTR_CMPA,
			CMPB 		=> CMPB,
			CMPBE 		=> SIG_CTR_CMPB,
			SHDWBMODE 	=> SHDWBMODE,
			LOADBMODE 	=> LOADBMODE
			--SHDWBFULL => SHDWBFULL
		);	
																				
	action_qualifier: ENTITY work.action_qualifier 	
		PORT MAP 
		(
			TBCLK 		=> TBCLK,
			CTR_PRD 	=> SIG_CTR_PRD,
			CTR_ZERO 	=> SIG_CTR_ZERO,
			CTR_CMPA 	=> SIG_CTR_CMPA,
			CTR_CMPB 	=> SIG_CTR_CMPB,
			CTR_DIR  	=> SIG_CTR_DIR,
			CTR_MODE	=> CTRMODE,
			A_CBD 		=> A_CBD,
			A_CBU 		=> A_CBU,
			A_CAD 		=> A_CAD,
			A_CAU 		=> A_CAU,
			A_PRD 		=> A_PRD,
			A_ZRO 		=> A_ZRO,
			B_CBD 		=> B_CBD,
			B_CBU 		=> B_CBU,
			B_CAD 		=> B_CAD,
			B_CAU 		=> B_CAU,
			B_PRD 		=> B_PRD,
			B_ZRO 		=> B_ZRO,	
			EPWMXA 		=> SIG_EPWMXA,
			EPWMXB		=> SIG_EPWMXB
		);
																				
	dead_band: ENTITY work.dead_band
		PORT MAP 
		(
			TBCLK 		=> TBCLK,
			EPWMXA_IN	=> SIG_EPWMXA,
			EPWMXB_IN 	=> SIG_EPWMXB,
			IN_MODE 	=> IN_MODE,
			POLSEL 		=> POLSEL,
			OUT_MODE 	=> OUT_MODE,
			RIS_DEL 	=> RIS_DEL,
			FAL_DEL 	=> FAL_DEL,
			EPWMXA_OUT 	=> SIG_EPWMXA_DT,
			EPWMXB_OUT 	=> SIG_EPWMXB_DT
		);
																				
	pwm_chopper: ENTITY work.pwm_chopper 		
		PORT MAP 
		(
			SYSCLK 		=> SYSCLK,
			EPWMXA_IN 	=> SIG_EPWMXA_DT,
			EPWMXB_IN 	=> SIG_EPWMXB_DT,
			CHPDUTY 	=> CHPDUTY,
			CHPFREQ 	=> CHPFREQ,
			OSHTWTH 	=> OSHTWTH,
			CHPEN 		=> CHPEN,
			EPWMXA_OUT 	=> SIG_EPWMXA_CHP,
			EPWMXB_OUT 	=> SIG_EPWMXB_CHP
		);
																				
	trip_zone: ENTITY work.trip_zone
		PORT MAP 
		(	
			TBCLK 		=> TBCLK,
			EPWMXA_IN 	=> SIG_EPWMXA_CHP,
			EPWMXB_IN 	=> SIG_EPWMXB_CHP,
			TZ 			=> TZ,
			TZSEL_CBC 	=> TZSEL_CBC,
			TZSEL_OSHT 	=> TZSEL_OSHT,	
			TZA 		=> TZA,
			TZB 		=> TZB,
			CTR_ZERO 	=> SIG_CTR_ZERO,
			TZEINT_CBC 	=> TZEINT_CBC,
			TZEINT_OST	=> TZEINT_OST,
			TZFLG_CBC 	=> TZFLG_CBC,
			TZFLG_OST 	=> TZFLG_OST,
			TZFLG_INT 	=> TZFLG_INT,
			TZCLR_CBC 	=> TZCLR_CBC,
			TZCLR_OST 	=> TZCLR_OST,
			TZCLR_INT 	=> TZCLR_OST,
			TZFRC_CBC 	=> TZFRC_CBC,
			TZFRC_OSHT 	=> TZFRC_OSHT,
			EPWMXA_OUT 	=> EPWMXA,
			EPWMXB_OUT 	=> EPWMXB,
			EPWMXTZINT 	=> EPWMXTZINT
		);
																			
	event_trigger: ENTITY work.event_trigger
		PORT MAP 
		(	
			TBCLK 		=> TBCLK,
			CTR_CMPA 	=> SIG_CTR_CMPA,
			CTR_CMPB 	=> SIG_CTR_CMPB,
			CTR_dir 	=> SIG_CTR_DIR,
			CTR_zero 	=> SIG_CTR_ZERO,
			CTR_prd 	=> SIG_CTR_PRD,
			EPWMxSOCA 	=> EPWMxSOCA,
			EPWMxSOCB 	=> EPWMxSOCB,
			EPWMxINTn 	=> EPWMxINTn,
			SOCB_EN 	=> SOCB_EN,
			SOCB_SEL 	=> SOCB_SEL,
			SOCA_EN 	=> SOCA_EN,
			SOCA_SEL 	=> SOCA_SEL,
			INT_EN 		=> INT_EN,
			INT_SEL 	=> INT_SEL,
			SOCB_CNT 	=> SOCB_CNT,
			SOCB_PRD 	=> SOCB_PRD,
			SOCA_CNT 	=> SOCA_CNT,
			SOCA_PRD 	=> SOCA_PRD,
			INT_CNT 	=> INT_CNT,
			INT_PRD 	=> INT_PRD,
			SOCB_ETFLG 	=> SOCB_ETFLG,
			SOCA_ETFLG 	=> SOCA_ETFLG,
			INT_ETFLG 	=> INT_ETFLG,
			SOCB_ETCLR 	=> SOCB_ETCLR,
			SOCA_ETCLR 	=> SOCA_ETCLR,
			INT_ETCLR 	=> INT_ETCLR,
			SOCB_ETFRC 	=> SOCB_ETFRC,
			SOCA_ETFRC	=> SOCA_ETFRC,
			INT_ETFRC 	=> INT_ETFRC
		);

	TBCTR <= SIG_CTR;

END Structural;