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

ENTITY testbench_hbridge IS
END;

ARCHITECTURE Behavioral OF testbench_hbridge IS
	
	CONSTANT NumOfePWM:	integer	:=	2;

	CONSTANT clock_period: delay_length := 20 ns;	-- 1/50MHz

	SIGNAL SYSCLK, EPWMxSYNCO: std_logic := '0';
	
	SIGNAL EPWMxSYNCI : std_logic := '0';
	
	SIGNAL TZ : std_logic_vector(5 DOWNTO 0) := (OTHERS => '0');
	
	-- 
	-- ePWM registers
	--
	
	TYPE reg16bit IS ARRAY (NumOfePWM-1 downto 0) of std_logic_vector(15 DOWNTO 0);
	
	SIGNAL TBCTL	: reg16bit;
	SIGNAL TBSTS	: reg16bit;
	SIGNAL TBPHS	: reg16bit;
	SIGNAL TBCTR	: reg16bit;
	SIGNAL TBPRD	: reg16bit;
	
	SIGNAL CMPCTL	: reg16bit;
	SIGNAL CMPA 	: reg16bit;
	SIGNAL CMPB 	: reg16bit;
	
	SIGNAL AQCTLA	: reg16bit;
	SIGNAL AQCTLB	: reg16bit;
	
	SIGNAL DBCTL	: reg16bit;
	SIGNAL DBRED	: reg16bit;
	SIGNAL DBFED	: reg16bit;
	
	SIGNAL SYNCI: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	SIGNAL SYNCO: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	
	SIGNAL EPWMXA: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	SIGNAL EPWMXB: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	
	SIGNAL EPWMxSOCA: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	SIGNAL EPWMxSOCB: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	SIGNAL EPWMxINTn: std_logic_vector(NumOfePWM-1 DOWNTO 0);
	
BEGIN

	--
	-- clk signal generation
	--
	
	clock_process: PROCESS 
	BEGIN
		SYSCLK <= NOT SYSCLK;
      WAIT FOR clock_period/2;
	END PROCESS;
	
	--
	-- devices under test
	--
												
	AddePWM: for i IN 0 TO 1 GENERATE
	
		ePWM: ENTITY work.ePWM PORT MAP(	SYSCLK 		=> SYSCLK, 
													EPWMXA 		=> EPWMXA(i), 
													EPWMXB 		=> EPWMXB(i), 
													TBCTL 		=> TBCTL(i),
													TBSTS 		=>	TBSTS(i),
													TBPHS 		=> TBPHS(i), 
													TBCTR 		=> TBCTR(i), 
													TBPRD 		=> TBPRD(i),
													CMPCTL 		=> CMPCTL(i), 
													CMPA 			=> CMPA(i), 
													CMPB 			=> CMPB(i),
													AQCTLA 		=> AQCTLA(i), 
													AQCTLB 		=> AQCTLA(i), 
													DBCTL 		=> DBCTL(i), 
													DBRED 		=> DBRED(i), 
													DBFED 		=> DBFED(i),
													TZSEL 		=> "0000000000000000", 
													TZCTL 		=> "0000000000001111", 
													TZEINT 		=>	"0000000000000000", 
													TZFLG 		=> open, 
													TZCLR		 	=> "0000000000000000", 
													TZFRC 		=> "0000000000000110",
													ETSEL 		=> "1100110000001100", 
													--ETPS 			=> "0011111100000000", 
													ETFLG 		=> open,
													ETCLR 		=> "0000000000000000", 
													ETFRC 		=> "0000000000001101", 
													PCCTL 		=> "0000000000000000",													
													TZ 			=> TZ,
													EPWMxSYNCI 	=> SYNCI(i), 
													EPWMxSYNCO 	=> SYNCO(i),
													EPWMxSOCA 	=> EPWMxSOCA(i),
													EPWMxSOCB 	=> EPWMxSOCB(i),
													EPWMxINTn 	=> EPWMxINTn(i));	
	
	END GENERATE AddePWM;
	
	--! ePWM sync signals connect
	
	SYNCI(0) <= EPWMxSYNCI;
	
	generateSig: for i IN 1 TO NumOfePWM-1 GENERATE
	
		SYNCI(i) <= SYNCO(i-1);
		
	END GENERATE generateSig;	
	
	
	--! testbench sequence

	main_sequence: PROCESS
	
	BEGIN
	
		WAIT FOR 100 us;	-- power up and wait for 100 us
	
		-- registers initialization
	
/*		
   bit 15-14   FREE,SOFT = 00   ; 11 => nezastavovat casovou zakladnu pri emulaci
   bit 13      PHSDIR    = 0    ; 0 => v up-down rezimu citat po synchronizaci smerem dolu
   bit 12-10   CLKDIV    = 000  ; TBCLK = SYSCLKOUT / (2*"HSPCLKDIV" * 2^CLKDIV)
   bit 9-7     HSPCLKDIV = 000  ; TBCLK = SYSCLKOUT / (2*"HSPCLKDIV" * 2^CLKDIV)
   bit 6       SWFSYNC   = 0    ; zapis jednicky by pri PHSEN=1 vyvolal softwarovou synchronizaci
   bit 5-4     SYNCOSEL  = 01   ; 11 => signal EWMxSYNCO zakazan
   bit 3       PRDLD     = 0    ; 0  => perioda casove zakladny pres stinovy registr (kopiruje se pri TBCTR=0)
   bit 2       PHSEN     = 1    ; 0  => ignorovat synchronizaci (EPWMxSYNCI nebo softwarovou synchronizace).
   bit 1-0     CTRMODE   = 00   ; 10 => timer UP/DOWN
*/	 
		TBCTL(0)	<= x"0014";
		TBCTL(1)	<= x"0014";
		
/*
	posunuti faze
*/		
		TBPHS(0)	<=	x"0000";
		TBPHS(1)	<= x"0000";		
		
/*
	frekvence clk = 50 MHz
	frekvence pwm = 10 kHz
	(50 000 000 / 10 000) = 5000 = 0x1388
*/		
		TBPRD(0)	<= x"1388";
		TBPRD(1)	<= x"1388";
		
		
		CMPCTL(0) <= x"0050";
		CMPCTL(1) <= x"0050";


		CMPA(0) 		<= x"09c4";		-- change duty cycle 0%
		CMPA(1) 		<= x"09c4";		-- change duty cycle 0%
		
		CMPB(0) 		<= x"0001";		-- must contain different value than CMPA because of priority in Action Qualifier (described in sprug04a)
		CMPB(1) 		<= x"0001";		-- must contain different value than CMPA because of priority in Action Qualifier (described in sprug04a)		

/*
   bit 11-10     00:     CBD, 00 = do nothing
   bit 9-8       00:     CBU, 00 = do nothing
   bit 7-6       01:     CAD, 01 = do nothing
   bit 5-4       10:     CAU, 01 = clear
   bit 3-2       00:     PRD, 00 = do nothing
   bit 1-0       00:     ZRO, 10 = set	
*/		
		AQCTLA(0) 	<= x"0061";
		AQCTLA(1) 	<= x"0061";
		
		AQCTLB(0) 	<= x"0000";
		AQCTLB(1) 	<= x"0000";
/*		
   bit 15-6      0's:    reserved
   bit 5-4       00:     IN_MODE, 00 = EPWMxA is source EPWM1A & EPWM1B
   bit 3-2       10:     POLSEL, 10 = channel B output is inverted
   bit 1-0       11:     OUT_MODE, 11 = delay on A input, delay on B input (rising & falling edge!)		
*/		
		DBCTL(0) 	<= x"000b";
		DBCTL(1) 	<= x"000b";
		
/* t_dead = 3.5 us (3500ns/20ns = 175 clk = 0x00af)*/

		DBRED(0) 	<= x"00af";  	
		DBFED(0) 	<= x"00af";		
		
		DBRED(1) 	<= x"00af";  	
		DBFED(1) 	<= x"00af";		
		

		WAIT FOR 100 us;			-- wait for 1 period and 10 us to test shadow register
		
		TBPHS(1)	<= x"09c4";		-- change phase offset to 90 deg
		
		WAIT FOR 200 us;
		
		--TBPHS(1)	<= x"04e2";		-- change duty cycle to 50%

		WAIT FOR 200 us;
		
		--TBPHS(1)	<= x"0753";		-- change duty cycle to 75%

		WAIT FOR 200 us;
		
		--TBPHS(1)	<= x"09c4";		-- change duty cycle to 100%

		WAIT;
	
	END PROCESS;	
	

END Behavioral;