verilog 编写uart串口代码之接收端(RX)
程序员文章站
2022-07-09 12:47:04
...
UART模块可以划分为三个模块:接收端、发送端、以及波特率发生器。
首先我们来介绍接收端的实现:
UART整体模块框图包括了RX端和TX端;RX端有 input UART_RXD,output uart_rx_en,output uart_rx_dat[7:0];TX端有 output UART_TXD,input uart_tx_en,input uart_tx_dat[7:0]这几根信号线。数据整体流向是从左边tx_dat串行输入然后输入并行TXD;然后再到并行RXD转串行rx_dat。
下面是UART RX的串口代码:
module UART_RX(
input sys_clk,//clock
input rst_n,//reset
input baud_9600_x16_flag,
output reg uart_rx_en,
output reg [7:0] uart_rx_dat,
input UART_RXD
);
parameter STATE_IDLE = 4'd0;
parameter STATE_STR = 4'd1;
parameter STATE_D0 = 4'd2;
parameter STATE_D1 = 4'd3;
parameter STATE_D2 = 4'd4;
parameter STATE_D3 = 4'd5;
parameter STATE_D4 = 4'd6;
parameter STATE_D5 = 4'd7;
parameter STATE_D6 = 4'd8;
parameter STATE_D7 = 4'd9;
parameter STATE_STP = 4'd10;
reg [3:0] crt_state;
reg [7:0] dat_tmp;
reg [3:0] count;
reg uart_reg1;
reg uart_reg2;
always @ (posedge sys_clk `ES_ASYNC_RESET ) begin
if (!rst_n) begin
uart_reg1 <= 1'd0;
uart_reg2 <= 1'd1;
end
else begin
uart_reg1 <= UART_RXD; //reg beat
uart_reg2 <= uart_reg1; //reg beat
end
end
always @ (posedge sys_clk `ES_ASYNC_RESET ) begin
if (!rst_n) begin
crt_state <= STATE_IDLE;
dat_tmp <= 8'b0;
count <= 4'd0;
uart_rx_en <= 1'd0;
uart_rx_dat <= 8'b0;
end
else begin
case(crt_state)
STATE_IDLE : begin
uart_rx_en <= 1'd0;
if((baud_9600_x16_flag) && (uart_reg2 == 1'd0)) begin //uart start flag = 0
crt_state <= STATE_STR; //jump state
dat_tmp <= 8'b0;
count <= 4'd0;
end
end
STATE_STR : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
crt_state <= STATE_D0; //jump state, once into STATE_STR the RXD must = 0
count <= 4'd0;
end
else begin
count <= count + 4'd1;
end
end
end
STATE_D0 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D1;
end
else begin
count <= count + 4'd1;
if(count == 4'd8) begin
dat_tmp [0] <= uart_reg2; //receive data[0] ,count = 8 is in the mid to be safe
end
end
end
end
STATE_D1 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D2;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [1] <= uart_reg2; //receive data[1]
end
end
end
end
STATE_D2 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D3;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [2] <= uart_reg2; //receive data[2]
end
end
end
end
STATE_D3 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D4;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [3] <= uart_reg2; //receive data[3]
end
end
end
end
STATE_D4 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 5'd0;
crt_state <= STATE_D5;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [4] <= uart_reg2; //receive data[4]
end
end
end
end
STATE_D5 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D6;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [5] <= uart_reg2; //receive data[5]
end
end
end
end
STATE_D6 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_D7;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [6] <= uart_reg2; //receive data[6]
end
end
end
end
STATE_D7 : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_STP;
end
else begin
count <= count +4'd1;
if(count == 4'd8) begin
dat_tmp [7] <= uart_reg2; //receive data[7],8 bit data is already received
end
end
end
end
STATE_STP : begin
if(baud_9600_x16_flag) begin
if(count == 4'd15) begin
count <= 4'd0;
crt_state <= STATE_IDLE;
end
else begin
count <= count +4'd1;
if((count == 4'd8) && (uart_reg2 == 1'd1)) begin //data stop flag
uart_rx_dat <= dat_tmp; //save data
uart_rx_en <= 1'd1; //it means data is vaild
end
else begin
if(count == 4'd8 && (uart_reg2 == 1'd0)) begin
uart_rx_en <= 1'd0; //data is invaild
end
end
end
end
end
default : begin
crt_state <= STATE_IDLE; //default
end
endcase
end
end
endmodule
上一篇: Perl与JS的对比分析(数组、哈希)
下一篇: 8种玩法+11个案例教你玩转微信群营销