vhdl手动时钟小时设置 [英] vhdl manual clock hour set

查看:268
本文介绍了vhdl手动时钟小时设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的一个班的最后一个项目制作闹钟。我正在使用DE1 Altera板上的按钮来手动增加小时和分钟。分钟的工作,但我无法手动增加小时数。所有引脚分配均正确。

I am trying to make an alarm clock for a final project in one of my classes. I am using push buttons on a DE1 Altera board to manually increment hours and mins. The mins work but I can not get the hours to increment manually. All pin assignments are correct.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity ClkMain is port (
    clk,pb_hr,pb_min,clk_set,almr_enbl: in std_logic;
    almr_hr: in integer range 0 to 23;
    almr_min: in integer range 0 to 59;
    clk_min : out integer range 0 to 59;
    clk_hr : out integer range 0 to 23;
    almr_indct : out bit
);
end ClkMain;

architecture Behavioral of ClkMain is
    signal sec, min: integer range 0 to 60 :=0;
    signal hr: integer range 0 to 24 := 0;

begin
    clk_min <= min;
    clk_hr <= hr;

    process(clk)   --normal clock operation
    begin

        if(clk'event and clk='1') then
            sec <= sec + 1;

            if(sec + 1 = 60 or (pb_min = '1' and clk_set = '1') ) then
                sec <= 0;
                min <= min + 1;

                if (min + 1 = almr_min and hr = almr_hr and almr_enbl = '1') then
                    almr_indct <= '1';
                else
                    almr_indct <= '0';
                end if;

                if(min + 1 = 60 ) then
                    hr <= hr + 1;
                    min <= 0;

                    if(hr + 1 = 24) then
                        hr <= 0;

                        if (clk'event and clk='1' and pb_hr = '1' and clk_set = '1')then
                            hr <= hr + 1;
                        end if;

                    end if;
                end if;
            end if;
        end if;

    end process;
end Behavioral;


推荐答案

通过正确地缩进可以看到错误所在:

You can see where the error is by indenting properly:

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all;
-- use ieee.std_logic_unsigned.all;

entity ClkMain is
    port (
        clk,pb_hr,pb_min,clk_set,almr_enbl: in std_logic;
        almr_hr: in integer range 0 to 23;
        almr_min: in integer range 0 to 59;
        clk_min: out integer range 0 to 59;
        clk_hr: out integer range 0 to 23;
        almr_indct : out bit
     );
end ClkMain;

architecture Behavioral of ClkMain is
    signal sec, min: integer range 0 to 60 :=0;
    signal hr: integer range 0 to 24 := 0;

begin
    clk_min <= min;
    clk_hr <= hr;

    process(clk)   --normal clock operation
    begin

        if clk'event and clk = '1'  then
            sec <= sec + 1;

            if sec + 1 = 60 or (pb_min = '1' and clk_set = '1') then
                sec <= 0;
                min <= min + 1;

                if min + 1 = almr_min and hr = almr_hr and almr_enbl = '1' then
                        almr_indct <= '1';
                    else
                        almr_indct <= '0';
                end if;

                if min + 1 = 60  then
                    hr <= hr + 1;
                    min <= 0;

                    if hr + 1 = 24 then
                        hr <= 0;

                        if clk'event and clk = '1' and pb_hr = '1' and clk_set = '1' then
                            hr <= hr + 1;

                        end if; 
                    end if; 
                end if; 
            end if; 
        end if;
    end process;
end Behavioral;

clk 条件包含在最外面if语句,并且不是必需的:

The clk condition is enclosed in the outermost if statement and isn't necessary:

if clk'event and clk = '1' and pb_hr = '1' and clk_set = '1' then

应该是

if pb_hr = '1' and clk_set = '1' then

那把我们带到哪里出了问题。 pb_hr 仅在晚上11点进行评估:

And that brings us to what's wrong. pb_hr is only evaluated at 11 PM:

                if hr + 1 = 24 then
                    hr <= 0;

                    if pb_hr = '1' and clk_set = '1' then
                        hr <= hr + 1;

                    end if; 
                end if; 

至少这两个if语句需要处于相同的嵌套级别。

At a minimum these two if statements need to be at the same nesting level.

不幸的是,这也使您查找了if语句嵌套级别,在该级别您发现只能将时间设置为23:59:59,否则您将 pb_min clk_set 是正确的。

Unfortunately it also makes you take a look up the if statement nesting levels where you notice you can only set hours at 23:59:59, or you're also holding down pb_min and clk_set is true.

也请注意无论您做什么,您 almr_indct 一分钟都是正确的。我建议将带有时钟条件的设置和警报检测移动到封闭的if语句之外(保持它们处于同一过程中)。当 clk_set 为true时,它也应该无效。

Also notice you almr_indct is true for a minute no matter what you do. I'd suggest moving the sets and alarm detection outside the enclosing if statement with the clock condition (keep them in the same process). It should also be invalidated when clk_set is true.

再往前看:

        if sec + 1 = 60 or (pb_min = '1' and clk_set = '1') then
            sec <= 0;
            min <= min + 1;

我们看到您按下按钮可能会达到60。一切都需要修复。也可以将警报比较移出计数器并在时钟设置期间禁用。

We see you could reach 60 for a button push. That all needs to be fixed. It's also possible to move the alarm comparison outside of the counters and disable during clock set.

因此您可以操纵流程语句:

So you could manipulate the process statement:

architecture foo of clkmain is
    signal sec, min: integer range 0 to 59 := 0;
    signal hr: integer range 0 to 23 := 0;
    signal sec_neq_59:       std_logic;
    signal min_neq_59:       std_logic;
    signal hr_neq_23:        std_logic;

begin

    clk_min <= min;
    clk_hr <= hr;

    sec_neq_59 <= '0' when sec = 59 else '1';
    min_neq_59 <= '0' when min = 59 else '1';
    hr_neq_23  <= '0' when  hr = 23 else '1';

CLOCK_PROCESS:
    process(clk)
    begin
        if clk'event and clk = '1'  then
ALARM_INDICATON:
            if min = almr_min and hr = almr_hr and almr_enbl = '1' then
                almr_indct <= to_bit(not clk_set);
            else
                almr_indct <= '0';
            end if;
SET_MINUTES:
            if pb_min = '1' and clk_set = '1' then
                if min_neq_59 = '1' then
                    min <= min + 1;
                else
                    min <= 0;
                end if;
SET_HOURS:
            elsif pb_hr = '1' and clk_set = '1' then
                if hr_neq_23 = '1' then
                    hr <= hr + 1;
                else 
                    hr <= 0;
                end if;
INCREMENT_SECONDS:
            elsif sec_neq_59 = '1' then
                sec <= sec + 1;
            else                -- sec = 59
                sec <= 0;
INCREMENT_MINUTES:
                if min_neq_59 = '1' then
                    min <= min + 1;
                else               -- :59:59
                    min <= 0;
INCREMENT_HOURS:
                    if hr_neq_23 = '1' then 
                        hr <= hr + 1;
                    else           -- 23:59:59
                        hr <= 0;
                    end if;
                end if;
            end if; 
        end if;
    end process;
end architecture foo;

有机会我固定了 sec 分钟小时计数器。秘密是在递增之前进行评估,您会截获具有同步负载的终端计数。

And with the opportunity I fixed the range for the sec, min and hr counters. The secret is evaluating before incrementing, you intercept a terminal count with a synchronous load.

还切换为对特定值进行相等比较,将它们分开以减少硬件消耗,因为一组

Also switched to equality comparisons to specific values, separated them to reduce hardware by having one set and prioritized the push buttons over the clock operation by using elsif.

因此,现在按钮不能在几分钟和几小时内引起范围误差,并且与实际时钟时间无关

So now push buttons can't cause range errors in minutes and hours, and are independent of actual clock time.

我认为用按钮增加分钟数时重置秒是无效的。在clock_set为true时将秒数保持为0可能是有效的,这将在设置时钟时停止运行时钟。不过,如果您只是固定夏令时或更改时区,则无法使用。

I don't think it's valid to reset seconds when incrementing minutes with the push button. It might be valid to keep seconds at 0 while clock_set is true, which would stop the clock from running when being set. That doesn't work if you're only fixing daylight savings time or changing time zones, though.

我没有对此进行模拟。它进行分析和阐述。

I haven't simulated this. It analyzes and elaborates. Range errors in assignment would show up during simulation.

我把 almr_indct 留为类型位,但确实使用了 clk_set 作为警报指示的条件。

I left almr_indct as type bit, but did use clk_set as a condition for the alarm indication.

这篇关于vhdl手动时钟小时设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆