这里波特率的单位是绝对的,用秒相关的单位进行衡量。
但是在FPGA中,时间的最小单位是时钟周期,例如100Mhz的时钟,那么我们在这个系统衡量时间的最小单位就是10ns。(10^9)/(100*10^6)=10ns
所以在异步串口传输中。典型的就是UART传输中,根据协议中波特率的大小,搞清楚在本系统的时钟作用下,传输1bit的数据需要多少个时钟周期的问题。
要搞清楚这个问题。(tip:一般时间以ns为换算单位)
基本思路是:
1. 根据波特率(115200)算出来传输1bit需要多少时间(ns)。
10^9/115200 (1/115200按秒)
2.FPGA系统(100Mhz)中一个时钟周期是多少时间(ns)。
(10^9)/(100*10^6) (1/100*10^6按秒)
常用的频率与周期的转换:
200Mhz-->5ns
100Mhz-->10ns
50Mhz-->20ns
3.计算1bit需要多少时钟周期。
波特周期/时钟周期
一般FPGA编写相关的程序时,主要是需要做一个分频计数器。以上问题转换为如何计算这个计数器是多少进制的问题。
parameter RX_MAX = 100_000_000/(115200 * 16); // 100MHz as clk_in; 115200 as clk_rate
parameter TX_MAX = 100_000_000/(115200);
以下附上一个完整的根据波特率产生采样和发送使能的完整代码
module baud_gen(clk_in,tx_en,rx_en);
// Genrating The Baud For Uart
// Creaating Certain Baud Rate With The Incoming Clk
// The RX CLK is Oversampled 16
input wire clk_in;
output wire tx_en;
output wire rx_en;
parameter RX_MAX = 100_000_000/(115200 * 16); // 100MHz as clk_in; 115200 as clk_rate
parameter TX_MAX = 100_000_000/(115200);
reg[15:0] rx_cnt = 0;
reg[15:0] tx_cnt = 0;
assign rx_en = (rx_cnt == 0);
assign tx_en = (tx_cnt == 0);
always @(posedge clk_in) begin
if (rx_cnt == RX_MAX) begin
rx_cnt <= 0;
end
else begin
rx_cnt <= rx_cnt+1;
end
end
always @(posedge clk_in) begin
if (tx_cnt == TX_MAX) begin
tx_cnt <= 0;
end
else begin
tx_cnt <= tx_cnt + 1;
end
end
endmodule