Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Induced delay

Altera_Forum
Honored Contributor II
2,745 Views

I have just started learning how to use VHDL and Quartus and I use it for a Cyclone II FPGA. 

 

I need to write a code , which makes my Output High after a fixed time interval , 60 seconds for example. 

Thus I wrote the following code for the same, however it gives me a warning that my Output pins are stuck at VCC and therefore the the Output ( an LED ) , which is ideally supposed to be OFF and glow only after 60 seconds, is always ON. 

 

I also tried using a wait for 60 seconds statement, however that gives me a Wait statement error, saying that at WAIT UNTIL is required. 

 

 

--------------------- 

The code is  

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.numeric_std.all; 

 

 

entity timer is 

port ( q : buffer bit := '0'); 

end entity; 

 

 

architecture behaviour of timer is 

begin 

 

 

q <= '1' after 60 sec; 

 

 

end behaviour;
0 Kudos
25 Replies
Altera_Forum
Honored Contributor II
1,434 Views

Hi shbhuk, 

 

To provide a delay,you need to use the counter.Counter can divide the frequency and you should use the divided frequency to provide delay.The code you have written can work in simulation.But when you synthesize it "after" 

 

keyword will be ignored by the synthesis tool and that is why value of q will remain 1. 

 

Regards, 

 

Krupesh
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

Thank you, will work on the frequency divider now then.

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

For a timer of 20 seconds. 

 

I wrote the following code, however the code still gives me the OUTPUT as always high. 

 

The clock used is 50 MHz ( 20 ns ) and therefore I seek to count till 10^9 to obtain 20 seconds. 

 

 

Below is the code -  

--------------------------------------- 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.numeric_std.all; 

 

entity timer is 

port ( clk : in std_logic ; q : buffer bit ); 

end entity; 

 

architecture Behavioral of timer is 

begin 

 

process(clk) 

variable cnt, cnt1: integer range 0 to 10**9 := 0 ; 

constant int: integer := (10**6)+1 ; 

 

begin 

 

if rising_edge(clk) then cnt := (cnt + 1)mod int; 

 

if cnt = 10**6 then cnt1 := (cnt1 + 1) mod 1001; 

 

end if; 

end if; 

 

 

if cnt1 = 1000 then q <= '1' ;  

 

end if ; 

end process; 

end behavioral; 

 

Please help.
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

this will be very expensive in hardware, and timing will be rather slow because of use of the mod function (which is essentially a divider)

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

I will be using an FPGA ( Cyclone II ) , what would you recommend instead ? 

 

The timer works as a timed preset for a counter in turn.
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

There's no point in using mod function: test when the counter reaches the divider value and then reset it. 

 

if rising_edge(clk) then  

if cnt = int 

cnt := 0; 

else 

cnt:= (cnt + 1); 

end if; 

end if; 

 

Same for cnt1
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

You can use simple 16 or 32 bit counter and output of this counter can be assigned to your output.For example,we can divide a frequency by 8 using 3 bit counter.You can assign msb of counter to your output which will stay high for four clock cycle and low for four clock cycle.

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

 

--- Quote Start ---  

You can use simple 16 or 32 bit counter and output of this counter can be assigned to your output.For example,we can divide a frequency by 8 using 3 bit counter.You can assign msb of counter to your output which will stay high for four clock cycle and low for four clock cycle. 

--- Quote End ---  

 

 

 

The problem with that would be the low frequency I require .  

My final time requirement ranges from 30 sec to 30 minutes. 

 

 

 

 

 

 

 

I changed the code to the following , which still gives OUTPUT as always HIGH. 

 

 

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.numeric_std.all; 

use ieee.std_logic_unsigned.all; 

 

entity timernew is 

port (clk : in std_logic;  

flag : out std_logic:='0' ); 

end timernew; 

 

architecture behavioral of timernew is 

begin 

 

process(clk) 

variable count : integer:=0; 

variable count1: integer:=0; 

constant int: integer :=(10**6); 

 

begin 

if(clk'event and clk='1') then 

count := count +1; --increment counter. 

end if; 

 

if count = int then  

count := 0; 

else 

count := count + 1; 

end if; 

 

if count1 > 1000 then flag <= '1' ; 

end if; 

 

 

 

end process; 

 

end behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

I think your count1 variable is not incremented.You should try count instead of count1.

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

There are 3 major errors: 

- You increment count twice and count1 never. 

- When count1>1000 you also need to reset count1 to 0 in addition to setting flag output. 

- You set flag output but never reset it
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

I rectified the error. 

Now however, when I run the code on the FPGA , even though according to the code the LED should light up after 20 seconds, the LED is lit from the beginning.
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

The new code is -  

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

 

entity timernew is 

port (clk : in std_logic;  

flag : out std_logic := '0' ); 

end timernew; 

 

architecture Behavioral of timernew is 

begin 

 

process(clk) 

variable count : integer:=0; 

variable count1: integer:=0; 

constant int: integer :=(10**6); 

 

begin 

if(clk'event and clk='1') then 

count := count +1; --increment counter. 

 

if count = int then  

count := 0; 

else 

count1 := count1 + 1; 

 

if count1 > 1000 then flag <= '1' ; 

end if; 

end if; 

end if; 

 

 

end process; 

 

end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

Do the counters create registers? Check the RTL schematic. You have used a variable after updating it, which usually risks the synthesisor not creating a register for it. The best way to avoid this as a beginner is to always use signals, never variables.

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

I changed the variables to signals, however still the LED glows instantaneously rather than waiting for 20 seconds and glowing. 

 

 

Is the structure of the IF statements correct ( Nested or not ) .
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

Try changing 

if count1 > 1000 then flag <= '1' ; 

with 

if count1 > 1000 then flag <= '1' ; 

else flag <= '0' ; 

 

Did you assign the flag signal to the correct fpga pin?
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

Changed as asked above. 

Also , pin assigned correctly.  

Still problem persists.  

 

Please help.
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

have you got a testbench?

0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

No test bench.  

Any idea regarding what could possibly be the source of error ?
0 Kudos
Altera_Forum
Honored Contributor II
1,434 Views

How about I use a wait until count = 10**9; ?

0 Kudos
Altera_Forum
Honored Contributor II
1,353 Views

You would find the error more easily with a testbench.

0 Kudos
Reply