2
\$\begingroup\$

Question:
I was trying to make a counter that counts from 0 to 255 with different steps. For example this counter based on a control input could start counting from 0 with a step of +5. So we will have the sequence 0,5,10,15... In order to avoid overflow I used a signal called valid that will freeze the counter when we are on a state of overflow and in order to reset the counter I used a signal called RST that sets the counter on 0 so it can count again. The RST must be synchronous. The problem is that when I am changing the signal RST from 1 to 0 it seems that I need more than 1 clock circle. And I don't know why this is happening. Any help would be appreciated. You can see my code below and the waveforms from simulation.

My module

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--This library is used for numeral operations(+/-) 
use IEEE.STD_LOGIC_UNSIGNED.all;
use ieee.STD_LOGIC_ARITH.all;

entity lab1 is
    Port ( Clk : in  STD_LOGIC;
           RST : in  STD_LOGIC;
           Control : in  STD_LOGIC_VECTOR (2 downto 0);
           Count : out  STD_LOGIC_VECTOR (7 downto 0);
           Overflow : out  STD_LOGIC;
           Underflow : out  STD_LOGIC;
           Valid : out  STD_LOGIC);
end lab1;

architecture Behavioral of lab1 is

signal Qtemp: STD_LOGIC_VECTOR(7 downto 0):= "00000000" ;
signal overflow_temp:STD_LOGIC := '0';
signal underflow_temp:STD_LOGIC := '0';
signal Valid_temp: std_logic := '0';



begin
process

begin
    
    Valid<= Valid_temp;
    Count<= Qtemp;
    Overflow<= overflow_temp;
    Underflow <= underflow_temp;


 Wait Until Clk'Event and Clk='1';

        if RST= '1' then
                Valid_temp <= '1';
                overflow_temp<='0';
                underflow_temp<='0';

                Qtemp<="00000000";
                Count<="00000000";
                

          else
              if Valid_temp='0' then
                   Qtemp<=Qtemp;

            elsif Control = "000" then
                    if Qtemp < 5 then 
                        Valid_temp <= '0';
                        underflow_temp<='1';
                    else

                        Qtemp <= Qtemp - 5;
                    end if;

            elsif Control = "001" then
                    if Qtemp < 2 then 
                        Valid_temp <= '0';
                        underflow_temp<='1';
                    else

                        Qtemp <= Qtemp - 2;
                    end if;                 

            elsif Control = "010" then

                        Qtemp <= Qtemp; -- no need to check for overflow/underflow

            elsif Control = "011" then
                    if Qtemp > 254 then 
                        Valid_temp <= '0';
                        overflow_temp<='1';
                    else

                        Qtemp <= Qtemp + 1;
                    end if; 

            elsif Control = "100" then
                    if Qtemp > 253 then 
                        Valid_temp <= '0';
                        overflow_temp<='1';
                    else

                        Qtemp <= Qtemp + 2;
                    end if;

            elsif Control = "101" then 
                    if Qtemp > 250 then 
                        Valid_temp <= '0';
                        overflow_temp<='1';
                    else

                        Qtemp <= Qtemp + 5;
                    end if;

            elsif Control = "110" then
                    if Qtemp > 249 then 
                        Valid_temp <= '0';
                        overflow_temp<='1';
                    else

                        Qtemp <= Qtemp + 6;
                    end if; 

            else
                    if Qtemp > 243 then 
                        Valid_temp <= '0';
                        overflow_temp<='1';
                    else

                        Qtemp <= Qtemp + 12;
                    end if;

                end if;

        end if; 



end process;

end Behavioral;

TestBench

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
--USE ieee.numeric_std.ALL;
 
ENTITY lab1_test IS
END lab1_test;
 
ARCHITECTURE behavior OF lab1_test IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT lab1
    PORT(
         Clk : IN  std_logic;
         RST : IN  std_logic;
         Control : IN  std_logic_vector(2 downto 0);
         Count : OUT  std_logic_vector(7 downto 0);
         Overflow : OUT  std_logic;
         Underflow : OUT  std_logic;
         Valid : OUT  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal Clk : std_logic := '0';
   signal RST : std_logic := '0';
   signal Control : std_logic_vector(2 downto 0) := (others => '0');

    --Outputs
   signal Count : std_logic_vector(7 downto 0);
   signal Overflow : std_logic;
   signal Underflow : std_logic;
   signal Valid : std_logic;

   -- Clock period definitions
   constant Clk_period : time := 10 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: lab1 PORT MAP (
          Clk => Clk,
          RST => RST,
          Control => Control,
          Count => Count,
          Overflow => Overflow,
          Underflow => Underflow,
          Valid => Valid
        );

   -- Clock process definitions
   Clk_process :process
   begin
        Clk <= '0';
        wait for Clk_period/2;
        Clk <= '1';
        wait for Clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
    RST <= '1'; 
    wait for Clk_period*10; -- hold reset for (at least) 10 cycles 
    
     
      Control <= "101"; -- control = 5 => count+ = 5 
        RST <= '0'; -- deactivate reset
      wait for Clk_period*54; -- 5(count step) * 52 = 260 > 255 so it overflows
      RST <= '1'; -- resets the state because of overflow
      wait for Clk_period*2;
      
      
   
      Control <= "010"; -- +0 Count = 0
        RST <= '0'; -- deactivate reset so it starts counting again
      wait for Clk_period*2;
    
      Control <= "011"; -- +1 Count = 1
      wait for Clk_period*2;

      Control <= "100"; -- +2 Count = 3 
      wait for Clk_period*2;
    
      Control <= "101"; -- +5 Count = 8
      wait for Clk_period*2;
    
      Control <= "110"; -- +6 Count = 14
      wait for Clk_period*2;
   
      Control <= "111"; -- +12 Count = 26
      wait for Clk_period*2;
    
      Control <= "000"; -- -5 Count = 21
      wait for Clk_period*2;
        
        RST <= '1'; -- resets the state because of overflow
      wait for Clk_period*2;
    
        
      Control <= "001"; -- -2 Count = 19
        RST <= '0';
      wait for Clk_period*11;-- 19 - 22 = -3 < 0, so it underflows
      --RST <= '1'; -- resets the state because of underflow
 
    wait;
  end process;

END;

Waveforms Waveforms

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

Your RST is apparently generated synchronously, too. As such, it becomes "1" in the same instant as the clock edge. Therefore, the Count (and other registers) will not read it (setup time violated in real hardware) and will reset with the following clock edge.

Add a little delay (like a "phase angle") to your testbench's generation of RST.

You can for example add a fraction of the clock cycle to the beginning of your process to generate RST:

    -- Stimulus process
    stim_proc: process
    begin
        -- This is added:
        wait for Clk_period / 4; -- add a little phase angle

        RST <= '1'; 
        wait for Clk_period * 10; -- hold reset for (at least) 10 cycles
        -- rest unmodified...

This will also help with the other input signals, which would give you similar headaches otherwise.

\$\endgroup\$
6
  • \$\begingroup\$ It seems that still there is a delay in my waveforms.Its exactly one circle so i believe its a bug of xilinx. \$\endgroup\$ Commented Oct 19, 2022 at 18:29
  • \$\begingroup\$ Please edit your question and add the new stuff. If you added just the line I suggest, you can show it similarly as an excerpt (just in case my answer gets lost). But we need to see the resulting waveform to help you. \$\endgroup\$ Commented Oct 20, 2022 at 6:00
  • \$\begingroup\$ Post has been updated it. \$\endgroup\$ Commented Oct 20, 2022 at 17:54
  • \$\begingroup\$ Hm, you wrote an answer and accepted it. But I don't see the changed code and no waveform showing that the code change still needs an additional clock. \$\endgroup\$ Commented Oct 21, 2022 at 6:31
  • \$\begingroup\$ The delay that you said doesn't solve the problem on my computer.That's why i didn't changed the code. \$\endgroup\$ Commented Oct 22, 2022 at 9:08
2
\$\begingroup\$

It seems it's a problem of my computer/problem of Xilinx that there is a delay on some signals. I guess it's a problem of the software (Xilinx suite), because when I ran it on a lab's computer it was working fine.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.