VHDL设计 - 时钟

时间:2013-10-22 04:43:19

标签: vhdl

有人可以帮我解决以下问题:

使用VHDL设计数字电路,以HH:MM:SS的形式跟踪时间。该电路应产生6个独立的4位数字输出(HH为2个4位输出,MM为2个,SS为2个)。 HH可以是00到99范围内的2位数字,即它不是时钟,即使99小时的磁带不存在,它只是一个小时的计数器。时间将显示在DE2的最右边7段显示屏上。您已经设计了一个7段解码器和驱动程序作为上一个实验的一部分,因此可以用于将每个4位输出转换为每个7段显示器的7位信号。不要忘记为这些显示器(和所有其他信号)设置针式刨床

电路应具有以下单个位输入:时钟,递增,递减和复位。增量/减量输入应使磁带计数器在时钟信号的下一个上升沿从磁带时间加1秒或减1秒。如果既不存在递增或递减输入,则磁带计数器也不会改变。复位与时钟同步(以避免故障意外复位)。递增和递减信号都是有效高电平信号(即逻辑1),复位为低电平有效(逻辑0)。

您的磁带计数器应处理完整的小时,分​​钟和秒翻转,例如如果计数器显示9:59:59,那么下一个增量应该显示10:00:00,反之亦然。当减量出现时。

3 个答案:

答案 0 :(得分:2)

我不想解决你的功课,而是想给你一个主意。大多数设计师倾向于使用逐位翻转来实现这个时钟(一些数字将从9-0翻滚,其他数字从5-0翻滚)。我想提出不同的建议。

总体思路是:以秒为单位将时间值保持为整数。这将极大地促进递增和递减的任务。然后,您只需实现一个转换函数,该函数返回给定整数秒数的小时数,分钟数和秒数。

您的时钟实体将如下所示:

library ieee;
use ieee.std_logic_1164.all;
use work.clock_pkg.all;

entity clock is
    port (
        clock: in std_logic;
        n_reset: in std_logic;
        increment: in std_logic;
        decrement: in std_logic;
        hours: out natural range 0 to 99;
        minutes: out natural range 0 to 59;
        seconds: out natural range 0 to 59
    );
end;

architecture rtl of clock is
    signal time_in_seconds: natural range 0 to 359999;
begin

    process (clock, n_reset) begin
        if rising_edge(clock) then
            if n_reset = '0' then
                time_in_seconds <= 0;
            elsif increment then
                time_in_seconds <= time_in_seconds + 1;
            elsif decrement then
                time_in_seconds <= time_in_seconds - 1;
            end if;
        end if;
    end process;

    process (time_in_seconds) begin
        (hours, minutes, seconds) <= seconds_to_time_type(time_in_seconds);
    end process;

end;

您可以想象,此解决方案的主力是seconds_to_time_type()功能。你可以像这样实现它:

package clock_pkg is
    type time_type is record
        hours: natural range 0 to 99;
        minutes, seconds: natural range 0 to 59;
    end record;

    function seconds_to_time_type(seconds: in natural) return time_type;
end;

package body clock_pkg is

    function seconds_to_time_type(seconds: in natural) return time_type is
        variable hh: natural range 0 to 99;
        variable mm: natural range 0 to 119;
        variable ss: natural range 0 to 119;
    begin
        hh := seconds / 3600;
        mm := (seconds mod 3600) / 60;
        ss := (seconds mod 3600) mod 60;
        return (hh, mm, ss);
    end;

end;

现在您有一个实体可以输出小时,分钟和秒的单独整数值。将这些值从整数转换为BCD,并在显示器上显示这些值是留给读者的练习。

答案 1 :(得分:1)

实现计数时钟的典型方法是使用二进制编码的十进制(BCD),其中每个数字由一个单独的n位计数器组成,具有所需的范围。

例如,为了计算秒数(从0到59),您可以使用类似下面的代码:

process(clk, reset) begin
    if(reset='1') then
        second_tens <= (others=>'0');
        second_ones <= (others=>'0');
    elsif(rising_edge(clk)) then
        if(count_en='1') then
            if(second_ones = 9) then
                second_ones <= (others=>'0');

                if(second_tens = 5) then
                    second_tens <= (others=>'0');
                    -- Count up minutes.
                else
                    second_tens <= second_tens + 1;
                end if;

            else
                second_ones <= second_ones + 1;
            end if;
        end if;
    end if;
end process;

可以类似地计算分钟和小时数。

答案 2 :(得分:1)

你跳过了一步。你试图用一个措辞问题陈述来考虑代码。第一步是通过绘制框图来设计硬件。将问题分解成碎片。

初始分区可能是秒,分钟和小时。如果您使用BCD计数,您可能希望将其进行逐位分区。弄清楚你的硬件应该做什么。画一张图。编写描述图片内容的代码。

在一天结束时,您的RTL程序框图是您的HDL流程图。