library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.MyPackage.all; entity PWM_Unit is port(PWMCON_1: in BitVect16; PWMCON_0: in BitVect16; CPU_CLK:in SBit; HW_RESET:in SBit; PP0:in BitVect16; PW0:in BitVect16; PP1:in BitVect16; PW1:in BitVect16; PP2:in BitVect16; PW2:in BitVect16; PP3:in BitVect16; PW3:in BitVect16; CHANNEL_0:Out SBit; CHANNEL_1:out SBit; CHANNEL_2:out SBit; CHANNEL_3:out SBit); end PWM_Unit; architecture Behavioral of PWM_Unit is --Interne Signale für die Übernahme der Werte der Konfigurationsregister signal PWMCONInternal_0:BitVect16:=(others=>'0'); signal PWMCONInternal_1:BitVect16:=(others=>'0'); --Signale der Prescaler bzw. Clocksignale für die PWM-Timer signal PRE_CLK_0:SBit:='0'; signal PRE_CLK_1:SBit:='0'; signal PRE_CLK_2:SBit:='0'; signal PRE_CLK_3:SBit:='0'; --Aliaszuweisungen für die einzelnen Steuerleitungen/hier für PWMCON0 --PTR bzw.PWM-Timer Run-Control Bit(Stoppt/Startet den Timer) alias PTR_0:SBit is PWMCONInternal_0(0); alias PTR_1:SBit is PWMCONInternal_0(1); alias PTR_2:SBit is PWMCONInternal_0(2); alias PTR_3:SBit is PWMCONInternal_0(3); --PTI bzw. PWM-Timer Input-Clock-Selection(Prescaler an/aus) alias PTI_0:SBit is PWMCONInternal_0(4); alias PTI_1:SBit is PWMCONInternal_0(5); alias PTI_2:SBit is PWMCONInternal_0(6); alias PTI_3:SBit is PWMCONInternal_0(7); --PIE bzw. PWM-Channel Interrupt Enable Flags/wird nicht benutzt alias PIE_0:SBit is PWMCONInternal_0(8); alias PIE_1:SBit is PWMCONInternal_0(9); alias PIE_2:SBit is PWMCONInternal_0(10); alias PIE_3:SBit is PWMCONInternal_0(11); --PIR bzw. PWM-Channel Interrupt Request Flags/wird nicht benutzt alias PIR_0:SBit is PWMCONInternal_0(12); alias PIR_1:SBit is PWMCONInternal_0(13); alias PIR_2:SBit is PWMCONInternal_0(14); alias PIR_3:SBit is PWMCONInternal_0(15); --Aliaszuweisungen für die einzelnen Steuerleitungen/hier für PWMCON1 --PEN bzw. PWM-Channel Output Enable Bits alias PEN_0:SBit is PWMCONInternal_1(0); alias PEN_1:SBit is PWMCONInternal_1(1); alias PEN_2:SBit is PWMCONInternal_1(2); alias PEN_3:SBit is PWMCONInternal_1(3); --PM bzw. PWM-Channel Mode Control Bits/Edge oder Center Aligned alias PM_0:SBit is PWMCONInternal_1(4); alias PM_1:SBit is PWMCONInternal_1(5); alias PM_2:SBit is PWMCONInternal_1(6); alias PM_3:SBit is PWMCONInternal_1(7); --PB_01 bzw.PWM-Channel 0/1 Control Bit alias PB_01:SBit is PWMCONInternal_1(12); --PS3 und PS2 bzw. die Controlbits für den SingleShot-Modus alias PS_2:SBit is PWMCONInternal_1(14); alias PS_3:SBit is PWMCONInternal_1(15); --Nicht genutzte Bits der Signale alias Redundant13 :SBit is PWMCONInternal_1(13); alias Redundant11_8:BitVect4 is PWMCONInternal_1(11 downto 8); --Signale und Konstanten für den internen Timer_0 nebst dazugehörigen Registerpaar signal InternalPPValue:BitVect16:=Zero_16Bit; signal InternalPWValue:BitVect16:=Zero_16Bit; signal InternalPPValue2:BitVect16:=Zero_16Bit; signal InternalPWValue2:BitVect16:=Zero_16Bit; signal InternalPPValue3:BitVect16:=Zero_16Bit; signal InternalPWValue3:BitVect16:=Zero_16Bit; signal InternalPPValue4:BitVect16:=Zero_16Bit; signal InternalPWValue4:BitVect16:=Zero_16Bit; --Signale für die Übernahme der Zählwerte signal CountValue:BitVect16:=Zero_16Bit; signal CountValue2:BitVect16:=Zero_16Bit; signal CountValue3:BitVect16:=Zero_16Bit; signal CountValue4:BitVect16:=Zero_16Bit; --Generierte Taktsignale für die Steuerung der Shadowregister signal FetchCLK:SBit:='0'; signal FirstFetch:SBit:='0'; signal switch:SBit:='0'; signal FetchCLK2:SBit:='0'; signal FirstFetch2:SBit:='0'; signal switch2:SBit:='0'; signal FetchCLK3:SBit:='0'; signal FirstFetch3:SBit:='0'; signal switch3:SBit:='0'; signal FetchCLK4:SBit:='0'; signal FirstFetch4:SBit:='0'; signal switch4:SBit:='0'; --Signale für die Steuereinheit des Burstmodus signal burst0:SBit:='0'; signal burst1:SBit:='0'; begin --Prozess für die Übernahme der Konfigurationswerte in interne Register config:process(CPU_CLK,HW_RESET) begin --asynchroner Reset durch Phasengenerator/Löschen der Registerinhalte if(HW_RESET='0')then PWMCONInternal_0<=Zero_16Bit; PWMCONInternal_1<=Zero_16Bit; --taktflankensensitive Übernahme anliegender Konfigurationswerte elsif(rising_edge(CPU_CLK))then PWMCONInternal_0<=PWMCON_0; PWMCONInternal_1<=PWMCON_1; else --Inhalte sonst unverändert lassen PWMCONInternal_0<=PWMCONInternal_0; PWMCONInternal_1<=PWMCONInternal_1; end if; end process config; --nicht benutzte Signale deaktivieren/Signale sind nur der Vollständigkeit wegen aufgeführt PIR_0<=not PIR_0; PIR_1<=not PIR_1; PIR_2<=not PIR_2; PIR_3<=not PIR_3; PIE_0<=not PIE_0; PIE_1<=not PIE_1; PIE_2<=not PIE_2; PIE_3<=not PIE_3; Redundant13<=not Redundant13; Redundant11_8<=not Redundant11_8; --Prozesse für die Taktgenerierung/////////////////////////////////////////////////////////////// --Generierung des Taktes für den PWM-Timer 0 prescale_0:process(CPU_CLK,PTI_0,HW_RESET) --Zählvariable des Counters variable count:Integer:=0; begin --asynchroner Reset/Zurücksetzen des internen Counters if (HW_RESET='0')then count:=0; elsif(rising_edge(CPU_CLK))then--taktflankensensititv inkrementieren if(count'0'); switch<='0'; mode:='0'; FirstFetch<='1'; FetchCLK<='0'; elsif(PTR_0='1')then if(PM_0='0')then if(rising_edge(PRE_CLK_0))then if(count>=InternalPPValue)then count:=Zero_16Bit; CountValue<=count; switch<='1'; FetchCLK<='1'; FirstFetch<='0'; elsif(countZero_16Bit)then count:=count-1; FirstFetch<='0'; switch<='1'; CountValue<=count; FetchCLK<='0'; elsif(count-1=Zero_16Bit)then count:=count+1; FirstFetch<='0'; switch<='1'; CountValue<=count; FetchCLK<='1'; mode:='0'; elsif(count=Zero_16Bit)then count:=count+1; FirstFetch<='1'; switch<='1'; CountValue<=count; FetchCLK<='0'; mode:='0'; end if; end if;end if;end if;end if; end process COUNT0; --Kanal 1------------------------------------------------------------------- COUNT1:process(PM_1,PTR_1,PRE_CLK_1,HW_RESET, InternalPPValue2) variable count:BitVect16:=Zero_16Bit; variable mode:SBit:='0'; begin if(HW_RESET='0'or(InternalPPValue2=Zero_16Bit))then count:=Zero_16Bit; switch2<='0'; mode:='0'; FirstFetch2<='1'; FetchCLK2<='0'; elsif(PTR_1='1')then if(PM_1='0')then if(rising_edge(PRE_CLK_1))then if(count>=InternalPPValue2)then count:=Zero_16Bit; CountValue2<=count; switch2<='1'; FetchCLK2<='1'; FirstFetch2<='0'; elsif(countZero_16Bit)then count:=count-1; FirstFetch2<='0'; switch2<='1'; CountValue2<=count; FetchCLK2<='0'; elsif(count-1=Zero_16Bit)then count:=count+1; FirstFetch2<='0'; switch2<='1'; CountValue2<=count; FetchCLK2<='1'; mode:='0'; elsif(count=Zero_16Bit)then count:=count+1; FirstFetch2<='1'; switch2<='1'; CountValue2<=count; FetchCLK2<='0'; mode:='0'; end if; end if;end if;end if;end if; end process COUNT1; --Register zum Puffern von PP0 und PW0 Reload:process(FirstFetch,PP0,HW_RESET,InternalPPValue,PW0,FetchCLK) begin if(HW_RESET='0')then InternalPPValue<=(others=>'0'); InternalPWValue<=(others=>'0'); elsif(FirstFetch='1')then InternalPPValue<=PP0; InternalPWValue<=PW0; elsif(rising_edge(FetchCLK) )then InternalPPValue<=PP0; InternalPWValue<=PW0; else InternalPWValue<=InternalPWValue; InternalPPValue<=InternalPPValue;end if; end process Reload; Reload2:process(FirstFetch2,PP1,HW_RESET,InternalPPValue2,PW1,FetchCLK2) begin if(HW_RESET='0')then InternalPPValue2<=(others=>'0'); InternalPWValue2<=(others=>'0'); elsif(FirstFetch2='1')then InternalPPValue2<=PP1; InternalPWValue2<=PW1; elsif(rising_edge(FetchCLK2) )then InternalPPValue2<=PP1; InternalPWValue2<=PW1; else InternalPWValue2<=InternalPWValue2; InternalPPValue2<=InternalPPValue2;end if; end process Reload2; --Compare-Einheit für die Modulation der Pulsweite für Channel 0 --Generierte Pulsweite wird in ein internes Signal geschrieben/siehe Burst compare_0:process(switch,InternalPWValue,HW_RESET,InternalPPValue,CountValue,PEN_0) begin if(PEN_0='1')then--PWM-Channel Output eingeschaltet --Reset durch Phasengenerator->Ausgang auf logisch null setzen bzw.Abfrage, --ob ein Reset stattgefunden hat, sonst fehlerhaftes Verhalten aufgrund gleicher Inhalte der --PT-Register(beide auf null->PP gleich PW->Generierung der Pulsweite) if(HW_RESET='0' or switch='0')then burst0<='0';--Ausgang auf logisch null setzen --sonst Generierung der Pulsweite durch Vergleich von Pulsperiode und Pulsweite elsif((CountValue>=InternalPWValue)and(InternalPPValue>Zero_16Bit)and switch='1')then burst0<='1';--Pulsperiode grösser/gleich Pulsweite->Ausgang logisch eins else burst0<='0';--sonst null end if; else burst0<='0';--sonst null,da PWM-Channel Output ausgeschaltet end if; end process compare_0; --Compare-Einheit für die Modulation der Pulsweite für Channel 1 --Generierte Pulsweite wird in ein internes Signal geschrieben/siehe Prozess burst --Das Verhalten dieser Compare-Einheit ist identisch der für Channel 0/siehe Kommentare compare_1:process(switch2,InternalPWValue2,HW_RESET,InternalPPValue2,CountValue2,PEN_1) begin if(PEN_1='1')then if(HW_RESET='0' or switch2='0')then burst1<='0'; elsif((CountValue2>=InternalPWValue2)and(InternalPPValue2>Zero_16Bit)and switch2='1')then burst1<='1'; else burst1<='0'; end if; else burst1<='0'; end if; end process compare_1; --Prozess für die Steuerung des Burstmodus burst:process(PB_01,burst0,burst1) begin if(PB_01='1')then if(burst0='1' and burst1='1')then CHANNEL_0<='1'; CHANNEL_1<=burst1; else CHANNEL_0<='0'; CHANNEL_1<=burst1; end if; else CHANNEL_0<=burst0; CHANNEL_1<=burst1; end if; end process burst; --Behandlung der Kanäle 2 und 3/Single Shot implementiert COUNT3:process(PM_2,PTR_2,PRE_CLK_2,HW_RESET,InternalPPValue3,PS_2,PW2) variable count:BitVect16:=Zero_16Bit; variable mode:SBit:='0'; begin if(HW_RESET='0'or(InternalPPValue3=Zero_16Bit))then count:=Zero_16Bit; switch3<='0'; mode:='0'; FirstFetch3<='1'; FetchCLK3<='0'; elsif(PTR_2='1')then if(PM_2='0')then if(rising_edge(PRE_CLK_2))then if(PS_2='1')then FirstFetch3<='1'; FetchCLK3<='0'; switch3<='1'; count:=PW2; CountValue3<=count;--*** elsif(count>=InternalPPValue3)then count:=Zero_16Bit; CountValue3<=count; switch3<='1'; FetchCLK3<='1'; FirstFetch3<='0'; elsif(countZero_16Bit)then count:=count-1; FirstFetch3<='0'; switch3<='1'; CountValue3<=count; FetchCLK3<='0'; elsif(count-1=Zero_16Bit)then count:=count+1; FirstFetch3<='0'; switch3<='1'; CountValue3<=count; FetchCLK3<='1'; mode:='0'; elsif(count=Zero_16Bit)then count:=count+1; FirstFetch3<='1'; switch3<='1'; CountValue3<=count; FetchCLK3<='0'; mode:='0'; end if; end if;end if;end if;end if; end process COUNT3; --Kanal4 COUNT4:process(PM_3,PTR_3,PRE_CLK_3,HW_RESET,InternalPPValue4,PS_3) variable count:BitVect16:=Zero_16Bit; variable mode:SBit:='0'; begin if(HW_RESET='0'or(InternalPPValue4=Zero_16Bit))then count:=Zero_16Bit; switch4<='0'; mode:='0'; FirstFetch4<='1'; FetchCLK4<='0'; elsif(PTR_3='1')then if(PM_3='0')then if(rising_edge(PRE_CLK_3))then if(PS_3='1')then FirstFetch4<='1'; FetchCLK4<='0'; switch4<='1'; count:=PW3;--*** CountValue4<=count; elsif(count>=InternalPPValue4)then count:=Zero_16Bit; CountValue4<=count; switch4<='1'; FetchCLK4<='1'; FirstFetch4<='0'; elsif(countZero_16Bit)then count:=count-1; FirstFetch4<='0'; switch4<='1'; CountValue4<=count; FetchCLK4<='0'; elsif(count-1=Zero_16Bit)then count:=count+1; FirstFetch4<='0'; switch4<='1'; CountValue4<=count; FetchCLK4<='1'; mode:='0'; elsif(count=Zero_16Bit)then count:=count+1; FirstFetch4<='1'; switch4<='1'; CountValue4<=count; FetchCLK4<='0'; mode:='0'; end if; end if;end if;end if;end if; end process COUNT4; Reload3:process(FirstFetch3,PP2,HW_RESET,InternalPPValue3,PW2,FetchCLK3) begin if(HW_RESET='0')then InternalPPValue3<=(others=>'0'); InternalPWValue3<=(others=>'0'); elsif(FirstFetch3='1')then InternalPPValue3<=PP2; InternalPWValue3<=PW2; elsif(rising_edge(FetchCLK3) )then InternalPPValue3<=PP2; InternalPWValue3<=PW2; else InternalPWValue3<=InternalPWValue3; InternalPPValue3<=InternalPPValue3;end if; end process Reload3; Reload4:process(FirstFetch4,PP3,HW_RESET,InternalPPValue3,PW3,FetchCLK4) begin if(HW_RESET='0')then InternalPPValue4<=(others=>'0'); InternalPWValue4<=(others=>'0'); elsif(FirstFetch4='1')then InternalPPValue4<=PP3; InternalPWValue4<=PW3; elsif(rising_edge(FetchCLK4) )then InternalPPValue4<=PP3; InternalPWValue4<=PW3; else InternalPWValue4<=InternalPWValue4; InternalPPValue4<=InternalPPValue4;end if; end process Reload4; compare:process(CountValue3,InternalPWValue3,PEN_2,switch3) begin if(PEN_2='1')then if(switch3='0')then CHANNEL_2<='0'; elsif(CountValue3>=InternalPWValue3)then CHANNEL_2<='1'; else CHANNEL_2<='0'; end if; else CHANNEL_2<='0'; end if; end process compare; compare2:process(CountValue4,InternalPWValue4,PEN_3,switch4) begin if(PEN_3='1')then if(switch4='0')then CHANNEL_3<='0'; elsif(CountValue4>=InternalPWValue4)then CHANNEL_3<='1'; else CHANNEL_3<='0'; end if; else CHANNEL_3<='0'; end if; end process compare2; end Behavioral;