Lehre.EDS_ProgF4 (Struktur)


Beispielprogramme zu Foliensatz EDS-F4

Zahlenschloss

Serielle Schnittstelle (UART)

  • 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:
  • -- 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;
    

Serieller Dividierer

  • Simulation einer seriellen Division:
  • -- division algorithm
    -- Author: gkemnitz
    -- Last change: 02.02.2016
    
    
    library ieee;
    use ieee.numeric_std.all;
    use ieee.std_logic_1164.all;
    
    entity div_alg is end entity;
    
    architecture a of div_alg is
    
    function str(w: unsigned) return string is
     variable tmp: string(1 to 3);
     variable s: string(1 to w'length);
     variable i: positive:=1;
    begin
     for j in w'range loop
      tmp := std_logic'image(w(j));
      s(i) := tmp(2);
      i := i +1;
     end loop;
     return s;
    end function;
     
    begin
     process
      variable a: unsigned(7 downto 0) := x"A3";
      variable b: unsigned(7 downto 0) := x"27";
      variable r: unsigned(7 downto 0) := x"00";
      variable q: unsigned(7 downto 0);
      variable d: unsigned(8 downto 0);
     begin
      report(lf&"a/b=q+r/b: a=" & str(a) & " b=" & str(b));
      report("i|rest (r)|diff. (d)|quot.(q)");
      for i in 0 to 7 loop
       r := r(6 downto 0) & a(7-i);
       d := '0'&r - b;
       q := q(6 downto 0) & not d(8);
       if d(8)='0' then r := d(7 downto 0); end if;
       report(integer'image(i) &"|"& str(r) &"|"& str(d)  &"|"& str(q));
      end loop;
      report("soll: r=" & str(a rem b) & " q=" & str(a/b) & lf);
      wait;
     end process;
    end architecture;
    
       
    
  • Verhaltensbeschreibung des Dividierers:
  • -- serial divider
    -- Author: gkemnitz
    -- Last change: 02.02.2016
    
    
    library ieee;
    use ieee.numeric_std.all;
    use ieee.std_logic_1164.all;
    
    entity ser_div is 
     generic (constant n: positive:=8); 
     port (
       T, I, start: in std_logic;
       sa, sb: in unsigned(n-1 downto 0);
       busy: out std_logic;
       sr, sq: out unsigned(n-1 downto 0)
     );
    end entity;
    
    architecture aaa of ser_div is
    
    function str(w: unsigned) return string is
     variable tmp: string(1 to 3);
     variable s: string(1 to w'length);
     variable i: positive:=1;
    begin
     for j in w'range loop
      tmp := std_logic'image(w(j));
      s(i) := tmp(2);
      i := i +1;
     end loop;
     return s;
    end function;
    
     signal si: natural range 0 to n-1;
     signal sd: unsigned(n downto 0);
    begin
     process(T, I)
      variable vi: natural range 0 to n-1;
      variable vBusy: std_logic;
      variable vr: unsigned(n-1 downto 0);
      variable vq: unsigned(n-1 downto 0);
      variable vd: unsigned(n downto 0);
     begin
      if I='1' then vBusy := '0';
      elsif rising_edge(T) then
       if vBusy='0' and start='1' then 
         vBusy :='1';
         vi :=0;
         vr := (others=> '0');
       end if;
       if vBusy = '1' then
        vr := vr(6 downto 0) & sa(n-1-vi);
        vd := ('0' & vr) - sb;
        vq := vq(6 downto 0) & not vd(8);
        if vd(8)='0' then vr := vd(7 downto 0); end if;
        report(integer'image(vi) &"|"& str(vr) &"|"& str(vd)  &"|"& str(vq));
        if vi<n-1 then vi := vi + 1;
        else 
         vBusy := '0';
         report("soll: r=" & str(sa rem sb) & " q=" & str(sa/sb) & lf);
        end if;
       end if;
       si <= vi; sr<= vr; sq <= vq; sd <= vd; busy <= vBusy;
      end if;
     end process;
    end architecture;
    
    
  • Testrahmen:
  • library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity test_ser_div is end entity;
    
    architecture aaa of test_ser_div is
     signal a, b, r, q:       unsigned(7 downto 0);
     signal I, T, Start, busy: std_logic;
    begin
     TObj: entity work.ser_div generic map(n=>8) 
        port map(T=>T, I=>I, Start=>Start, sa=>a, sb=>b, busy=>busy, sr=>r, sq=>q);
     ClkProc: process
       begin
        T <= '0'; I<='1'; wait for 5 ns;
        T <= '1'; wait for 5 ns;
        T <= '0'; I<='0'; wait for 5 ns;
        while now < 200 ns loop
         T <= not T; wait for 5 ns;
        end loop;
        wait;
       end process;
    
     InpProc: process
       begin
        wait until busy = '0'; wait for 3 ns;
        a <= x"56"; b <= x"19"; Start <='1';
        wait until busy = '1'; wait for 3 ns;
        Start <='0';
        wait until busy = '0'; wait for 3 ns;
        a <= x"E1"; b <= x"2A"; Start <='1';
        wait until busy = '1'; wait for 3 ns;
        Start <='0';
        wait;
      end process; 
    
    end architecture;
     
    
    


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


 TU Clausthal 2020  Impressum