-- 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;
-- 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;
-- 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;
-- 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;
-- 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;
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: 17.12.2020 11:54:46