完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 yaokangning 于 2014-11-29 21:58 编辑
代码如下: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 [AccWidth:0] 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[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0]; end assign tick = Acc[AccWidth]; 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 ([9:0]), and one extra bit for the accumulator carry-out ([10]) reg [10:0] acc; // 11 bits total! always @(posedge clk) acc <= acc[9:0] + 59; // use only 10 bits from the previous result, but save the full 11 bits wire BaudTick = acc[10]; // 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< reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc; always @(posedge clk) BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc; wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth]; 疑问如下: Instead of "2000000/115200", let's use "1024/59" = 17.356. 近似的时候为什么选择了1024 ? 然后累加器就用了十位的, 25M的时候 又近似的多少呢? 65535? 然后用了16位的? 我是想知道这个近似是怎么确定的? 还是只要精度够 就没必要纠结是多少? 这点并没有介绍? 望大家有这方面经验的朋友不吝点拨~~ |
|
相关推荐
|
|
1.jpg (55.97 KB, 下载次数: 0) Modelsim仿真图 [url=][/url] |
|
|
|
|
|
用的VHDL,看得不太明白。
这个用小数分频就解决了的,思想和他写的一样,有时候17,有时候18。小数分频都这样的,抖动和你分频的时钟相关,就是25MHz。115200的话,肯定是达到要求了。 |
|
|
|
|
|
应该是200,000/115200=1250/72≈17.36,他是为了方便编程就近似为1024/17.36≈59,选1024只不过是因为2的10次方且最接近1250,都是为了后面的程序好写,刚开始学FPGA,请多指教!
|
|
|
|
|
|
1779 浏览 1 评论
1518 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
1735 浏览 0 评论
954 浏览 0 评论
2525 浏览 0 评论
1558 浏览 38 评论
5791 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-2 09:54 , Processed in 0.729385 second(s), Total 70, Slave 53 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号