UART_TX_buf[7:0] (資料)、UART_TX_EN (啟動)、UART_TX_TI (發送中旗標)、UART_TXD (串列輸出)-- 50MHz / (2 * 94) ≈ 265.9 kHz ≈ 19200 * 14
signal baudrate_counter : std_logic_vector(6 downto 0);
signal baudrate_out : std_logic;
process(UART_clk)
begin
if rising_edge(UART_clk) then
if baudrate_counter >= "1011100" (94) then
baudrate_counter <= "0000000";
baudrate_out <= not baudrate_out; -- 翻轉產生方波
else
baudrate_counter <= baudrate_counter + 1;
end if;
end if;
end process;
type TX_STATE is (TX_idle, TX_transfer);
signal TX_current_state, TX_next_state : TX_STATE;
-- 同步進程:狀態暖存器 (baudrate_out 下降沿觸發)
sync_proc_tx: process(baudrate_out, UART_rst)
begin
if UART_rst = '1' then TX_current_state <= TX_idle;
elsif falling_edge(baudrate_out) then TX_current_state <= TX_next_state;
end if;
end process;
-- 組合進程:下一狀態邏輯 + 輸出邏輯 (baudrate_out 上升沿)
comb_proc_tx: process(baudrate_out, UART_rst)
begin
if UART_rst = '1' then -- 重置所有暖存器/旗標
TX_next_state <= TX_idle; TX_counter <= "0000"; TXD_buf <= '1';
TX_start <= '0'; TX_TI <= '1'; TX_clk_counter <= "0000";
TX_buf_shift <= "1111111111";
elsif rising_edge(baudrate_out) then
case TX_current_state is
when TX_idle =>
if UART_TX_EN = '1' and TX_TI = '1' then
TX_next_state <= TX_transfer;
TX_counter <= "1010"; -- 10 位元
TX_buf_shift <= '1' & UART_TX_buf & '0'; -- 停止位 + 資料 + 起始位
TX_start <= '1'; TX_TI <= '0'; TX_clk_counter <= "1101"; -- 13 週期分頻
else -- 保持 idle 預設值
end if;
when TX_transfer =>
if TX_start = '1' and TX_TI = '0' and TX_counter /= "0000" then
if TX_clk_counter >= "1101" then -- 分頻完成,發送 1 位元
TX_counter <= TX_counter - 1;
TXD_buf <= TX_buf_shift(0); -- 發送 LSB
TX_buf_shift <= '1' & TX_buf_shift(9 downto 1); -- 右移並補 1 (線路保持高)
TX_clk_counter <= "0000";
else
TX_clk_counter <= TX_clk_counter + 1;
end if;
else -- 發送結束或異常
TX_next_state <= TX_idle; -- 復位所有
end if;
when others => TX_next_state <= TX_idle;
end case;
end if;
end process;
UART_TXD <= TXD_buf;
UART_TX_TI <= TX_TI;
TX_clk_counter) 模擬位元週期,接收端通常在中間採樣點 (第 7 個過採樣) 讀取。'1' & DATA & '0' → 停止位(1) 在最左 (MSB),起始位(0) 在最右 (LSB)。右移發送順序:起始位 → D0~D7 → 停止位。發送結束後線路拉高 (補 1)。falling_edge 更新,組合邏輯在 rising_edge 計算,避免建立/保持時間違例,提升時序邊緣。TX_TI (Transmitter Idle) 旗標:高電平表示可接受新資料,低電平表示忙碌。上層邏輯需輪詢此旗標決定何時寫入 UART_TX_buf 並拉高 UART_TX_EN。第二段代碼展示單進程、計數器驅動的簡化版 (transmitter 實體),邏輯相似但無明確狀態機枚舉,適合資源受限場景。
generic),支援運行時切換。本 VHDL 實現展示了工業級 UART 發送器的核心要素:精確波特率分頻、雙沿同步狀態機、帶起停位的移位暖存器、忙碌旗標交互。代碼結構清晰、可綜合、易擴展,可直接作為 FPGA/ASIC 專案的串口通訊 IP 核心模組。