countervhdl

My counter "4-digit BCD Counter" does not work well!


I have designed 4-digit BCD Counter and BCD-to-7segment Converter as a project of one of my courses in the university.

Here is the circuit: http://img849.imageshack.us/img849/930/111vr.png

enter image description here

and here is the source code:

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

entity IC_74163 is
port(LdN, ClrN, P, T, ClK: in std_logic;  
D: in std_logic_vector(3 downto 0);
Cout: out std_logic; Qout: out std_logic_vector(3 downto 0) );
end entity;

architecture IC_74163_1 of IC_74163 is
signal Q: std_logic_vector(3 downto 0);    -- Q is the counter register
begin
Qout <= Q;
Cout <= Q(3) and Q(2) and Q(1) and Q(0) and T;
process (CLK)
begin
if CLK'event and CLK = '1' then     -- change state on rising edge
if ClrN = '0' then  Q <= "0000";
elsif LdN = '0' then Q <= D;
elsif (P and T) = '1' then Q <= Q+1;
   end if;
   end if;
end process;
end architecture;

==============================

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

entity Four_Digit_BCD_Counter is
port(Clk: in std_logic;
     Q1, Q2, Q3, Q4: inout std_logic_vector(3 downto 0):= "0000");
end entity;

architecture Four_Digit_BCD_Counter_1 of Four_Digit_BCD_Counter is
component IC_74163 is
port(LdN, ClrN, P, T, ClK: in std_logic;  
D: in std_logic_vector(3 downto 0);
Cout: out std_logic; Qout: out std_logic_vector(3 downto 0) );
end component;
signal ClrN1, ClrN2, ClrN3, ClrN4: std_logic;
signal T2, T3, T4: std_logic;
begin
ClrN1 <= Q1(3) NOR Q1(0);
ClrN2 <= Q2(3) NOR Q2(0);
ClrN3 <= Q3(3) NOR Q3(0);
ClrN4 <= Q4(3) NOR Q4(0);
T2 <= not (Q1(3) NOR Q1(0));
T3 <= not (Q2(3) NOR Q2(0));
T4 <= not (Q3(3) NOR Q3(0));
IC_1: IC_74163 port map ('1',ClrN1,'1','1',Clk,"ZZZZ",open,Q1);
IC_2: IC_74163 port map ('1',ClrN2,'1',T2,Clk,"ZZZZ",open,Q2);
IC_3: IC_74163 port map ('1',ClrN3,'1',T3,Clk,"ZZZZ",open,Q3);
IC_4: IC_74163 port map ('1',ClrN4,'1',T4,Clk,"ZZZZ",open,Q4);
end architecture;

==============================

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

entity BCD_to_Seven_Segment_Converter is
  port(B3, B2, B1, B0 :in std_logic; output:out integer range 0 to 9);
end entity;

architecture BCD_to_Seven_Segment_Converter_1 of BCD_to_Seven_Segment_Converter is
signal ss:std_logic_vector(6 downto 0);
signal a, b, c, d, e, f, g:std_logic;
begin
a <= B3 or ((not B0) and (not B2)) or B1 or (B0 and B2);
b <= (not B2) or ((not B0) and (not B1)) or (B0 and B1);
c <= (not B1) or B0 or B2;
d <= B3 or ((not B0) and (not B2)) or ((not B0) and B1) or (B0 and (not B1) and B2) or (B1 and (not B2));
e <= ((not B0) and B1) or ((not B0) and (not B2));
f <= B3 or ((not B0) and B2) or ((not B0) and (not B1)) or ((not B1) and B2);
g <= B3 or ((not B1) and B2) or (B1 and (not B2)) or ((not B0) and B1);
process(ss)
begin
case ss is
when "1111110" => output <= 0;
when "0110000" => output <= 1;
when "1101101" => output <= 2;
when "1111001" => output <= 3;
when "0110011" => output <= 4;
when "1011011" => output <= 5;
when "1011111" => output <= 6;
when "1110000" => output <= 7;
when "1111111" => output <= 8;
when "1111011" => output <= 9;
when others => null;
end case;
end process;



--process(input)
--begin
--case input is
--when "0000" => output <= "1111110";
--when "0001" => output <= "0110000";
--when "0010" => output <= "1101101";
--when "0011" => output <= "1111001";
--when "0100" => output <= "0110011";
--when "0101" => output <= "1011011";
--when "0110" => output <= "1011111";
--when "0111" => output <= "1110000";
--when "1000" => output <= "1111111";
--when "1001" => output <= "1111011";
--when others => null;
--end case;
--end process;


end architecture;

==============================

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

entity Project is
port(Clk: in std_logic; Count: out integer range 0000 to 9999 := 0000);
end entity;

architecture The_Circiut of Project is
component Four_Digit_BCD_Counter is
port(Clk: in std_logic;
     Q1, Q2, Q3, Q4: inout std_logic_vector(3 downto 0):= "0000");
end component;

component BCD_to_Seven_Segment_Converter is
  port(B3, B2, B1, B0 :in std_logic; output:out integer range 0 to 9);
end component;

signal Qout1, Qout2, Qout3, Qout4: std_logic_vector(3 downto 0):= "0000";
signal D0, D1, D2, D3:integer range 0 to 9;
begin

BCD_Counter_4Digit: Four_Digit_BCD_Counter port map (Clk, Qout1, Qout2, Qout3, Qout4);
BCD_7Segment_Converter1: BCD_to_Seven_Segment_Converter port map (Qout1(0), Qout1(1), Qout1(2), Qout1(3), D0);
BCD_7Segment_Converter2: BCD_to_Seven_Segment_Converter port map (Qout2(0), Qout2(1), Qout2(2), Qout2(3), D1);
BCD_7Segment_Converter3: BCD_to_Seven_Segment_Converter port map (Qout3(0), Qout3(1), Qout3(2), Qout3(3), D2);
BCD_7Segment_Converter4: BCD_to_Seven_Segment_Converter port map (Qout4(0), Qout4(1), Qout4(2), Qout4(3), D3);
Count <= D3 * 1000 + D2 * 100 + D1 * 10 + D0;
end architecture;

The problem is that, Count stays 0 forever and does not change and count up. Could you help me to figure out the problem?

====================================

EDIT:

Well, after I edited the problems that @MRAB and @Tomi Junnila mentioned the problem does not fixed! Also, I have tried to test IC_74163 alone, and I think it is the source of the problem, it gives me Qout as X !! Can you guys test it for me please? I am using Active-HDL btw.

====================================

EDIT2:

Here is the waveform for IC_74163: http://img851.imageshack.us/img851/8117/52226324.png

enter image description here

====================================

EDIT3:

OK, the counter is working very well but I still have very small issue. I have four std_logic_vector(3 downto 0) which are Qout1, Qout2, Qout3 and Qout4 .. How can I convert them to an integer of 4 digits ? std_logic_vector(3 downto 0):= "0000" does not work well.

====================================

EDIT4:

OK guys, the counter is working as required and there is no issue. Thank you for your help, I really appreciate it.

Here is the final source code for anyone interested:

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

entity IC_74163 is
port(LdN, ClrN, P, T, ClK: in std_logic:='0';  
D: in std_logic_vector(3 downto 0):="0000";
Cout: out std_logic; Qout: inout std_logic_vector(3 downto 0):="0000");
end entity;

architecture IC_74163_1 of IC_74163 is
begin
Cout <= Qout(3) and Qout(2) and Qout(1) and Qout(0) and T;
process (CLK)
begin
if CLK'event and CLK = '1' then     -- change state on rising edge
if ClrN = '0' then  Qout <= "0000";
elsif LdN = '0' then Qout <= D;
elsif (P and T) = '1' then Qout <= Qout+1;
   end if;
   end if;
end process;
end architecture;

==============================

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

entity Four_Digit_BCD_Counter is
port(Clk: in std_logic;
     Q1, Q2, Q3, Q4: inout std_logic_vector(3 downto 0):= "0000");
end entity;

architecture Four_Digit_BCD_Counter_1 of Four_Digit_BCD_Counter is
component IC_74163 is
port(LdN, ClrN, P, T, ClK: in std_logic;  
D: in std_logic_vector(3 downto 0);
Cout: out std_logic; Qout: inout std_logic_vector(3 downto 0) );
end component;
signal ClrN1, ClrN2, ClrN3, ClrN4: std_logic;
signal T2, T3, T4: std_logic;
begin
ClrN1 <= Q1(3) NAND Q1(0);
ClrN2 <= Q2(3) NAND Q2(0);
ClrN3 <= Q3(3) NAND Q3(0);
ClrN4 <= Q4(3) NAND Q4(0);
T2 <= not (Q1(3) NAND Q1(0));
T3 <= not (Q2(3) NAND Q2(0));
T4 <= not (Q3(3) NAND Q3(0));
IC_1: IC_74163 port map ('1',ClrN1,'1','1',Clk,"ZZZZ",open,Q1);
IC_2: IC_74163 port map ('1',ClrN2,'1',T2,Clk,"ZZZZ",open,Q2);
IC_3: IC_74163 port map ('1',ClrN3,'1',T3,Clk,"ZZZZ",open,Q3);
IC_4: IC_74163 port map ('1',ClrN4,'1',T4,Clk,"ZZZZ",open,Q4);
end architecture;

==============================

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

entity BCD_to_Seven_Segment_Converter is
  port(B3, B2, B1, B0 :in std_logic; output:out integer range 0 to 9);
end entity;

architecture BCD_to_Seven_Segment_Converter_1 of BCD_to_Seven_Segment_Converter is
signal ss:std_logic_vector(6 downto 0);
signal a, b, c, d, e, f, g:std_logic;
begin
a <= B3 or ((not B0) and (not B2)) or B1 or (B0 and B2);
b <= (not B2) or ((not B0) and (not B1)) or (B0 and B1);
c <= (not B1) or B0 or B2;
d <= B3 or ((not B0) and (not B2)) or ((not B0) and B1) or (B0 and (not B1) and B2) or (B1 and (not B2));
e <= ((not B0) and B1) or ((not B0) and (not B2));
f <= B3 or ((not B0) and B2) or ((not B0) and (not B1)) or ((not B1) and B2);
g <= B3 or ((not B1) and B2) or (B1 and (not B2)) or ((not B0) and B1);
ss <= a&b&c&d&e&f&g;
process(ss)
begin
case ss is
when "1111110" => output <= 0;
when "0110000" => output <= 1;
when "1101101" => output <= 2;
when "1111001" => output <= 3;
when "0110011" => output <= 4;
when "1011011" => output <= 5;
when "1011111" => output <= 6;
when "1110000" => output <= 7;
when "1111111" => output <= 8;
when "1111011" => output <= 9;
when others => null;
end case;
end process;

--process(input)
--begin
--case input is
--when "0000" => output <= "1111110";
--when "0001" => output <= "0110000";
--when "0010" => output <= "1101101";
--when "0011" => output <= "1111001";
--when "0100" => output <= "0110011";
--when "0101" => output <= "1011011";
--when "0110" => output <= "1011111";
--when "0111" => output <= "1110000";
--when "1000" => output <= "1111111";
--when "1001" => output <= "1111011";
--when others => null;
--end case;
--end process;


end architecture;

==============================

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

entity Project is
port(Clk: in std_logic; Count: out integer range 0000 to 9999 := 0000);
end entity;

architecture The_Circiut of Project is
component Four_Digit_BCD_Counter is
port(Clk: in std_logic;
     Q1, Q2, Q3, Q4: inout std_logic_vector(3 downto 0):= "0000");
end component;

component BCD_to_Seven_Segment_Converter is
  port(B3, B2, B1, B0 :in std_logic; output:out integer range 0 to 9);
end component;

signal Qout1, Qout2, Qout3, Qout4: std_logic_vector(3 downto 0):= "0000";
signal D0, D1, D2, D3:integer range 0 to 9;
begin
BCD_Counter_4Digit: Four_Digit_BCD_Counter port map (Clk, Qout1, Qout2, Qout3, Qout4);
BCD_7Segment_Converter1: BCD_to_Seven_Segment_Converter port map (Qout1(3), Qout1(2), Qout1(1), Qout1(0), D0);
BCD_7Segment_Converter2: BCD_to_Seven_Segment_Converter port map (Qout2(3), Qout2(2), Qout2(1), Qout2(0), D1);
BCD_7Segment_Converter3: BCD_to_Seven_Segment_Converter port map (Qout3(3), Qout3(2), Qout3(1), Qout3(0), D2);
BCD_7Segment_Converter4: BCD_to_Seven_Segment_Converter port map (Qout4(3), Qout4(2), Qout4(1), Qout4(0), D3);
Count <= D3 * 1000 + D2 * 100 + D1 * 10 + D0;
end architecture;

Solution

  • You don't assign anything to the ss signal in the BCD_to_Seven_Segment_Converter_1 architecture, yet that signal is used to determine the output signal. If I had to hazard a guess, you actually want to look at the signals a through g.

    There is also a far easier way to convert the 4 bits to an integer:

    --...
        signal v : std_logic_vector(3 downto 0);
    begin
        v <= B3 & B2 & B1 & B0;
    
        CONV: process(v)
            case v is
                when "0000" => output <= 0;
                when "0001" => output <= 1;
                when "0010" => output <= 2;
                -- etc, don't forget "when others"
            end case;
        end process CONV;
    --...
    

    You are probably also not resetting the IC_74163 properly. It uses a synchronous reset, so it will only reset on a rising clock edge when ClrN is '0'. However, ClrN is driven by combo logic based on the output, so it will never get set to '0', since Qouts initialize to "UUUU".