Lehre.EDS_ProgGU5 (Struktur)


Beispielprogramme zur 5. Grossen Übung

  • Simulationsmodell des Senders:
  • -- Foliensatz EDS-F4, Abschnitt 3.1 Operationsablaeufe. Serielle Schnittstelle
    -- Datei: uart_sender.vhd
    -- Simulations- und Synthesebeschreibung fuer den UART-Sender
    -- letzte Aenderung: 14.06.2016
    -- Autor: G. Kemnitz
    
    
    library IEEE;
    use ieee.std_logic_1164.all;
    
    entity uart_sender is
     port(start, T, I: in std_logic; 
      dat: in std_logic_vector(7 downto 0);
      TxD, busy: out std_logic);
    end entity;
    
    architecture a of uart_sender is
     type t_state is (s0, sd, s1);
     signal state: t_state;
     signal I_del, start_del: std_logic;
     signal ct: natural range 0 to 7;
    begin
    
     process(T)        -- sampling
     begin
      if rising_edge(T) then
       I_del <= I;
       start_del<= start;
      end if;
     end process;
     
     process(I_del, T) -- state machine
     begin 
      if I_del='1' then
       state <= s1;              
       TxD <= '1'; busy<='0';
      elsif rising_edge(T) then
       case state is
        when s1 => TxD<='1';      -- stopbit (send 1)
         busy<='0';  ct<=0; 
         if start_del='1' then state<=s0; end if;
        when s0 => TxD<='0';     -- start bit (send 0)
         busy<='1';  ct<=0;   state<=sd; 
        when sd => TxD<=dat(ct); -- send data bit
         busy<='1'; 
         if ct=7 then state<=s1; ct <= 0;
         else ct<=ct+1;
         end if;
       end case;
      end if;
     end process;
    end architecture;
    
  • Simulationsmodell des Empfängers:
  • -- Foliensatz EDS-F4, Abschnitt 3.1 Operationsablaeufe. Serielle Schnittstelle
    -- Datei: uart_receiver.vhd
    -- Simulations- und Synthesebeschreibung fuer den UART-Empfaenger
    -- letzte Aenderung: 14.06.2016
    -- Autor: G. Kemnitz
    
    library IEEE;
    use ieee.std_logic_1164.all;
    
    entity uart_receiver is
     port(T, I, RxD: in std_logic; 
     dat:  out std_logic_vector(7 downto 0);
     busy: out std_logic);
    end entity;
    
    architecture a of uart_receiver is
     type t_state is (s1, s0, sd);
     signal state: t_state;
     signal vt: natural range 0 to 15;
     signal ct: natural range 0 to 7;
     signal RxD_del, I_del: std_logic;
    begin
    
     process(T)        -- sampling
     begin
      if rising_edge(T) then
       RxD_del <= RxD;
       I_del   <= I;
      end if;
     end process;
     
     process(I_del, T) -- state machine
     begin 
      if I_del='1' then
       state <= s1;
      elsif rising_edge(T) then
      case state is
       when s1 => 
        ct <= 0; vt <= 0; busy<='0';
        if RxD_del='0' then state <= s0; end if;
       when s0 =>
        ct <= 0; busy <= '1';
        if vt=15 then vt <= 0; state <= sd; 
        else vt <= vt +1;
        end if;
       when sd => 
        busy<='1';   
        if vt=7 then dat(ct)<=RxD_del; end if;
        if vt = 15 then vt <= 0;
         if ct=7 then state <= s1; Ct<=0;
         else ct <= ct +1;
         end if;
    	else vt <= vt +1;
    	end if;
       end case;
      end if;
     end process;
     
    end architecture;    
    
  • Testrahmen für die Simulation:
  • -- Foliensatz EDS-F4, Abschnitt 3.1 Operationsablaeufe. Serielle Schnittstelle
    -- Datei: test_uart.vhd
    -- Testrahmen fuer UART-Sender und -Empfaenger
    -- letzte Aenderung: 14.06.2016
    -- Autor: G. Kemnitz
    
    -- Zum Ausprobieren
    -- ghdl -a uart_sender.vhd
    -- ghdl -a uart_receiver.vhd
    -- ghdl -a test_uart.vhd
    -- ghdl -m test_uart
    -- ghdl -r test_uart --wave=test_uart.ghw
    -- gtkwave test_uart.ghw test_uart.sav
    
    
    library IEEE;
    use ieee.std_logic_1164.all;
    
    entity test_uart is end entity;
    
    architecture a of test_uart is
     signal dat_s, dat_r: std_logic_vector(7 downto 0);
     signal T_send, I_send, T_rec, I_rec: std_logic;
     signal start, TxD, RxD, busy_send, busy_rec: std_logic;
     constant tb_send: delay_length := 1 sec/9620;
     constant tb_rec:  delay_length := 1 sec/9513;
    begin
    
    sender: entity work.uart_sender
     port map (start=>start, T=>T_send, I=>I_send, dat=>dat_s, TxD=>TxD, 
                busy=>busy_send);
    
    receiver: entity work.uart_receiver 
     port map (T=>T_rec, I=>I_rec, RxD=>RxD, dat=>dat_r, busy=>busy_rec);
     
     RxD <= transport TxD after 27 us;
    
     process    -- init and clock generation sender
     begin
      T_send <= '0'; I_send<='1'; wait for tb_send/2;
      T_send <= '1';              wait for tb_send/2;
      T_send <= '0'; I_send<='0'; wait for tb_send/2;
      while now < 3 ms loop
       T_send <= not T_send;      wait for tb_send/2;
      end loop;
      wait;
     end process;
    
     process    -- init and clock generation receiver
     begin
      T_rec <= '0'; I_rec<='1'; wait for tb_rec/32;
      T_rec <= '1';             wait for tb_rec/32;
      T_rec <= '0'; I_rec<='0'; wait for tb_rec/32;
      while now < 3 ms loop
       T_rec <= not T_rec;      wait for tb_rec/32;
      end loop;
      wait;
     end process;
    
     InpProc: process
       begin
        start <= '0'; wait for 200 us;
        start <= '1'; dat_s <= x"D5";
        wait until busy_send = '1'; wait for 40 us;
        start <= '0';
        wait until busy_send = '0'; wait for 150 us;
        start <= '1'; dat_s <= x"6A";
        wait until busy_send = '1'; wait for 63 us;
        start <= '0';
        wait;
      end process; 
    
    end architecture;
    
  • Programmrahmen für die Synthese:
  • -- Grosse Uebung GUe5: Implementierung und Test einer UART
    -- Datei: uart.vhd
    -- Rahmenprogramm fuer den Test des UART-Empfaengers und -Senders
    -- letzte Aenderung: 14.06.2016
    -- Autor: C. Giesemann
    
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity uart is
     port (
      GCLK: in std_logic;                     -- 100MHz Takt von der Baugruppe
      RXD : in std_logic;                     -- serieller Eingang vom PC (bzw. vom USB-Seriell-Umsetzer)
      TXD : out std_logic;                    -- serieller Ausgang zum PC (bzw. vom USB-Seriell-Umsetzer)
      SW  : in std_logic_vector(7 downto 0);  -- 8 Schalter auf der Baugruppe
      LD  : out std_logic_vector(7 downto 0); -- 8 Leuchtdioden auf der Baugruppe
      BTNR: in std_logic;                     -- Taster für "right" als Reset-Taster
      LA  : out std_logic_vector(3 downto 0));-- Ausgaenge zum Logikanalysator
    end uart;
    
    architecture Behavioral of uart is
    
     signal clk_16x_baud, clk_baud : std_logic;
     signal start, busy_sender, busy_receiver, busy_receiver_del: std_logic;
     signal RXD_int, TXD_int : std_logic;
    
    begin
    
     sender: entity work.uart_sender 
      port map(start=>start, T=>clk_baud, I=>BTNR, dat=>SW, TxD=>TXD_int, busy=>busy_sender); 
    
     receiver: entity work.uart_receiver 
      port map(T=>clk_16x_baud, I=>BTNR, RxD=>RXD_int, dat=>LD, busy=>busy_receiver); 
    
    
     -- Taktteiler fuer den Empfaengertakt (16-fachen Baudrate)
     process(GCLK)
      variable counter : integer range 0 to 333 := 333;
     begin
      if rising_edge(GCLK) then
       if counter = 0 then
        clk_16x_baud <= not clk_16x_baud;
        counter := 333;
       else
        counter := counter - 1;
       end if;
      end if;
     end process;
    	 
     -- Taktteiler fuer den Sendertakt (einfache Baudrate)
     process(clk_16x_baud)
      variable cnt : integer range 0 to 7 := 0;
     begin
      if rising_edge(clk_16x_baud) then
       if cnt < 7 then
        cnt := cnt + 1;
       else
        clk_baud <= not clk_baud;
        cnt := 0;
       end if;
      end if;
     end process;
    	 
     -- Automat, der bei jedem Datenempfang eine Sendeoperation startet 
     process(clk_16x_baud)
      begin
       if rising_edge(clk_16x_baud) then
        if busy_receiver = '1' and busy_receiver_del = '0' then
         start <= '1';
        elsif start = '1' and busy_sender = '1' then 
         start <= '0';
        end if;
        busy_receiver_del <= busy_receiver;
       end if;
      end process; 
    
     RXD_int <= RXD;
     TXD <= TXD_int;
     LA(0) <= RXD_int;
     LA(1) <= busy_receiver;
     LA(2) <= TXD_int;
     LA(3) <= busy_sender;
    
    end Behavioral;
    
    
  • UCF-Datei:
  • NET "GCLK" LOC = V10;       # Takteingang
    # Fuer Takteingaenge sollte dem System immer die Taktperiode
    # mitgeteilt werden, damit das System die Schaltung entsprechend 
    # optimiert. Fuer den 100-MHz-Takt ist die Periodendauer 10ns 
    NET "GCLK" PERIOD = 10ns;  
    # Serielle Schnittstelle
    NET "RXD"   LOC = "N17";
    NET "TXD"   LOC = "N18";
    # Schalter
    NET "SW<0>" LOC = "T10";
    NET "SW<1>" LOC = "T9";
    NET "SW<2>" LOC = "V9";
    NET "SW<3>" LOC = "M8";
    NET "SW<4>" LOC = "N8";
    NET "SW<5>" LOC = "U8";
    NET "SW<6>" LOC = "V8";
    NET "SW<7>" LOC = "T5";
    # Leuchtdioden
    NET "LD<0>" LOC = U16;
    NET "LD<1>" LOC = V16;
    NET "LD<2>" LOC = U15;
    NET "LD<3>" LOC = V15;
    NET "LD<4>" LOC = M11;
    NET "LD<5>" LOC = N11;
    NET "LD<6>" LOC = R11;
    NET "LD<7>" LOC = T11;
    NET "BTNR" LOC = D9;
    # LA-Ausgaenge
    NET "LA<0>" LOC = T12;
    NET "LA<1>" LOC = V12;
    NET "LA<2>" LOC = N10;
    NET "LA<3>" LOC = P11;
    


Autor: gkemnitz, Letzte Änderung: 26.11.2020 16:26:44


 TU Clausthal 2020  Impressum