在 VHDL 中创建分频器
主要编辑:
阅读威尔·迪恩的评论后问题得到解决。原来的问题在修改后的代码下面:
-- REVISED CODE (NOW WORKS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity CLOCK_DIVIDER is
port(
reset : in std_logic;
clk : in std_logic;
half_clk : out std_logic
);
end CLOCK_DIVIDER;
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;
begin
process(clk, reset)
begin
if reset = '1' then
tick <= '0';
elsif clk = '1' and clk'EVENT then
if tick = '0' then
tick <= '1';
elsif tick = '1' then
tick <= '0';
end if;
end if;
end process;
process(tick)
begin
half_clk <= tick;
end process
end CLOCK_DIVIDER;
修改后的代码的综合逻辑块是一个异步复位DFF,它以half_clk作为输出,反相half_clk作为输入,这意味着half_clk的值在clk的每个上升沿发生变化。
谢谢,威尔·迪恩:)
==== ==== ==== ==== ====
原问题如下:
==== ==== ==== ==== ====
我需要一个简单的时钟分频器(只需除以二),而不是使用模板,我想我应该尝试自己编写一个以保持训练。
不幸的是,合成的逻辑块似乎不起作用 - 我按顺序展示了逻辑块和代码(我确实认为应该起作用)。
逻辑块http://img808.imageshack.us/img808/3333/unledly.png< /a>
我真正想知道的是“tick”DFF 到底是怎么回事 - 它显然从多路复用器选择器中获取输入,这是......是的。
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity CLOCK_DIVIDER is
port(
reset : in std_logic;
clk : in std_logic;
half_clk : out std_logic
);
end CLOCK_DIVIDER;
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;
begin
process(clk, reset)
begin
if reset = '1' then
half_clk <= '0';
tick <= '0';
elsif clk = '1' and clk'EVENT then
if tick = '0' then
half_clk <= '0';
tick <= '1';
elsif tick = '1' then
half_clk <= '1';
tick <= '0';
end if;
end if;
end process;
end CLOCK_DIVIDER;
我确信代码中的错误是显而易见的,但我一直盲目地盯着自己试图找到它。
MAJOR EDIT:
Problem was solved after reading Will Dean's comment. The original question is below the revised code:
-- REVISED CODE (NOW WORKS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity CLOCK_DIVIDER is
port(
reset : in std_logic;
clk : in std_logic;
half_clk : out std_logic
);
end CLOCK_DIVIDER;
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;
begin
process(clk, reset)
begin
if reset = '1' then
tick <= '0';
elsif clk = '1' and clk'EVENT then
if tick = '0' then
tick <= '1';
elsif tick = '1' then
tick <= '0';
end if;
end if;
end process;
process(tick)
begin
half_clk <= tick;
end process
end CLOCK_DIVIDER;
The synthesized logic block of the revised code is a single asynchronous-reset DFF that takes half_clk as output and inverted half_clk as input, which means the value of half_clk changes on every rising edge of clk.
Thanks, Will Dean :)
==== ==== ==== ==== ====
Original question below:
==== ==== ==== ==== ====
I need a simple clock divider (just divide-by-two) and instead of usinga template, I thought I'd try to write one myself to keep in training.
Unfortunately, the synthesized logic block does not appear to work - I present the logic block and the code (which I really think ought to work), in that order.
logic block http://img808.imageshack.us/img808/3333/unledly.png
What I'm really wondering is what the devil is up with the "tick" DFF - it apparently takes its input from the mux-selector which is... Yeah.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity CLOCK_DIVIDER is
port(
reset : in std_logic;
clk : in std_logic;
half_clk : out std_logic
);
end CLOCK_DIVIDER;
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;
begin
process(clk, reset)
begin
if reset = '1' then
half_clk <= '0';
tick <= '0';
elsif clk = '1' and clk'EVENT then
if tick = '0' then
half_clk <= '0';
tick <= '1';
elsif tick = '1' then
half_clk <= '1';
tick <= '0';
end if;
end if;
end process;
end CLOCK_DIVIDER;
I'm sure the error in the code is obvious but I've been staring myself blind trying to find it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果 halfclk 用作使能而不是真正的时钟,请忽略此建议...
如果这是针对 FPGA 目标并且“half_clk”确实用作时钟(例如,将DFF 上的时钟引脚,而不是使能引脚)...不要这样做。
使用通用 FPGA 逻辑/结构创建派生时钟将导致构建工具出现问题,并最终导致构建失败(无法满足时序要求),或者由于约束未正确传递到所有时钟网络而导致构建不按预期运行。
相反,请使用专门用于此目的的 FPGA 结构中内置的时钟管理模块。在 Xilinx 部件领域,这些部件被称为数字时钟管理器 (DCM) 或混合模式时钟管理器 (MMCM)。我不确定等效的 Altera 组件是什么。阅读文档以确定最适合您的应用程序的用途。
If halfclk is to be used as an enable and not a true clock, disregard this advice...
If this is for an FPGA target and "half_clk" is really being used as a clock (e.g. going to the clock pin on a DFF, and not the enable pin)... Don't do this.
Creating derived clocks using general FPGA logic/fabic will lead to problems with build tools, and can eventually lead to failed builds (won't meet timing), or builds that do not behave as expected because constraints not correctly passed through to all clock networks.
Instead use clock management blocks that are built into FPGA fabric especially for this purpose. In the world of Xilinx parts, these are called Digital Clock Managers (DCM) or Mixed Mode Clock Manager (MMCM). I am not sure what the equivalent Altera component is. Read up on the documentation to determine the best use for your application.
根据您修改后的代码,我对架构进行了修改:
我删除了这个过程并用并发分配代替:
因为它要求的是在
tick
的两个边缘上计时的触发器。这似乎可以实现您想要的波形摆动方式,但不会合成。它还为输出增加了额外的增量延迟,如果您将其用作“后续”时钟,这可能会或可能不会导致问题。正如其他人评论的那样,在大多数架构中这都不是一个好的计划(但对于某些架构来说这是“正确的方式”)。
Based on your revised code, I offer this modification to the architecture:
I've removed this process and replaced with a concurrent assignment:
as what this is asking for is a flipflop clocked on both edges of
tick
.This will appear to achieve what you want in terms of the waveforms wiggling the way you want them to, but will not synthesise. It also adds an extra delta delay to the output which may or may not cause problems if you use it as a clock "down the road". As others have commented, this is not a good plan anyway in most architectures (but for some it is "the right way").
您确定要在启动时重置吗?按照您定义的刻度条件的方式,如果刻度不是零或一(即:它可能是 U、Z、X 等),则不会发生任何情况。
我通常建议用条件表达式涵盖所有情况,即:
或
Are you sure you're resetting at startup? The way you've got your conditional for tick defined, nothing will happen if tick isn't zero or one (ie: it could be U, Z, X, etc).
I generally suggest covering all cases with your conditional expressions, ie:
or
一个简单的计数器就可以解决问题(正确的方法当然是 DCM):
A simple counter does the trick (proper way is DCM of course):