Binary counter

Guest #6988594
Rate this post
useful
not useful
Hello I would love your help
I designed a simple binary counter,
though if I do not put the single Q in the sensitivity list. The counter 
updates falling_edge Why is that?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity Binary_Counter is
--generic( n :   positive:=24);
    Port (
           Clk : in STD_LOGIC;
           -- the LTF(n) signal

           Up_Down : in STD_LOGIC;
           -- Up_Down ='1'  the counter counts up
           -- Up_Down ='0'  the counter counts down

           T_Gate : in STD_LOGIC;
           -- Enable count

           O : in integer range 0 to 10:=2;
           -- The number of times the counter works

           ResetS : in STD_LOGIC;
           -- Asynchronously reset

           Pe : in STD_LOGIC;
           -- Asynchronously loads data on the Preset Inputs.

           Pi : in STD_LOGIC_VECTOR(23 downto 0);
           --Data on these inputs is loaded into the counter when PE is 
taken high.

           Q_Out : out STD_LOGIC_VECTOR(23 downto 0);
           -- Binary data is present outputs

           Carry_Out : out STD_LOGIC);
           --used to indicate terminal count.

end Binary_Counter;

architecture Behavioral of Binary_Counter is
signal Q : STD_LOGIC_VECTOR(23 downto 0):=(others=>'0');
begin

process(Clk,ResetS,Pe,T_Gate,Up_Down)
variable CountQ : integer range 0 to 10:=O;
begin

if( ResetS = '1') then Q<=(others=>'0');

            elsif(CountQ /=0 and T_Gate='1') then

             if(rising_edge(clk)) then

                if( pe='1' ) then Q<= pi;

                        elsif(Up_Down='1') then
                                if(Q=x"111111") then
                                    Carry_Out<='1';
                                    Q<=x"000000";
                                else
                                    Q<=Q+1;
                                end if;
                         else
                            if(Q=x"000000") then
                                Carry_Out<='1';
                                Q<=x"111111";
                            else
                                Q<=Q-1;
                            end if;

                 end if;

             end if;
end if;
Q_Out<=Q;
end process;
end Behavioral;
Attached files:
Guest #6988637
Rate this post
useful
not useful
Oh well ... where to start?

--- 1. ---

use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

Do not use those! But use instead

use ieee.numeric_std.all;

--- 2. ---

O : in integer range 0 to 10:=2;

Try to use only std_logic and std_logic_vectors for ports.

--- 3. ---

Try to avoid variables if you do not know how they work.
And the code suggests you do not know that.

--- 4. ---

CountQ is only assigned at the start of the process but never changed. 
So there is no need to use it at all.

--- 5. ---

process(Clk,ResetS,Pe,T_Gate,Up_Down)

You can write it that way, but you only need the asynchronous signals + 
clock. So O, T_Gate, ResetS and Clk would be sufficient.

--- 6. ---

I do not understand the function of O.

--- 7. ---

Try to use "speaking Names"
Pe, Pi say nothing to me, you could name them
Preset_load and Preset_value or the like.

--- 8. ---

A very simmilar question (same counter) was asked in the german section 
of the forum. Look here:
Beitrag "VHDL Anfänger braucht Unterstützung (keine Lösung)"
Guest #6988649
Rate this post
useful
not useful
--- 9. ---

Carry_Out is undefinded till it is set to '1'. This is an error!

--- 10. ---

Try to format your code for easy reding + understanding.

--- 11. ---

To your initial question:

daniel wrote:
> The counter updates falling_edge Why is that?

This is because you have written (shorted):
1
process (Clk,ResetS,Pe,T_Gate,Up_Down)
2
begin
3
  if rising_edge(clk) then
4

5
    if Up_Down='1' then
6
      if Q = x"111111" then
7
        Carry_Out <= '1';
8
        Q <= x"000000";
9
      else
10
        Q <= Q + 1;
11
      end if;
12
    else
13
      if Q = x"000000" then
14
        Carry_Out <= '1';
15
        Q <= x"111111";
16
      else
17
        Q <= Q - 1;
18
      end if;
19
    end if;
20
  end if;
21
  
22
  Q_Out <= Q;
23

24
end process;

So Q updates with every rising_edge of the clock. But the process itself 
is restarted with every action on all of these signals 
(Clk,ResetS,Pe,T_Gate,Up_Down), so it is restarted on the falling_edge 
of the clock, too. And because Q was updated on the rising_edge, with 
Q_Out gets the new value with the next process run which is with the 
next falling_edge.

To avoid this you should write
Q_Out <= Q;
outside the process or write it inside the
if rising_edge(clk) then

end if;
part. But: If you write it in the if rising_edge(clk) then ... part, you 
get 1 clock cycle latency. So you may want to write it outside the 
process.

Reply

Please log in before posting.

or

Log in with Google account

Registration is free and takes only a minute.

Register now