Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > BCD counter and 7 segment LCD help.

Reply
Thread Tools

BCD counter and 7 segment LCD help.

 
 
bob
Guest
Posts: n/a
 
      11-18-2003
Hi I have installed a 6 digit 7 segment LCD on my protoboard.

I have a signal (pulses) that I want to count and then display.
I want to send the pulses to 6 cascaded BCD counters.
I will send each BCD output to a BCD to 7 segment Decoder and then out
to my LCD
I am using Xilinx webpack but there is no VHDL BCD counters or BCD to
7 segment modules in its library.

Does enyone have a example code or could they point me to a example on
the web?

A 7 segment LED driver could be converted with a phase input to toggle
the outputs for the LCD.

If there is a better way to do the same thing I would be interested.

Thanks
Martin
 
Reply With Quote
 
 
 
 
Mark van de Belt
Guest
Posts: n/a
 
      11-18-2003

"bob" <(E-Mail Removed)> schreef in bericht
news:(E-Mail Removed)...
> Hi I have installed a 6 digit 7 segment LCD on my protoboard.
>
> I have a signal (pulses) that I want to count and then display.
> I want to send the pulses to 6 cascaded BCD counters.
> I will send each BCD output to a BCD to 7 segment Decoder and then out
> to my LCD
> I am using Xilinx webpack but there is no VHDL BCD counters or BCD to
> 7 segment modules in its library.
>
> Does enyone have a example code or could they point me to a example on
> the web?
>
> A 7 segment LED driver could be converted with a phase input to toggle
> the outputs for the LCD.
>
> If there is a better way to do the same thing I would be interested.
>
> Thanks
> Martin


Hello Martin,

Use a look-up table if you want to create a BCD to 7 segment converter:

signal BCD_IN: std_logic_vector (3 downto 0);
signal SEG_OUT: std_logic_vector (7 downto 0);

BCD_2_7SEGM:
process(BCD_IN)
begin
case BCD_IN is
when X"0" => SEG_OUT<= "0111111";
when X"1" => SEG_OUT<= "0000110";
when X"2" => SEG_OUT<= "1011011";
when X"3" => SEG_OUT<= "1001111";
when X"4" => SEG_OUT<= "1100110";
when X"5" => SEG_OUT<= "1101101";
when X"6" => SEG_OUT<= "1111101";
when X"7" => SEG_OUT<= "0000111";
when X"8" => SEG_OUT<= "1111111";
when X"9" => SEG_OUT<= "1101111";
when others => SEG_OUT<= "0000000";
end case;
end process;

A BCD counter is probably easiest (quick and dirty) with the following code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity bcdtest is
port (
CLK : in std_logic;
COUNT_OUT : out std_logic_vector (23 downto 0));
end bcdtest;

architecture arch of bcdtest is

signal bcd_count : unsigned (23 downto 0);

begin

COUNTER:
process (CLK)
begin
if CLK'event and CLK = '1' then
if bcd_count (3 downto 0) = "1001" then
bcd_count (3 downto 0) <= (others => '0');
if bcd_count (7 downto 4) = "1001" then
bcd_count (7 downto 4) <= (others => '0');
if bcd_count (11 downto = "1001" then
bcd_count (11 downto <= (others => '0');
if bcd_count (15 downto 12) = "1001" then
bcd_count (15 downto 12) <= (others => '0');
if bcd_count (19 downto 16) = "1001" then
bcd_count (19 downto 16) <= (others => '0');
if bcd_count (23 downto 20) = "1001" then
bcd_count (23 downto 20) <= (others => '0');
else
bcd_count (23 downto 20) <= bcd_count (23 downto 20) + 1;
end if;
else
bcd_count (19 downto 16) <= bcd_count (19 downto 16) + 1;
end if;
else
bcd_count (15 downto 12) <= bcd_count (15 downto 12) + 1;
end if;
else
bcd_count (11 downto <= bcd_count (11 downto + 1;
end if;
else
bcd_count (7 downto 4) <= bcd_count (7 downto 4) + 1;
end if;
else
bcd_count (3 downto 0) <= bcd_count (3 downto 0) + 1;
end if;
end if;
end process;

COUNT_OUT <= std_logic_vector(bcd_count);

end arch;


This code will probably produce a lot of logic. there is probably a cleaner
way to generate a BCD counter, specially with more digits.
This code will create 6 adders and 24 registers (35 slices in Xilinx spartan
2E). There should be a way to use only one adder, because only one of the
digits will count, but I can't come up with that at the moment.

I hope this helps,

Mark.



 
Reply With Quote
 
 
 
 
Charles M. Elias
Guest
Posts: n/a
 
      11-19-2003
bob <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> Hi I have installed a 6 digit 7 segment LCD on my protoboard.
>
> I have a signal (pulses) that I want to count and then display.
> I want to send the pulses to 6 cascaded BCD counters.
> I will send each BCD output to a BCD to 7 segment Decoder and then out
> to my LCD
> I am using Xilinx webpack but there is no VHDL BCD counters or BCD to
> 7 segment modules in its library.
>
> Does enyone have a example code or could they point me to a example on
> the web?
>
> A 7 segment LED driver could be converted with a phase input to toggle
> the outputs for the LCD.
>
> If there is a better way to do the same thing I would be interested.
>
> Thanks
> Martin

Martin here is a decade counter and an example that cascades three of
the counters. It is quite simple to add 3 more counters. This scheme
will require no adders.

library ieee;
use ieee.std_logic_1164.all;
--------------------------------------------------------------------------------
package pkgdecade is
component decade_counter
port ( clock : in std_logic;
clear_L : in std_logic := '1'; --optional low-assertive
clear
enable : in std_logic := '1'; --enable in
en_nxt : out std_logic; --enable to next decade
DigOut : out natural range 9 downto 0 );
end component;

end pkgdecade;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.pkgdecade.all;

entity decade_counter is
port ( clock : in std_logic;
clear_L : in std_logic := '1';
enable : in std_logic := '1';
en_nxt : out std_logic;
DigOut : out natural range 9 downto 0 );
end decade_counter;


architecture behav of decade_counter is
begin
process ( clock, clear_L, enable )

variable int_count : integer range 0 to 9;

begin
if clock = '1' and clock'event then
if clear_L = '0' then
int_count := 0;
elsif enable = '1' then
if int_count = 9 then
int_count := 0;
else
int_count := int_count + 1;
end if; --int_count = 9
end if; -- clear_L = '0'
end if; --clock transition
if enable = '1' and int_count = 9 then
en_nxt <= '1';
else
en_nxt <= '0';
end if;
DigOut <= int_count;
end process;
end behav;
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.pkgdecade.all;
--------------------------------------------------------------------------------
entity DecadeChain is
port ( Cclock : in std_logic;
Cclear_L : in std_logic;
CDigit2 : out natural range 9 downto 0;
CDigit1 : out natural range 9 downto 0;
CDigit0 : out natural range 9 downto 0 );
end DecadeChain;

architecture archDecadeChain of DecadeChain is

signal en2, en1 : std_logic;

begin
Dec2 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
enable => en2,
en_nxt => open,
DigOut => CDigit2 );

Dec1 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
enable => en1,
en_nxt => en2,
DigOut => CDigit1 );

Dec0 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
en_nxt => en1,
DigOut => CDigit0 );

end archDecadeChain;
 
Reply With Quote
 
Charles M. Elias
Guest
Posts: n/a
 
      11-19-2003
bob <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> Hi I have installed a 6 digit 7 segment LCD on my protoboard.
>
> I have a signal (pulses) that I want to count and then display.
> I want to send the pulses to 6 cascaded BCD counters.
> I will send each BCD output to a BCD to 7 segment Decoder and then out
> to my LCD
> I am using Xilinx webpack but there is no VHDL BCD counters or BCD to
> 7 segment modules in its library.
>
> Does enyone have a example code or could they point me to a example on
> the web?
>
> A 7 segment LED driver could be converted with a phase input to toggle
> the outputs for the LCD.
>
> If there is a better way to do the same thing I would be interested.
>
> Thanks

Martin,

Here is another version of the decade counter chain that I posted
earlier. The only difference is that the decade outputs are a subtype
of std_logic_vector instead of type natural. I thought I'd better do
this before I get a lot of flack for using an integer output instead
of a binary one. The first version would work OK, but I do like the
second version better.

Charles
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

----------------------------------------------------------------------------------


package pkgdecade is

subtype digit is std_logic_vector( 9 downto 0 );

component decade_counter
port ( clock : in std_logic;
clear_L : in std_logic := '1'; --optional low-assertive
clear
enable : in std_logic := '1'; --enable in
en_nxt : out std_logic; --enable to next decade
DigOut : out digit
);
end component;

end pkgdecade;
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.pkgdecade.all;

entity decade_counter is
port ( clock : in std_logic;
clear_L : in std_logic := '1';
enable : in std_logic := '1';
en_nxt : out std_logic;
DigOut : out digit
);
end decade_counter;


architecture behav of decade_counter is
begin
process ( clock, clear_L, enable )

variable int_count : integer range 0 to 9;

begin
if clock = '1' and clock'event then
if clear_L = '0' then
int_count := 0;
elsif enable = '1' then
if int_count = 9 then
int_count := 0;
else
int_count := int_count + 1;
end if; --int_count = 9
end if; -- clear_L = '0'
end if; --clock transition
if enable = '1' and int_count = 9 then
en_nxt <= '1';
else
en_nxt <= '0';
end if;
DigOut <= std_logic_vector(To_Unsigned( int_count, digout'length
));
end process;
end behav;
-------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.pkgdecade.all;
--------------------------------------------------------------------------------------
entity DecadeChain is
port ( Cclock : in std_logic;
Cclear_L : in std_logic;
CDigit2 : out digit;
CDigit1 : out digit;
CDigit0 : out digit );
end DecadeChain;

architecture archDecadeChain of DecadeChain is

signal en2, en1 : std_logic;

begin
Dec2 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
enable => en2,
en_nxt => open,
DigOut => CDigit2 );

Dec1 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
enable => en1,
en_nxt => en2,
DigOut => CDigit1 );

Dec0 : decade_counter port map ( clock => Cclock,
clear_L => Cclear_L,
en_nxt => en1,
DigOut => CDigit0 );

end archDecadeChain;

> Martin

 
Reply With Quote
 
bob
Guest
Posts: n/a
 
      11-20-2003
Thanks
If I want to togle the outputs with a phase signal (keeps LCD from
burning) whats the best way?
Should I check if the phase input is high

if phase= '1' then
case BCD_IN is
when X"0" => SEG_OUT<= "0111111";
when X"1" => SEG_OUT<= "0000110";
when X"2" => SEG_OUT<= "1011011";
when X"3" => SEG_OUT<= "1001111";
when X"4" => SEG_OUT<= "1100110";
when X"5" => SEG_OUT<= "1101101";
when X"6" => SEG_OUT<= "1111101";
when X"7" => SEG_OUT<= "0000111";
when X"8" => SEG_OUT<= "1111111";
when X"9" => SEG_OUT<= "1101111";
when others => SEG_OUT<= "0000000";
end case;
else
case BCD_IN is
when X"0" => SEG_OUT<= "1000000";
when X"1" => SEG_OUT<= "1111001";
when X"2" => SEG_OUT<= "0100100";
when X"3" => SEG_OUT<= "0110000";
when X"4" => SEG_OUT<= "0011001";
when X"5" => SEG_OUT<= "0010010";
when X"6" => SEG_OUT<= "0000010";
when X"7" => SEG_OUT<= "1111000";
when X"8" => SEG_OUT<= "0000000";
when X"9" => SEG_OUT<= "0010000";
when others => SEG_OUT<= "1111111";
end case;

or is there a better way?

On Wed, 19 Nov 2003 00:01:57 +0100, "Mark van de Belt"
<(E-Mail Removed)> wrote:

>
>"bob" <(E-Mail Removed)> schreef in bericht
>news:(E-Mail Removed).. .
>> Hi I have installed a 6 digit 7 segment LCD on my protoboard.
>>
>> I have a signal (pulses) that I want to count and then display.
>> I want to send the pulses to 6 cascaded BCD counters.
>> I will send each BCD output to a BCD to 7 segment Decoder and then out
>> to my LCD
>> I am using Xilinx webpack but there is no VHDL BCD counters or BCD to
>> 7 segment modules in its library.
>>
>> Does enyone have a example code or could they point me to a example on
>> the web?
>>
>> A 7 segment LED driver could be converted with a phase input to toggle
>> the outputs for the LCD.
>>
>> If there is a better way to do the same thing I would be interested.
>>
>> Thanks
>> Martin

>
>Hello Martin,
>
>Use a look-up table if you want to create a BCD to 7 segment converter:
>
>signal BCD_IN: std_logic_vector (3 downto 0);
>signal SEG_OUT: std_logic_vector (7 downto 0);
>
>BCD_2_7SEGM:
>process(BCD_IN)
>begin
> case BCD_IN is
> when X"0" => SEG_OUT<= "0111111";
> when X"1" => SEG_OUT<= "0000110";
> when X"2" => SEG_OUT<= "1011011";
> when X"3" => SEG_OUT<= "1001111";
> when X"4" => SEG_OUT<= "1100110";
> when X"5" => SEG_OUT<= "1101101";
> when X"6" => SEG_OUT<= "1111101";
> when X"7" => SEG_OUT<= "0000111";
> when X"8" => SEG_OUT<= "1111111";
> when X"9" => SEG_OUT<= "1101111";
> when others => SEG_OUT<= "0000000";
> end case;
>end process;
>
>A BCD counter is probably easiest (quick and dirty) with the following code:
>
>library IEEE;
>use IEEE.STD_LOGIC_1164.ALL;
>use IEEE.numeric_std.ALL;
>
>entity bcdtest is
> port (
> CLK : in std_logic;
> COUNT_OUT : out std_logic_vector (23 downto 0));
>end bcdtest;
>
>architecture arch of bcdtest is
>
>signal bcd_count : unsigned (23 downto 0);
>
>begin
>
> COUNTER:
> process (CLK)
> begin
> if CLK'event and CLK = '1' then
> if bcd_count (3 downto 0) = "1001" then
> bcd_count (3 downto 0) <= (others => '0');
> if bcd_count (7 downto 4) = "1001" then
> bcd_count (7 downto 4) <= (others => '0');
> if bcd_count (11 downto = "1001" then
> bcd_count (11 downto <= (others => '0');
> if bcd_count (15 downto 12) = "1001" then
> bcd_count (15 downto 12) <= (others => '0');
> if bcd_count (19 downto 16) = "1001" then
> bcd_count (19 downto 16) <= (others => '0');
> if bcd_count (23 downto 20) = "1001" then
> bcd_count (23 downto 20) <= (others => '0');
> else
> bcd_count (23 downto 20) <= bcd_count (23 downto 20) + 1;
> end if;
> else
> bcd_count (19 downto 16) <= bcd_count (19 downto 16) + 1;
> end if;
> else
> bcd_count (15 downto 12) <= bcd_count (15 downto 12) + 1;
> end if;
> else
> bcd_count (11 downto <= bcd_count (11 downto + 1;
> end if;
> else
> bcd_count (7 downto 4) <= bcd_count (7 downto 4) + 1;
> end if;
> else
> bcd_count (3 downto 0) <= bcd_count (3 downto 0) + 1;
> end if;
> end if;
> end process;
>
> COUNT_OUT <= std_logic_vector(bcd_count);
>
>end arch;
>
>
>This code will probably produce a lot of logic. there is probably a cleaner
>way to generate a BCD counter, specially with more digits.
>This code will create 6 adders and 24 registers (35 slices in Xilinx spartan
>2E). There should be a way to use only one adder, because only one of the
>digits will count, but I can't come up with that at the moment.
>
>I hope this helps,
>
>Mark.
>
>


 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      11-20-2003
"bob" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> If I want to togle the outputs with a phase signal (keeps LCD from
> burning) whats the best way?
> Should I check if the phase input is high
>
> if phase= '1' then
> case BCD_IN is
> when X"0" => SEG_OUT<= "0111111";

[...]
> end case;
> else
> case BCD_IN is

[...]
> end case;
>
> or is there a better way?


Yes, there's a much better way. Just write
your case statement once, creating the (non-toggled)
signal SEG_VALUE. Then XOR that signal with the
phase (backplane) signal to create the signal that
will actually drive the LCD segments, SEG_TO_LCD:

signal SEG_TO_LCD: std_logic_vector(SEG_VALUE'range);
...
SEG_TO_LCD <= SEG_VALUE when phase = '1' else not SEG_VALUE;

General rule of life: If you end up writing almost exactly
the same piece of code twice, you're probably doing it wrong.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: http://www.velocityreviews.com/forums/(E-Mail Removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.



 
Reply With Quote
 
G. G. Ditzel
Guest
Posts: n/a
 
      11-25-2003
Is there an easy (or at least not so difficult) way to make a
"generic" version of this counter, that is, a way to especify the
number of digits to be used? In your code you used 3 digits (CDigit2,
CDigit1, CDigit0), but what if I want to use N digits?

Thank you.

Ditzel


(E-Mail Removed) (Charles M. Elias) wrote in message news:<(E-Mail Removed). com>...

> Here is another version of the decade counter chain that I posted
> earlier. The only difference is that the decade outputs are a subtype
> of std_logic_vector instead of type natural. I thought I'd better do
> this before I get a lot of flack for using an integer output instead
> of a binary one. The first version would work OK, but I do like the
> second version better.
>
> Charles
> ----------------------------------------------------------------------------------
> library ieee;
> use ieee.std_logic_1164.all;
>
> ----------------------------------------------------------------------------------
>
>
> package pkgdecade is
>
> subtype digit is std_logic_vector( 9 downto 0 );
>
> component decade_counter
> port ( clock : in std_logic;
> clear_L : in std_logic := '1'; --optional low-assertive
> clear
> enable : in std_logic := '1'; --enable in
> en_nxt : out std_logic; --enable to next decade
> DigOut : out digit
> );
> end component;
>
> end pkgdecade;
> ----------------------------------------------------------------------------------
> ----------------------------------------------------------------------------------
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
> use work.pkgdecade.all;
>
> entity decade_counter is
> port ( clock : in std_logic;
> clear_L : in std_logic := '1';
> enable : in std_logic := '1';
> en_nxt : out std_logic;
> DigOut : out digit
> );
> end decade_counter;
>
>
> architecture behav of decade_counter is
> begin
> process ( clock, clear_L, enable )
>
> variable int_count : integer range 0 to 9;
>
> begin
> if clock = '1' and clock'event then
> if clear_L = '0' then
> int_count := 0;
> elsif enable = '1' then
> if int_count = 9 then
> int_count := 0;
> else
> int_count := int_count + 1;
> end if; --int_count = 9
> end if; -- clear_L = '0'
> end if; --clock transition
> if enable = '1' and int_count = 9 then
> en_nxt <= '1';
> else
> en_nxt <= '0';
> end if;
> DigOut <= std_logic_vector(To_Unsigned( int_count, digout'length
> ));
> end process;
> end behav;
> -------------------------------------------------------------------------------------
> library ieee;
> use ieee.std_logic_1164.all;
> use work.pkgdecade.all;
> --------------------------------------------------------------------------------------
> entity DecadeChain is
> port ( Cclock : in std_logic;
> Cclear_L : in std_logic;
> CDigit2 : out digit;
> CDigit1 : out digit;
> CDigit0 : out digit );
> end DecadeChain;
>
> architecture archDecadeChain of DecadeChain is
>
> signal en2, en1 : std_logic;
>
> begin
> Dec2 : decade_counter port map ( clock => Cclock,
> clear_L => Cclear_L,
> enable => en2,
> en_nxt => open,
> DigOut => CDigit2 );
>
> Dec1 : decade_counter port map ( clock => Cclock,
> clear_L => Cclear_L,
> enable => en1,
> en_nxt => en2,
> DigOut => CDigit1 );
>
> Dec0 : decade_counter port map ( clock => Cclock,
> clear_L => Cclear_L,
> en_nxt => en1,
> DigOut => CDigit0 );
>
> end archDecadeChain;
>
> > Martin

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VHDL 12 bit BCD counter dv09 Hardware 0 10-07-2009 04:57 PM
plz ...Verilog-HDL an up/down BCD counter SQU VHDL 1 04-28-2009 03:54 PM
(8-bit binary to two digit bcd) or (8-bit binary to two digit seven segment) Fangs VHDL 3 10-26-2008 06:41 AM
binary to BCD updown counter gina VHDL 0 10-08-2007 03:32 PM
BCD Counter daveip VHDL 0 04-25-2007 05:53 PM



Advertisments