UART란?? Block Diagram Transmitter / Receiver / Baud Rate generator Simulation_top Reference VHDL coding (Top 3block)Contents비동기 통신 (Universal Asynchronous Receiver Transmitter) ● 직렬데이터를 송수신하는 직렬 통신 인터페이스 ● 동기 클럭이 없는 상태에서 통신 ● Start / End bit 첨가 ● RX / TX port가 모두 존재 - full duplex ● Baud Rate (통신속도 지정) data 처리속도 조절!!UART란??직렬 데이터 송수신표준 직렬 데이터 형식직렬 데이터 전송Baud Rate : 단위 시간당 전송된 비트 수UART Block Diagram(1)UART Block Diagram(2)직렬통신 제어/상태 레지스터SCCR (Serial Communication Control Register) : 직렬 통신 제어 레지스터 ● RIE (Receiver Interrupt Enable) - UART 수신부의 인터럽트 발생을 허용 - RIE=1이고, 데이터 수신 완료시(RDRE) Host Processor에게 인터럽트(SCI_IRQ) 발생 ● TIE (Transmitter Interrupt Enable) - UART 송신부의 인터럽트 발생을 허용 - TIE=1이고, TDR이 비어있는 경우(TDRE=1) 인터럽트(SCI_IRQ) 발생 ● SEL[1:0] : Baud Rate를 지정 적절한 송수신 클럭 생성SCSR (Serial Communication Status Register) : 직렬 통신 상태 레지스터 ● TDRE (TDR Empty) - TDR이 Empty인 경우 지시 ● RDRF (RDR Full) - RDR이 Full인 경우 지시 ● OE (Overrun Error) - 이전에 수신된 데이터를 Host Processor가 읽지 않은 상태에서 새로운 데이터가 수신된 경우 ● FE (Framing 의해서 8가지 Baud Rate 중에 하나를 선택!! (TDR Empty) ● 시스템 클럭 주파수 : 8MHz (T=125ns=0.125us)Top_simulation*************101VHDL Coding_Toplibrary ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity uart is port( clock : in std_logic; rx_sdata : in std_logic; tx_sdata : out std_logic; rx_pdata : out std_logic_vector(7 downto 0); tx_pdata : in std_logic_vector(7 downto 0); rx_full, tx_empty : out std_logic; load : in std_logic; read : in std_logic; baud : in std_logic_vector(2 downto 0)); end uart; architecture behavioral of uart is signal rxclk : std_logic := '0'; signal txclk : std_logic := '0';begin clock_gen : entity work.baudgen port map( clk_in = clock, baudsel = baud, rxclk_out = rxclk, txclk_out = txclk); rx_block : entity work.rs232_rx port map( clk = rxclk, din = rx_sdata, dataready = rx_full, read = read, dout = rx_pdata); tx_block : entity work.rs232_tx port map( clk = txclk, load = load, din = tx_pdata, dout = tx_sdata, empty = tx_emptit : std_logic := '0'; constant stopbit : std_logic := '1'; signal data : std_logic_vector(MAXCNT - 1 downto 0) := (others = stopbit); signal cnt : integer range 0 to MAXCNT := MAXCNT; signal latched : std_logic := '0'; signal latch : std_logic_vector(7 downto 0);Transmit Component(2)begin dout = data(0); empty = '1' when latched = '0' and cnt = MAXCNT else '0'; process (load,cnt) variable flag : std_logic := '0'; begin -- load new data on edge if rising_edge(load) then flag := '1'; latch = din; end if; if cnt = 0 then flag := '0'; end if; latched = flag; end process;Transmit Component(3)process (clk) begin if rising_edge(clk) then if (cnt = MAXCNT) then if latched = '1' then data = stopbit latch startbit; cnt = 0; end if; else cnt = cnt + 1; data (MAXCNT - 2 downto 0) = data (MAXCNT - 1 downto 1); end if; end if; end process; end behavioral;Receive Component(1)library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity rs232_rx is px_states; signal data : std_logic_vector(7 downto 0);Receive Component(2)begin process (clk, read) variable bit_cnt : integer range 0 to MAXCOUNT; variable sync_cnt : integer range 0 to CLK_SCALE; begin if rising_edge(clk) then case rx_state is when idle = if din = '0' then -- we are receiving a start bit bit_cnt := 0; sync_cnt := 0; rx_state = synchronize; end if; when synchronize = sync_cnt := sync_cnt + 1; if sync_cnt = SYNC_VAL then -- halfway into the start bit, now synchronized sync_cnt := 0; if din = '0' then rx_state = receive; -- good start bit else rx_state = idle; -- bad start bit end if; end if;Receive Component(3)when receive = sync_cnt := sync_cnt + 1; -- don't want to sample until we are in the middle of the next bit if sync_cnt = CLK_SCALE then sync_cnt := 0; bit_cnt := bit_cnt + 1; data = din data(7 downto 1); if bit_cnt = MAXCOUNT then rx_state = stopping; end if; end if; when stopping = sync_cnt := sync_cnt + 1; -- don't want to finish until we are in the middle of tudgen ; architecture behavioral of baudgen is constant FCLK : integer := 50000000; constant CLKSCALE : integer := 16; constant max_rx : integer := ((FCLK/9600)/2)/CLKSCALE; constant max_tx : integer := (FCLK/9600)/2; signal rx_count : integer range 0 to max_rx; signal tx_count : integer range 0 to max_tx; signal rxclk : std_logic := '0'; signal txclk : std_logic := '0';Baud Rate Component(2)begin process (baudsel) begin case baudsel is when 000 = rx_count = ((FCLK/9600)/2)/CLKSCALE; tx_count = (FCLK/9600)/2; when 001 = rx_count = ((FCLK/19200)/2)/CLKSCALE; tx_count = (FCLK/19200)/2; when 010 = rx_count = ((FCLK/38400)/2)/CLKSCALE; tx_count = (FCLK/38400)/2; when 011 = rx_count = ((FCLK/57600)/2)/CLKSCALE; tx_count = (FCLK/57600)/2; when 111 = rx_count = 2; tx_count = 2 * CLKSCALE; when others = rx_count = ((FCLK/115200)/2)/CLKSCALE; tx_count = (FCLK/115200)/2; end case; end process;Baud Rate Component(3)process (clk_in) variable count1 : integer range 0 to max_rx := 0; variable count2