UART(Universal Asynchronous Receiver-Transmitter):即通用异步收发器,是一种通用串行数据总线,用于异步通信。一般UART接口常指串口。
UART在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。
单工通信:数据只能沿一个方向传输。
半双工通信:数据可以沿两个方向传输,但需要分时进行。
全双工通信:数据可以同时进行双向传输。
同步通信:带时钟端口的数据传输。
异步通信:没有时钟端口,发送方和接收方使用各自的时钟控制数据的收发过程。
常见串行通信接口:




- // uart的接收模块,要求波特率可调,回环实验
- // 完成回环实验后加入校验位
- // 然后加入led与蜂鸣器的控制模块
- `include "para.v"
- module rx (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire rx ,
-
- output reg [7:0] po_data , // port_output
- output reg po_flag
- );
- // parameter
- parameter MAX_BPS_CNT = `CLOCK/`BPS ,//434 ,
- MAX_BIT_CNT = `BIT_CHACK ;//10 ;
- localparam RX_MOD = 1'b1 ,
- CHECK_MOD = `EVEN ;
- // reg signal define
- reg rx_r1 ;
- reg rx_r2 ;
- reg [31:0] cnt_bps ;
- reg work ;
- reg [3:0] cnt_bit ;
- reg [7:0] data_reg ;
- reg check ;
- reg check_reg;
- // wire signal define
- wire nege ;
- /*******************************************************************/
- // // reg signal define
- // reg rx_r1 ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- rx_r1 <= 1'b1 ;
- else
- rx_r1 <= rx ;
- end
- // reg rx_r2 ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- rx_r2 <= 1'b1 ;
- else
- rx_r2 <= rx_r1 ;
- end
- // reg work ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- work <= 1'b0 ;
- else if(nege)
- work <= 1'b1 ;
- else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))) // 这俩条件可以用end_cnt_XXX来代替,组合逻辑赋
- work <= 1'b0 ;
- else
- work <= work ;
- end
- // reg [31:0] cnt_bps ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_bps <= 32'd0 ;
- else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
- cnt_bps <= 32'd0 ;
- else if(work)
- cnt_bps <= cnt_bps + 1'b1 ;
- else
- cnt_bps <= 32'd0 ;
- end
- // reg [3:0] cnt_bit ; 应该会归0
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_bit <= 4'd0 ;
- else if (work && (cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1)))
- cnt_bit <= 4'd0 ;
- else if (work && (cnt_bps == (MAX_BPS_CNT - 1)))
- cnt_bit <= cnt_bit + 1'b1 ;
- else if(work)
- cnt_bit <= cnt_bit ;
- else
- cnt_bit <= 8'd0 ;
- end
- // reg [7:0] data_reg;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- data_reg <= 8'd0 ;
- else if(work && cnt_bps == (MAX_BPS_CNT/2)) begin // 采样,采集数据的时刻
- case (cnt_bit)
- 0 : data_reg <= 8'd0 ;
- 1 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 2 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 3 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 4 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 5 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 6 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 7 : data_reg[cnt_bit - 1] <= rx_r2 ;
- 8 : data_reg[cnt_bit - 1] <= rx_r2 ;
- default: data_reg <= data_reg ;
- endcase
- end else
- data_reg <= data_reg ;
- end
- // // wire signal define
- // wire nege ;
- assign nege = ~rx_r1 && rx_r2 ;
- // reg check ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- check <= 1'b0 ;
- else if(CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
- check <= ~^data_reg ;
- else if(~CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
- check <= ^data_reg ;
- else
- check <= check ;
- end
- // reg check_reg;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- check_reg <= 1'b0 ;
- else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT /2)))
- check_reg <= rx_r2 ;
- else
- check_reg <= check_reg ;
- end
- // output reg [7:0] po_data , // port_output
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data <= 8'd0 ;
- else if((check == check_reg) && (cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1)))
- po_data <= data_reg ;
- else if(RX_MOD)
- po_data <= po_data ;
- else
- po_data <= 8'd0 ;
- end
- // output reg po_flag
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_flag <= 8'd0 ;
- else if((check == check_reg) && ((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))))
- po_flag <= 1'b1 ;
- else
- po_flag <= 8'd0 ;
- end
- endmodule
- // uart的数据发送模块。停止位 1bit
- `include "para.v"
- module tx(
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [7:0] pi_data ,
- input wire pi_flag ,
-
- output reg tx
- );
- // parameter
- parameter MAX_BPS_CNT = `CLOCK/`BPS ,
- MAX_BIT_CNT = `BIT_CHACK + 1;
- localparam CHECK_MOD = `EVEN ;
- // reg signal define
- reg [7:0] data_reg ;
- reg work ;
- reg [31:0] cnt_bps ;
- reg [3:0] cnt_bit ;
-
- /********************************************************************/
- // // reg signal define
- // reg [7:0] data_reg ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- data_reg <= 8'd0 ;
- else if(pi_flag)
- data_reg <= pi_data ;
- else
- data_reg <= data_reg ;
- end
- // reg work ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- work <= 1'b0 ;
- else if(pi_flag)
- work <= 1'b1 ;
- else if(cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1))
- work <= 1'b0 ;
- else
- work <= work ;
- end
- // reg [31:0] cnt_bps ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_bps <= 32'd0 ;
- else if((work && (cnt_bps == (MAX_BPS_CNT - 1)))
- || (work && (cnt_bit == (MAX_BIT_CNT - 1)) && cnt_bps == (MAX_BPS_CNT - 1)))
- cnt_bps <= 32'd0 ;
- else if(work)
- cnt_bps <= cnt_bps + 1'b1 ;
- else
- cnt_bps <= 32'd0 ;
- end
- // reg [3:0] cnt_bit ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_bit <= 4'd0 ;
- else if(work && (cnt_bps == (MAX_BPS_CNT - 1)) && cnt_bit == (MAX_BIT_CNT - 1))
- cnt_bit <= 4'd0 ;
- else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
- cnt_bit <= cnt_bit + 1'b1 ;
- else if(work)
- cnt_bit <= cnt_bit ;
- else
- cnt_bit <= 4'd0 ;
- end
- // output reg tx
- always @(*) begin
- if(~sys_rst_n)
- tx = 1'b1 ;
- else if(work) begin
- case (cnt_bit)
- 4'd0: tx = 1'b0 ;
- 4'd1: tx = data_reg[cnt_bit - 1] ;
- 4'd2: tx = data_reg[cnt_bit - 1] ;
- 4'd3: tx = data_reg[cnt_bit - 1] ;
- 4'd4: tx = data_reg[cnt_bit - 1] ;
- 4'd5: tx = data_reg[cnt_bit - 1] ;
- 4'd6: tx = data_reg[cnt_bit - 1] ;
- 4'd7: tx = data_reg[cnt_bit - 1] ;
- 4'd8: tx = data_reg[cnt_bit - 1] ;
- 4'd9: begin
- if(CHECK_MOD)
- tx = ~^data_reg ;
- else
- tx = ^data_reg ;
- end
- default: tx = 1'b1 ;
- endcase
- end else
- tx = 1'b1 ;
- end
- endmodule
- module top(
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire rx ,
-
- output wire tx
- );
- // 例化间连线 Wiring between instantiations
- wire clk_100Mhz ;
- wire clk_50Mhz ;
- wire locked ;
- wire rst_n ;
- assign rst_n = sys_rst_n && locked ;
- wire [7:0] po_data ;
- wire po_flag ;
- pll pll_inst(
- .clk_in1 ( sys_clk ) ,
- .resetn ( sys_rst_n ) ,
-
- .clk_out1 ( clk_100Mhz ) ,
- .clk_out2 ( clk_50Mhz ) ,
- .locked ( locked )
- );
-
- rx rx_inst(
- .sys_clk ( clk_50Mhz ) ,
- .sys_rst_n ( rst_n ) ,
- .rx ( rx ) ,
-
- .po_data ( po_data ) ,
- .po_flag ( po_flag )
- );
-
- tx tx_inst(
- .sys_clk ( clk_50Mhz ) ,
- .sys_rst_n ( rst_n ) ,
- .pi_data ( po_data ) ,
- .pi_flag ( po_flag ) ,
-
- .tx ( tx )
- );
- endmodule
