-1

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

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

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

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

4

3 回答 3

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,并在显示器上显示这些值作为练习留给读者。

于 2013-10-22T12:26:03.910 回答
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;

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

于 2013-10-22T13:20:50.730 回答
1

你跳过了一步。您正在尝试仅使用措辞问题陈述来考虑代码。第一步是通过绘制框图来设计硬件。把问题分解成小块。

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

归根结底,您的 RTL 框图就是您的 HDL 流程图。

于 2013-10-22T17:16:02.137 回答