00 簡(jiǎn)介
UART接收數(shù)據(jù)部分是接收另一個(gè)串口設(shè)備發(fā)送的數(shù)據(jù),緩存到接收FIFO中。FIFO快要寫滿時(shí),產(chǎn)生中斷通知CPU拿取數(shù)據(jù),實(shí)現(xiàn)串口數(shù)據(jù)的接收。
模塊涉及到兩個(gè)時(shí)鐘域,ARM時(shí)鐘和26MHz功能時(shí)鐘。其中 接收FIFO讀寫邏輯是ARM時(shí)鐘域,接收數(shù)據(jù)狀態(tài)機(jī)和同步邏輯等是功能時(shí)鐘域 。
01 模塊接口與描述
02 實(shí)現(xiàn)
UART_RX模塊主要由三部分組成: 配置信息同步 、接收狀態(tài)機(jī)和 接收數(shù)據(jù)FIFO控制 。
配置信息是reg_if模塊由APB總線配置寄存器產(chǎn)生,功能時(shí)鐘域做兩級(jí)同步處理。
接收狀態(tài)機(jī)是根據(jù)串口協(xié)議劃分,分為IDLE、START、RX_DATA、CHECK_DATA、STOP和SEND六種狀態(tài)。
接收數(shù)據(jù)FIFO控制部分將接收完成的數(shù)據(jù)寫入到FIFO,在CPU讀取RX_FIFO寄存器時(shí)將FIFO數(shù)據(jù)讀出送到RX_FIFO寄存器。
- 配置信息同步
由于配置信息是由ARM時(shí)鐘產(chǎn)生,到接收模塊的功能時(shí)鐘域需要做同步處理。配置信息是電平信號(hào),通常不會(huì)像數(shù)據(jù)一樣變化快,所以只需要兩級(jí)同步。
- 接收狀態(tài)產(chǎn)生
接收數(shù)據(jù)停止位狀態(tài)指示st_error和接收數(shù)據(jù)校驗(yàn)位狀態(tài)指示p_error是串口校驗(yàn)位和停止位檢測(cè)狀態(tài)指示。前者為1表示停止位錯(cuò)誤;后者為1表示校驗(yàn)位錯(cuò)誤。兩個(gè)狀態(tài)位都會(huì)傳到reg_if模塊,指示URAT當(dāng)前狀態(tài),供CPU查詢。當(dāng)CPU發(fā)現(xiàn)停止位或者校驗(yàn)位錯(cuò)誤時(shí),會(huì)決定當(dāng)前數(shù)據(jù)的處理方式(丟棄或者接受),清除狀態(tài)位(即寫1清0)。reg_if模塊發(fā)現(xiàn)該狀態(tài)位清除后,會(huì)回送一個(gè)ack到接收模塊,即st_error_ack和p_error_ack。接收模塊接收到ack后釋放狀態(tài)指示st_error和p_error,繼續(xù)接收數(shù)據(jù)。
這個(gè)過(guò)程就是狀態(tài)位的握手,本模塊設(shè)計(jì)方式是握手期間,即發(fā)現(xiàn)校驗(yàn)位或者停止位錯(cuò)誤后停止接收數(shù)據(jù),直到CPU清除狀態(tài)后才開(kāi)始正常接收。讀者可以根據(jù)自己的需要判斷錯(cuò)誤后是否繼續(xù)接收數(shù)據(jù)。
- 接收狀態(tài)機(jī)
使用典型的三段式狀態(tài)機(jī)設(shè)計(jì),包含六種狀態(tài),IDLE、START、RX_DATA、CHECK_DATA、STOP和SEND。
uart接收狀態(tài)轉(zhuǎn)移圖
IDLE:狀態(tài)機(jī)從IDLE狀態(tài)開(kāi)始,檢測(cè)到uart_i的下降沿,進(jìn)入START狀態(tài)。
START:START狀態(tài)起始位是否為低(避免毛刺觸發(fā)狀態(tài)機(jī)),起始位正常即進(jìn)入RX_DATA開(kāi)始接收數(shù)據(jù)。RX_DATA:接收滿8bit后判斷是否使能校驗(yàn)位,如使能,進(jìn)入CHECK_DATA狀態(tài)進(jìn)行奇偶校驗(yàn)的判斷;如不使能,直接進(jìn)入停止?fàn)顟B(tài)STOP。
CHECK_DATA:CHECK_DATA狀態(tài)判斷奇偶校驗(yàn)是否正確,不正確則發(fā)出p_error信號(hào),在狀態(tài)寄存器指示校驗(yàn)錯(cuò)誤,待CPU處理返回p_error_ack后回到IDLE狀態(tài)。如果正確,判斷是否使能停止位檢查;使能停止位檢查則跳轉(zhuǎn)到STOP狀態(tài);不使能則跳轉(zhuǎn)到SEND狀態(tài)。
STOP:同樣的,在STOP狀態(tài)檢測(cè)停止位是否是高電平。如果是,表示停止位正確,跳轉(zhuǎn)到SEND狀態(tài);如果不是,則發(fā)出st_error信號(hào),在狀態(tài)寄存器指示停止位錯(cuò)誤,待CPU處理返回st_error_ack后回到IDLE狀態(tài)。
SEND:SEND狀態(tài)主要是產(chǎn)生rx_start信號(hào)表示8bits數(shù)據(jù)接收正確,可以將數(shù)據(jù)寫到接收FIFO。
前兩段狀態(tài)機(jī),狀態(tài)跳轉(zhuǎn):
// state to nextstate with clk in this block.
always@(posedge clk26m ornegedge rst26m_)begin
if(!rst26m_) begin
state <= IDLE;
end
elsebegin
state <= nextstate;
end
end
// nextstate transform
always@(*) begin
case(state)
IDLE: begin
if(neg_urxd_i) begin
nextstate = START;
end
elsebegin
nextstate = IDLE;
end
end
START: begin
if(start_right) begin// start bit is right,then reserve data
nextstate = RX_DATA;
end
elsebegin
nextstate = IDLE;
end
end
RX_DATA: begin
if(data_cnt < 4'd8) begin// reserve 8 datas
nextstate = RX_DATA;
end
elsebegin
if(rx_bpsclk) begin
if(check_syn2) begin
nextstate = CHECK_DATA;
end
elsebegin
nextstate = STOP;
end
end
elsebegin
nextstate = RX_DATA;
end
end
end
CHECK_DATA: begin
if(p_error_ack_delay2) begin
nextstate = IDLE;
end
elsebegin
if(rx_bpsclk) begin
// p_error:1:parity bit error,0:parity bit error
if(p_error) begin
nextstate = CHECK_DATA;
end
elsebegin
// st_check:1:check stop bit,0:don't check stop bit
if(st_check_syn2) begin
nextstate = STOP;
end
elsebegin
nextstate = SEND;
end
end
end
elsebegin
nextstate = CHECK_DATA;
end
end
end
STOP: begin
if(st_error_ack_delay2) begin
nextstate = IDLE;
end
elsebegin
if(rx_bpsclk) begin
// st_error:1:stop bit error,0:stop bit error
if(st_error) begin
nextstate = STOP;
end
elsebegin
nextstate = SEND;
end
end
elsebegin
nextstate = STOP;
end
end
end
SEND: begin
if(rx_ack_delay2) begin
nextstate = IDLE;
end
elsebegin
nextstate = SEND;
end
end
default: begin
nextstate = IDLE;
end
endcase
end