protocolo UART

unidad de comunicación asíncrona para transmitir un carácter, cómo el intervalo de tiempo de comunicación no es fija entre los dos personajes, pero al mismo tiempo entre dos bits adyacentes en un espacio entre caracteres es fijo.
La interfaz de serie es un dispositivo que puede recibir caracteres de datos en paralelo enviados desde la CPU se convierte en una corriente de datos en serie continua, mientras que el aceptados suministra a la corriente de datos en serie CPU en un datos en paralelo de un dispositivo de caracteres.
Aquí Insertar imagen Descripción
Bit de arranque: la emisión de una primera señal "0" indica el carácter de comienzo de la transmisión de la lógica.
Bits de datos: 5 a 8 pueden ser una lógica "0" o "1" El código ASCII (7), código BCD extendido (8). Extremo pequeño de transmisión
de bits de paridad: después de los bits de datos, además de éste, por lo que el número de bits "1" debe ser un número par (paridad par) o (paridad impar) impar
Bits de parada: se trata de una señal del fin de los datos de carácter. Puede ser 1, 1,5, 2 es un nivel alto.
posición de ralentí: en un estado lógico "1", lo que indica ninguna transmisión de datos en la línea actual.

Transmitida
en la tasa de comunicación de transmisión en serie de los datos que representan los bits puede ser transmitida por segundo, 9.600 por segundo, que es capaz de transmitir 9600
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
bytes transmitidos

//-------1字节数据的发送-------
module uart_tx(
    input clk,
    input rst_n,
    input cnt_start,                                        //发送使能
	input [7:0]tx_data,
    output reg tx,
    output reg tx_done                                      //传输一个字节完成标志
    );
    
    reg [12:0]cnt_bps; 
    parameter bps_t = 13'd5207;                             //传输1bit所需计数值 
    always @(posedge clk or negedge rst_n)
    begin
       if(!rst_n) 
          cnt_bps <= 13'd0;
       else if(cnt_bps == bps_t) 
          cnt_bps <= 13'd0;
       else if(cnt_start) 
          cnt_bps <= cnt_bps + 1'b1;
       else 
          cnt_bps <= 1'b0;
    end
    wire bps_sig;
    assign bps_sig = (cnt_bps ==  13'd2604) ? 1'b1 : 1'b0;  //将采集数据的时刻放在波特率计数器每次循环计数的中间位置
       
    reg [3:0]state;	
    always @(posedge clk or negedge rst_n)
    begin
       if(!rst_n) begin
          state <= 4'd0;
          tx <= 1'b1;
          tx_done <= 1'b0;
		  end
       else begin
          case(state)
			0: if(cnt_start & bps_sig) begin
				state <= state + 1'b1;
				tx <= 1'b0;
				end
			else begin
				state <= state;
				tx <= 1'b1;
				end
			1,2,3,4,5,6,7,8: if(bps_sig) begin
					tx <= tx_data[state - 1'b1]; //注意,从低位依次往高位发送
					state <= state + 1'b1;
					end
				else begin
					state <= state;
					tx <= tx;
					end
			9,10: if(bps_sig) begin
					state <= state + 1'b1;
					tx <= 1'b1;
					end
			11: begin
					state <= state + 1'b1;
					tx_done <= 1'b1;
				end
			12: begin
					state <= 1'b0;
					tx_done <= 1'b0;
				end
          endcase
		  end
    end
endmodule

Recibir datos
, en forma de transferencia de bytes: 1-0-xxxxxxxx-0-1, es decir, -1-0- detectado flanco de bajada (bandera de inicio) después del comienzo de bytes recibidos, la recibieron uno a uno en el registro , el extremo del receptor de 8 bits está recibiendo un byte simple.
Se hace notar que, aunque la 1 byte = 8 bits, pero debido a que la bandera de salida (2 bits: -1-0-) y marcador de final (2bit: -0-1-), por lo que la transmisión y recepción, se requieren teniendo esto en cuenta.

//-------1字节的接收-------
module uart_rx(
    input clk,
    input rst_n,
	input data_rx,
    output [7:0] data_tx,
    output reg rx_int                                       //接收字节时状态为1
    );
    
    reg [12:0]cnt_bps;
	reg bps_start;
    parameter bps_t = 13'd5207;                             //传输1bit所需计数值 
    always @(posedge clk or negedge rst_n)
    begin
       if(!rst_n) 
          cnt_bps <= 13'd0;
       else if(cnt_bps == bps_t) 
          cnt_bps <= 13'd0;
       else if(bps_start) 
          cnt_bps <= cnt_bps + 1'b1;
       else 
          cnt_bps <= 1'b0;
    end
    wire bps_sig;
    assign bps_sig = (cnt_bps ==  13'd2604) ? 1'b1 : 1'b0;  //将采集数据的时刻放在波特率计数器每次循环计数的中间位置
	
	reg	[1:0]	rx;
	always @(posedge	clk	or	negedge	rst_n)begin
		if(!rst_n)	rx <= 2'b11;
		else	begin
			rx[0]	<=	data_rx;
			rx[1]	<=	rx[0];
		end
	end
	wire nege_edge;
	assign nege_edge= rx[1]	& ~rx[0];						//检测下降沿

	reg	[3:0]num;	
	always@(posedge	clk	or	negedge	rst_n)begin
		if(!rst_n)	begin	
			bps_start <= 1'b0;	
			rx_int <= 1'b0;
		end
		else	if(nege_edge)begin
			bps_start <= 1'b1;
			rx_int <= 1'b1;
		end
		else if(num == 4'd10)begin
			bps_start <= 1'b0;	
			rx_int <= 1'b0;
		end
	end

	reg	[7:0]	rx_data_temp_r;								//当前数据接收寄存器
	reg	[7:0]	rx_data_r;									//用来锁存数据
	always@(posedge	clk	or	negedge	rst_n)begin
		if(!rst_n)	begin	
			rx_data_r	<= 8'd0;
			rx_data_temp_r	<= 8'd0;
			num <= 4'd0;
			end
		else if(rx_int) begin
			if(bps_sig) begin
				num <= num + 1'b1;
				case(num)
					4'd1: rx_data_temp_r[0] <= data_rx;		//锁存第0bit
					4'd2: rx_data_temp_r[1] <= data_rx;		//锁存第1bit
					4'd3: rx_data_temp_r[2] <= data_rx;		//锁存第2bit
					4'd4: rx_data_temp_r[3] <= data_rx;		//锁存第3bit
					4'd5: rx_data_temp_r[4] <= data_rx;		//锁存第4bit
					4'd6: rx_data_temp_r[5] <= data_rx;		//锁存第5bit
					4'd7: rx_data_temp_r[6] <= data_rx;		//锁存第6bit
					4'd8: rx_data_temp_r[7] <= data_rx;		//锁存第7bit
					default: ;
				endcase
			end
			else if(num == 4'd10)begin
				rx_data_r <= rx_data_temp_r;
				num <= 4'd0;
			end
		end
	end

	assign	data_tx = rx_data_r;							
	
endmodule

tuberculosis

module tb_uart_rx;

	// Inputs
	reg clk;
	reg rst_n;
	reg data_rx;

	// Outputs
	wire [7:0] data_tx;
	wire rx_int;

	// Instantiate the Unit Under Test (UUT)
	uart_rx uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.data_rx(data_rx), 
		.data_tx(data_tx), 
		.rx_int(rx_int)
	);

	always #10 clk = ~clk;
	initial begin
		clk = 0;
		rst_n = 0;
		data_rx = 0;
		// Wait 20 ns for global reset to finish
		#20
		rst_n = 1;
		data_rx = 1;
		#104160
		rst_n = 1;
		data_rx = 0;	//起始位:-1-0-
		#104160			//传输11001011 (倒序)
		rst_n = 1;
		data_rx = 1;
		#104160
		rst_n = 1;
		data_rx = 1;
		#104160
		rst_n = 1;
		data_rx = 0;
		#104160
		rst_n = 1;
		data_rx = 1;
		#104160
		rst_n = 1;
		data_rx = 0;
		#104160
		rst_n = 1;
		data_rx = 0;
		#104160
		rst_n = 1;
		data_rx = 1;
		#104160
		rst_n = 1;
		data_rx = 1;
		#104160			//结束位 -0-1-
		rst_n = 1;
		data_rx = 0;
		#104160
		rst_n = 1;
		data_rx = 1;
		
		#104160			//复位
		rst_n = 0;
		data_rx = 0;
	end
      
endmodule

árbitro

https://blog.csdn.net/qq_40789587/article/details/84073419?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5

ref
https://blog.csdn.net/zjy900507/article/details/79789671

Publicados 452 artículos originales · ganado elogios 271 · vistas 730 000 +

Supongo que te gusta

Origin blog.csdn.net/qq_35608277/article/details/105286695
Recomendado
Clasificación