empfangsteil eines „software“-uarts:
ACHTUNG: versuch aus der zeit, in der ich mir VHDL erst noch beigebracht habe. 😉
-- uart.vhd -- -- UART-RX -- -- erstellt durch maximilian pautsch -> maximilian[at]hackwerk[punkt]de -- 40MHz clock, 9600 baud, even parity, 8 bit! LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY uart_rx IS PORT( clk: IN std_logic; data: OUT std_logic_vector(7 downto 0); rx_port: IN std_logic; rx_error: OUT std_logic ); END uart_rx; ARCHITECTURE arch OF uart_rx IS SIGNAL clk_count: INTEGER RANGE 0 TO 260; SIGNAL bitcount: INTEGER RANGE 0 TO 10; --wir brauchen 12 bit. das letzte ist force-high SIGNAL data_cache: std_logic_vector(10 downto 0); SIGNAL abtastung: INTEGER RANGE 0 TO 15; SIGNAL abtastung_val: INTEGER RANGE 0 TO 15; SIGNAL parity : std_logic :='0'; SIGNAL rx_run: BIT :='0'; SIGNAL rx_ready: BIT :='0'; BEGIN run_check: PROCESS(rx_port,rx_ready) BEGIN IF rx_port='0' OR rx_ready='0' THEN rx_run <= '1'; ELSE rx_run <= '0'; END IF; END PROCESS run_check; run_rx: PROCESS (clk, rx_port) BEGIN IF (clk'event AND clk='1') THEN IF rx_run='1' THEN rx_ready<='0'; IF clk_count = 260 THEN --- wir tasten jedes bit 16 mal ab! clk_count <= 0; IF abtastung < 15 THEN abtastung <= abtastung +1; IF rx_port='1' THEN abtastung_val <= abtastung_val +1; END IF; ELSE --- ein bit komplett abgetastet! IF abtastung_val < 9 THEN data_cache(bitcount) <= '0'; ELSE data_cache(bitcount) <= '1'; IF bitcount > 0 AND bitcount < 9 THEN ---- parity-control IF parity='0' THEN parity<='1'; ELSE parity<='0'; END IF; END IF; END IF; abtastung <= 0; abtastung_val <= 0; IF bitcount = 10 THEN -- alles komplett? --- bit 1 ist das startbit und muss 0 sein. dann 8 daten, 1 parity und MINDESTENS 1 stopbit (high) --- 9 muss noch auf parity gecheckt werden: IF data_cache(0)='0' AND ((data_cache(9)='0' AND parity='0') OR (data_cache(9)='1' AND parity='1')) AND data_cache(10)='1' THEN rx_error<='0'; data <= data_cache(8 DOWNTO 1); ELSE rx_error<='1'; END IF; -- den ganzen uart_rx zurücksetzen: rx_ready <='1'; bitcount <= 0; parity <='0'; ELSE bitcount <= bitcount+1; END IF; END IF; ELSE clk_count <= clk_count+1; END IF; END IF; END IF; END PROCESS run_rx; END arch;