Issue with 12 bit counter.

The favorite HDL language in Europe and in Universities

Issue with 12 bit counter.

Postby Nemi » Sun Oct 03, 2010 5:30 pm

I'm working on a 3-digit up/down counter with 12 bits. The 3 digits is going to be displayed on a LED-display and the sequence (up or down) is chosen with a push button. This is one of my first VHDL assignments and I'm not sure how to complete the VHDL code for the displays. (And a little unsure about the counter as well. This is my code so far:

Code: Select all
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity COUNTER is
   port(
      clk     : in std_logic;
      button  : in std_logic;
      display3: out std_logic_vector(6 downto 0);
      display2: out std_logic_vector(6 downto 0);
      display1: out std_logic_vector(6 downto 0));
end COUNTER;

architecture U_D_COUNTER of COUNTER is
   
   component clockdivider is
      port(
         CLKin    : in std_logic;
         CLKout : out std_logic);
   end component;
   
   signal clk: std_logic;
   signal teller: std_logic_vector(3 downto 0);

begin
   
   CLK DIVIDER: clockdivider
   port map (CLKin => clk, CLKout => clk);

   process(clk)
   begin
      if clk'event and (clk = '1') then
         if (button = '1' ) then
            teller <= teller + "0001";
         else
            teller <= teller - "0001";
         end if;
      end if;
   end process;
   
   process(teller)
   begin
      case teller is
         when "0000" => display3 <= "1000000"; -- 0         when "0001" => display3 <= "1111001"; -- 1
         when "0010" => display3 <= "0100100"; -- 2
         when "0011" => display3 <= "0110000"; -- 3
         when "0100" => display3 <= "0011001"; -- 4
         when "0101" => display3 <= "0010010"; -- 5
         when "0110" => display3 <= "0000010"; -- 6
         when "0111" => display3 <= "1111000"; -- 7
         when "1000" => display3 <= "0000000"; -- 8
         when "1001" => display3 <= "0010000"; -- 9
      end case;
      
      case teller is
         when "0000" => display2 <= "1000000"; -- 0         when "0001" => display2 <= "1111001"; -- 1
         when "0010" => display2 <= "0100100"; -- 2
         when "0011" => display2 <= "0110000"; -- 3
         when "0100" => display2 <= "0011001"; -- 4
         when "0101" => display2 <= "0010010"; -- 5
         when "0110" => display2 <= "0000010"; -- 6
         when "0111" => display2 <= "1111000"; -- 7
         when "1000" => display2 <= "0000000"; -- 8
         when "1001" => display2 <= "0010000"; -- 9
      end case;
         
      case teller is   
         when "0000" => display1 <= "1000000"; -- 0         when "0001" => display1 <= "1111001"; -- 1
         when "0010" => display1 <= "0100100"; -- 2
         when "0011" => display1 <= "0110000"; -- 3
         when "0100" => display1 <= "0011001"; -- 4
         when "0101" => display1 <= "0010010"; -- 5
         when "0110" => display1 <= "0000010"; -- 6
         when "0111" => display1 <= "1111000"; -- 7
         when "1000" => display1 <= "0000000"; -- 8
         when "1001" => display1 <= "0010000"; -- 9
      end case;
   end process;         
         
end U_D_COUNTER;


Can I do it like this? Divide the 12 bits in three and have 4 bits in each of them? And is my counter (called "teller" in the code) ok?

Or should I in line 24 define: "signal teller: std_logic_vector(11 downto 0);" and then make 999 cases for the display?

Any tips is greatly appreaciated since I really want to get this right!
Nemi
 
Posts: 3
Joined: Sun Oct 03, 2010 5:14 pm

Postby jducluzeau » Sun Oct 03, 2010 9:01 pm

First, you should have one process. I think it is better.
in your case statement, you must have when others => ....

Your code don't display a coder.
when teller equals 1 each digits equals 1 that means
for 1 display=111
for 2 display=222
etc

Regards
jducluzeau
 
Posts: 2
Joined: Sun Oct 03, 2010 8:16 pm
Location: france

Postby Nemi » Mon Oct 04, 2010 7:47 am

jducluzeau wrote:First, you should have one process. I think it is better.
in your case statement, you must have when others => ....

Your code don't display a coder.
when teller equals 1 each digits equals 1 that means
for 1 display=111
for 2 display=222
etc

Regards


Ok, so what you're saying is that I should drop the process(teller) and put it all under the other process?

And for the second part of the answer. Ok, I see your point. And that was what I was afraid of. But should I solve this by making 3 "teller"s like teller, teller2 and teller3 or is it better (according to the assignment and for coding in general) to change the teller to:

Code: Select all
   process(clk)
   begin
      if clk'event and (clk = '1') then
         if (button = '1' ) then
            teller <= teller + "000000000001";
         else
            teller <= teller - "000000000001";
         end if;
      end if;
   end process;


But then I am again stuck with the display part of it all. Since I figure each digit will have to be display-coded separately? Or do I do that by doing something like:

Code: Select all
case teller(11 downto 8) is
when "0000" => display3 <= "10000000";
........

case teller(7 downto 4) is
......
when "0011" => display2 <= "0110000";
......

case teller(3 downto 0) is
......
when "0100" => display1 <= "0011001";
.....
end case;


Will that work?

As you can see, my knowledge of VHDL is very limited, but I really want to learn so sorry for all the questions! :)
Nemi
 
Posts: 3
Joined: Sun Oct 03, 2010 5:14 pm

Postby tricky » Tue Oct 05, 2010 7:40 am

First up - why is teller a std_logic_vector. Why not make it an integer?
Then you can write:

case teller is
when 0 => ...
when 1 => ...
when 2 => ...
..etc

Instead of an array of bits.

second. you cannot connect clk to CLKin and CLKout of the clock divider. you also cannot have an internal signal called clk because you have an input called clk.

third. How are you dividing the clock? are you running it off a counter? this is generally a bad thing. have the clock divider generate a clock enable instead of a clock. using counters as clock dividers will cause you problems when you put it on the chip.

fourth. There is nothing wrong with what you have written, but you need a "when others =>" case for all case statements that are not clocked. This will prevent the formation of latches. If you move the case statement inside the clocked process, you dont need a "when others =>" case.
tricky
 
Posts: 56
Joined: Wed Dec 09, 2009 11:50 am

Postby Nemi » Tue Oct 05, 2010 9:12 am

tricky wrote:First up - why is teller a std_logic_vector. Why not make it an integer?
Then you can write:

case teller is
when 0 => ...
when 1 => ...
when 2 => ...
..etc

Instead of an array of bits.


Because we're supposed to use std_logic_vector according to the assignment. ;)

second. you cannot connect clk to CLKin and CLKout of the clock divider. you also cannot have an internal signal called clk because you have an input called clk.


This part I got from a tutorial I tried out before starting this assignment. And in the tutorial we made a clockdivider module that we the "imported" or what it's called in "VHDL'sk" into the counter.

But it worked fine in the tutorial. Why should it not work here?

third. How are you dividing the clock? are you running it off a counter? this is generally a bad thing. have the clock divider generate a clock enable instead of a clock. using counters as clock dividers will cause you problems when you put it on the chip.


I don't remember. I don't think I used a counter in that part.

fourth. There is nothing wrong with what you have written, but you need a "when others =>" case for all case statements that are not clocked. This will prevent the formation of latches. If you move the case statement inside the clocked process, you dont need a "when others =>" case.


Yes, that part I've done. :)

But the counter doesn't work. According to the simulation, the clocksignal works fine, so does the count up or down button, but the counter doesn't output anything to the displays. I think this is because the code for the counter is wrong.
Nemi
 
Posts: 3
Joined: Sun Oct 03, 2010 5:14 pm

Postby tricky » Tue Oct 05, 2010 1:54 pm

Nemi wrote:Because we're supposed to use std_logic_vector according to the assignment. ;)


What a shit assignment. Doesnt teach you VHDL properly in that case. std_logic_vector is not the best way to do everything in VHDL. If you're tutor dissagrees, call him an idiot from me. Also ask him why he's taching you non standard VHDL libraries std_logic_arith and std_logic_unsigned. numeric_std is the standard that should be used - and it was standardised in 1993, 17 years ago!

second. you cannot connect clk to CLKin and CLKout of the clock divider. you also cannot have an internal signal called clk because you have an input called clk.


This part I got from a tutorial I tried out before starting this assignment. And in the tutorial we made a clockdivider module that we the "imported" or what it's called in "VHDL'sk" into the counter.

But it worked fine in the tutorial. Why should it not work here?



Because you have an input called "clk" and an internal signal called "clk". you cannot have two wires with the same name. I cannot compile the code you posted!


But the counter doesn't work. According to the simulation, the clocksignal works fine, so does the count up or down button, but the counter doesn't output anything to the displays. I think this is because the code for the counter is wrong.


Is the button signal actually going high on the board? there is nothing wrong with your counter code, other than the fact its going to count really fast when the button is pressed.
tricky
 
Posts: 56
Joined: Wed Dec 09, 2009 11:50 am


Return to VHDL