BCD counter and 7 segment LCD help.

B

bob

Guest
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
 
"bob" <kmart@nospam.com> schreef in bericht
news:5c1lrvsd5cgg4q5cl86fuf36qqqtu3g952@4ax.com...
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 8) = "1001" then
bcd_count (11 downto 8) <= (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 8) <= bcd_count (11 downto 8) + 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.
 
bob <kmart@nospam.com> wrote in message news:<5c1lrvsd5cgg4q5cl86fuf36qqqtu3g952@4ax.com>...
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;
 
bob <kmart@nospam.com> wrote in message news:<5c1lrvsd5cgg4q5cl86fuf36qqqtu3g952@4ax.com>...
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
 
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"
<mark@nijenrode.nospam.demon.nl> wrote:

"bob" <kmart@nospam.com> schreef in bericht
news:5c1lrvsd5cgg4q5cl86fuf36qqqtu3g952@4ax.com...
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 8) = "1001" then
bcd_count (11 downto 8) <= (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 8) <= bcd_count (11 downto 8) + 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.
 
"bob" <kmart@nospam.com> wrote in message
news:6kjprvkpinep0sa2bc1e7kfsa54e0r93ep@4ax.com...

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: jonathan.bromley@doulos.com
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.
 
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


charles.elias@wpafb.af.mil (Charles M. Elias) wrote in message news:<35849667.0311190435.6bdc3f4c@posting.google.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
 

Welcome to EDABoard.com

Sponsor

Back
Top