BCD counter and 7 segment LCD help.

Discussion in 'VHDL' started by bob, Nov 18, 2003.

  1. bob

    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, Nov 18, 2003
    #1
    1. Advertising

  2. "bob" <> schreef in bericht
    news:...
    > 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.
     
    Mark van de Belt, Nov 18, 2003
    #2
    1. Advertising

  3. bob <> wrote in message news:<>...
    > 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;
     
    Charles M. Elias, Nov 19, 2003
    #3
  4. bob <> wrote in message news:<>...
    > 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
     
    Charles M. Elias, Nov 19, 2003
    #4
  5. bob

    bob Guest

    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"
    <> wrote:

    >
    >"bob" <> schreef in bericht
    >news:...
    >> 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, Nov 20, 2003
    #5
  6. "bob" <> wrote in message
    news:...

    > 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:
    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.
     
    Jonathan Bromley, Nov 20, 2003
    #6
  7. bob

    G. G. Ditzel Guest

    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 M. Elias) wrote in message news:<>...

    > 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
     
    G. G. Ditzel, Nov 25, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fangs
    Replies:
    3
    Views:
    9,939
    darshana
    Oct 26, 2008
  2. daveip

    BCD Counter

    daveip, Apr 25, 2007, in forum: VHDL
    Replies:
    0
    Views:
    1,454
    daveip
    Apr 25, 2007
  3. gina
    Replies:
    0
    Views:
    935
  4. George2
    Replies:
    1
    Views:
    851
    Alf P. Steinbach
    Jan 31, 2008
  5. SQU
    Replies:
    1
    Views:
    2,303
    JohnDuq
    Apr 28, 2009
Loading...

Share This Page