Done.
Compared to the C code the VHDL description is very long, not just because there are more and longer names. And it even does less. It does not convert. It can only change it's state in the right sequence.
As mentioned earlier, though this is not a normal binary number counter, the larger, smaller operators (<,>,=) for normal binary numbers can be used, although you might have to flip it around because I used "... to ..." thinking it would not matter.
This VHDL balanced counter with the same number/amount of ones and zeros is fully parametrized and thus may be synthesized for any even number of bit equal or greater to 6. It's size scales linearly.
The basic bit wise element is:
LIBRARY ieee;
use ieee.std_logic_1164.all;
ENTITY bit_block IS
GENERIC(
position, ones : positive
);
PORT(
reset_in : IN std_logic;--globales reset
pI_rst_down : IN std_logic;
pI_sta_down : IN std_logic;
pi_state : IN std_logic;
lower_can, pi_moving_up : IN std_logic;
pi_loc_set : IN std_logic;
pi_rst_count : IN std_logic_vector(1 to ones-1);
po_move_higher : OUT std_logic;
po_state_down : OUT std_logic;
po_state_next : OUT std_logic;
po_inhibit : OUT std_logic;
pO_rst_down : OUT std_logic;
pO_rst_count : OUT std_logic_vector(1 to ones-1)
);
end bit_block;
architecture bit_wise of bit_block is
signal preset, ws_mov_hi : std_logic;
signal ws_rst_count : std_logic_vector(1 to ones-1);
begin
preset <= '1' when position <= ones else '0';
po_state_down <= pi_state;
po_inhibit <= lower_can OR pi_moving_up;
ws_rst_count(1) <= pi_rst_count(1) OR (pi_state AND pI_rst_down);
l_zaehlen : for i in 2 to ones-1 generate
ws_rst_count(i) <= (pI_rst_down AND pi_state AND pi_rst_count(i-1)) OR pi_rst_count(i);
end generate;
pO_rst_count <= ws_rst_count;
ws_mov_hi <= pi_state AND not pI_sta_down AND not lower_can;
po_state_next <= (pi_state AND pI_sta_down AND not reset_in AND not pI_rst_down) OR --kann nicht
(pi_state AND lower_can AND not reset_in AND not pI_rst_down) OR --braucht nicht
(pi_moving_up AND not reset_in) OR --von links
(pI_rst_down AND pi_loc_set AND not reset_in) OR --alle anderen nach links
(reset_in AND preset);--reset
po_move_higher <= ws_mov_hi;
pO_rst_down <= (ws_mov_hi OR pI_rst_down) AND not reset_in;
end bit_wise;
And this block then chains them together:
LIBRARY ieee;
use ieee.std_logic_1164.all;
ENTITY balancedcounter IS
GENERIC(
ones : positive := 3
);
PORT(
clk, enable, reset : IN std_logic;
po_count : OUT std_logic_vector(1 to 2*ones)
);
END balancedcounter;
ARCHITECTURE bitblock OF balancedcounter IS
--constant ones : positive := 3;
COMPONENT bit_block IS
GENERIC(
position, ones : positive
);
PORT(
reset_in : IN std_logic;--globales reset
pI_rst_down : IN std_logic;
pI_sta_down : IN std_logic;
pi_state : IN std_logic;
lower_can, pi_moving_up : IN std_logic;
pi_loc_set : IN std_logic;
pi_rst_count : IN std_logic_vector(1 to ones-1);
po_move_higher : OUT std_logic;
po_state_down : OUT std_logic;
po_state_next : OUT std_logic;
po_inhibit : OUT std_logic;
pO_rst_down : OUT std_logic;
pO_rst_count : OUT std_logic_vector(1 to ones-1)
);
end component bit_block;
type sindmat is array (0 to 2*ones-1) of std_logic_vector(1 to ones-1);
--Signale:
signal ws_sta_next : std_logic_vector(1 to 2*ones);-- logik zu Register
signal ws_sta_now : std_logic_vector(1 to 2*ones);-- Register zu Logik
signal verbinder_zustand_innen_links : std_logic_vector(1 to 2*ones-1);
signal verbinder_ruecken : std_logic_vector(1 to 2*ones-1);
signal verbinder_reset_links : std_logic_vector(1 to 2*ones-1);--selektives inneres reset nach links
signal verbinder_links_meldet_potential : std_logic_vector(1 to 2*ones-1);
signal verbind_sind : sindmat;--propagiert die zu resetenen Einsen
signal local_sind_vec : std_logic_vector(1 to ones-1);
signal local_sind : std_logic_vector(1 to 2* ones);
BEGIN
l_register : process(clk)
begin
if clk'EVENT and clk = '1' then
if enable = '1' then
ws_sta_now <= ws_sta_next;
end if;
end if;
end process;
local_sind_vec <= verbind_sind(0);
l_locsind : for i in 1 to 2* ones generate
local_sind(i) <= local_sind_vec(i) when i < ones else '0';
end generate;
l_gen : for i in 2 to 2*ones-1 generate
l_component_lable : bit_block
GENERIC MAP(
position => i,
ones => ones
)
PORT MAP(
reset_in => reset,
pI_rst_down => verbinder_reset_links(i),
pI_sta_down => verbinder_zustand_innen_links(i),
pi_state => ws_sta_now(i),
lower_can => verbinder_links_meldet_potential(i-1),
pi_moving_up => verbinder_ruecken(i-1),
pi_loc_set => local_sind(i),
pi_rst_count => verbind_sind(i),
--outs:
po_move_higher => verbinder_ruecken(i),
po_state_down => verbinder_zustand_innen_links(i-1),
po_state_next => ws_sta_next(i),
po_inhibit => verbinder_links_meldet_potential(i),
pO_rst_down => verbinder_reset_links(i-1),
pO_rst_count => verbind_sind(i-1)
);
end generate;
l_ganzrechts : bit_block
GENERIC MAP(
position => 2*ones,
ones => ones
)
PORT MAP(
reset_in => reset,
pI_rst_down => '0',
pI_sta_down => '1',
pi_state => ws_sta_now(2*ones),
lower_can => verbinder_links_meldet_potential(2*ones-1),
pi_moving_up => verbinder_ruecken(2*ones-1),
pi_loc_set => local_sind(2*ones),
pi_rst_count => (others => '0'),
po_move_higher => open,
po_state_down => verbinder_zustand_innen_links(2*ones-1),
po_state_next => ws_sta_next(2*ones),
po_inhibit => open,
pO_rst_down => verbinder_reset_links(2*ones-1),
pO_rst_count => verbind_sind(2*ones-1)
);
l_ganzlinks : bit_block
GENERIC MAP(
position => 1,
ones => ones
)
PORT MAP(
reset_in => reset,
pI_rst_down => verbinder_reset_links(1),
pI_sta_down => verbinder_zustand_innen_links(1),
pi_state => ws_sta_now(1),
lower_can => '0',
pi_moving_up => '0',
pi_loc_set => local_sind(1),
pi_rst_count => verbind_sind(1),
po_move_higher => verbinder_ruecken(1),
po_state_down => open,
po_state_next => ws_sta_next(1),
po_inhibit => verbinder_links_meldet_potential(1),
pO_rst_down => open,
pO_rst_count => verbind_sind(0)
);
po_count <= ws_sta_now;
END ARCHITECTURE bitblock;