打印
[VHDL]

玩转VHDL-003分频

[复制链接]
766|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ucx|  楼主 | 2017-9-18 16:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

分频器
我们知道串口常用的波特率为300,600, 1200, 2400, 4800, 9600, 19200, 38400, 43000, 56000, 57600, 115200。在用FPGA实现UART协议时,我们期望最好有上述波特率整数倍的系统时钟,但这样的时钟频率不常见。不过,我们可以通过分数分频的方法实现这一功能。为清晰阐明分数分频,在此先不考虑4300bps的波特率。

假设FPGA系统时钟为80M,如果我们能通过分数分频实现64.512M的时钟,那么除43000外其他所有波特率值均可以整除64.512M。再分别实现各个波特率,接下来就只剩下整数分频的问题了。由于64512 / 80000 = 504 / 625,那么在80M时钟下每625个时钟取504个时钟则等效为64.512M时钟了。

进一步分析,625=125×5504=125×4 + 4。设计两个计数器partsshareshare按照80M时钟节拍模5计数,而partsshare=4为节拍模125计数。那么partsshare的组合625个时钟周期重复一次。每个share5个时钟周期,取4个周期,这样在625个时钟周期中获得了500个周期。再从125parts中选择4个,在这4个选出的partsshare的第5个周期也被选择使能,那么就获得了125×4 + 4 = 504个周期。程序代码如下:

--fraction_div.vhd
Library ieee;Useieee.std_logic_1164.all,ieee.std_logic_unsigned.all;
Library ucxLib; Use ucxLib.ucx_2008pkg.all;

Entity fraction_div is port(
         clock                                                        :in std_logic;
         q                                                            :out std_logic
         );
End fraction_div;

Architecture myFavor of fraction_div is
         signal parts                                  : std_vector(0to 6);
         signal share                                 : std_vector(0to 2);
         signalclk32256K,clk_en                  : std_logic :='0';
Begin
Process(clock) begin
         if rising_edge(clock)then
                   RstIncDec(share,share(0), '1');
                   RstIncDec(parts,share(0) and parts=124, share(0));
                   clk_en <=not share(0) or parts=0 or parts=31 or parts=62 or parts=93;
         end if;
End process;
Process(clock, clk_en) begin
         if rising_edge(clock)and clk_en then
                   clk32256K<= not clk32256K;
         end if;
End process;
q <= clk32256K;
End myFavor;

fraction_div.vhd实现的功能是输入clock为80MHz,输出q为32.256M。即表明程序中rising_edge(clock) and clk_en实现64.512M时钟功能。不过q的占空比不是固定50%。

代码行18表明parts在parts=124和share >=4时清零,否则在share>=4条件下增1计数。
行19中not share(0)表示share=0,1,2,3四个周期,parts=0or parts=31 or parts=62 or parts=93表示均匀选取4个parts。
行18中与运算share(0)and parts=124第一个参数share(0)是std_logic型,第二个参数parts=124是boolean。这样书写可以编译通过,因为在ucx_2008pkg.vhd中重载了and运算符。

         Function"and"(bL: std_logic;  bR:boolean) return std_logic is
         begin
                   return bLand STDZ(bR);
         End;
         Function"and"(bL: boolean;             bR:std_logic) return boolean is
         begin
                   return bLand bR='1';
         End;
运算符and重载后,boolean和std_logic两个不同类型的变量运算后结果同第一个变量。类似地可以重载or,xor,nand,nor和xnor。并加入到自定义库中。



相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

ucx

29

主题

89

帖子

5

粉丝