以下是笔者用AHDL (Altera HDL)语言写的关于外部PLL控制器,50%占空比的5分频和50%占空比的3分频模块的源程序及其生成的模块图,程序中文字部分为注释。
AHDL 是Altera 公司的硬件逻辑描述语言的简称,其特点是非常易学易用,学过高级语言的人可以在很短的时间(如几周)内掌握AHDL。它的缺点是移植性不好,通常只用于ALTERA自己的开发系统。
由于我们研发的系统采用“自顶向下”层次化设计的思想,这里提供的只是各个模块的源程序,在实际设计中采用以下源程序生成各个相应的模块,然后在顶层文件中加以组合,以完成相应的功能。
----------------------------------------------------------------------------------------------------------------------
--该程序为外部PLL系数控制源程序
SUBDESIGN Pll_control -- 设计实体名;
(
gear_v[1..0]: INPUT; --定义一个模4计数器的输出值作为该控制器的输入; --模4计数器用于记录切换按键的脉冲,每按一次按键,计数器加1;
v[8..0],r[6..0],s[2..0]: OUTPUT;
)
BEGIN
TABLE
gear_v[1..0]=> v[8..0],r[6..0],s[2..0];
0 => B"001111000",B"0010111",B"100";
1 => B"100000000",B"0010111",B"100";
2 => B"010101011",B"0010111",B"100";
3 => B"100001000",B"0010111",B"100";
END TABLE;
END;
----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
--该程序为50%占空比5分频模块源程序
SUBDESIGN clk_divider_5 -- 设计实体名;
(
Clock, en : INPUT;
Divide_Clk : OUTPUT;
)
VARIABLE
Interior_Clk : Node; -- 建立一个内部时钟;
Divide_DFF[1..0] : DFF; -- 说明一个 D 触发组;
Result_DFF : DFF; -- 建立一个输出 D 触发器;
BEGIN
IF en THEN
Interior_Clk = Clock $ Result_DFF; -- 输入时钟异或结果触发器值;
Divide_DFF[].Clk = Interior_Clk; -- D 触发器的时钟连接;
IF Divide_DFF[] = = 2 THEN --D 触发器的输入端处理;
Divide_DFF[].D = 0;
ELSE
Divide_DFF[].D = Divide_DFF[] + 1;
END IF;
-- 计数器计满一次,结果触发器翻转一次;
Result_DFF.Clk = Divide_DFF[1];
Result_DFF.D = !Result_DFF;
Divide_Clk = Result_DFF; -- 分频信号输出;
END IF;
END;
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
--该程序为50%占空比3分频模块源程序
SUBDESIGN clk_divider_3 -- 设计实体名;
(
Clock, en : INPUT;
Divide_Clk : OUTPUT;
)
VARIABLE
Interior_Clk : Node; -- 建立一个内部时钟;
Divide_DFF : DFF; -- 说明一个 D 触发器;
Result_DFF : DFF; -- 建立一个输出 D 触发器;
BEGIN
IF en THEN
Interior_Clk = Clock $ Result_DFF; -- 输入时钟异或结果触发器值;
Divide_DFF[].Clk = Interior_Clk; -- D 触发器的时钟连接;
IF Divide_DFF[] = = 1 THEN --D 触发器的输入端处理;
Divide_DFF[].D = 0;
ELSE
Divide_DFF[].D = Divide_DFF[] + 1;
END IF;
-- 计数器计满一次,结果触发器翻转一次;
Result_DFF.Clk = Divide_DFF;
Result_DFF.D = !Result_DFF;
Divide_Clk = Result_DFF; -- 分频信号输出;
END IF;
END;
-------------------------------------------------------------------------------------------------------------------
对于模10分频器,因为是偶数倍分频,可直接调用Quartus II开发工具中参数化计数器来实现。为确保占空比为50%,先进行5分频,然后进行2分频实现。具体如下图所示:
![](http://www.picavr.com/upload/2008_01/08010415491421.jpg)