input wire rst_n,
input wire rx_in, //串行输入
verilog实现的UART,带中断、奇偶校验、帧错误
module uart_top( input wire clk, //50MHz input wire rst_n, input wire rx_in, //串行输入 outputwire intrrupt, //接收数据中断,已收到一个8bit的数据 outputwire tx //串行输出); parameter BPS9600 = 16'd5200; //50MHz时的计数值 parameter PARITY_EN = 1'b1; //无校验 PARITY_EN = 0,PARITY_ODD = 0,PARITY_EVEN = 0; parameter PARITY_ODD= 1'b1; //奇校验 PARITY_EN = 1,PARITY_ODD = 1,PARITY_EVEN = 0; parameter PARITY_EVEN = 1'b0; //偶校验 PARITY_EN = 1,PARITY_ODD = 0,PARITY_EVEN = 1; wire bps_start; //接收数据bps开始标志 wire rx_bps_clk; //接收数据标志,在一个bit位的中点 wire tx_bps_clk; //发送数据标志,在一个bit位的起点 wire data_flag; //进入数据位(8位数据位)的标志 wire parity_flag; //进入校验位的标志 wire stop_flag; //进入停止位的标志 wire end_stop; //停止位结束标志 wire parity_enable; //校验使能标志 wire[7:0] rec_data; //接收到的8bit数据 wire bps_start1; //发送数据bps开始标志 wire data_flag1; //进入数据位(8位数据位)的标志 wire parity_flag1; //进入校验位的标志 wire stop_flag1; //进入停止位的标志 wire end_stop1; //停止位的标志 uart_bpsinst_rx_bps ( .clk (clk ), .rst_n (rst_n ), .bps_set (BPS9600 ), .bps_start (bps_start ), .parity_enable(PARITY_EN ), .rx_bps_clk (rx_bps_clk ), .tx_bps_clk ( ), .data_flag (data_flag ), .parity_flag(parity_flag), .stop_flag (stop_flag ), .end_stop (end_stop ) ); uart_bpsinst_tx_bps ( .clk (clk ), .rst_n (rst_n ), .bps_set (BPS9600 ), .bps_start (bps_start1 ), .parity_enable(PARITY_EN ), .rx_bps_clk ( ), .tx_bps_clk (tx_bps_clk ), .data_flag (data_flag1 ), .parity_flag(parity_flag1 ), .stop_flag (stop_flag1 ), .end_stop (end_stop1 ) ); uart_rx inst_uart_rx ( .clk (clk ), .rst_n (rst_n ), .rx_in (rx_in ), .rx_bps_clk (rx_bps_clk ), .pari_odd (PARITY_ODD ), .pari_even (PARITY_EVEN), .data_flag (data_flag ), .parity_flag(parity_flag), .stop_flag (stop_flag ), .end_stop (end_stop ), .bps_start (bps_start ), .rec_data (rec_data ), .intrrupt (intrrupt ) ); uart_tx inst_uart_tx ( .clk (clk ), .rst_n (rst_n ), .rec_data (rec_data ), .tx_bps_clk (tx_bps_clk ), .pari_odd (PARITY_ODD ), .pari_even (PARITY_EVEN), .data_flag (data_flag1 ), .parity_flag(parity_flag1 ), .stop_flag (stop_flag1 ), .end_stop (end_stop1 ), .intrrupt (intrrupt ), .bps_start (bps_start1 ), .tx (tx ) ); endmodulemodule uart_bps( input wire clk, input wire rst_n, input wire[15:0]bps_set, input wire bps_start, input wire parity_enable, outputwire rx_bps_clk, outputwire tx_bps_clk, outputwire data_flag, outputwire parity_flag, outputwire stop_flag, outputwire end_stop); reg[ 3:0] frame_num; reg[15:0] cnt; reg[ 3:0] num_bit; reg en_cnt; always @ (posedge clk or negedge rst_n) begin if(~rst_n) frame_num <= 4'd9; else if(parity_enable) frame_num <= 4'd10; //有校验位,则一帧为10bit else frame_num <= 4'd9; //无校验位,一帧为9bit end assignrx_bps_clk= ( cnt == bps_set/2); //接收数据标志,在一个bit位的中点 assigntx_bps_clk= ( cnt == 16'd2); //发送数据标志,在一个bit位的起点 assigndata_flag = ((cnt == 16'd0) & (num_bit == 4'd1)); //进入数据位(8位数据位)的标志 assignparity_flag = parity_enable ? ((cnt == 16'd0) & (num_bit == (frame_num - 1'b1))) : 1'b0; //进入校验位的标志 assignstop_flag = ((cnt == 16'd0) & (num_bit == frame_num));//进入停止位的标志 assignend_stop = ((cnt == bps_set) & (num_bit == frame_num));//停止位结束标志 always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin cnt <= 16'b0; num_bit <= 4'b0; en_cnt<= 1'b0; end else begin if(bps_start) en_cnt <= 1'b1; if((cnt == bps_set) & (num_bit == frame_num)) en_cnt <= 1'b0; if(cnt == bps_set) cnt <= 16'b0; else if(en_cnt) cnt <= cnt + 1'b1; else cnt <= 16'b0; if((cnt == bps_set) & (num_bit == frame_num)) num_bit <= 16'b0; else if(cnt == bps_set) num_bit <= num_bit + 1'b1; end end endmodulemodule uart_rx( input wire clk, input wire rst_n, input wire rx_in, input wire rx_bps_clk, input wire pari_odd, input wire pari_even, input wire data_flag, input wire parity_flag, input wire stop_flag, input wire end_stop, outputreg bps_start, outputreg[7:0]rec_data, outputreg intrrupt); parameter IDLE = 4'd0; //空闲状态 parameter START = 4'd1; //开始位状态 parameter REC_DAT = 4'd2; //接收数据位状态 parameter PARITY= 4'd3; //校验为状态 parameter STOP = 4'd4; //停止位状态 parameter INT_GEN = 4'd5; //接收数据中断状态 reg rx_in_r1; reg rx_in_r2; reg rx_in_r3; reg[3:0] int_cnt; reg data_error; reg frame_error; reg[3:0] state; always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin rx_in_r1 <= 1'b0; rx_in_r2 <= 1'b0; rx_in_r3 <= 1'b0; end else begin rx_in_r1 <= rx_in; rx_in_r2 <= rx_in_r1; rx_in_r3 <= rx_in_r2; end end wireneg_rx_flag = ~rx_in_r2 & rx_in_r3; //检测数据开始标志1 --> 0变化 always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin state <= IDLE; bps_start <= 1'b0; rec_data <= 8'b0; intrrupt <= 1'b0; int_cnt <= 4'b0; data_error<= 1'b0; frame_error <= 1'b0; end else begin case(state) IDLE : begin intrrupt <= 1'b0; data_error<= 1'b0; frame_error <= 1'b0; int_cnt <= 4'b0; if(neg_rx_flag) begin state <= START; bps_start <= 1'b1; //产生接收数据波特率开始标志 end else state <= IDLE; end START : begin bps_start <= 1'b0; if(data_flag) state <= REC_DAT; else state <= START; end REC_DAT : begin if(stop_flag) state <= STOP; else if(parity_flag) state <= PARITY; else state <= REC_DAT; if(rx_bps_clk) rec_data <= {rx_in,rec_data[7:1]}; //接收数据 end PARITY : begin if(stop_flag) state <= STOP; else state <= PARITY; if(rx_bps_clk) begin if(((pari_odd) & ((^rec_data) == (~rx_in))) | ((pari_even) & ((^rec_data) == rx_in))) data_error <= 1'b0; else data_error <= 1'b1; end end STOP : begin if(end_stop) state <= INT_GEN; else state <= STOP; if(rx_bps_clk) begin if(rx_in == 1'b1) frame_error <= 1'b0; else frame_error <= 1'b1; end end INT_GEN : begin if(int_cnt < 4'd10) //产生中断计数 int_cnt <= int_cnt + 1'b1; if(int_cnt == 4'd10) state <= IDLE; if((int_cnt >= 4'd0) & (int_cnt <= 4'd10) & (data_error == 1'b0) & (frame_error == 1'b0)) intrrupt <= 1'b1; else intrrupt <= 1'b0; end default : begin state <= IDLE; bps_start <= 1'b0; rec_data <= 8'b0; intrrupt <= 1'b0; int_cnt <= 4'b0; data_error<= 1'b0; frame_error <= 1'b0; end endcase end end endmodulemodule uart_tx( input wire clk, input wire rst_n, input wire[7:0]rec_data, input wire tx_bps_clk, input wire pari_odd, input wire pari_even, input wire data_flag, input wire parity_flag, input wire stop_flag, input wire end_stop, input wire intrrupt, outputreg bps_start, outputreg tx ); parameter IDLE = 4'd0; //空闲状态 parameter START = 4'd1; //开始状态 parameter TX_DAT= 4'd2; //发送数据位状态 parameter PARITY= 4'd3; //校验位状态 parameter STOP = 4'd4; //停止位状态 reg parity_r; reg[3:0] state; reg[7:0] data_temp; reg intrrupt_r1; reg intrrupt_r2; wire neg_intrrupt; always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin intrrupt_r1 <= 1'b0; intrrupt_r2 <= 1'b0; end else begin intrrupt_r1 <= intrrupt; intrrupt_r2 <= intrrupt_r1; end end assign neg_intrrupt = (~intrrupt_r1) & intrrupt_r2; //检测接收数据中断的下降沿 always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin state <= IDLE; bps_start <= 1'b0; data_temp <= 8'b0; tx <= 1'b1; end else begin case(state) IDLE : begin if(neg_intrrupt) begin state <= START; bps_start <= 1'b1; //产生发送数据波特率开始标志 data_temp <= rec_data; end else state <= IDLE; end START : begin bps_start <= 1'b0; if(data_flag) state <= TX_DAT; else state <= START; if(tx_bps_clk) tx <= 1'b0; end TX_DAT : begin if(stop_flag) state <= STOP; else if(parity_flag) state <= PARITY; else state <= TX_DAT; if(tx_bps_clk) begin tx <= data_temp[0]; data_temp <= {data_temp[0],data_temp[7:1]}; end end PARITY : begin if(stop_flag) state <= STOP; else state <= PARITY; if(tx_bps_clk) begin if(pari_odd & (^data_temp)) tx <= 1'b0; if(pari_odd & (~(^data_temp))) tx <= 1'b1; if(pari_even & (^data_temp)) tx <= 1'b1; if(pari_even & (~(^data_temp))) &