实现功能:
- FPGA实现串口接收,波特率可修改
- 按字节接收,有完成标志位输出
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// 模块 1: UART 字节接收器 (修正版)
//
// 文件名: Uart_Rec.v
// 描述:
// - 用户提供的UART接收模块。
// - **FIXED**: 将系统时钟参数 CLK_FREQ 修改为 50MHz,以匹配顶层设计,
// 确保波特率计算正确。
//
//////////////////////////////////////////////////////////////////////////////////
module Uart_Rec(input sys_clk, //系统时钟input sys_rst_n, //系统复位,低电平有效input uart_rxd, //UART接收端口output reg uart_done, //接收一帧数据完成标志output reg [7:0] uart_data //接收的数据
);//parameter defineparameter CLK_FREQ = 50000000; // **FIXED**: 系统时钟频率为50MHzparameter UART_BPS = 115200; // 串口波特率localparam BPS_CNT = CLK_FREQ/UART_BPS; // 计算每个比特位的时钟周期数//reg definereg uart_rxd_d0;reg uart_rxd_d1;reg [15:0] clk_cnt;reg [3:0] rx_cnt;reg [7:0] rxdata;reg rx_flag;//wire definewire start_flag;assign start_flag = uart_rxd_d1 & (~uart_rxd_d0);always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginuart_rxd_d0 <= 1'b1;uart_rxd_d1 <= 1'b1;endelse beginuart_rxd_d0 <= uart_rxd;uart_rxd_d1 <= uart_rxd_d0;endendalways @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)rx_flag <= 1'b0;else beginif(start_flag)rx_flag <= 1'b1;else if((rx_cnt == 4'd9) && (clk_cnt == BPS_CNT/2))rx_flag <= 1'b0;endendalways @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)clk_cnt <= 16'd0;else if (rx_flag) beginif (clk_cnt < BPS_CNT - 1)clk_cnt <= clk_cnt + 1'b1;elseclk_cnt <= 16'd0;endelseclk_cnt <= 16'd0;endalways @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)rx_cnt <= 4'd0;else if (rx_flag) beginif (clk_cnt == BPS_CNT - 1)rx_cnt <= rx_cnt + 1'b1;endelserx_cnt <= 4'd0;endalways @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)rxdata <= 8'd0;else if(rx_flag)if (clk_cnt == BPS_CNT/2) begincase (rx_cnt)4'd1 : rxdata[0] <= uart_rxd_d1;4'd2 : rxdata[1] <= uart_rxd_d1;4'd3 : rxdata[2] <= uart_rxd_d1;4'd4 : rxdata[3] <= uart_rxd_d1;4'd5 : rxdata[4] <= uart_rxd_d1;4'd6 : rxdata[5] <= uart_rxd_d1;4'd7 : rxdata[6] <= uart_rxd_d1;4'd8 : rxdata[7] <= uart_rxd_d1;default:;endcaseendendalways @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginuart_data <= 8'd0;uart_done <= 1'b0;endelse if(rx_cnt == 4'd9 && clk_cnt == BPS_CNT/2) beginuart_data <= rxdata;uart_done <= 1'b1;endelse beginuart_done <= 1'b0;endend
endmodule