Synchronization 级联计数器的十位数增量太晚
我正试图设计一个两位数的计数器,使计数在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板 计数器模块为一位数,溢出成为十位数的启用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语句,该语句提前将溢出发送到一个状态,但这只是一个补充修复。如果我
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;