我正在尝试将50MHz时钟降至25.175MHz以用于VGA控制器。我已经有一个时钟分频器,但是当每个当前时钟速度和所需时钟速度的分频不是一个整数时,我就无法减慢时钟速度。 I.E. 50000000/25175000~1.98。时钟分频器编译并运行,但如果除法是十进制数,则不输出任何内容。这是我的代码:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Clockdiv IS PORT (
Clkin: IN STD_LOGIC;
Clk: OUT STD_LOGIC);
END Clockdiv;
ARCHITECTURE Behavior OF Clockdiv IS
CONSTANT max: INTEGER := 50000000/25175000;
CONSTANT half: INTEGER := max/2;
SIGNAL count: INTEGER RANGE 0 TO max;
BEGIN
PROCESS
BEGIN
WAIT UNTIL Clkin'EVENT and Clkin = '1';
IF count < max THEN
count <= count + 1;
ELSE
count <= 0;
END IF;
IF count < half THEN
Clk <= '0';
ELSE
Clk <= '1';
END IF;
END PROCESS;
END Behavior;
我在谷歌搜索,发现使用REAL数据类型将允许你使用小数,但当我改变我用于REALs的变量时,Quartus给了我错误:Error (10414): VHDL Unsupported Feature error at Clockdiv.vhd(12): cannot synthesize non-constant real objects or values
。
然后,如果我将“count”更改为CONSTANT
类型,则会收到错误:Error (10477): VHDL error at Clockdiv.vhd(18): name "count" must represent signal
。
有人知道如何将时钟降低到25.175MHz吗?另外,有没有人知道如何减慢时钟速度,以便编译器对结果除法是十进制值感到满意?
由于
答案 0 :(得分:4)
实际上,实际上,实数不可合成,因此您需要提出一个基于整数的解决方案。
这个比例相当棘手,因为它几乎是2:1,但并不完全。大多数基于边沿的时钟分频器电路仅在原始时钟的一个边沿上工作,因此可以除以的最低比率为2.在这种情况下,您将必须在时钟的两个边缘上工作。
一旦你得到了它,你需要一个计数器,它以你的比率的分母递增,并且它超过了分子,然后输出一个时钟边缘。
PROCESS
BEGIN
WAIT UNTIL Clkin'EVENT;
IF count < max THEN
count <= count + DENOMINATOR;
ELSE
count <= 0;
END IF;
IF count > NOMINATOR THEN
Clk <= ~Clk;
END IF;
END PROCESS;
对于这个比例,我认为你能代表它的最小方式是2000/1007。
这样做的问题在于你将获得一个基本上为25MHz的时钟,但偶尔(每个2000/7次迭代)你将获得额外的优势。它不会是25.175MHz的时钟。没有PLL,从50MHz获得25.175MHz是不可能的。
答案 1 :(得分:2)
我已经编写了大量的VGA控制器,而使用25 MHz时钟从来就不是一个问题。如果你绝对想要靠近,你的FPGA可能有某种类型的时钟管理器(我只熟悉Xilinx器件),它允许你通过乘以和分频输入时钟来合成输出时钟。
此外,在这种情况下,使用派生/门控时钟(在进程中直接设置值的时钟)可能对您有用,但它可能会导致很多难以调试的问题。更好的解决方案是生成时钟使能,然后在相同(快速)时钟上运行所有内容。
最后一点,尽管它可能是首选样式的问题,但我通常使用时钟流程语句而不是WAIT
语句(如下所示,带有上升沿触发,同步复位和时钟使能) 。我发现阅读和理解更加清晰,并且不太容易编写不可合成的结构,例如wait for 10ns;
或具有多个WAIT
的语句。
process(clk)
begin
if(rising_edge(clk)) then
if(sync_reset = '1') then
--Reset logic
elsif(clk_enable = '1') then
--Actual functionality
end if;
end if;
end process;