VHDL BCD计数器十位计数异常:每时钟周期递增而非单次进位
问题分析与解决
问题根源
十位计数器持续递增的核心原因是个位计数器的overflow信号不是单次脉冲,而是在计数到最大值后一直保持高电平。
查看GenericBCDCounter的代码逻辑:当enable为'0'时,仍会判断value = COUNT_MAX,若成立就将overflow置为'1'。当个位计数器(COUNT_MAX=9)计数到9后,只要后续enable(即clock_seconds)为'0',overflow就会一直保持'1',导致十位计数器的enable始终有效,每个时钟周期都递增。
修复方案
修改GenericBCDCounter的逻辑,让overflow仅在**enable有效且计数即将溢出**的那个时钟周期输出高电平脉冲,其他时刻保持低电平。修改后的代码如下:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity GenericBCDCounter is generic( COUNT_MAX : integer ); port( clk : in std_logic; reset : in std_logic; enable : in std_logic; count : out std_logic_vector(3 downto 0); overflow : out std_logic ); end GenericBCDCounter; architecture rtl of GenericBCDCounter is signal value : unsigned(3 downto 0); begin process(clk, reset) begin if(reset = '1') then value <= (others => '0'); overflow <= '0'; elsif(rising_edge(clk)) then overflow <= '0'; -- 默认置低,仅在溢出时拉高 if(enable = '1') then if(value = COUNT_MAX) then value <= (others => '0'); overflow <= '1'; -- 仅溢出时输出单周期高电平 else value <= value + 1; end if; end if; end if; end process; count <= std_logic_vector(value); end architecture rtl;
逻辑说明
- 每次时钟上升沿先将
overflow置为低电平,确保默认状态无效。 - 仅当
enable有效,且当前计数达到COUNT_MAX时,才将overflow置为高电平,同时清零计数。这样overflow只会在溢出发生的那个时钟周期保持高电平,之后立刻回到低电平,给十位计数器提供单次进位脉冲。
修改后,个位计数器从9→0时,overflow才会输出一个时钟周期的高电平,触发十位计数器加1,即可实现09→10→11…的正常计数逻辑。
内容的提问来源于stack exchange,提问作者focus0941
相关产品推荐
相关产品推荐

