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.
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
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