EmbDev.net

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


von Karthiga G. (karthiga05)


Rate this post
0 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. (lkmiller) (Moderator)


Rate this post
0 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
0 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. (lkmiller) (Moderator)


Rate this post
0 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
0 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
0 useful
not useful
OMG! IT WORKS NOW!! THANK YOU SO MUCH!

von Lothar M. (lkmiller) (Moderator)


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

von Duke Scarring (Guest)


Rate this post
0 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. (lkmiller) (Moderator)


Rate this post
0 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
0 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
0 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
0 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
0 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
0 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
0 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
0 useful
not useful
what is combinatoric?

von Karthiga G. (karthiga05)


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

von Lothar M. (lkmiller) (Moderator)


Rate this post
0 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
0 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. (lkmiller) (Moderator)


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

von Lothar M. (lkmiller) (Moderator)


Rate this post
0 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.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.