LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--LIBRARY ALTERA; --USE ALTERA.MAXPLUS2.ALL;
LIBRARY LPM; USE LPM.LPM_COMPONENTS.ALL;
ENTITY Uart_Tx IS GENERIC(Tx_D_Width : POSITIVE := 8; Check: STRING:="Even";Check_En:STRING:="En"); PORT ( Clk: IN STD_LOGIC; Rst: IN STD_LOGIC; Tx_En: IN STD_LOGIC; Tx_Data: IN STD_LOGIC_VECTOR(Tx_D_Width-1 DOWNTO 0); Tx_Busy: OUT STD_LOGIC; Txd : OUT STD_LOGIC ); END Uart_Tx;
ARCHITECTURE Arch_Uart_Tx OF Uart_Tx IS CONSTANT Start_Bit: STD_LOGIC:='0'; CONSTANT Stop_Bit : STD_LOGIC:='1'; SIGNAL TxData_Reg,TxShift_Reg: STD_LOGIC_VECTOR(Tx_D_Width-1 DOWNTO 0); SIGNAL Par_Bit: STD_LOGIC; SIGNAL Tx_Data_Buffer:STD_LOGIC_VECTOR(Tx_D_Width+2 DOWNTO 0); TYPE State IS (Idle,Data_Ready,Tx_Pro,Start_Tx,Start_Even_Tx,Start_Odd_Tx,Data_Cal,Data_Shift,Tx_Over,Data_Get); SIGNAL Tx_Current_State,Tx_Next_State : State ; SIGNAL Txd_Reg,Tx_Busy_Reg:STD_LOGIC; SIGNAL Tx_En_Reg: STD_LOGIC; SIGNAL Tx_Data_Reg:STD_LOGIC_VECTOR(Tx_D_Width-1 DOWNTO 0); SIGNAL TxDataBit: INTEGER RANGE 0 TO Tx_D_Width+3; SIGNAL Baud_Cnt : INTEGER RANGE 0 TO Tx_D_Width+1; SIGNAL Cnt: INTEGER RANGE 0 TO Tx_D_Width; BEGIN PROCESS(Clk,Rst) BEGIN IF (Rst='1') THEN Tx_Current_State<=Idle; ELSIF Clk'EVENT AND Clk='1' THEN Tx_Current_State<=Tx_Next_State; END IF; END PROCESS;
PROCESS(Rst,Tx_En_Reg,Tx_Current_State,Baud_Cnt,Cnt,TxDataBit) BEGIN IF (Rst='1') THEN Tx_Next_State<=Idle; ELSE CASE (Tx_Current_State) IS WHEN Idle=> IF (Tx_En_Reg='1') THEN Tx_Next_State<=Data_Get; ELSE Tx_Next_State<=Idle; END IF; WHEN Data_Get=> Tx_Next_State<=Data_Shift; WHEN Data_Shift=> Tx_Next_State<=Data_Ready; WHEN Data_Ready=> IF (Cnt=Tx_D_Width-1) THEN Tx_Next_State<=Tx_Pro; ELSE Tx_Next_State<=Data_Shift; END IF; WHEN Tx_Pro=> IF (Check="Even") THEN Tx_Next_State<=Start_Even_Tx; ELSE Tx_Next_State<=Start_Odd_Tx; END IF; WHEN Start_Even_Tx=> Tx_Next_State<=Start_Tx; WHEN Start_Odd_Tx=> Tx_Next_State<=Start_Tx; WHEN Start_Tx=> IF (Baud_Cnt=(Tx_D_Width+1)) THEN Tx_Next_State<=Data_Cal; ELSE Tx_Next_State<=Start_Tx; END IF; WHEN Data_Cal=> IF (TxDataBit=(Tx_D_Width+3)) THEN Tx_Next_State<=Tx_Over; ELSE Tx_Next_State<=Start_Tx; END IF; WHEN Tx_Over=> Tx_Next_State<=Idle; WHEN OTHERS=> Tx_Next_State<=Idle; END CASE; END IF; END PROCESS; PROCESS(Clk,Rst)
BEGIN IF (Rst='1') THEN Txd<='1'; Tx_Busy<='0'; Tx_Busy_Reg<='0'; Txd_Reg<='1'; Par_Bit<='0'; Tx_Data_Buffer<=(OTHERS=>'0'); TxShift_Reg<=(OTHERS=>'0'); TxData_Reg<=(OTHERS=>'0'); TxDataBit<=0; Baud_Cnt<=0; Cnt<=0; ELSIF Clk'EVENT AND Clk='1' THEN Txd<=Txd_Reg; Tx_Busy<=Tx_Busy_Reg; Tx_En_Reg<=Tx_En; Tx_Data_Reg<=Tx_Data; CASE Tx_Next_State IS WHEN Data_Get=> TxData_Reg<=Tx_Data_Reg; TxShift_Reg<=Tx_Data_Reg; Par_Bit<=TxShift_Reg(0); Baud_Cnt<=0; Cnt<=0; WHEN Data_Shift=> Cnt<=Cnt+1; TxShift_Reg<='0' & TxShift_Reg(Tx_D_Width-1 DOWNTO 1); WHEN Data_Ready=> Par_Bit<=Par_Bit XOR TxShift_Reg(0); Tx_Busy_Reg<='1'; WHEN Start_Even_Tx=> Tx_Data_Buffer<=Stop_Bit & Par_Bit & TxData_Reg & Start_Bit; WHEN Start_Odd_Tx=> Tx_Data_Buffer<=Stop_Bit & (NOT Par_Bit) & TxData_Reg & Start_Bit; WHEN Start_Tx=> Baud_Cnt<=Baud_Cnt+1; WHEN Data_Cal=> Txd_Reg<=Tx_Data_Buffer(0); Tx_Data_Buffer<='1' & Tx_Data_Buffer(10 DOWNTO 1); TxDataBit<=TxDataBit+1; Baud_Cnt<=0; WHEN Tx_Over=> TxDataBit<=0; Tx_Busy_Reg<='0'; WHEN OTHERS=> NULL; END CASE; END IF; END PROCESS; END Arch_Uart_Tx;
三段式描述的程序,电路结构合理,综合器生成的电路更稳定! 本程序支持宽度和和校验位的参数化, 请放心使用!
|