FPGA 串口 波特率 发生器 代码 求教
代码如下:25M晶振下产生115200的波特率 没有过采样//////////////////////////////////////////////////////////////////////////////////
module BaudTickGen(
input clk, enable,
output tick// generate a tick at the specified baud rate * oversampling
);
parameter ClkFrequency = 25000000;
parameter Baud = 115200;
parameter Oversampling = 1;
function integer log2(input integer v);
begin
log2=0;
while(v>>log2) log2=log2+1;
end
endfunction
localparam AccWidth = log2(ClkFrequency/Baud)+8;// +/- 2% max timing error over a byte
reg Acc = 0;
localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth));// this makes sure Inc calculation doesn't overflow
localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter);
always @(posedge clk)
begin
if(enable) Acc <= Acc + Inc;
else Acc <= Inc;
end
assign tick = Acc;
endmodule
///////////////////////////////////////////////////////////////////////////////
有如下疑问:
1.ACC的宽度处有一个+8,不明白为什么是8
2.+/- 2% max timing error over a byte 是如何计算的?
其实这个程序源于以下波特率发生器的介绍,但同样有疑问:
But what do you do if all your have is, say, a 2MHz clock? To generate 115200Hz from a 2MHz clock, you divide the clock by "17.361111111..." Not exactly a round number. The solution is to divide sometimes by 17, sometimes by 18, making sure the ratio stays "17.361111111". That's actually easy to do.
Look at the following "C" code:
while(1) // repeat forever
{
acc += 115200;
if(acc>=2000000) printf("*"); else printf(" ");
acc %= 2000000;
}
That prints the "*" in the exact ratio, once every "17.361111111..." loops on average.
To obtain the same thing efficiently in an FPGA, we rely on the fact that the serial interface can tolerate a few % of error in the baud frequency generator.
It is desirable that the 2000000 be a power of two. Obviously 2000000 is not. So we change the ratio... Instead of "2000000/115200", let's use "1024/59" = 17.356. That's very close to our ideal ratio, and makes an efficient FPGA implementation.
// 10 bits for the accumulator (), and one extra bit for the accumulator carry-out ()
reg acc; // 11 bits total!
always @(posedge clk)
acc <= acc + 59; // use only 10 bits from the previous result, but save the full 11 bits
wire BaudTick = acc; // so that the 11th bit is the carry-out
Using our 2MHz clock, "BaudTick" is asserted 115234 times a second, a 0.03% error from the ideal 115200.
Parameterized FPGA baud generator
The previous design was using a 10 bits accumulator, but as the clock frequency increases, more bits are required.
Here's a design with a 25MHz clock and a 16 bits accumulator. The design is parameterized, so easy to customize.
parameter ClkFrequency = 25000000; // 25MHz
parameter Baud = 115200;
parameter BaudGeneratorAccWidth = 16;
parameter BaudGeneratorInc = (Baud<<BaudGeneratorAccWidth)/ClkFrequency;
reg BaudGeneratorAcc;
always @(posedge clk)
BaudGeneratorAcc <= BaudGeneratorAcc + BaudGeneratorInc;
wire BaudTick = BaudGeneratorAcc;
疑问如下:
Instead of "2000000/115200", let's use "1024/59" = 17.356.
近似的时候为什么选择了1024 ?
然后累加器就用了十位的,
25M的时候 又近似的多少呢? 65535? 然后用了16位的?
我是想知道这个近似是怎么确定的?
还是只要精度够 就没必要纠结是多少?
这点并没有介绍?
望大家有这方面经验的朋友不吝点拨~~
亲爱的大家一点儿想法也没有么~~~~,,,求教求教~~~ 代码倒是很好使 吼吼:) 本帖最后由 aibing 于 2014-11-30 21:21 编辑
自说自话吧...这是modelsim里的仿真图大致计算了下25M晶振下,1s计115207次,误差在0.006%,满足串口波特率误差容忍范围 <p>有结果了吗?我现在也在思考这个问题,能解答下吗?</p>
页:
[1]