Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Code for the 16 Bit BCD(Binary Coded Decimal) Counter i.e. 4 Decades Counter

Status
Not open for further replies.

beast_boy

Junior Member level 1
Joined
Jul 9, 2012
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
I am trying to write the VHDL code for a Timing Genarator Chip :
in the VHDL code i have to incorporate a code for the 16 Bit BCD(Binary Coded Decimal) Counter i.e. 4 Decades , i tried a lot but unable to figure it out how to get it working...
as the 16 bit BCD counter can count from 0 to 9999 ,for the first 9 clock pulses i can easily create a counter as i will use the last your bits out of 16 bits for the count but for counting 10 i have to make the bits from 7 to 4 as BCD one and the last four bits as 0 (0000) , for counting eleven the bits from 7 to 4 should make a BCD one (0001) and the last four bits as (0001) and so on it will continue its count.....

can someone give me a hint how can i do it or if possible a small piece of working C or VHDL code for this.....as i also searched on net but everyone has written code for 4 bit BCD counter that can count from 0 to 9 only...
 

I have an assembler sub-routine for PIC 16F876A. It uses TMR1 as 16 bit counter and then convert it into 5 BCD registers.
Tell if this can help you.

Best regards.
 

Gosh after so many efforts i am able to write down some piece of code that is working ......atleast partially
in the below code my count is going well till 90 , after that it is going to 101 instead of going to 91 , i am trying to figure out
what changes i have to make in the mean time if anyone can analyze the code below and tell me what i am doing wrong
and what changes should i make so that the code will work properly then i will be very grateful



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

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
 
entity bcd_counter is
    port (
           clk : in std_logic ;
           up_count : in std_logic;
           count    : out unsigned(15 downto 0)
         );  
end bcd_counter ;
 
 
architecture behavior of bcd_counter is
 
signal i : unsigned(3 downto 0) := "0000";
signal j : unsigned(3 downto 0) := "0000";
signal k : unsigned(3 downto 0) := "0000";
signal l : unsigned(3 downto 0) := "0000";
 
 
    begin
    
    process(clk)
    
        begin
        
        if clk = '1' and clk'event then
         
         if up_count = '1' then
           
           if l <= to_unsigned(9,4) then
           
            if k <= to_unsigned(9,4) then
           
              if i <= to_unsigned(9,4) then
                 
             if j <= to_unsigned(9,4) then
                  j <= j + to_unsigned(1,4);             
                        if j = to_unsigned(9,4) then         
                           i <= i + to_unsigned(1,4);
                           j <= "0000";
                        end if;                               
             
                if i = to_unsigned(9,4) then
                   k <= k + to_unsigned(1,4);
                   i <= "0000";
                end if;
                
                if k = to_unsigned(9,4) then
                   l <= l + to_unsigned(1,4);
                   k <= "0000";
                end if;
                                 
             end if;
                                      
              end if;
              
           end if;
           
         end if;
         
        end if;
          
           end if; 
         
        end process;
    
    process(clk)
    
        begin
        
        if clk = '0' and clk'event then 
           if j <= to_unsigned(9,4) then
             count <= to_unsigned(1000*(to_integer(l)) +100*(to_integer(k)) + 10*(to_integer(i)) + 1*(to_integer(j)),16);
           end if;
        end if;  
        
    end process;
 
end behavior;



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

Attachments

  • gtkwave.png
    gtkwave.png
    100.7 KB · Views: 130
Last edited by a moderator:

My updated VHDL code is below but my friend told me that......each if statement in VHDL code uses a MUX so this approach is not good and if i am emphasizing to use the if statements then i should write separate process's for which i am also posting my code below

1.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
 
entity bcd_counter is
  port (
    clk      : in  std_logic;
    up_count : in  std_logic;
    count    : out unsigned(15 downto 0)
    );  
end bcd_counter;
 
 
architecture behavior of bcd_counter is
 
  signal temp : unsigned(15 downto 0);
  signal a0    : unsigned(3 downto 0) := "0000";
  signal a1    : unsigned(3 downto 0) := "0000";
  signal a2    : unsigned(3 downto 0) := "0000";
  signal a3    : unsigned(3 downto 0) := "0000";
 
 
begin
  
  process(clk)
 
  begin
    
    if clk = '1' and clk'event then         ---1
      
      if up_count = '1' then                ---2
        
        if a3 <= to_unsigned(9, 4) then     ---3
          
          if a2 <= to_unsigned(9, 4) then   ---4
            
            if a1 <= to_unsigned(9, 4) then     ---5
              
              if a0 <= to_unsigned(9, 4) then   ---6
          
                a0    <= a0 + to_unsigned(1, 4);
        
        temp <= to_unsigned(1000*(to_integer(a3)) + 100*(to_integer(a2)) + 10*(to_integer(a1)) + 1*(to_integer(a0)) + 1, 16);
 
                if a0 = to_unsigned(9, 4) then
                  a1 <= a1 + to_unsigned(1, 4);
                  a0 <= "0000";
                end if;
 
                if a1 = to_unsigned(9, 4) and a0 = to_unsigned(9, 4) then-- and temp >= to_unsigned(99, 16) and temp <= to_unsigned(999, 16)then
                  a2 <= a2 + to_unsigned(1, 4);
                  a1 <= "0000";
          a0 <= "0000";
                end if;
 
                if a2 = to_unsigned(9, 4) and a0 = to_unsigned(9,4) then--and temp >= to_unsigned(999, 16) and temp <= to_unsigned(9999, 16) then
                  a3 <= a3 + to_unsigned(1, 4);
                  a2 <= "0000";
          a1 <= "0000";
          a0 <= "0000";
                end if;
                        
              end if;  ---6
              
            end if;                 ---5
            
          end if;               ---4
          
        end if;                 ---3
        
      end if;                   ---2
      
    end if;                     ---1
    
  end process;
 
end behavior;



- - - Updated - - -

2.This is what my friend asked to do by including in processes but this is not working at all and is only counting till 9 and going to high impedance state after that , please correct this


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
 
entity bcd_counter is
  port (
    clk      : in  std_logic;
    up_count : in  std_logic;
    count    : out unsigned(15 downto 0)
    );  
end bcd_counter;
 
 
architecture behavior of bcd_counter is
 
  signal temp : unsigned(15 downto 0);
  signal a0    : unsigned(3 downto 0) := "0000";
  signal a1    : unsigned(3 downto 0) := "0000";
  signal a2    : unsigned(3 downto 0) := "0000";
  signal a3    : unsigned(3 downto 0) := "0000";
  
begin
  
  process(clk)
 
  begin
  
   if clk = '1' and clk'event and up_count = '1' then
      temp <= to_unsigned(1000*(to_integer(a3)) + 100*(to_integer(a2)) + 10*(to_integer(a1)) + 1*(to_integer(a0)) + 1, 16);
     if a0 = to_unsigned(9,4) then
       a0 <= "0000";
       a1 <= "0001";
     else
       a0    <= a0 + to_unsigned(1, 4);
     end if;
       
   end if;
   
  end process;
  
  process(clk)
 
  begin
  
   if clk = '1' and clk'event and up_count = '1' then
     if a1 = to_unsigned(9,4) then
       a1 <= "0000";
       a2 <= "0001";
     else
       a0    <= a0 + to_unsigned(1, 4);
     end if;
     
    end if;
   
  end process;
  
  process(clk)
 
  begin
  
   if clk = '1' and clk'event and up_count = '1' then
     if a2 = to_unsigned(9,4) then
       a2 <= "0000";
       a3 <= "0001";
     else
       a2    <= a0 + to_unsigned(1, 4);
     end if;
       
   end if;
   
  end process; 
  
  process(clk)
 
  begin
  
   if clk = '1' and clk'event and up_count = '1' then
     if a3 = to_unsigned(9,4) then
       a2 <= "0000";
       a3 <= "1001";
     else
       a2    <= a0 + to_unsigned(1, 4);
     end if;
       
   end if;
   
  end process; 
  
end behavior;

 

Here is what i got from this forum and this thread after searching.............
https://www.edaboard.com/threads/184152/


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
entity c09 is
port( rst,clk: in std_logic;
op0,op1,op2,op3: out std_logic_vector(6 downto 0));
end c09;
 
architecture count of c09 is
 
component clk_div
Port (
clk : in std_logic;
rst : in std_logic;
op : out std_logic
);
end component;
 
component segd
port(m: in std_logic_vector(3 downto 0);
num: out std_logic_vector(6 downto 0));
end component;
 
 
signal flag: std_logic;
signal a: std_logic_vector(3 downto 0);
signal b: std_logic_vector(3 downto 0);
signal c: std_logic_vector(3 downto 0);
signal d: std_logic_vector(3 downto 0);
begin
 
c1: clk_div port map(clk,rst,flag);
 
process(rst,flag)
variable m0: std_logic_vector(3 downto 0):="0000";
variable m1: std_logic_vector(3 downto 0):="0000";
variable m2: std_logic_vector(3 downto 0):="0000";
variable m3: std_logic_vector(3 downto 0):="0000";
 
begin
 
if rst='0' then
m0:="0000";
m1:="0000";
m2:="0000";
m3:="0000";
elsif flag'event and flag='1' then
a<=m0;
b<=m1;
c<=m2;
d<=m3;
if m0 /= "1001" then
m0:= m0 + 1;
elsif m0="1001" and m1 /= "1001" then
m0:="0000";
m1:= m1 + 1;
elsif m1="1001" and m2 /= "1001" and m0="1001" then
m1:="0000";
m0:="0000";
m2:= m2 + 1;
elsif m2="1001" and m3/= "1001" and m0="1001" and m1="1001" then
m1:="0000";
m0:="0000";
m2 :="0000";
m3 := m3 + 1;
elsif m3="1001" then
m0:="0000";
m1:="0000";
m2:="0000";
m3:="0000";
end if;
end if;
 
end process;
 
z0: segd port map(a,op0);
z1: segd port map(b,op1);
z2: segd port map(c,op2);
z3: segd port map(d,op3);
 
end count;
 
 
 
 
 
 
seven seg lookup table code:
 
library ieee;
use ieee.std_logic_1164.all;
 
entity segd is
 
port(m: in std_logic_vector(3 downto 0);
num: out std_logic_vector(6 downto 0));
end segd;
 
architecture sseg of segd is
begin
process(m)
begin
if(m="0000") then
num<="1000000";
elsif(m="0001") then
num<="1111001";
elsif(m="0010") then
num<="0100100";
elsif(m="0011") then
num<="0110000";
elsif(m="0100") then
num<="0011001";
elsif(m="0101") then
num<="0010010";
elsif(m="0110") then
num<="0000010";
elsif(m="0111") then
num<="1111000";
elsif(m="1000") then
num<="0000000";
elsif(m="1001") then
num<="0010000";
else
num<="1111111";
end if;
end process;
end sseg;
 
 
 
 
most imortant CLOCK CODE:
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
 
entity clk_div is
Port (
Clk : in std_logic;
rst: in std_logic;
op : out std_logic
);
end clk_div;
 
architecture RTL of clk_div is
constant max_count : natural := 6000000;
 
begin
 
compteur : process(Clk,rst)
variable count : natural range 0 to max_count;
begin
if rst = '0' then
count := 0;
op <= '1';
elsif rising_edge(Clk) then
if count < max_count/2 then
op <='1';
count := count + 1;
elsif count < max_count then
op <='0';
count := count + 1;
else
count := 0;
op <='1';
end if;
end if;
end process compteur;
end RTL;

 

Now seems that i finally got a working code for this.........and this is for down counter


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
 
entity bcd_counter is
  port (
    clk      : in  std_logic;
    down_count : in  std_logic;
    count    : out unsigned(15 downto 0);
    );  
end bcd_counter;
 
 
architecture behavior of bcd_counter is
 
  signal temp : unsigned(15 downto 0);
  signal a0   : unsigned(3 downto 0) := "0000";
  signal a1   : unsigned(3 downto 0) := "0000";
  signal a2   : unsigned(3 downto 0) := "0000";
  signal a3   : unsigned(3 downto 0) := "0000";
  
begin
  
  process(clk)
 
  begin
 
    if clk = '1' and clk'event  and down_count = '1' then
    
      if a0 /= to_unsigned(0, 4) then
      
        a0 <= a0 - to_unsigned(1, 4);
    
      elsif a1 /= to_unsigned(0, 4) and a0 = to_unsigned(0, 4) then
      
        a0 <= "1001";
    a1 <= a1 - to_unsigned(1, 4);
    
      elsif a2 /= to_unsigned(0, 4) and a1 = to_unsigned(0, 4) and  a0 = to_unsigned(0, 4)then 
      
    a0 <= "1001";
    a1 <= "1001";
    a2 <= a2 - to_unsigned(1, 4);
    
      elsif a3 /= to_unsigned(0, 4) and a2 = to_unsigned(0, 4) and  a1 = to_unsigned(0, 4) and a0 = to_unsigned(0, 4)then
      
    a0 <= "1001";
    a1 <= "1001";
    a2 <= "1001";
    a3 <= a3 - to_unsigned(1, 4);
    
      elsif a3 = to_unsigned(0, 4) then
      
    a0 <= "1001";
    a1 <= "1001";
    a2 <= "1001";
    a3 <= "1001";
    
      end if;    
      
    end if;
    
  end process;
 
 
  temp(15 downto 12) <= a3;
  temp(11 downto 8)  <= a2;
  temp(7 downto 4)   <= a1;
  temp(3 downto 0)   <= a0;
  count              <= temp;
  
end behavior;

 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top