Hi, vitalsys:
I went through a similar designe coping with A-B signals 10 years ago, not using VHDL then. I think I understand your application well. Here is my solution to your problem. I did the synthesis and post-layout simulation and proved it works. The design consists 5 entities, the top counter is what you need, 4 other entities are sub-components to be used inside the top one.
-- cnt1 file
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CNT1 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end entity CNT1;
architecture Behaviour of CNT1 is
signal Q_IN : std_logic_vector(7 downto 0);
begin
Q <= Q_IN;
process( CLR, CLK_A )
begin
if CLR='1' then
Q_IN <= (others=>'0');
elsif rising_edge( CLK_A ) then
if CLK_B='0' then
Q_IN <= Q_IN+'1';
else
Q_IN <= Q_IN-'1';
end if;
end if;
end process;
end architecture Behaviour;
-- cnt2 file
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CNT2 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end entity CNT2;
architecture Behaviour of CNT2 is
signal Q_IN : std_logic_vector(7 downto 0);
begin
Q <= Q_IN;
process( CLR, CLK_A )
begin
if CLR='1' then
Q_IN <= (others=>'0');
elsif falling_edge( CLK_A ) then
if CLK_B='0' then
Q_IN <= Q_IN-'1';
else
Q_IN <= Q_IN+'1';
end if;
end if;
end process;
end architecture Behaviour;
-- cnt3 file
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CNT3 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end entity CNT3;
architecture Behaviour of CNT3 is
signal Q_IN : std_logic_vector(7 downto 0);
begin
Q <= Q_IN;
process( CLR, CLK_B )
begin
if CLR='1' then
Q_IN <= (others=>'0');
elsif falling_edge( CLK_B ) then
if CLK_A='0' then
Q_IN <= Q_IN+'1';
else
Q_IN <= Q_IN-'1';
end if;
end if;
end process;
end architecture Behaviour;
-- cnt4 file
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CNT4 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end entity CNT4;
architecture Behaviour of CNT4 is
signal Q_IN : std_logic_vector(7 downto 0);
begin
Q <= Q_IN;
process( CLR, CLK_B )
begin
if CLR='1' then
Q_IN <= (others=>'0');
elsif rising_edge( CLK_B ) then
if CLK_A='1' then
Q_IN <= Q_IN+'1';
else
Q_IN <= Q_IN-'1';
end if;
end if;
end process;
end architecture Behaviour;
-- top cnt file
entity CounterScaler is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector( 7 downto 0 )
);
end entity CounterScaler;
architecture Behaviour of CounterScaler is
signal Q1 : std_logic_vector( 7 downto 0 );
signal Q2 : std_logic_vector( 7 downto 0 );
signal Q3 : std_logic_vector( 7 downto 0 );
signal Q4 : std_logic_vector( 7 downto 0 );
component CNT1 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end component CNT1;
component CNT2 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end component CNT2;
component CNT3 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end component CNT3;
component CNT4 is
port(
CLR : in std_logic;
CLK_A : in std_logic;
CLK_B : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end component CNT4;
begin
Q <= Q1 + Q2 + Q3 + Q4;
C1 : CNT1 port map(CLR=>CLR, CLK_A=>CLK_A, CLK_B=>CLK_B, Q=>Q1);
C2 : CNT2 port map(CLR=>CLR, CLK_A=>CLK_A, CLK_B=>CLK_B, Q=>Q2);
C3 : CNT3 port map(CLR=>CLR, CLK_A=>CLK_A, CLK_B=>CLK_B, Q=>Q3);
C4 : CNT4 port map(CLR=>CLR, CLK_A=>CLK_A, CLK_B=>CLK_B, Q=>Q4);
end architecture Behaviour;
Good luck with your project.