Synchronization 级联计数器的十位数增量太晚

Synchronization 级联计数器的十位数增量太晚,synchronization,vhdl,counter,Synchronization,Vhdl,Counter,我正试图设计一个两位数的计数器,使计数在00和99之间,上下循环。我有它的大部分工作,然而,无论我尝试什么,我都无法使十位数与第一位数保持同步。我现在的结果给了我这样的东西: 08->09->00->11。。。18->19->10->21 及 21->20->29->18。。。11->10->19->08 由此看来,第一个数字的溢出在达到十位数时被延迟了。我试过几种方法来解决这个问题。提供任何有益结果的唯一方法是添加一个额外的if语句,该语句提前将溢出发送到一个状态,但这只是一个补充修复。如果我

我正试图设计一个两位数的计数器,使计数在00和99之间,上下循环。我有它的大部分工作,然而,无论我尝试什么,我都无法使十位数与第一位数保持同步。我现在的结果给了我这样的东西:

08->09->00->11。。。18->19->10->21

21->20->29->18。。。11->10->19->08

由此看来,第一个数字的溢出在达到十位数时被延迟了。我试过几种方法来解决这个问题。提供任何有益结果的唯一方法是添加一个额外的if语句,该语句提前将溢出发送到一个状态,但这只是一个补充修复。如果我在第一个数字为8或0时停止计数器,然后再次启动,我就会回到以前的问题

我还试着制作一个额外的“同步器”模块,我想也许我可以设置它,这样即使它们不同步,它们也会像同步一样显示,但它没有改变任何东西

两个多星期来我一直在努力解决这个问题,现在我已经束手无策了

这是我的计数器代码和同步器,如果有人想查看,非常感谢您的帮助

**我正在使用VHDL,用Vivado 2015.2编程Zybo Digilent板

计数器模块为一位数,溢出成为十位数的启用

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;

entity counter is
    generic(N      : positive := 4);
    port(
        AR       : in  STD_LOGIC;
        clk      : in  STD_LOGIC;
        ld       : in  STD_LOGIC;
        en       : in  STD_LOGIC;
        up_dn    : in  STD_LOGIC;
        D        : in  STD_LOGIC_VECTOR(N - 1 downto 0);
        overflow : out STD_LOGIC;
        Q        : out STD_LOGIC_VECTOR(N - 1 downto 0);
        sync_in  : in STD_LOGIC;
        sync_out : out STD_LOGIC
    );
end counter;

architecture counter of counter is
    signal Qt : std_logic_vector(N - 1 downto 0);
    signal OvrFlw : std_logic;
    signal sync : std_logic;

begin
    process(clk, AR)
    begin
        if (AR = '1') then
            Qt       <= (others => '0');
            OvrFlw <= '0';
            sync <= sync_in;
        elsif (clk = '1' and clk'event) then
            if ld = '1' then
                Qt <= D;
                sync <= sync_in;
            elsif en = '1' then
                if up_dn = '0' then     -- if counting down
                    if (unsigned(Qt) = 0) then
                        Qt       <= "1001";--(others => '1');
                        OvrFlw <= '1';
                        sync <= sync_in and en;
                    --elsif (unsigned(Qt) = 1) then
                    --    Qt       <= std_logic_vector(unsigned(Qt) - 1);
                    --    OvrFlw <= '1';
                    else
                        Qt       <= std_logic_vector(unsigned(Qt) - 1);
                        OvrFlw <= '0';
                        sync <= sync_in and en;
                    end if;
                else                    -- if counting up
                    if (unsigned(Qt) = 2**N-7) then
                        Qt       <= (others => '0');
                        OvrFlw <= '1';
                        sync <= sync_in and en;
                    --elsif (unsigned(Qt) = 2**N-8) then
                    --    Qt       <= std_logic_vector(unsigned(Qt) + 1);
                    --    OvrFlw <= '1';
                    else
                        Qt       <= std_logic_vector(unsigned(Qt) + 1);
                        OvrFlw <= '0';
                        sync <= sync_in and en;
                    end if;
                end if;
            end if;
        end if;
    end process;

    sync_out <= sync;
    Q <= Qt;
    overflow <= OvrFlw;
end counter;
IEEE库;
使用IEEE.STD_LOGIC_1164.all;
使用ieee.numeric_std.all;
实体计数器为
一般(N:正:=4);
港口(
AR:标准逻辑中;
clk:标准逻辑中;
ld:标准逻辑中;
en:标准逻辑;
up\U dn:标准逻辑中;
D:标准逻辑向量(N-1到0);
溢出:输出标准逻辑;
Q:输出标准逻辑向量(N-1到0);
同步输入:标准输入逻辑;
同步输出:输出标准输出逻辑
);
末端计数器;
计数器的结构计数器是
信号Qt:std_逻辑_向量(N-1到0);
信号OvrFlw:std_逻辑;
信号同步:标准逻辑;
开始
过程(时钟、AR)
开始
如果(AR='1'),则
Qt'0');

OvrFlw导致同步的一个明显的基本问题是注册了“溢出”信号,它的赋值在if语句中以上升时钟边缘为条件

在以下示例中,我转储了同步内容并删除了溢出寄存器:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bcd_ud_ctr is
    port (
        AR:         in  std_logic;
        clk:        in  std_logic;
        ld:         in  std_logic;
        en:         in  std_logic;
        up_dn:      in  std_logic;
        D:          in  std_logic_vector (3 downto 0);
        overflow:   out std_logic;
        Q:          out std_logic_vector (3 downto 0)
    );
end entity;

architecture off of bcd_ud_ctr is
    signal Qt:      unsigned (3 downto 0);
    signal nine:    std_logic;
    signal zero:    std_logic;

begin
    -- Count recognizers
    nine <= '1' when Qt = "1001" else
            '0';
    zero <= '1' when Qt = "0000" else
            '0';
COUNT:
    process (clk, AR)
    begin
        if AR = '1' then
            Qt <= (others => '0');
        elsif rising_edge(clk) then
            if ld = '1' then
                Qt <= unsigned(D);
            elsif en = '1' then
                if up_dn = '0' then  -- up
                    if nine = '1' then
                        Qt <= (others => '0');
                    else
                        Qt <= Qt + 1;
                    end if;
                else                  -- down
                    if zero = '1' then 
                        Qt <= "1001"; 
                    else 
                        Qt <= Qt - 1;
                    end if;
                end if;
            end if;
        end if;
    end process;

BUFFERED_OUT:    
    Q <= std_logic_vector(Qt);

CARRY_BORROW:
    overflow <= (en and     up_dn and zero) or
                (en and not up_dn and nine);
end architecture;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体bcd\U ud\U ctr为
港口(
AR:标准逻辑中;
clk:标准逻辑中;
ld:标准逻辑中;
en:标准逻辑;
up\U dn:标准逻辑中;
D:标准逻辑向量(3到0);
溢出:输出标准逻辑;
Q:输出标准逻辑向量(3到0)
);
终端实体;
bcd\U ud\U ctr的架构是
信号Qt:无符号(3到0);
信号九:标准逻辑;
信号零:标准逻辑;
开始
--计数识别器
九Q(3到0)
);
经皮电刺激神经疗法:
实体工作.bcd_ud_ctr
港口地图(
AR=>AR,
时钟=>clk,
ld=>ld,
en=>滚动,
up\U Dn=>up\U Dn,
D=>10个标准杆,
溢出=>打开,
Q=>Q(7到4)
);
刺激:
过程
开始
等待10纳秒;

AR如果(unsigned(Qt)=2**N-7),那么当N设置为4以外的值时,
应该怎么做?谢谢!它的工作原理和它应该的完全一样!我知道问题与时钟敲响时发生的变化有关,但我不知道该怎么解决。我真的很感谢你的帮助!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bcd_ud_ctr is
    port (
        AR:         in  std_logic;
        clk:        in  std_logic;
        ld:         in  std_logic;
        en:         in  std_logic;
        up_dn:      in  std_logic;
        D:          in  std_logic_vector (3 downto 0);
        overflow:   out std_logic;
        Q:          out std_logic_vector (3 downto 0)
    );
end entity;

architecture off of bcd_ud_ctr is
    signal Qt:      unsigned (3 downto 0);
    signal nine:    std_logic;
    signal zero:    std_logic;

begin
    -- Count recognizers
    nine <= '1' when Qt = "1001" else
            '0';
    zero <= '1' when Qt = "0000" else
            '0';
COUNT:
    process (clk, AR)
    begin
        if AR = '1' then
            Qt <= (others => '0');
        elsif rising_edge(clk) then
            if ld = '1' then
                Qt <= unsigned(D);
            elsif en = '1' then
                if up_dn = '0' then  -- up
                    if nine = '1' then
                        Qt <= (others => '0');
                    else
                        Qt <= Qt + 1;
                    end if;
                else                  -- down
                    if zero = '1' then 
                        Qt <= "1001"; 
                    else 
                        Qt <= Qt - 1;
                    end if;
                end if;
            end if;
        end if;
    end process;

BUFFERED_OUT:    
    Q <= std_logic_vector(Qt);

CARRY_BORROW:
    overflow <= (en and     up_dn and zero) or
                (en and not up_dn and nine);
end architecture;
library ieee;
use ieee.std_logic_1164.all;

entity bcd_2digit_tb is
end entity;

architecture foo of bcd_2digit_tb is
    signal AR:          std_logic;
    signal clk:         std_logic := '0';
    signal ld:          std_logic := '0'; 
    signal en:          std_logic := '0';
    signal up_dn:       std_logic := '1';
    signal rollover:    std_logic;
    signal Q:           std_logic_vector (7 downto 0);

    constant DIG_PAR:   std_logic_vector(3 downto 0) := "0010"; -- 2
    constant TEN_PAR:   std_logic_vector(3 downto 0) := "0100"; -- 4 (42)
begin

CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if Now > 500 ns then
            wait;
        end if;
    end process;

DIGITS:
    entity work.bcd_ud_ctr
        port map (
            AR => AR,
            clk => clk,
            ld => ld,
            en => en,
            up_Dn => up_dn,
            D => DIG_PAR,
            overflow => rollover,
            Q => Q(3 downto 0)
        );
TENS:
    entity work.bcd_ud_ctr
        port map (
            AR => AR,
            clk => clk,
            ld => ld,
            en => rollover, 
            up_Dn => up_dn,
            D => TEN_PAR,
            overflow => open,
            Q => Q(7 downto 4)
        );
STIMULUS:
    process
    begin
        wait for 10 ns;
        AR <= '1';
        wait for 10 ns;
        AR <= '0';
        up_dn <= '0'; -- up
        en <= '1';
        wait for 260 ns;
        up_dn <= '1';
        wait;
    end process;
end architecture;