UART VHDL 接收程式會當機! |
缺席
|
mis881085
一般會員 ![]() ![]() 發表:2 回覆:7 積分:6 註冊:2005-04-30 發送簡訊給我 |
我的程式會當機!
接收那一段,RECEIVER_DATA:以下
可是不是每次都會當機!
當程式執行過一陣子後!就會有不明原因的當機!
誰能幫我看看??
LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY UART IS GENERIC ( CLK_DIV : natural := 50; INSIDE_CLK_DIV : natural := 26; INSIDE_CLK_MID : natural := 13; STOP_BIT : natural := 1; DATA_BIT : natural := 8 ); PORT ( CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; LD : IN STD_LOGIC; RX : IN STD_LOGIC; DATA_IN : IN STD_LOGIC_VECTOR(DATA_BIT-1 DOWNTO 0); STATE_OUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); DATA_OUT : OUT STD_LOGIC_VECTOR(DATA_BIT-1 DOWNTO 0); READY_RX : OUT STD_LOGIC; TX_BUSY : OUT STD_LOGIC; TX : OUT STD_LOGIC ); END UART; ARCHITECTURE UART_START OF UART IS TYPE TX_STATE_TYPE IS (IDLE,LOAD_TX,SHIFT_TX,STOP_TX); TYPE RX_STATE_TYPE IS (IDLE,READ,SHIFT,STOP_RX); SIGNAL TX_FSM :TX_STATE_TYPE; SIGNAL RX_FSM :RX_STATE_TYPE; SIGNAL INSIDE_CLK :STD_LOGIC; SIGNAL TX_REG :STD_LOGIC_VECTOR(DATA_BIT STOP_BIT DOWNTO 0); SIGNAL RX_OUT_REG :STD_LOGIC_VECTOR(DATA_BIT-1 DOWNTO 0); BEGIN SYS_CLK: PROCESS(RESET,CLK,INSIDE_CLK) VARIABLE CNT : INTEGER; BEGIN IF (RESET = '1') THEN CNT := 0; INSIDE_CLK <= '0'; ELSIF (CLK'EVENT AND CLK = '1') THEN CNT := CNT 1; IF (CNT > (CLK_DIV)) THEN INSIDE_CLK <= NOT INSIDE_CLK; CNT := 0; END IF; END IF; END PROCESS; RECEIVER_DATA: PROCESS(RESET,INSIDE_CLK,RX) VARIABLE FRAME_CNT:INTEGER; VARIABLE CNT:INTEGER; VARIABLE REG_RX :STD_LOGIC_VECTOR(DATA_BIT STOP_BIT DOWNTO 0); VARIABLE PRE_STATE :STD_LOGIC; BEGIN IF (RESET = '1')THEN RX_FSM <= IDLE; FRAME_CNT := 0; CNT := 0; REG_RX := (OTHERS=>'1'); PRE_STATE := '1'; READY_RX <= '0'; RX_OUT_REG <= (OTHERS=>'1'); ELSIF (INSIDE_CLK'EVENT AND INSIDE_CLK = '1') THEN CNT := CNT 1; CASE RX_FSM IS WHEN IDLE => IF (PRE_STATE = '1' AND RX = '0')THEN RX_FSM <= READ; END IF; FRAME_CNT := 0; CNT := 0; WHEN READ => IF (CNT = (INSIDE_CLK_MID))THEN REG_RX(REG_RX'HIGH):= RX; ELSIF (CNT >= INSIDE_CLK_DIV)THEN RX_FSM <= SHIFT; FRAME_CNT := FRAME_CNT 1; CNT := 0; END IF; WHEN SHIFT => IF (FRAME_CNT > (DATA_BIT STOP_BIT))THEN READY_RX <= '0'; RX_FSM <= STOP_RX; ELSE RX_FSM <= READ; REG_RX := ('U'®_RX(REG_RX'HIGH DOWNTO 1)); END IF; WHEN STOP_RX => IF (REG_RX(REG_RX'HIGH)= '1' AND REG_RX(0)= '0')THEN RX_OUT_REG <= REG_RX(REG_RX'HIGH-STOP_BIT DOWNTO 1); READY_RX <= '1'; ELSE READY_RX <= '0'; RX_OUT_REG <= (OTHERS=>'1'); END IF; RX_FSM <= IDLE; WHEN OTHERS => RX_FSM <= IDLE; END CASE; PRE_STATE := RX; END IF; END PROCESS; DATA_OUT <= RX_OUT_REG; TRANSFER_DATA: PROCESS(RESET,INSIDE_CLK,TX_REG) VARIABLE FRAME_CNT:INTEGER; VARIABLE CNT:INTEGER; VARIABLE REG_DIN :STD_LOGIC_VECTOR(DATA_BIT-1 DOWNTO 0); BEGIN IF (RESET = '1')THEN TX_FSM <= IDLE; TX_BUSY <= '0'; FRAME_CNT := 0; CNT := 0; REG_DIN := (OTHERS=>'1'); TX_REG <= (OTHERS=>'1'); STATE_OUT <= "1000"; ELSIF(INSIDE_CLK'EVENT AND INSIDE_CLK = '1')THEN CNT := CNT 1; IF (CNT > (INSIDE_CLK_DIV))THEN TX_BUSY <= '1'; CNT := 0; STATE_OUT <= "0000"; CASE TX_FSM IS WHEN IDLE => IF (LD = '1') THEN REG_DIN := DATA_IN; TX_FSM <= LOAD_TX; STATE_OUT <= "0001"; ELSE REG_DIN := (OTHERS=>'X'); TX_BUSY <= '0'; STATE_OUT <= "0010"; END IF; FRAME_CNT := 0; WHEN LOAD_TX => TX_REG(TX_REG'HIGH)<='1'; TX_REG(TX_REG'HIGH-1 DOWNTO 1)<=REG_DIN; TX_REG(0)<='0'; FRAME_CNT := 1; TX_FSM <= SHIFT_TX; STATE_OUT <= "0011"; WHEN SHIFT_TX => TX_REG <= ('X'&TX_REG(TX_REG'HIGH DOWNTO 1)); FRAME_CNT := FRAME_CNT 1; STATE_OUT <= "0100"; IF (FRAME_CNT > (DATA_BIT STOP_BIT))THEN TX_FSM <= STOP_TX; STATE_OUT <= "0101"; END IF; WHEN STOP_TX => TX_FSM <= IDLE; TX_BUSY <= '0'; REG_DIN := (OTHERS=>'1'); STATE_OUT <= "0110"; WHEN OTHERS => TX_FSM <= IDLE; TX_BUSY <= '0'; REG_DIN := (OTHERS=>'1'); STATE_OUT <= "0111"; END CASE; END IF; END IF; END PROCESS; TX <=TX_REG(0); END UART_START; |
ssejack
高階會員 ![]() ![]() ![]() ![]() 發表:87 回覆:143 積分:106 註冊:2005-06-27 發送簡訊給我 |
您的code 直接 compiler 有問題!
引言: REG_RX := ('U'®_RX(REG_RX'HIGH DOWNTO 1));是否如下?? REG_RX := 'U'&(REG_RX(REG_RX'HIGH DOWNTO 1)); 您所謂當機是simulation出來的 or 實作的呢? 是否附上 simulation waveform 及有問題處? 另有點疑問,您的 FSM 暫存器 是用 variable ,但 variable 在 process 結束後是無法 hold data 的,也就是說下次再執行process 時 variable 的內容就???遺失了耶! |
addn
高階會員 ![]() ![]() ![]() ![]() 發表:64 回覆:221 積分:202 註冊:2005-03-21 發送簡訊給我 |
|
ssejack
高階會員 ![]() ![]() ![]() ![]() 發表:87 回覆:143 積分:106 註冊:2005-06-27 發送簡訊給我 |
Sorry!
上回沒仔細看
引言: REG_RX := ('U'®_RX(REG_RX'HIGH DOWNTO 1));應為 REG_RX := RX&(REG_RX(REG_RX'HIGH DOWNTO 1)); 另Variable 沒有給其他process 用所以也是沒問題的, 可能有問題的地方於 INSIDE_CLK 和 LD,RX 的setup/hold time關係! 因INSIDE_CLK 為內部除頻產生,固與input 的LD,RX 如有setup/hold time 的問題可能會有非預期的狀態吧! 建議改成以 CLK 的 central clock RX_FSM & FX_RSM 以除頻之 overflow 來當enable 信號,這時候只要對好 CLK,LD,RX,DATA_IN 的 setup/hold time 就應該比較容易沒問題 |
mis881085
一般會員 ![]() ![]() 發表:2 回覆:7 積分:6 註冊:2005-04-30 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |