Uart回环测试
一、Uart接受模块设计
## 1.串口模块的时序设计图



PS:1. 0-bit_cnt 接受了起始位;1-bit_cnt 接受了数据位第一位;以此类推,8_bit-cnt 接受了数据位第八位;(此时拉高po_flag,表示数据接收完成。
2. bit_cnt>=1时代表着传输数据的开始,结合bit_flag,进行数据的位移操作;****
如下所示,为具体的verilog实现代码:
点击查看代码
`timescale 1ns / 1ps
`define sim
module uart_rx(
//system signal
input sclk ,
input rst_n ,
//uart interface
input uart_rx ,
//others
output reg [7:0] rx_data ,
output reg rx_done
);
reg rx_r1 ;
reg rx_r2 ; //打两拍跨时钟域
reg rx_r3 ; //检测下降沿
reg rx_flag ;
reg[12:0] baud_cnt ;
reg bit_flag ;
reg[3:0] bit_cnt ;
wire rx_in_nedge;
assign rx_in_nedge = ~rx_r2 & rx_r3;
`ifndef sim
localparam BAUD_END = 5208 - 1; //根据波特率设置
`else
localparam BAUD_END = 56;
`endif
localparam BAUD_M = BAUD_END / 2 - 1; //在每一位的中间采样
localparam BIT_END = 8 ;
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)begin
rx_r1 <= 1'b0;
rx_r2 <= 1'b0;
rx_r3 <= 1'b0;
end
else begin
rx_r1 <= uart_rx;
rx_r2 <= rx_r1;
rx_r3 <= rx_r2;
end
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
rx_flag <= 1'b0;
else if(rx_in_nedge)
rx_flag <= 1'b1;
else if(bit_cnt == 0 && baud_cnt == BAUD_END)
rx_flag <= 1'b0;
else
rx_flag <= rx_flag;
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
baud_cnt <= 13'b0;
else if(baud_cnt == BAUD_END)
baud_cnt <= 13'b0;
else if(rx_flag)
baud_cnt <= baud_cnt + 1;
else
baud_cnt <= 13'b0;
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
bit_flag <= 1'b0;
else if(baud_cnt == BAUD_M)
bit_flag <= 1'b1;
else
bit_flag <= 1'b0;
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
bit_cnt <= 4'b0;
else if(bit_cnt == 8 && bit_flag)
bit_cnt <= 4'b0;
else if(bit_flag)
bit_cnt <= bit_cnt + 1;
else
bit_cnt <= bit_cnt;
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
rx_data <= 8'b0;
else if(bit_cnt>=1 && bit_flag)
rx_data <= {rx_r2,rx_data[7:1]};
else
rx_data <= rx_data;
end
always@(posedge sclk,negedge rst_n)begin
if(!rst_n)
rx_done <= 1'b0;
else if(bit_cnt == 8 && bit_flag)
rx_done <= 1'b1;
else
rx_done <= 1'b0;
end
endmodule
点击查看代码
`timescale 1ns / 1ps
module uart_rx_tb();
reg sclk;
reg rst_n;
reg uart_rx;
wire[7:0] rx_data;
wire rx_done;
reg[7:0] mem_a[3:0]; //定义了一个深度为4.位宽为8的寄存器
initial sclk = 1;
always #5 sclk =~sclk;
initial $readmemb("tx_data.txt",mem_a);
initial begin
rst_n = 0;
uart_rx = 1;
#100
rst_n = 1;
#200
tx_byte();
end
task tx_byte();
integer i;
for(i=0;i<4;i=i+1)begin
tx_bit(mem_a[i]);
end
endtask
task tx_bit (
input [7:0] data
);
integer i;
for(i = 0;i<10;i=i+1)begin
case(i)
0: uart_rx <= 1'b0;
1: uart_rx <= data[0];
2: uart_rx <= data[1];
3: uart_rx <= data[2];
4: uart_rx <= data[3];
5: uart_rx <= data[4];
6: uart_rx <= data[5];
7: uart_rx <= data[6];
8: uart_rx <= data[7];
9: uart_rx <= 1'b1;
endcase
#560;
end
endtask
uart_rx inst0(
//system signal
.sclk (sclk ),
.rst_n (rst_n ),
//uart interface
.uart_rx (uart_rx ),
//others
.rx_data (rx_data ),
.rx_done (rx_done )
);
endmodule
posted on 2024-06-16 23:00 MVP-curry-萌神 阅读(147) 评论(0) 收藏 举报
浙公网安备 33010602011771号