EmbDev.net

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


Author: Karthiga G. (karthiga05)
Posted on:

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!

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter4 is
   port(count:out std_logic_vector(3 downto 0);
        clk:in std_logic;
        reset:in std_logic);
end counter4;

architecture behav_counter4 of counter4 is
    
   component ha port (a: in  std_logic;
                      b: in  std_logic;
                      sum: out std_logic;
                      c_out: out std_logic);
   end component;
   
   component fa port (a, b, cin : in std_logic;
                      sum, c_out : out std_logic);
   end component;
     
     
     
   signal ain,s,c:std_logic_vector(3 downto 0) :="0000";
   signal bin:std_logic_vector(3 downto 0):="0001";
               
   --configuration specification   
   for all:ha use entity work.ha(rtl);
   for all:fa use entity work.fa(fa_behav);
      
   begin
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));

      counter:process(clk, reset) --process(sensitivity list)
      begin
         if reset'event and (reset = '1') then
            s <= (others => '0'); 

         elsif clk'event and (clk='1') then
            ain <= c xor ain;
            s <= ain xor bin;
            c <= s and c;
            
         end if;
      end process;
            
      count <= s;
    
end behav_counter4; 

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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
      counter:process(clk, reset) --process(sensitivity list)
      begin
         if (reset = '1') then
            s <= (others => '0'); 

         elsif (clk'event and clk='1') then
            ain <= s;
         end if;
      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!

Author: Duke Scarring (Guest)
Posted on:

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

Duke

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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:
      counter:process(clk, reset) --process(sensitivity list)
      begin
         if (reset = '1') then
            ain <= (others => '0'); 
         elsif (clk'event and clk='1') then
            ain <= s;
         end if;
      end process;

Author: Karthiga G. (karthiga05)
Posted on:

Rate this post
0 useful
not useful
Duke Scarring wrote:
> Homework?
> Write:
>
> begin
>  if reset = '1' then
>   s <= (others => '0');
>  [...]
> 
> 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.

Author: Karthiga G. (karthiga05)
Posted on:

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

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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

Author: Duke Scarring (Guest)
Posted on:

Rate this post
0 useful
not useful
Next time, tell your professor or teacher the world use "+" to make an 
addition:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter4 is
    port(
        count : out std_logic_vector(3 downto 0);
        clk   : in  std_logic;
        reset : in  std_logic
    );
end entity counter4;

architecture behav_counter4 of counter4 is
    
    signal s : unsigned(3 downto 0) := "0000";

    counter : process(clk, reset) -- process(sensitivity list)
    begin
         if reset = '1' then
            s <= (others => '0'); 

         elsif rising_edge( clk) then
            s <= s + 1;
         end if;

    end process;
            
    count <= std_logic_vector( s);

end architecture behav_counter4;

She or he needs an recent textbook...

Duke

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
But, Duke, EVERYBODY MUST write a RTL adder to understand how an 
addition is working in hardware...  ;-)
    counter : process(clk, reset) -- process(sensitivity list)
    begin
         if reset = '1' then
            s <= (others => '0'); 
         elsif rising_edge( clk) then
            s <= s + 1;
         end if;
    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:
    counter : process(clk)
    begin
        if rising_edge( clk) then
            if reset = '1' then
               s <= (others => '0'); 
            else 
               s <= s + 1;
            end if;
         end if;
    end process;

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

Author: Karthiga G. (karthiga05)
Posted on:

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...  ;-)
>
>
>     counter : process(clk, reset) -- process(sensitivity list)
>     begin
>          if reset = '1' then
>             s <= (others => '0');
>          elsif rising_edge( clk) then
>             s <= s + 1;
>          end if;
>     end process;

> 

i cant use 's = s+1'.

Author: Karthiga G. (karthiga05)
Posted on:

Rate this post
0 useful
not useful
Lothar Miller wrote:
>> OMG! IT WORKS NOW!! THANK YOU SO MUCH!
> And whats your code now?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter4 is
   port(count:out std_logic_vector(3 downto 0);
        clk:in std_logic;
        reset:in std_logic);
end counter4;

architecture behav_counter4 of counter4 is

   component ha port (a: in  std_logic;
                      b: in  std_logic;
                      sum: out std_logic;
                      c_out: out std_logic);
   end component;

   component fa port (a, b, cin : in std_logic;
                      sum, c_out : out std_logic);
   end component;

   signal ain,s,c:std_logic_vector(3 downto 0) :="0000";
   signal bin:std_logic_vector(3 downto 0):="0001";

   --configuration specification
   for all:ha use entity work.ha(rtl);
   for all:fa use entity work.fa(fa_behav);

   begin
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out =>
c(0));
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0),
c_out => c(1));
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1),
c_out => c(2));
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2),
c_out => c(3));


      counter:process(clk, reset) --process(sensitivity list)
      begin
      if reset = '1' then
         ain <= (others => '0');
      elsif (clk'event and clk='1') then
         ain <= s;

         end if;
      end process;

      count <= s;

end behav_counter4 

Author: Karthiga G. (karthiga05)
Posted on:

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?

Author: Duke Scarring (Guest)
Posted on:

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

Duke

Author: Karthiga G. (karthiga05)
Posted on:
Attached files:

Rate this post
0 useful
not useful
attached is my waveform and my testbench is below.
library ieee;
use ieee.std_logic_1164.all;

entity mycounter_testbench4 is
end mycounter_testbench4;

architecture mycounter_tb4 of mycounter_testbench4 is

   signal count: std_logic_vector(3 downto 0):="0000";
   signal clk: std_logic:='0';
   signal reset: std_logic;

   component counter4
      port(count:out std_logic_vector(3 downto 0):="0000";
           clk:in std_logic:='0';
           reset:in std_logic);

   end component;

      begin
      counter_circuit : counter4 
         port map(count => count, clk => clk, reset => reset);
             
            clock:process
               begin
                  wait for 10ns; 
                  clk <= not clk;
            end process clock;

            test_reset:process
               begin
                  wait for 5ns; reset <= '1';
                  wait for 4ns; reset <= '0';
                  wait;
            end process test_reset;                  

end mycounter_tb4;

Author: Duke Scarring (Guest)
Posted on:

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

Author: Karthiga G. (karthiga05)
Posted on:

Rate this post
0 useful
not useful
what is combinatoric?

Author: Karthiga G. (karthiga05)
Posted on:

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

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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";

Author: Karthiga G. (karthiga05)
Posted on:

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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter4 is
   port(count:out std_logic_vector(3 downto 0);
        clk:in std_logic;
        reset:in std_logic);
end counter4;

architecture behav_counter4 of counter4 is
    
   component ha port (a: in  std_logic;
                      b: in  std_logic;
                      sum: out std_logic;
                      c_out: out std_logic);
   end component;
   
   component fa port (a, b, cin : in std_logic;
                      sum, c_out : out std_logic);
   end component;
   
   signal ain,s,c:std_logic_vector(3 downto 0) :="1111";
   signal bin:std_logic_vector(3 downto 0):="0001";
               
   --configuration specification   
   for all:ha use entity work.ha(rtl);
   for all:fa use entity work.fa(fa_behav);
      
   begin
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
      
      
      counter:process(clk, reset) --process(sensitivity list)
      begin
         if reset = '1' then 
            ain <= (others => '0'); 
         
         elsif (clk'event and clk='1') then
            ain <= s;
            count <= s;
                
         end if;
      end process;

end behav_counter4; 


testbench:
library ieee;
use ieee.std_logic_1164.all;

entity mycounter_testbench4 is
end mycounter_testbench4;

architecture mycounter_tb4 of mycounter_testbench4 is

   signal count: std_logic_vector(3 downto 0):="1111";
   signal clk: std_logic:='0';
   signal reset: std_logic;

   component counter4
      port(count:out std_logic_vector(3 downto 0):="1111";
           clk:in std_logic:='0';
           reset:in std_logic);

   end component;

      begin
      counter_circuit : counter4 
         port map(count => count, clk => clk, reset => reset);
             
            clock:process
               begin
                  wait for 10ns; 
                  clk <= not clk;
            end process clock;

            test_reset:process
               begin
                  wait for 5ns; reset <= '1';
                  wait for 4ns; reset <= '0';
                  wait;
            end process test_reset;                  

end mycounter_tb4;

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ha is
   port (a: in  std_logic;
         b: in  std_logic;
         sum: out std_logic;
         c_out: out std_logic);
end ha;

architecture rtl of ha is
begin
   sum   <= a xor b;
   c_out <= a and b;
end rtl;


----------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity fa is
   port (a, b, cin : in std_logic;
         sum, c_out : out std_logic);
end fa;

architecture rtl of fa is
begin
   sum   <= a xor b xor cin;
   c_out <= (a and b) or (a and cin) or (b and cin);
end rtl;

----------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter4 is
   port(count: out std_logic_vector(3 downto 0);
        clk  : in std_logic;
        reset: in std_logic);
end counter4;

architecture behav_counter4 of counter4 is
    
   component ha port (a: in  std_logic;
                      b: in  std_logic;
                      sum: out std_logic;
                      c_out: out std_logic);
   end component;
   
   component fa port (a, b, cin : in std_logic;
                      sum, c_out : out std_logic);
   end component;
   
   signal ain,s,c:std_logic_vector(3 downto 0) :="1111";
   signal bin:std_logic_vector(3 downto 0):="0001";
               
   --configuration specification   
   for all:ha use entity work.ha(rtl);
   for all:fa use entity work.fa(rtl);
      
   begin
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
      
      
      counter:process(clk, reset) --process(sensitivity list)
      begin
         if reset = '1' then 
            ain   <= "1111"; -- Set here the initial value also
         elsif (clk'event and clk='1') then
            ain   <= s;
         end if;
      end process;
      
      count <= s; 
      
end behav_counter4;
REMIND this: because i didn't have your adders, i had to use mine.

You can do it this way also:
architecture behav_counter4 of counter4 is
    
   component ha port (a: in  std_logic;
                      b: in  std_logic;
                      sum: out std_logic;
                      c_out: out std_logic);
   end component;
   
   component fa port (a, b, cin : in std_logic;
                      sum, c_out : out std_logic);
   end component;
   
   signal ain,s,c : std_logic_vector(3 downto 0);
   signal bin : std_logic_vector(3 downto 0) :="0001";
               
   signal cnt : std_logic_vector(3 downto 0) :="0000"; -- these are the counter registers
   
   --configuration specification   
   for all:ha use entity work.ha(rtl);
   for all:fa use entity work.fa(rtl);
      
   begin
      u1:ha port map(a => ain(0), b => bin(0), sum => s(0), c_out => c(0));
      u2:fa port map(a => ain(1), b => bin(1), sum => s(1), cin => c(0), c_out => c(1));
      u3:fa port map(a => ain(2), b => bin(2), sum => s(2), cin => c(1), c_out => c(2));
      u4:fa port map(a => ain(3), b => bin(3), sum => s(3), cin => c(2), c_out => c(3));
      
      
      counter:process(clk, reset) --process(sensitivity list)
      begin
         if reset = '1' then 
            cnt   <= "0000"; 
         elsif (clk'event and clk='1') then
            cnt   <= s; -- take over the next value
         end if;
      end process;
      
      ain   <= cnt; -- connect the counter value to the adder input
      
      count <= cnt; -- pass to output
      
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]
  • [avrasm]AVR assembler code[/avrasm]
  • [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.