EmbDev.net

Forum: FPGA, VHDL & Verilog URGENT. Help on 4bit counter.


von Karthiga G. (karthiga05)


Rate this post
useful
not useful
Hi. this is my vhdl code for a 4 bit counter using 1 half adder and 3 
fulladders. i have done my code. bt the waveform only shows "0000" and 
"0001". aftr "0001", it doesnt add anymore. how do i do that? Thanks in 
advance!

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
5
entity counter4 is
6
   port(count:out std_logic_vector(3 downto 0);
7
        clk:in std_logic;
8
        reset:in std_logic);
9
end counter4;
10
11
architecture behav_counter4 of counter4 is
12
    
13
   component ha port (a: in  std_logic;
14
                      b: in  std_logic;
15
                      sum: out std_logic;
16
                      c_out: out std_logic);
17
   end component;
18
   
19
   component fa port (a, b, cin : in std_logic;
20
                      sum, c_out : out std_logic);
21
   end component;
22
     
23
     
24
     
25
   signal ain,s,c:std_logic_vector(3 downto 0) :="0000";
26
   signal bin:std_logic_vector(3 downto 0):="0001";
27
               
28
   --configuration specification   
29
   for all:ha use entity work.ha(rtl);
30
   for all:fa use entity work.fa(fa_behav);
31
      
32
   begin
33
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
34
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
35
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
36
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
37
38
      counter:process(clk, reset) --process(sensitivity list)
39
      begin
40
         if reset'event and (reset = '1') then
41
            s <= (others => '0'); 
42
43
         elsif clk'event and (clk='1') then
44
            ain <= c xor ain;
45
            s <= ain xor bin;
46
            c <= s and c;
47
            
48
         end if;
49
      end process;
50
            
51
      count <= s;
52
    
53
end behav_counter4;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
This is not the complete description. I do not see anything about the 
components ha and fa.

And as far as I see: if your ha and fa are working and the wiring is ok, 
the only thing you must do in the process is this
1
      counter:process(clk, reset) --process(sensitivity list)
2
      begin
3
         if (reset = '1') then
4
            s <= (others => '0'); 
5
6
         elsif (clk'event and clk='1') then
7
            ain <= s;
8
         end if;
9
      end process;
And why?
Because the adder should do s=a+b.
With b=1 it does s=a+1.
And so for a counter you must just say a(new)=s(old) for each clock 
cycle.


>  if reset'event and (reset = '1') then
Whats that?
A clock sensitive reset? Thats not possible with real flipflops!

von Duke Scarring (Guest)


Rate this post
useful
not useful
Homework?
Write:
1
begin
2
 if reset = '1' then
3
  s <= (others => '0');
4
 [...]
Otherwise it will only react if there are events on reset signal...

Duke

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Another little problem:
Because the sum s is a result of a combinational calculation, its not 
possible to reset it in a process.
But you can reset the counter flipflops. And these are the ain 
flipflops, because they are affected by the clock. so it must look like 
this:
1
      counter:process(clk, reset) --process(sensitivity list)
2
      begin
3
         if (reset = '1') then
4
            ain <= (others => '0'); 
5
         elsif (clk'event and clk='1') then
6
            ain <= s;
7
         end if;
8
      end process;

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
Duke Scarring wrote:
> Homework?
> Write:
>
1
> begin
2
>  if reset = '1' then
3
>   s <= (others => '0');
4
>  [...]
5
>
> Otherwise it will only react if there are events on reset signal...
>
> Duke

Now is shows 000X, 00XX and 0XXX only. its still not looping.
i used "if reset'event and (reset = '1') then
            s <= (others => '0'); "
for my 8 bit counter and it worked.

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
OMG! IT WORKS NOW!! THANK YOU SO MUCH!

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> OMG! IT WORKS NOW!! THANK YOU SO MUCH!
And whats your code now?

von Duke Scarring (Guest)


Rate this post
useful
not useful
Next time, tell your professor or teacher the world use "+" to make an 
addition:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity counter4 is
6
    port(
7
        count : out std_logic_vector(3 downto 0);
8
        clk   : in  std_logic;
9
        reset : in  std_logic
10
    );
11
end entity counter4;
12
13
architecture behav_counter4 of counter4 is
14
    
15
    signal s : unsigned(3 downto 0) := "0000";
16
17
    counter : process(clk, reset) -- process(sensitivity list)
18
    begin
19
         if reset = '1' then
20
            s <= (others => '0'); 
21
22
         elsif rising_edge( clk) then
23
            s <= s + 1;
24
         end if;
25
26
    end process;
27
            
28
    count <= std_logic_vector( s);
29
30
end architecture behav_counter4;

She or he needs an recent textbook...

Duke

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
But, Duke, EVERYBODY MUST write a RTL adder to understand how an 
addition is working in hardware...  ;-)
1
    counter : process(clk, reset) -- process(sensitivity list)
2
    begin
3
         if reset = '1' then
4
            s <= (others => '0'); 
5
         elsif rising_edge( clk) then
6
            s <= s + 1;
7
         end if;
8
    end process;
Thats the most ancient way to write an adder. This comes just after the 
RTL code.

For todays FPGAs (Xilinx) it may be good to use a synchronous reset:
1
    counter : process(clk)
2
    begin
3
        if rising_edge( clk) then
4
            if reset = '1' then
5
               s <= (others => '0'); 
6
            else 
7
               s <= s + 1;
8
            end if;
9
         end if;
10
    end process;

This also will work in the same manner:
1
    counter : process -- NO sensitivity list
2
    begin
3
        wait for rising_edge(clk);
4
        if reset = '1' then
5
           s <= (others => '0'); 
6
        else 
7
           s <= s + 1;
8
        end if;
9
    end process;

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
Lothar Miller wrote:
> But, Duke, EVERYBODY MUST write a RTL adder to understand how an
> addition is working in hardware...  ;-)
>
>
1
>     counter : process(clk, reset) -- process(sensitivity list)
2
>     begin
3
>          if reset = '1' then
4
>             s <= (others => '0');
5
>          elsif rising_edge( clk) then
6
>             s <= s + 1;
7
>          end if;
8
>     end process;
9
10
>

i cant use 's = s+1'.

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
Lothar Miller wrote:
>> OMG! IT WORKS NOW!! THANK YOU SO MUCH!
> And whats your code now?
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
5
entity counter4 is
6
   port(count:out std_logic_vector(3 downto 0);
7
        clk:in std_logic;
8
        reset:in std_logic);
9
end counter4;
10
11
architecture behav_counter4 of counter4 is
12
13
   component ha port (a: in  std_logic;
14
                      b: in  std_logic;
15
                      sum: out std_logic;
16
                      c_out: out std_logic);
17
   end component;
18
19
   component fa port (a, b, cin : in std_logic;
20
                      sum, c_out : out std_logic);
21
   end component;
22
23
   signal ain,s,c:std_logic_vector(3 downto 0) :="0000";
24
   signal bin:std_logic_vector(3 downto 0):="0001";
25
26
   --configuration specification
27
   for all:ha use entity work.ha(rtl);
28
   for all:fa use entity work.fa(fa_behav);
29
30
   begin
31
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out =>
32
c(0));
33
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0),
34
c_out => c(1));
35
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1),
36
c_out => c(2));
37
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2),
38
c_out => c(3));
39
40
41
      counter:process(clk, reset) --process(sensitivity list)
42
      begin
43
      if reset = '1' then
44
         ain <= (others => '0');
45
      elsif (clk'event and clk='1') then
46
         ain <= s;
47
48
         end if;
49
      end process;
50
51
      count <= s;
52
53
end behav_counter4

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
my waveform starts from 0001. and the reset is uninitialized at the
beginning. i need to start my counter frm 0000. hw do i do that?

von Duke Scarring (Guest)


Rate this post
useful
not useful
Can you post a screenshot of your simulation?
Can we see yout testbench?

Duke

von Karthiga G. (karthiga05)


Attached files:

Rate this post
useful
not useful
attached is my waveform and my testbench is below.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity mycounter_testbench4 is
5
end mycounter_testbench4;
6
7
architecture mycounter_tb4 of mycounter_testbench4 is
8
9
   signal count: std_logic_vector(3 downto 0):="0000";
10
   signal clk: std_logic:='0';
11
   signal reset: std_logic;
12
13
   component counter4
14
      port(count:out std_logic_vector(3 downto 0):="0000";
15
           clk:in std_logic:='0';
16
           reset:in std_logic);
17
18
   end component;
19
20
      begin
21
      counter_circuit : counter4 
22
         port map(count => count, clk => clk, reset => reset);
23
             
24
            clock:process
25
               begin
26
                  wait for 10ns; 
27
                  clk <= not clk;
28
            end process clock;
29
30
            test_reset:process
31
               begin
32
                  wait for 5ns; reset <= '1';
33
                  wait for 4ns; reset <= '0';
34
                  wait;
35
            end process test_reset;                  
36
37
end mycounter_tb4;

von Duke Scarring (Guest)


Rate this post
useful
not useful
Your adder is combinatoric. And your output (count <= s;) is also 
combinatoric. You can put "count <= s;" in the clocked process...

Duke

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
what is combinatoric?

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
it still doesnt start frm 0000. it starts frm 0001.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> it still doesnt start frm 0000. it starts frm 0001.
Thats correct: ain is initialized as "0000".
And with s=ain+1 this results in "0000"+"0001"="0001"
So just try to initialize ain with "1111", because "1111"+"0001"="0000"
;-)
> signal ain :std_logic_vector(3 downto 0) :="1111";

von Karthiga G. (karthiga05)


Rate this post
useful
not useful
Lothar Miller wrote:
>> it still doesnt start frm 0000. it starts frm 0001.
> Thats correct: ain is initialized as "0000".
> And with s=ain+1 this results in "0000"+"0001"="0001"
> So just try to initialize ain with "1111", because "1111"+"0001"="0000"
> ;-)
>> signal ain :std_logic_vector(3 downto 0) :="1111";

it still starts with 0001. and not 000o although ive changed the initial 
values to 1111.

4bitcount.vhd:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
5
entity counter4 is
6
   port(count:out std_logic_vector(3 downto 0);
7
        clk:in std_logic;
8
        reset:in std_logic);
9
end counter4;
10
11
architecture behav_counter4 of counter4 is
12
    
13
   component ha port (a: in  std_logic;
14
                      b: in  std_logic;
15
                      sum: out std_logic;
16
                      c_out: out std_logic);
17
   end component;
18
   
19
   component fa port (a, b, cin : in std_logic;
20
                      sum, c_out : out std_logic);
21
   end component;
22
   
23
   signal ain,s,c:std_logic_vector(3 downto 0) :="1111";
24
   signal bin:std_logic_vector(3 downto 0):="0001";
25
               
26
   --configuration specification   
27
   for all:ha use entity work.ha(rtl);
28
   for all:fa use entity work.fa(fa_behav);
29
      
30
   begin
31
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
32
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
33
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
34
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
35
      
36
      
37
      counter:process(clk, reset) --process(sensitivity list)
38
      begin
39
         if reset = '1' then 
40
            ain <= (others => '0'); 
41
         
42
         elsif (clk'event and clk='1') then
43
            ain <= s;
44
            count <= s;
45
                
46
         end if;
47
      end process;
48
49
end behav_counter4;


testbench:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity mycounter_testbench4 is
5
end mycounter_testbench4;
6
7
architecture mycounter_tb4 of mycounter_testbench4 is
8
9
   signal count: std_logic_vector(3 downto 0):="1111";
10
   signal clk: std_logic:='0';
11
   signal reset: std_logic;
12
13
   component counter4
14
      port(count:out std_logic_vector(3 downto 0):="1111";
15
           clk:in std_logic:='0';
16
           reset:in std_logic);
17
18
   end component;
19
20
      begin
21
      counter_circuit : counter4 
22
         port map(count => count, clk => clk, reset => reset);
23
             
24
            clock:process
25
               begin
26
                  wait for 10ns; 
27
                  clk <= not clk;
28
            end process clock;
29
30
            test_reset:process
31
               begin
32
                  wait for 5ns; reset <= '1';
33
                  wait for 4ns; reset <= '0';
34
                  wait;
35
            end process test_reset;                  
36
37
end mycounter_tb4;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Pls show the code of your components fa and ha also.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> it still starts with 0001. and not 000o although ive changed the
> initial values to 1111.
NOW it is time to start THINKING on your own.
Just with a few clicks in the simulator i fixed the problem with your 
code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
5
entity ha is
6
   port (a: in  std_logic;
7
         b: in  std_logic;
8
         sum: out std_logic;
9
         c_out: out std_logic);
10
end ha;
11
12
architecture rtl of ha is
13
begin
14
   sum   <= a xor b;
15
   c_out <= a and b;
16
end rtl;
17
18
19
----------------------------------------------------------
20
library ieee;
21
use ieee.std_logic_1164.all;
22
use ieee.std_logic_unsigned.all;
23
24
entity fa is
25
   port (a, b, cin : in std_logic;
26
         sum, c_out : out std_logic);
27
end fa;
28
29
architecture rtl of fa is
30
begin
31
   sum   <= a xor b xor cin;
32
   c_out <= (a and b) or (a and cin) or (b and cin);
33
end rtl;
34
35
----------------------------------------------------------
36
library ieee;
37
use ieee.std_logic_1164.all;
38
use ieee.std_logic_unsigned.all;
39
40
entity counter4 is
41
   port(count: out std_logic_vector(3 downto 0);
42
        clk  : in std_logic;
43
        reset: in std_logic);
44
end counter4;
45
46
architecture behav_counter4 of counter4 is
47
    
48
   component ha port (a: in  std_logic;
49
                      b: in  std_logic;
50
                      sum: out std_logic;
51
                      c_out: out std_logic);
52
   end component;
53
   
54
   component fa port (a, b, cin : in std_logic;
55
                      sum, c_out : out std_logic);
56
   end component;
57
   
58
   signal ain,s,c:std_logic_vector(3 downto 0) :="1111";
59
   signal bin:std_logic_vector(3 downto 0):="0001";
60
               
61
   --configuration specification   
62
   for all:ha use entity work.ha(rtl);
63
   for all:fa use entity work.fa(rtl);
64
      
65
   begin
66
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
67
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
68
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
69
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
70
      
71
      
72
      counter:process(clk, reset) --process(sensitivity list)
73
      begin
74
         if reset = '1' then 
75
            ain   <= "1111"; -- Set here the initial value also
76
         elsif (clk'event and clk='1') then
77
            ain   <= s;
78
         end if;
79
      end process;
80
      
81
      count <= s; 
82
      
83
end behav_counter4;
REMIND this: because i didn't have your adders, i had to use mine.

You can do it this way also:
1
architecture behav_counter4 of counter4 is
2
    
3
   component ha port (a: in  std_logic;
4
                      b: in  std_logic;
5
                      sum: out std_logic;
6
                      c_out: out std_logic);
7
   end component;
8
   
9
   component fa port (a, b, cin : in std_logic;
10
                      sum, c_out : out std_logic);
11
   end component;
12
   
13
   signal ain,s,c : std_logic_vector(3 downto 0);
14
   signal bin : std_logic_vector(3 downto 0) :="0001";
15
               
16
   signal cnt : std_logic_vector(3 downto 0) :="0000"; -- these are the counter registers
17
   
18
   --configuration specification   
19
   for all:ha use entity work.ha(rtl);
20
   for all:fa use entity work.fa(rtl);
21
      
22
   begin
23
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
24
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
25
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
26
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
27
      
28
      
29
      counter:process(clk, reset) --process(sensitivity list)
30
      begin
31
         if reset = '1' then 
32
            cnt   <= "0000"; 
33
         elsif (clk'event and clk='1') then
34
            cnt   <= s; -- take over the next value
35
         end if;
36
      end process;
37
      
38
      ain   <= cnt; -- connect the counter value to the adder input
39
      
40
      count <= cnt; -- pass to output
41
      
42
end behav_counter4;
Here the counter registers are explicitly declared, and therefore the 
adder itself is completely combinatorial.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.