--library IEEE; --use IEEE.STD_LOGIC_1164.ALL; --use IEEE.NUMERIC_STD.ALL; Library UNISIM; use UNISIM.vcomponents.all; LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; entity blinkled is Port ( clk : in STD_LOGIC; led0 : out STD_LOGIC; led1 : out STD_LOGIC; led2 : out STD_LOGIC; led3 : out STD_LOGIC; pio1 : out STD_LOGIC; pio2 : out STD_LOGIC; uart_tx : out STD_LOGIC; uart_rx : in STD_LOGIC ); end blinkled; -- Clock-In == 6MHz, Toggeln nach 3000000 Schritten ergibt 1Hz Blinkfrequenz. architecture Behavioral of blinkled is signal ausgabefreq : natural range 0 to (2**31)-1 := 1000000; --- in Hz signal pulsdauer : natural range 0 to (2**31)-1 := 1000; --- in ps -- phaseshift state machine signal phaseshiftstate : natural range 0 to 63 := 0; signal phaseshiftcnt : natural range 0 to (2**31)-1 := 0; signal phaseist : natural range 0 to (2**31)-1 := 1000; -- terminal state machine signal terminalstate : natural range 0 to 63 := 0; signal terminalcnt : natural range 0 to (2**31)-1 := 0; -- Zeichenausgabe state machine signal zeichenstate : natural range 0 to 15 := 0; signal zeichencnt : natural range 0 to (2**31)-1 := 0; signal zeichenzeichen : natural range 0 to 255 := 16#61#; -- kleines a signal zeichenidle : std_logic := '1'; signal zeichenstart : std_logic := '0'; signal zeichenvec : std_logic_vector(7 downto 0); -- Zeicheneinsgabe state machine signal reinstate : natural range 0 to 15 := 0; signal reincnt : natural range 0 to (2**31)-1 := 0; signal reinticks : natural range 0 to (2**31)-1 := 0; signal reinfak : natural range 0 to (2**10)-1 := 1; signal reinrein : natural range 0 to (2**31)-1 := 0; signal reinstart : std_logic := '0'; signal reinidle : std_logic := '0'; -- Zahleingabegabe state machine signal zahlreinstate : natural range 0 to 15 := 0; signal zahlrein : natural range 0 to (2**31)-1 := 0; signal zahlreinstart : std_logic := '0'; signal zahlreinidle : std_logic := '1'; --type buftype is array (0 to 10) of integer range 0 to 9; --signal buf : buftype; signal zahlreincnt : natural range 0 to 9 := 0; signal zahlreinh : natural range 0 to (2**31)-1 := 0; -- Zahlausgabe state machine signal zahlstate : natural range 0 to 15 := 0; signal zahlzahl : natural range 0 to (2**31)-1 := 0; signal zahlstart : std_logic := '0'; signal zahlidle : std_logic := '1'; type buftype is array (0 to 10) of integer range 0 to 9; signal buf : buftype; signal zahlcnt : natural range 0 to 9 := 0; signal zahlh : natural range 0 to (2**31)-1 := 0; signal zaehler_a : integer range 0 to 2999999*40 := 0; signal logikpegel_a : std_logic := '0'; signal lp0_a : std_logic := '0'; signal lp1_a : std_logic := '0'; signal hh_a : std_logic_vector(4 downto 0) ; signal zaehler_b : integer range 0 to 2999999*40 := 0; signal logikpegel_b : std_logic := '0'; signal lp0_b : std_logic := '0'; signal lp1_b : std_logic := '0'; signal hh_b : std_logic_vector(4 downto 0) ; signal zaehler_c : integer range 0 to 2999999*40 := 0; signal logikpegel_c : std_logic := '0'; signal lp0_c : std_logic := '0'; signal lp1_c : std_logic := '0'; signal hh_c : std_logic_vector(4 downto 0) ; -- Signale fuer clock a signal clkoutb_a: std_logic; signal clkfbout_a: std_logic; signal clkfboutb_a: std_logic; signal clkout0_a: std_logic; signal clkout0b_a: std_logic; signal clkout1_a: std_logic; signal clkout1b_a: std_logic; signal clkout2_a: std_logic; signal clkout2b_a: std_logic; signal clkout3_a: std_logic; signal clkout3b_a: std_logic; signal clkout4_a: std_logic; signal clkout5_a: std_logic; signal clkout6_a: std_logic; signal clkfbin_a: std_logic; signal clkin1_a: std_logic; signal clkin2_a: std_logic; signal clkinsel_a: std_logic; signal dadddr_a: std_logic_vector(6 downto 0); signal dclk_a: std_logic; signal den_a : std_logic; signal di_a: std_logic_vector(15 downto 0); signal do_a: std_logic_vector(15 downto 0); signal drdy_a: std_logic; signal dwe_a: std_logic; -- Ports for dynamic phase shift signal psclk_a: std_logic; signal psen_a: std_logic:= '0'; signal psincdec_a: std_logic:= '0'; signal psdone_a: std_logic; -- Other control and status signals signal locked_a: std_logic; signal clkinstopped_a: std_logic; signal clkfbstopped_a: std_logic; signal pwrdwn_a: std_logic; signal rst_a: std_logic; signal clkraus_a: std_logic; -- Signale für clock b signal clkoutb_b: std_logic; signal clkfbout_b: std_logic; signal clkfboutb_b: std_logic; signal clkout0_b: std_logic; signal clkout0b_b: std_logic; signal clkout1_b: std_logic; signal clkout1b_b: std_logic; signal clkout2_b: std_logic; signal clkout2b_b: std_logic; signal clkout3_b: std_logic; signal clkout3b_b: std_logic; signal clkout4_b: std_logic; signal clkout5_b: std_logic; signal clkout6_b: std_logic; signal clkfbin_b: std_logic; signal clkin1_b: std_logic; signal clkin2_b: std_logic; signal clkinsel_b: std_logic; signal dadddr_b: std_logic_vector(6 downto 0); signal dclk_b: std_logic; signal den_b : std_logic; signal di_b: std_logic_vector(15 downto 0); signal do_b: std_logic_vector(15 downto 0); signal drdy_b: std_logic; signal dwe_b: std_logic; -- Ports for dynamic phase shift signal psclk_b: std_logic; signal psen_b: std_logic:= '0'; signal psincdec_b: std_logic:= '0'; signal psdone_b: std_logic; -- Other control and status signals signal locked_b: std_logic; signal clkinstopped_b: std_logic; signal clkfbstopped_b: std_logic; signal pwrdwn_b: std_logic; signal rst_b: std_logic; signal clkraus_b: std_logic; begin ------------------------------------- -- Die clock A clock_a : MMCME2_ADV generic map (BANDWIDTH => "OPTIMIZED", CLKOUT4_CASCADE => FALSE, COMPENSATION => "ZHOLD", STARTUP_WAIT => FALSE, DIVCLK_DIVIDE => 1, CLKFBOUT_MULT_F => 64.0 , CLKFBOUT_PHASE => 0.000, CLKFBOUT_USE_FINE_PS => FALSE, CLKOUT0_DIVIDE_F => 2.0, --CLKOUT0_DIVIDE => 2.0, CLKOUT0_PHASE => 0.000, CLKOUT0_DUTY_CYCLE => 0.500, CLKOUT0_USE_FINE_PS => FALSE, CLKOUT1_DIVIDE => 2, CLKOUT1_PHASE => 0.000, CLKOUT1_DUTY_CYCLE => 0.500, CLKOUT1_USE_FINE_PS => TRUE, CLKIN1_PERIOD => 83.333333333, REF_JITTER1 => 0.000) port map -- Output clocks ( CLKFBOUT => clkfbout_a, CLKFBOUTB => clkfboutb_a, CLKOUT0 => clkout0_a, CLKOUT0B => clkoutb_a, CLKOUT1 => clkout1_a, CLKOUT1B => clkout1b_a, CLKOUT2 => clkout2_a, CLKOUT2B => clkout2b_a, CLKOUT3 => clkout3_a, CLKOUT3B => clkout3b_a, CLKOUT4 => clkout4_a, CLKOUT5 => clkout5_a, CLKOUT6 => clkout6_a, -- Input clock control CLKFBIN => clkfbin_a, CLKIN1 => clk, --- hier geht die clock rein CLKIN2 => '0', -- Tied to always select the primary input clock CLKINSEL => '1', -- Ports for dynamic reconfiguration DADDR => (others => '0'), DCLK => '0', DEN => '0', DI => (others => '0'), DO => do_a, DRDY => drdy_a, DWE => '0', -- Ports for dynamic phase shift PSCLK => clk, --'0', PSEN => psen_a, --'0', PSINCDEC => psincdec_a, -- '0', PSDONE => psdone_a, -- Other control and status signals LOCKED => locked_a, CLKINSTOPPED => clkinstopped_a, CLKFBSTOPPED => clkfbstopped_a, PWRDWN => '0', RST => '0'); -- feedback clkf_buf_a : BUFG port map (O => clkfbin_a, I => clkfbout_a); -- Ausgang clkout1_buf_a : BUFG port map (O => clkraus_a, I => clkout0_a); ------------------------------------- -- Die clock B clock_b : MMCME2_ADV generic map (BANDWIDTH => "OPTIMIZED", CLKOUT4_CASCADE => FALSE, COMPENSATION => "ZHOLD", STARTUP_WAIT => FALSE, DIVCLK_DIVIDE => 1, CLKFBOUT_MULT_F => 64.0 , CLKFBOUT_PHASE => 0.000, CLKFBOUT_USE_FINE_PS => FALSE, CLKOUT0_DIVIDE_F => 2.0, CLKOUT0_PHASE => 0.000, CLKOUT0_DUTY_CYCLE => 0.500, CLKOUT0_USE_FINE_PS => FALSE, CLKIN1_PERIOD => 83.333333333, REF_JITTER1 => 0.000) port map -- Output clocks ( CLKFBOUT => clkfbout_b, CLKFBOUTB => clkfboutb_b, CLKOUT0 => clkout0_b, CLKOUT0B => clkoutb_b, CLKOUT1 => clkout1_b, CLKOUT1B => clkout1b_b, CLKOUT2 => clkout2_b, CLKOUT2B => clkout2b_b, CLKOUT3 => clkout3_b, CLKOUT3B => clkout3b_b, CLKOUT4 => clkout4_b, CLKOUT5 => clkout5_b, CLKOUT6 => clkout6_b, -- Input clock control CLKFBIN => clkfbin_b, CLKIN1 => clk, --- hier geht die clock rein CLKIN2 => '0', -- Tied to always select the primary input clock CLKINSEL => '1', -- Ports for dynamic reconfiguration DADDR => (others => '0'), DCLK => '0', DEN => '0', DI => (others => '0'), DO => do_b, DRDY => drdy_b, DWE => '0', -- Ports for dynamic phase shift PSCLK => '0', PSEN => '0', PSINCDEC => '0', PSDONE => psdone_b, -- Other control and status signals LOCKED => locked_b, CLKINSTOPPED => clkinstopped_b, CLKFBSTOPPED => clkfbstopped_b, PWRDWN => '0', RST => '0'); -- feedback clkf_buf_b : BUFG port map (O => clkfbin_b, I => clkfbout_b); -- Ausgang clkout1_buf_b : BUFG port map (O => clkraus_b, I => clkout1_a); --I => clkout0_b); ------------------------------------- process begin -- die statemachine zum phase shift wait until rising_edge(clk); if (phaseshiftstate = 0 ) then ----idle if(phaseist /= pulsdauer) then phaseshiftstate <= 1; end if; elsif (phaseshiftstate = 1 ) then if(phaseist > pulsdauer) then psincdec_a <= '0'; --- up phaseist <= phaseist -1 ; else psincdec_a <= '1'; --- down phaseist <= phaseist + 1 ; end if; phaseshiftstate <= 2; elsif (phaseshiftstate = 2 ) then psen_a <= '1'; -- fire it up phaseshiftstate <= 3; phaseshiftcnt <= 0; elsif (phaseshiftstate = 3 ) then psen_a <= '0'; phaseshiftcnt <= phaseshiftcnt +1; if(phaseshiftcnt > 100000) then --- timeout phaseshiftstate <= 5; end if; phaseshiftstate <= 4; elsif (phaseshiftstate = 4 ) then phaseshiftcnt <= 0; phaseshiftstate <= 5; -- fettich elsif (phaseshiftstate = 5 ) then phaseshiftcnt <= phaseshiftcnt +1; if(phaseshiftcnt > 12000000/100) then phaseshiftstate <= 0; end if; end if; end process; process begin wait until rising_edge(clkraus_a); --lp0 <= not lp0; --lp1 <= not lp1; if (zaehler_a<1) then zaehler_a <= zaehler_a+1; else zaehler_a <= 0; logikpegel_a <= not logikpegel_a; end if; end process; process begin wait until rising_edge(clkraus_b); --lp0 <= not lp0; --lp1 <= not lp1; if (zaehler_b<1) then zaehler_b <= zaehler_b+1; else zaehler_b <= 0; logikpegel_b <= not logikpegel_b; end if; end process; process begin wait until rising_edge(clkraus_b); if (zaehler_c<2999999*40) then zaehler_c <= zaehler_c+1; else zaehler_c <= 0; logikpegel_c <= not logikpegel_c; end if; end process; ---------------------------------------------------------- -- Das Terminal process begin wait until rising_edge(clk); ---------- Zahl eingeben, das commando if (terminalstate =0) then -- 00000000000000 if(zahlreinidle = '1') then zahlreinstart <= '1'; terminalstate <= 1;---- hier else zahlreinstart <= '0'; end if; elsif (terminalstate = 1 ) then -- 11111111111111111111 zahlreinstart <= '0'; terminalstate <= 2; ---- hier elsif (terminalstate = 2) then -- 2222222222222222222222222222 if(zahlreinidle = '1') then terminalstate <= 5; end if; -- hier ---------- war es ein h? elsif (terminalstate = 5) then ---- 5555555555555555555 if (zahlrein = 54) then --- war ein f terminalstate <= 10; --- ausgeben elsif (zahlrein = 68) then --- war ein t terminalstate <= 13; --- frequenz eingeben else terminalstate <= 3; --- ausgeben end if; --------- Frequenz ausgeben --signal ausgabefreq : natural range 0 to (2**31)-1 := 1000000; --- in Hz --signal pulsdauer : natural range 0 to (2**31)-1 := 1000; --- in ps elsif (terminalstate = 3) then -- 333333333333333333333333333 if(zahlidle = '1') then -- idle? zahlstart <= '1'; zahlzahl <= ausgabefreq; terminalstate <= 4; else zahlstart <= '0'; end if; elsif (terminalstate = 4) then ---- 4444444444444444444444444 zahlstart <= '0'; terminalstate <= 8; ---- ----- pulsdauer ausgeben elsif (terminalstate = 8) then -- 88888888888888888888888 if(zahlidle = '1') then -- idle? zahlstart <= '1'; zahlzahl <= pulsdauer; terminalstate <= 9; else zahlstart <= '0'; end if; elsif (terminalstate = 9) then ---- 9999999999 zahlstart <= '0'; terminalstate <= 0; ---- ---- hier Frequenz eingeben elsif (terminalstate =10) then -- 101010101010 if(zahlreinidle = '1') then zahlreinstart <= '1'; terminalstate <= 11;---- hier else zahlreinstart <= '0'; end if; elsif (terminalstate = 11 ) then -- 11111111111111111111 zahlreinstart <= '0'; terminalstate <= 12; ---- hier elsif (terminalstate = 12) then -- 12121212 if(zahlreinidle = '1') then terminalstate <= 3; ausgabefreq <= zahlrein; end if; -- hier pulsdauer eingeben elsif (terminalstate =13) then -- 1313131313 if(zahlreinidle = '1') then zahlreinstart <= '1'; terminalstate <= 14;---- hier else zahlreinstart <= '0'; end if; elsif (terminalstate = 14 ) then -- 141414 zahlreinstart <= '0'; terminalstate <= 15; ---- hier elsif (terminalstate = 15) then -- 151515 if(zahlreinidle = '1') then terminalstate <= 3; pulsdauer <= zahlrein; end if; -- hier end if; end process; -- Zahlausgabe process begin wait until rising_edge(clk); if (zahlstate = 0) then ---- idle if(zahlstart = '1') then zahlidle <= '0'; zahlh <= zahlzahl; zahlcnt <= 0; zahlstate <= 2; else zahlidle <= '1'; end if; elsif (zahlstate = 2) then buf(zahlcnt) <= (zahlh rem 10); zahlcnt <= zahlcnt +1; zahlh <= zahlh/10; zahlstate <= 3; elsif (zahlstate = 3) then if(zahlh=0) then zahlstate <= 4; else zahlstate <= 2; end if; elsif (zahlstate = 4) then if(zeichenidle = '1') then -- idle? zeichenstart <= '1'; -- Ausgabe ankicken zahlcnt <= zahlcnt - 1; zeichenzeichen <= buf(zahlcnt-1)+48; zahlstate <= 5; else zeichenstart <= '0'; end if; elsif (zahlstate = 5) then zeichenstart <= '0'; if (zahlcnt = 0) then zahlstate <= 6; else zahlstate <= 4; end if; elsif (zahlstate = 6) then if(zeichenidle = '1') then -- idle? zeichenstart <= '1'; -- Ausgabe ankicken zeichenzeichen <= 13; zahlstate <= 7; else zeichenstart <= '0'; end if; elsif (zahlstate = 7) then zeichenstart <= '0'; zahlstate <= 8; elsif (zahlstate = 8) then if(zeichenidle = '1') then -- idle? zeichenstart <= '1'; -- Ausgabe ankicken zeichenzeichen <= 10; zahlstate <= 9; else zeichenstart <= '0'; end if; elsif (zahlstate = 9) then zeichenstart <= '0'; zahlstate <= 0; end if; end process; -- zahleingabe process begin wait until rising_edge(clk); ----------------------------- if (zahlreinstate =0 ) then -- idle if(zahlreinstart = '1') then zahlreinstate <= 1; zahlreinidle <= '0'; zahlrein <= 0; else zahlreinidle <= '1'; end if; ------------------------------------------ elsif (zahlreinstate =1 ) then if (reinidle = '1') then reinstart <= '1'; zahlreinstate <=4 ; else reinstart <= '0'; end if; ------------------------------- elsif (zahlreinstate = 4 ) then reinstart <= '0'; zahlreinstate <=2 ; ------------------------------- elsif (zahlreinstate = 2 ) then --reinstart <= '0'; if (reinidle = '1') then if((reinrein = 32) or( reinrein = 13 )or( reinrein = 10 )) then --CR LF SP zahlreinstate <= 3 ; else zahlrein <= 10*zahlrein + reinrein - 48; zahlreinstate <= 1; end if; end if; ------------------------------- elsif (zahlreinstate = 3 ) then --zahlrein <= 135; zahlreinidle <= '1'; zahlreinstate <= 0; end if; end process; -- zeicheneingabe process begin wait until rising_edge(clk); ----------------------------- if (reinstate =0 ) then -- idle if(reinstart = '1') then reinstate <= 1; else reinidle <= '1'; end if; ---------------------------------------------- elsif (reinstate = 1) then if (uart_rx = '0') then reincnt <= 0; reinticks <= 3*(12000000/9600)/2; -- Mitte abtasten reinstate <= 2; reinrein <= 0; reinfak <= 1; else reinidle <= '0'; end if; --------------------------------- elsif (reinstate = 2 ) then reinticks <= reinticks -1; if(reinticks = 0) then if(uart_rx = '1') then reinrein <= reinrein + reinfak; end if; reinfak <= 2*reinfak; reincnt <= reincnt + 1; reinticks <= (12000000/9600); if(reincnt = 7) then -- 8? reinstate <= 3; reinticks <= 10*(12000000/9600); --reinfertig <= '1'; end if; end if; --------------------------------- elsif (reinstate = 3 ) then reinticks <= reinticks -1; if(reinticks = 0) then reinstate <= 0; end if; end if; end process; -- zeichenausgabe process begin wait until rising_edge(clk); if (zeichenstate = 0) then uart_tx <= '1'; --- idle high zeichenidle <= '1'; if((zeichenstart = '1')) then zeichenidle <= '0'; zeichenstate <= 1; end if; --else zeichencnt <= zeichencnt +1; --end if; elsif (zeichenstate = 1) then zeichenvec <= CONV_STD_LOGIC_VECTOR(zeichenzeichen,8); zeichencnt <= 0; zeichenstate <=12; zeichenidle <= '0'; --end if; elsif (zeichenstate = 12) then if(zeichencnt > 20*12000000/9600) then -- warten 20 Bit lang zeichenstate<=2; zeichencnt <= 0; uart_tx <= '0'; -- low startbit else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 2) then if(zeichencnt > 12000000/9600) then zeichenstate<=3; zeichencnt <= 0; uart_tx <= zeichenvec(0); -- lsb else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 3) then if(zeichencnt > 12000000/9600) then -- LSB zeichenstate<=4; zeichencnt <= 0; uart_tx <= zeichenvec(1); --bit 1 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 4) then if(zeichencnt > 12000000/9600) then zeichenstate<=5; zeichencnt <= 0; uart_tx <= zeichenvec(2); -- bit 2 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 5) then if(zeichencnt > 12000000/9600) then zeichenstate<=6; zeichencnt <= 0; uart_tx <= zeichenvec(3); -- bit3 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 6) then if(zeichencnt > 12000000/9600) then zeichenstate<=7; zeichencnt <= 0; uart_tx <= zeichenvec(4); --bit 4 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 7) then if(zeichencnt > 12000000/9600) then zeichenstate<=8; zeichencnt <= 0; uart_tx <= zeichenvec(5); --bit 5 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 8) then if(zeichencnt > 12000000/9600) then zeichenstate<=9; zeichencnt <= 0; uart_tx <= zeichenvec(6); --bit 6 else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 9) then if(zeichencnt > 12000000/9600) then zeichenstate<=10; zeichencnt <= 0; uart_tx <= zeichenvec(7); -- bit 7, MSB else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 10) then if(zeichencnt > 12000000/9600) then zeichenstate<=11; zeichencnt <= 0; uart_tx <= '1'; -- stoppbit high else -- keep waiting zeichencnt <= zeichencnt +1; end if; elsif (zeichenstate = 11) then if(zeichencnt > 12000000/9600) then zeichenstate<=0; zeichencnt <= 0; uart_tx <= '1'; -- idle wieder high else -- keep waiting zeichencnt <= zeichencnt +1; end if; else zeichenstate <= 0; zeichencnt <=0; end if; -----Ende --------------------- end process; pio1 <= logikpegel_a; pio2 <= logikpegel_b; led0 <= logikpegel_a; led1 <= logikpegel_b; led2 <= logikpegel_c; led3 <= logikpegel_c; end Behavioral;