赞
踩
接收并行数据,将数据转成并行数据,依次发出。
和发送端的区别:
信号名 | 方向 | 含义 |
BAUD_RATE | parameter/input | parameter类型,波特率 |
clk | input | 模块工作时钟 |
reset_n | input | 模块复位信号 |
uart_rxd | input | 接收的串行数据 |
rx_data[7:0] | output | 解析出的并行数据 |
rx_dv | output | 接收数据有效指示信号,因为端口是clk,这个信号是clk的时钟域,一个时钟宽度 |
对串行线上进行16倍波特率的过采样(upsampling)(即1位数据采样16次),这样可以避免线上干扰,收发时钟skew的问题,通过过采样的数据判断起始位,数据位,还是停止位。
起始位判断这里有个技术细节:从哪一次开始计数到16次,这里需要边沿检测,检测到边沿后开始计数。
沿检测的方法:上一个时钟采样到1,下一个时钟采样到0(下降沿),这个时钟用哪个有不同的区别,这里选择与数据判断一致的16倍波特率时钟
每解析出一位数据位,将这一位数据存在寄存器中,等停止位判断正确后,将rx_dv拉高一个时钟周期。
如果停止位不对,就舍弃这8位数据,重新等待起始位。
这次rx的难度明显比tx大,其中一个关键点,就是多了一个时钟,如果觉得复杂,是否可以拆分成更小的module,每个module使用一个时钟
将rx分成如下几个部分:
Baud_rate_clk产生部分:输入系统时钟,输出预期波特率16倍的时钟
位检测处理部分:输入波特率16倍的时钟,输入串行数据,输入串行数据有效标志,输出位检测结果,并伴随数据有效信号
——这部分相对独立,可以考虑将其封装成一个module
- module uart_rx
- #(parameter SYSCLK = 50_000_000, BAUDRATE = 115200)
- (
- clk,
- reset_n,
- uart_rxd,
- rx_data,
- rx_dv
- );
-
- input clk;
- input reset_n;
- input uart_rxd;
- output reg [7:0] rx_data;
- output reg rx_dv;
-
- wire baud_clk_16;
-
- reg uart_rxd_r;
-
- wire sdata;
- reg sdata_valid;
- wire bit;
- wire bit_valid;
-
- parameter IDLE = 4'b0000;
- parameter START_BIT = 4'b0001;
- parameter RXD_BIT0 = 4'b0010;
- parameter RXD_BIT1 = 4'b0011;
- parameter RXD_BIT2 = 4'b0100;
- parameter RXD_BIT3 = 4'b0101;
- parameter RXD_BIT4 = 4'b0110;
- parameter RXD_BIT5 = 4'b0111;
- parameter RXD_BIT6 = 4'b1000;
- parameter RXD_BIT7 = 4'b1001;
- parameter STOP_BIT = 4'b1010;
-
- reg [3:0] state;
- reg [7:0] temp_data;
-
- reg [3:0] rxd_bit_cnt;
-
- //产生波特�??16倍的时钟
- baud_clk_gen
- #(SYSCLK, BAUDRATE)
- baud_clk_gen_inst
- (
- .clk(clk),
- .reset_n(reset_n),
- .baud_clk_16(baud_clk_16)
- );
-
- //起始位下降沿�??�??
- always@(posedge baud_clk_16)
- begin
- uart_rxd_r <= #1 uart_rxd;
- end
-
- //状�?�机
- //主状态机的输�??
- always@(posedge clk or negedge reset_n)
- begin
- if(!reset_n)
- begin
- rx_dv <= #1 0;
- rx_data <= #1 8'b0;
- temp_data <= #1 8'b0;
- end
- else
- begin
- case(state)
- RXD_BIT0:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:1],bit};
- end
-
- RXD_BIT1:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:2],bit,temp_data[0]};
- end
-
- RXD_BIT2:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:3],bit,temp_data[1:0]};
- end
-
- RXD_BIT3:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:4],bit,temp_data[2:0]};
- end
-
- RXD_BIT4:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:5],bit,temp_data[3:0]};
- end
-
- RXD_BIT5:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7:6],bit,temp_data[4:0]};
- end
-
- RXD_BIT6:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {temp_data[7],bit,temp_data[5:0]};
- end
-
- RXD_BIT7:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- if(bit_valid)
- temp_data <= #1 {bit,temp_data[6:0]};
- end
-
- STOP_BIT:
- begin
- if(bit_valid & (1 == bit) & (0 ==rx_dv))
- begin
- rx_dv <= #1 1;
- rx_data <= #1 temp_data;
- end
- else
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- end
- temp_data <= #1 temp_data;
- end
-
- default:
- begin
- rx_dv <= #1 0;
- rx_data <= #1 rx_data;
- temp_data <= #1 temp_data;
- end
- endcase
- end
- end
-
- //状�?�机的跳转条�??
- always@(posedge baud_clk_16 or negedge reset_n)
- begin
- if(!reset_n)
- state <= #1 IDLE;
- else if((IDLE == state) & (1 == uart_rxd_r) & (0 == uart_rxd))
- state <= #1 START_BIT;
- else if((START_BIT == state) & bit_valid & (0 == bit))
- state <= #1 RXD_BIT0;
- else if((START_BIT == state) & bit_valid & (1 == bit))
- state <= #1 IDLE;
- else if((RXD_BIT0 == state) & bit_valid)
- state <= #1 RXD_BIT1;
- else if((RXD_BIT1 == state) & bit_valid)
- state <= #1 RXD_BIT2;
- else if((RXD_BIT2 == state) & bit_valid)
- state <= #1 RXD_BIT3;
- else if((RXD_BIT3 == state) & bit_valid)
- state <= #1 RXD_BIT4;
- else if((RXD_BIT4 == state) & bit_valid)
- state <= #1 RXD_BIT5;
- else if((RXD_BIT5 == state) & bit_valid)
- state <= #1 RXD_BIT6;
- else if((RXD_BIT6 == state) & bit_valid)
- state <= #1 RXD_BIT7;
- else if((RXD_BIT7 == state) & bit_valid)
- state <= #1 STOP_BIT;
- else if((STOP_BIT == state) & bit_valid)
- state <= #1 IDLE;
- else
- state <= #1 state;
- end
-
-
- //位数据采�??
- assign sdata = uart_rxd_r;
-
- bit_sample bit_sample_inst
- (
- .baud_clk_16(baud_clk_16),
- .reset_n(reset_n),
- .sdata(sdata),
- .sdata_valid(sdata_valid),
- .bit(bit),
- .bit_valid(bit_valid)
- );
-
-
- always@(posedge baud_clk_16 or negedge reset_n)
- begin
- if(!reset_n)
- sdata_valid <= #1 0;
- else if((IDLE == state) & (1 == uart_rxd_r) & (0 == uart_rxd))
- sdata_valid <= #1 1;
- else if(IDLE == state)
- sdata_valid <= #1 0;
- else if((START_BIT == state) & bit_valid & (0 == bit))
- sdata_valid <= #1 1;
- else if((START_BIT == state) & bit_valid & (1 == bit))
- sdata_valid <= #1 0;
- else if((STOP_BIT == state) & bit_valid)
- sdata_valid <= #1 0;
- else
- sdata_valid <= #1 1;
- end
-
-
- endmodule

- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Create Date: 2022/09/18 17:13:49
- // Design Name:
- // Module Name: baud_clk_gen
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- // 产生期望的波特率×16倍的时钟,这个期望通过parameter传递,这个期望的波特率BAUDRATE需要小于等于SYSCLK/32
- // 如SYSCLK = 50MHz,BAUDRATE = 1.5625Mbps,640ns per bit,baud_clk_16=25MHz,50ns per bit
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //
-
-
- module baud_clk_gen
- #(parameter SYSCLK = 50_000_000, BAUDRATE = 115200)
- (
- clk,
- reset_n,
- baud_clk_16
- );
-
- input clk;
- input reset_n;
- output reg baud_clk_16;
-
- reg [7:0] cnt;
-
- always@(posedge clk or negedge reset_n)
- begin
- if(!reset_n)
- baud_clk_16 <= #1 1;
- else if((SYSCLK/BAUDRATE/16/2 -1) == cnt)
- baud_clk_16 <= #1 ~ baud_clk_16;
- else
- baud_clk_16 <= #1 baud_clk_16;
- end
-
- always@(posedge clk or negedge reset_n)
- begin
- if(!reset_n)
- cnt <= #1 8'b0;
- else if((SYSCLK/BAUDRATE/16/2-1) == cnt)
- cnt <= #1 8'b0;
- else
- cnt <= #1 cnt + 1'b1;
- end
- endmodule

- `timescale 1ns / 1ps
- //
- // Company:
- // Engineer:
- //
- // Create Date: 2022/09/18 21:28:06
- // Design Name:
- // Module Name: bit_sample
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description:
- // 每个bit位的采集。对16个采样值进行划分,前4不用,后3不用,
- // 选中间的9个值,9个值中,1的个数超过一半,即大于等于5,就算这一位是1;
- // 如果0的个数超过一半,即大于等于5,就算这一位是0。
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //
-
-
- module bit_sample
- (
- baud_clk_16,
- reset_n,
- sdata,
- sdata_valid,
- bit,
- bit_valid
- );
-
- input baud_clk_16;
- input reset_n;
- input sdata;
- input sdata_valid;
- output reg bit;
- output reg bit_valid;
-
- reg [3:0] cnt;
-
- always@(posedge baud_clk_16 or negedge reset_n)
- begin
- if(!reset_n)
- cnt <= #1 4'b0;
- else if(4'b1111 == cnt)
- cnt <= #1 4'b0;
- else if(1 == sdata_valid)
- cnt <= #1 cnt + 1;
- else
- cnt <= #1 cnt;
- end
- reg [3:0] temp;
- always@(posedge baud_clk_16 or negedge reset_n)
- begin
- if(!reset_n)
- temp <= #1 4'b0;
- else if(4'b0000 == cnt)
- temp <= #1 4'b0;
- else if((4'b0100 <= cnt) & (4'b1100 >= cnt))
- temp <= #1 temp + sdata;
- else
- temp <= #1 temp;
- end
-
- always@(posedge baud_clk_16 or negedge reset_n)
- begin
- if(!reset_n)
- begin
- bit <= #1 0;
- bit_valid <= #1 0;
- end
- else if(4'b1110 == cnt)
- begin
- bit <= #1 (temp >= 5) ? 1 : 0;
- bit_valid <= #1 1;
- end
- else
- begin
- bit <= #1 bit;
- bit_valid <= #1 0;
- end
- end
- endmodule

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。