Thejdeep
Thejdeep

Reputation: 57

I am trying to implement a 1-2-3-4-6 counter in VHDL but the count is incrementing form 1-7 .

This is a VHDL code to count in sequence 1-2-3-4-6-7 but seems to count form 1-7 The code seems to have a logical error somewhere . Please help

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

entity newtest is 
port(C, CLR : in  std_logic;  
Q : out std_logic_vector(2 downto 0));  
end newtest; 
architecture archi of newtest is  
signal tmp: std_logic_vector(2 downto 0); 
begin  
process (C, CLR) 
begin  
if (CLR='1') then  
tmp <= "000";  
elsif (C'event and C='1') then 
if (tmp="100") then
tmp <= tmp + 1;
end if; 
tmp <= tmp + 1; 
end if;  
end process; 
Q <= tmp;  
end archi; 

Upvotes: 1

Views: 1694

Answers (1)

user1155120
user1155120

Reputation:

In a process with two sequential signal assignments to tmp not separated by time the later assignment will occur. A signal has a current value and a future value. Signal assignments are not updated until after the current simulation cycle. You've updated the future value before it could be assigned to the current value in the next simulation cycle with a clock C'event and C = '1'.

The following uses the numeric_std package instead of the Synopsys std_logic_unsigned package without changing the type of tmp, hence the type conversions to and from unsigned. I simply didn't want to divert my ieee library to contain something non-standard compliant. You can use std_logic_unsigned and remove the type conversions.

You could likewise declare signal tmp as unsigned (2 downto 0) and type convert it when assigning to Q (Q <= std_logic_vector(tmp);) or if possible make both Q and tmp unsigned.

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

entity newtest is 
    port(C, CLR :   in  std_logic;  
         Q :        out std_logic_vector(2 downto 0));  
end newtest; 
architecture archi of newtest is  
    signal tmp: std_logic_vector(2 downto 0); 
begin  
    process (C, CLR) 
    begin  
        if (CLR='1') then  
            tmp <= "000";  
        elsif (C'event and C='1') then 
            if (tmp="100") then
                tmp <= std_logic_vector (unsigned (tmp) + 2);
            else
                tmp <= std_logic_vector (unsigned (tmp) + 1);
            end if; 
        end if;  
    end process; 
    Q <= tmp;  
end archi; 

Now there is only ever one assignment to tmp and it should go from "100" to "110". Someone is bound to point out tmp could be an unsigned instead of a std_logic_vector, or tmp could be an integer instead of either.

As far as synthesized hardware adding increment by 2 requires an additional term input for the two rightmost bits of tmp input

Upvotes: 1

Related Questions